From 4f3682f382d645a57e75e7cb975ae9e54ba5a06b Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Thu, 21 May 2026 10:26:21 +0100 Subject: [PATCH 01/13] feat(txe): add TXE oracle version check to bootstrap (#23324) --- yarn-project/bootstrap.sh | 4 +- yarn-project/pxe/package.json | 3 +- .../pxe/src/bin/check_oracle_version.ts | 66 +++++++++++-------- yarn-project/pxe/src/bin/index.ts | 1 + yarn-project/txe/package.json | 3 +- .../txe/src/bin/check_txe_oracle_version.ts | 37 +++++++++++ yarn-project/txe/src/txe_oracle_version.ts | 8 +++ 7 files changed, 91 insertions(+), 31 deletions(-) create mode 100644 yarn-project/pxe/src/bin/index.ts create mode 100644 yarn-project/txe/src/bin/check_txe_oracle_version.ts diff --git a/yarn-project/bootstrap.sh b/yarn-project/bootstrap.sh index d263e662de9c..140dd2c6ca78 100755 --- a/yarn-project/bootstrap.sh +++ b/yarn-project/bootstrap.sh @@ -143,9 +143,11 @@ function compile_all { get_projects | compile_project - # Run oracle version check for pxe after compilation + # Run oracle version checks after compilation cd pxe && yarn check_oracle_version cd .. + cd txe && yarn check_txe_oracle_version + cd .. cmds=('format --check' 'yarn tsgo -b --emitDeclarationOnly') if [ "${CI:-0}" -eq 1 ]; then diff --git a/yarn-project/pxe/package.json b/yarn-project/pxe/package.json index 0cfaf010e6e8..35908adc42f2 100644 --- a/yarn-project/pxe/package.json +++ b/yarn-project/pxe/package.json @@ -16,7 +16,8 @@ "./client/lazy": "./dest/entrypoints/client/lazy/index.js", "./client/bundle": "./dest/entrypoints/client/bundle/index.js", "./simulator": "./dest/contract_function_simulator/index.js", - "./config": "./dest/config/index.js" + "./config": "./dest/config/index.js", + "./bin": "./dest/bin/index.js" }, "bin": "./dest/bin/index.js", "scripts": { diff --git a/yarn-project/pxe/src/bin/check_oracle_version.ts b/yarn-project/pxe/src/bin/check_oracle_version.ts index 1393d7df640e..cf45050592cf 100644 --- a/yarn-project/pxe/src/bin/check_oracle_version.ts +++ b/yarn-project/pxe/src/bin/check_oracle_version.ts @@ -16,27 +16,8 @@ import { ORACLE_INTERFACE_HASH } from '../oracle_version.js'; * changed and the oracle version needs to be bumped: * - If the change is backward-breaking (e.g. removing/renaming an oracle), bump ORACLE_VERSION_MAJOR. * - If the change is an oracle addition (non-breaking), bump ORACLE_VERSION_MINOR. - * - * TODO(F-667): The following only takes into consideration changes to the oracles defined in Oracle.ts and omits TXE - * oracles. Ensure this checks TXE oracles as well. This hasn't been implemented yet since we don't have a clean TXE - * oracle interface like we do in PXE (i.e., there is no single Oracle class that contains only the oracles). */ function assertOracleInterfaceMatches(): void { - const oracleInterfaceSignature = getOracleInterfaceSignature(); - - // We use keccak256 here just because we already have it in the dependencies. - const oracleInterfaceHash = keccak256String(oracleInterfaceSignature); - if (oracleInterfaceHash !== ORACLE_INTERFACE_HASH) { - throw new Error( - `The Oracle interface has changed. Update ORACLE_INTERFACE_HASH to ${oracleInterfaceHash} in pxe/src/oracle_version.ts and bump the oracle version (ORACLE_VERSION_MAJOR for breaking changes, ORACLE_VERSION_MINOR for oracle additions).`, - ); - } -} - -/** - * Constructs a signature of the Oracle interface while ignoring methods that are not foreign call handlers. - */ -function getOracleInterfaceSignature(): string { const excludedProps = [ 'handler', 'constructor', @@ -44,7 +25,7 @@ function getOracleInterfaceSignature(): string { 'handlerAsMisc', 'handlerAsUtility', 'handlerAsPrivate', - ] as const; + ]; // Get the path to Oracle.ts source file // The script runs from dest/bin/ after compilation, so we need to go up to the package root @@ -54,23 +35,52 @@ function getOracleInterfaceSignature(): string { const packageRoot = dirname(dirname(currentDir)); // Go up from bin/ to pxe/ const oracleSourcePath = join(packageRoot, 'src/contract_function_simulator/oracle/oracle.ts'); + const oracleInterfaceSignature = getOracleInterfaceSignature(oracleSourcePath, ['Oracle'], excludedProps); + + // We use keccak256 here just because we already have it in the dependencies. + const oracleInterfaceHash = keccak256String(oracleInterfaceSignature); + if (oracleInterfaceHash !== ORACLE_INTERFACE_HASH) { + throw new Error( + `The Oracle interface has changed. Update ORACLE_INTERFACE_HASH to ${oracleInterfaceHash} in pxe/src/oracle_version.ts and bump the oracle version (ORACLE_VERSION_MAJOR for breaking changes, ORACLE_VERSION_MINOR for oracle additions).`, + ); + } +} + +/** + * Extracts method signatures from TypeScript classes or interfaces and returns a deterministic string representation. + * + * This is used to detect when an oracle interface changes so that the oracle version can be bumped. It works with both + * class declarations (e.g. PXE's `Oracle` class) and interface declarations (e.g. TXE's `IAvmExecutionOracle`). + * + * @param sourcePath - Absolute path to the TypeScript source file to parse. + * @param targets - Names of classes or interfaces to extract methods from. + * @param excludedMembers - Method names to skip (e.g. non-oracle helpers like `constructor`). + */ +export function getOracleInterfaceSignature(sourcePath: string, targets: string[], excludedMembers: string[]): string { // Read and parse the TypeScript source file - const sourceCode = readFileSync(oracleSourcePath, 'utf-8'); - const sourceFile = ts.createSourceFile('oracle.ts', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS); + const sourceCode = readFileSync(sourcePath, 'utf-8'); + const sourceFile = ts.createSourceFile(sourcePath, sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS); - // Extract method signatures from the Oracle class + // Extract method signatures from the target classes/interfaces const methodSignatures: string[] = []; function visit(node: ts.Node) { - // Look for class declaration named "Oracle" - if (ts.isClassDeclaration(node) && node.name?.text === 'Oracle') { - // Visit all members of the class + // Look for class or interface declarations matching the target names + const isTarget = + (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && targets.includes(node.name?.text ?? ''); + + if (isTarget) { + // Visit all members of the class/interface node.members.forEach(member => { - if (ts.isMethodDeclaration(member) && member.name && ts.isIdentifier(member.name)) { + if ( + (ts.isMethodDeclaration(member) || ts.isMethodSignature(member)) && + member.name && + ts.isIdentifier(member.name) + ) { const methodName = member.name.text; // Skip excluded methods - if (excludedProps.includes(methodName as (typeof excludedProps)[number])) { + if (excludedMembers.includes(methodName)) { return; } diff --git a/yarn-project/pxe/src/bin/index.ts b/yarn-project/pxe/src/bin/index.ts new file mode 100644 index 000000000000..bda0bdc9d99b --- /dev/null +++ b/yarn-project/pxe/src/bin/index.ts @@ -0,0 +1 @@ +export { getOracleInterfaceSignature } from './check_oracle_version.js'; diff --git a/yarn-project/txe/package.json b/yarn-project/txe/package.json index db43d45ef508..913283c72c0a 100644 --- a/yarn-project/txe/package.json +++ b/yarn-project/txe/package.json @@ -17,7 +17,8 @@ "clean": "rm -rf ./dest .tsbuildinfo", "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}", "dev": "LOG_LEVEL=\"debug; trace: simulator:state_manager; info: json-rpc:proxy\" node ./dest/bin/index.js", - "start": "node --no-warnings ./dest/bin/index.js" + "start": "node --no-warnings ./dest/bin/index.js", + "check_txe_oracle_version": "node ./dest/bin/check_txe_oracle_version.js" }, "inherits": [ "../package.common.json" diff --git a/yarn-project/txe/src/bin/check_txe_oracle_version.ts b/yarn-project/txe/src/bin/check_txe_oracle_version.ts new file mode 100644 index 000000000000..889b48f912ab --- /dev/null +++ b/yarn-project/txe/src/bin/check_txe_oracle_version.ts @@ -0,0 +1,37 @@ +import { keccak256String } from '@aztec/foundation/crypto/keccak'; +import { getOracleInterfaceSignature } from '@aztec/pxe/bin'; + +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +import { TXE_ORACLE_INTERFACE_HASH } from '../txe_oracle_version.js'; + +/** + * Verifies that the TXE oracle interfaces match the expected interface hash. + * + * The TXE oracle interfaces need to be versioned to ensure compatibility between Aztec.nr tests and TXE. This function + * computes a hash of the TXE oracle interfaces and compares it against a known hash. If they don't match, it means an + * interface has changed and the TXE oracle version needs to be bumped: + * - If the change is backward-breaking (e.g. removing/renaming an oracle), bump TXE_ORACLE_VERSION_MAJOR. + * - If the change is an oracle addition (non-breaking), bump TXE_ORACLE_VERSION_MINOR. + */ +function assertTxeOracleInterfaceMatches(): void { + const currentDir = dirname(fileURLToPath(import.meta.url)); + const packageRoot = dirname(dirname(currentDir)); + const interfacesSourcePath = join(packageRoot, 'src/oracle/interfaces.ts'); + + const targets = ['IAvmExecutionOracle', 'ITxeExecutionOracle']; + // Not an oracle foreign call handler (see TODO(F-335) in interfaces.ts). + const excludedMembers = ['syncContractNonOracleMethod']; + + const txeOracleInterfaceSignature = getOracleInterfaceSignature(interfacesSourcePath, targets, excludedMembers); + + const txeOracleInterfaceHash = keccak256String(txeOracleInterfaceSignature); + if (txeOracleInterfaceHash !== TXE_ORACLE_INTERFACE_HASH) { + throw new Error( + `The TXE oracle interface has changed. Update TXE_ORACLE_INTERFACE_HASH to ${txeOracleInterfaceHash} in txe/src/txe_oracle_version.ts and bump the TXE oracle version (TXE_ORACLE_VERSION_MAJOR for breaking changes, TXE_ORACLE_VERSION_MINOR for oracle additions).`, + ); + } +} + +assertTxeOracleInterfaceMatches(); diff --git a/yarn-project/txe/src/txe_oracle_version.ts b/yarn-project/txe/src/txe_oracle_version.ts index ae8712abb4c0..45d43f2be6a1 100644 --- a/yarn-project/txe/src/txe_oracle_version.ts +++ b/yarn-project/txe/src/txe_oracle_version.ts @@ -7,3 +7,11 @@ */ export const TXE_ORACLE_VERSION_MAJOR = 1; export const TXE_ORACLE_VERSION_MINOR = 0; + +/** + * This hash is computed from the TXE oracle interfaces (IAvmExecutionOracle and ITxeExecutionOracle) and is used to + * detect when those interfaces change. When it does, bump: + * - TXE_ORACLE_VERSION_MAJOR (and reset MINOR to 0) for breaking changes, or + * - TXE_ORACLE_VERSION_MINOR for additive changes (new oracle method added). + */ +export const TXE_ORACLE_INTERFACE_HASH = '6ab5922a46d54edc4e1f10d6bd734bd35d8e6dff0dd2660091d25af55563f68a'; From 7f674bb1f8f950438753f6ffd269b913baebba69 Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Thu, 21 May 2026 06:25:23 -0400 Subject: [PATCH 02/13] fix(txe): correct TXE_ORACLE_INTERFACE_HASH to match current oracle interface (#23460) --- yarn-project/txe/src/txe_oracle_version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/txe/src/txe_oracle_version.ts b/yarn-project/txe/src/txe_oracle_version.ts index 45d43f2be6a1..4c3b67b711c9 100644 --- a/yarn-project/txe/src/txe_oracle_version.ts +++ b/yarn-project/txe/src/txe_oracle_version.ts @@ -14,4 +14,4 @@ export const TXE_ORACLE_VERSION_MINOR = 0; * - TXE_ORACLE_VERSION_MAJOR (and reset MINOR to 0) for breaking changes, or * - TXE_ORACLE_VERSION_MINOR for additive changes (new oracle method added). */ -export const TXE_ORACLE_INTERFACE_HASH = '6ab5922a46d54edc4e1f10d6bd734bd35d8e6dff0dd2660091d25af55563f68a'; +export const TXE_ORACLE_INTERFACE_HASH = 'c5e3567b08790c8181254c0831de6b5af49e221e14d36dded3fc5d8787fba482'; From 0b78738da6c0fcba85f2796517f39706b7d3e78f Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Thu, 21 May 2026 12:09:19 +0100 Subject: [PATCH 03/13] feat(aztec-nr): add Serialize/Deserialize for EphemeralArray (#23417) --- .../aztec-nr/aztec/src/ephemeral/mod.nr | 29 ++++++++++++++++ .../aztec/src/messages/processing/mod.nr | 4 +-- .../aztec/src/oracle/message_processing.nr | 34 ++++++++++--------- .../aztec/src/oracle/shared_secret.nr | 7 ++-- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr b/noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr index 9e4efde8cd5a..35be7114e025 100644 --- a/noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr @@ -1,5 +1,6 @@ use crate::oracle::ephemeral; use crate::protocol::traits::{Deserialize, Serialize}; +use crate::protocol::utils::{reader::Reader, writer::Writer}; /// A dynamically sized array that exists only during a single contract call frame. /// @@ -101,6 +102,34 @@ impl EphemeralArray { } } +/// Serializes an `EphemeralArray` as its slot identifier, allowing oracle function signatures to use +/// `EphemeralArray` instead of opaque `Field` slots. +impl Serialize for EphemeralArray { + let N: u32 = 1; + + fn serialize(self) -> [Field; Self::N] { + [self.slot] + } + + fn stream_serialize(self, writer: &mut Writer) { + writer.write(self.slot); + } +} + +/// Deserializes a single Field into an `EphemeralArray` handle, treating the field value as the slot identifier. +/// This is the inverse of [`Serialize`]. +impl Deserialize for EphemeralArray { + let N: u32 = 1; + + fn deserialize(fields: [Field; Self::N]) -> Self { + Self { slot: fields[0] } + } + + fn stream_deserialize(reader: &mut Reader) -> Self { + Self { slot: reader.read() } + } +} + mod test { use crate::test::helpers::test_environment::TestEnvironment; use crate::test::mocks::MockStruct; diff --git a/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr b/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr index a793fe5df64f..df716e43ccbe 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr @@ -137,8 +137,8 @@ pub unconstrained fn enqueue_event_for_validation( /// API (PXE::getPrivateEvents). pub unconstrained fn validate_and_store_enqueued_notes_and_events(scope: AztecAddress) { message_processing::validate_and_store_enqueued_notes_and_events( - NOTE_VALIDATION_REQUESTS_ARRAY_BASE_SLOT, - EVENT_VALIDATION_REQUESTS_ARRAY_BASE_SLOT, + EphemeralArray::at(NOTE_VALIDATION_REQUESTS_ARRAY_BASE_SLOT), + EphemeralArray::at(EVENT_VALIDATION_REQUESTS_ARRAY_BASE_SLOT), MAX_NOTE_PACKED_LEN as Field, MAX_EVENT_SERIALIZED_LEN as Field, scope, diff --git a/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr b/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr index 7a2f2f5a666d..876f55dd9e96 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr @@ -1,7 +1,8 @@ use crate::ephemeral::EphemeralArray; use crate::messages::processing::{ + event_validation_request::EventValidationRequest, log_retrieval_request::LogRetrievalRequest, log_retrieval_response::LogRetrievalResponse, MessageContext, - pending_tagged_log::PendingTaggedLog, + NoteValidationRequest, pending_tagged_log::PendingTaggedLog, }; use crate::protocol::address::AztecAddress; use crate::protocol::blob_data::TxEffect; @@ -9,24 +10,23 @@ use crate::protocol::blob_data::TxEffect; /// Finds new private logs that may have been sent to all registered accounts in PXE in the current contract and /// returns them in an ephemeral array with an oracle-allocated base slot. pub(crate) unconstrained fn get_pending_tagged_logs(scope: AztecAddress) -> EphemeralArray { - let result_slot = get_pending_tagged_logs_oracle(scope); - EphemeralArray::at(result_slot) + get_pending_tagged_logs_oracle(scope) } #[oracle(aztec_utl_getPendingTaggedLogs)] -unconstrained fn get_pending_tagged_logs_oracle(scope: AztecAddress) -> Field {} +unconstrained fn get_pending_tagged_logs_oracle(scope: AztecAddress) -> EphemeralArray {} /// Validates note/event requests stored in ephemeral arrays. pub(crate) unconstrained fn validate_and_store_enqueued_notes_and_events( - note_validation_requests_array_slot: Field, - event_validation_requests_array_slot: Field, + note_validation_requests: EphemeralArray, + event_validation_requests: EphemeralArray, max_note_packed_len: Field, max_event_serialized_len: Field, scope: AztecAddress, ) { validate_and_store_enqueued_notes_and_events_oracle( - note_validation_requests_array_slot, - event_validation_requests_array_slot, + note_validation_requests, + event_validation_requests, max_note_packed_len, max_event_serialized_len, scope, @@ -35,8 +35,8 @@ pub(crate) unconstrained fn validate_and_store_enqueued_notes_and_events( #[oracle(aztec_utl_validateAndStoreEnqueuedNotesAndEvents)] unconstrained fn validate_and_store_enqueued_notes_and_events_oracle( - note_validation_requests_array_slot: Field, - event_validation_requests_array_slot: Field, + note_validation_requests: EphemeralArray, + event_validation_requests: EphemeralArray, max_note_packed_len: Field, max_event_serialized_len: Field, scope: AztecAddress, @@ -46,23 +46,25 @@ unconstrained fn validate_and_store_enqueued_notes_and_events_oracle( pub(crate) unconstrained fn get_logs_by_tag( requests: EphemeralArray, ) -> EphemeralArray> { - let response_slot = get_logs_by_tag_oracle(requests.slot); - EphemeralArray::at(response_slot) + get_logs_by_tag_oracle(requests) } #[oracle(aztec_utl_getLogsByTag)] -unconstrained fn get_logs_by_tag_oracle(request_array_slot: Field) -> Field {} +unconstrained fn get_logs_by_tag_oracle( + requests: EphemeralArray, +) -> EphemeralArray> {} /// Resolves message contexts for tx hashes in an ephemeral request array and returns a response ephemeral array. pub(crate) unconstrained fn get_message_contexts_by_tx_hash( requests: EphemeralArray, ) -> EphemeralArray> { - let response_slot = get_message_contexts_by_tx_hash_oracle(requests.slot); - EphemeralArray::at(response_slot) + get_message_contexts_by_tx_hash_oracle(requests) } #[oracle(aztec_utl_getMessageContextsByTxHash)] -unconstrained fn get_message_contexts_by_tx_hash_oracle(request_array_slot: Field) -> Field {} +unconstrained fn get_message_contexts_by_tx_hash_oracle( + requests: EphemeralArray, +) -> EphemeralArray> {} /// Fetches all effects of a settled transaction by its hash. pub unconstrained fn get_tx_effect(tx_hash: Field) -> Option { diff --git a/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr b/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr index 4785328f9d71..cbcd9390d71a 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr @@ -7,9 +7,9 @@ global GET_SHARED_SECRETS_REQUEST_SLOT: Field = #[oracle(aztec_utl_getSharedSecrets)] unconstrained fn get_shared_secrets_oracle( address: AztecAddress, - eph_pks_slot: Field, + eph_pks: EphemeralArray, contract_address: AztecAddress, -) -> Field {} +) -> EphemeralArray {} /// Convenience wrapper around [`get_shared_secrets`] for a single ephemeral public key. pub unconstrained fn get_shared_secret( @@ -48,8 +48,7 @@ pub unconstrained fn get_shared_secrets( EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT).clear(); eph_pks.for_each(|pk| request_array.push(pk)); - let response_slot = get_shared_secrets_oracle(address, request_array.slot, contract_address); - let response_array: EphemeralArray = EphemeralArray::at(response_slot); + let response_array = get_shared_secrets_oracle(address, request_array, contract_address); assert( response_array.len() == eph_pks.len(), "get_shared_secrets: response length does not match request length", From e2a3ae3a8785e1658dafde95fd1686efdd7fc2de Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Thu, 21 May 2026 14:33:36 +0100 Subject: [PATCH 04/13] refactor: move validation and error handling out of transport layer (#23422) = --- .../oracle/interfaces.ts | 20 +- .../oracle/oracle.ts | 32 +--- .../oracle/utility_execution_oracle.ts | 68 +++++-- yarn-project/txe/src/constants.ts | 6 + yarn-project/txe/src/oracle/interfaces.ts | 5 + .../src/oracle/txe_oracle_public_context.ts | 30 +++ .../oracle/txe_oracle_top_level_context.ts | 13 +- .../oracle/txe_private_execution_oracle.ts | 30 +++ yarn-project/txe/src/rpc_translator.ts | 173 ++++++++---------- yarn-project/txe/src/txe_session.ts | 37 +++- 10 files changed, 240 insertions(+), 174 deletions(-) create mode 100644 yarn-project/txe/src/oracle/txe_private_execution_oracle.ts diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/interfaces.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/interfaces.ts index 17a165e6babe..0d18d9ed747c 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/interfaces.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/interfaces.ts @@ -70,25 +70,19 @@ export interface IUtilityExecutionOracle { getNoteHashMembershipWitness( anchorBlockHash: BlockHash, noteHash: Fr, - ): Promise | undefined>; + ): Promise>; getBlockHashMembershipWitness( anchorBlockHash: BlockHash, blockHash: BlockHash, ): Promise | undefined>; - getNullifierMembershipWitness( - anchorBlockHash: BlockHash, - nullifier: Fr, - ): Promise; - getPublicDataWitness(anchorBlockHash: BlockHash, leafSlot: Fr): Promise; - getLowNullifierMembershipWitness( - anchorBlockHash: BlockHash, - nullifier: Fr, - ): Promise; - getBlockHeader(blockNumber: BlockNumber): Promise; + getNullifierMembershipWitness(anchorBlockHash: BlockHash, nullifier: Fr): Promise; + getPublicDataWitness(anchorBlockHash: BlockHash, leafSlot: Fr): Promise; + getLowNullifierMembershipWitness(anchorBlockHash: BlockHash, nullifier: Fr): Promise; + getBlockHeader(blockNumber: BlockNumber): Promise; getPublicKeysAndPartialAddress( account: AztecAddress, ): Promise<{ publicKeys: PublicKeys; partialAddress: PartialAddress } | undefined>; - getAuthWitness(messageHash: Fr): Promise; + getAuthWitness(messageHash: Fr): Promise; getNotes( owner: AztecAddress | undefined, storageSlot: Fr, @@ -139,7 +133,7 @@ export interface IUtilityExecutionOracle { numEntries: number, scope: AztecAddress, ): Promise; - decryptAes128(ciphertext: Buffer, iv: Buffer, symKey: Buffer): Promise; + decryptAes128(ciphertext: Buffer, iv: Buffer, symKey: Buffer): Promise; getSharedSecrets(address: AztecAddress, ephPksSlot: Fr, contractAddress: AztecAddress): Promise; setContractSyncCacheInvalid(contractAddress: AztecAddress, scopes: AztecAddress[]): void; emitOffchainEffect(data: Fr[]): Promise; diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts index 670d2bdc86b1..0a3fffe870bf 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts @@ -238,11 +238,6 @@ export class Oracle { const parsedNoteHash = Fr.fromString(noteHash); const witness = await this.handlerAsUtility().getNoteHashMembershipWitness(parsedAnchorBlockHash, parsedNoteHash); - if (!witness) { - throw new Error( - `Note hash ${noteHash} not found in the note hash tree at anchor block hash ${parsedAnchorBlockHash.toString()}.`, - ); - } return witness.toNoirRepresentation(); } @@ -268,11 +263,6 @@ export class Oracle { const parsedNullifier = Fr.fromString(nullifier); const witness = await this.handlerAsUtility().getNullifierMembershipWitness(parsedBlockHash, parsedNullifier); - if (!witness) { - throw new Error( - `Nullifier witness not found for nullifier ${parsedNullifier} at block hash ${parsedBlockHash.toString()}.`, - ); - } return witness.toNoirRepresentation(); } @@ -285,11 +275,6 @@ export class Oracle { const parsedNullifier = Fr.fromString(nullifier); const witness = await this.handlerAsUtility().getLowNullifierMembershipWitness(parsedBlockHash, parsedNullifier); - if (!witness) { - throw new Error( - `Low nullifier witness not found for nullifier ${parsedNullifier} at block hash ${parsedBlockHash.toString()}.`, - ); - } return witness.toNoirRepresentation(); } @@ -302,11 +287,6 @@ export class Oracle { const parsedLeafSlot = Fr.fromString(leafSlot); const witness = await this.handlerAsUtility().getPublicDataWitness(parsedBlockHash, parsedLeafSlot); - if (!witness) { - throw new Error( - `Public data witness not found for slot ${parsedLeafSlot} at block hash ${parsedBlockHash.toString()}.`, - ); - } return witness.toNoirRepresentation(); } @@ -315,9 +295,6 @@ export class Oracle { const parsedBlockNumber = Fr.fromString(blockNumber).toNumber(); const header = await this.handlerAsUtility().getBlockHeader(BlockNumber(parsedBlockNumber)); - if (!header) { - throw new Error(`Block header not found for block ${parsedBlockNumber}.`); - } return header.toFields().map(toACVMField); } @@ -325,9 +302,6 @@ export class Oracle { async aztec_utl_getAuthWitness([messageHash]: ACVMField[]): Promise { const messageHashField = Fr.fromString(messageHash); const witness = await this.handlerAsUtility().getAuthWitness(messageHashField); - if (!witness) { - throw new Error(`Unknown auth witness for message hash ${messageHashField}`); - } return [witness.map(toACVMField)]; } @@ -782,11 +756,11 @@ export class Oracle { const symKeyBuffer = fromUintArray(symKey, 8); // Noir Option is encoded as [is_some: Field, storage: Field[], length: Field]. - try { - const plaintext = await this.handlerAsUtility().decryptAes128(ciphertext, ivBuffer, symKeyBuffer); + const plaintext = await this.handlerAsUtility().decryptAes128(ciphertext, ivBuffer, symKeyBuffer); + if (plaintext) { const [storage, length] = bufferToBoundedVec(plaintext, ciphertextBVecStorage.length); return [toACVMField(1), storage, length]; - } catch { + } else { const zeroStorage = Array(ciphertextBVecStorage.length).fill(toACVMField(0)); return [toACVMField(0), zeroStorage, toACVMField(0)]; } diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts index 14b728ce67b4..27f789b4dff9 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts @@ -201,13 +201,19 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra * @param noteHash - The note hash to find in the note hash tree. * @returns The membership witness containing the leaf index and sibling path */ - public getNoteHashMembershipWitness( + public async getNoteHashMembershipWitness( blockHash: BlockHash, noteHash: Fr, - ): Promise | undefined> { - return this.#queryWithBlockHashNotAfterAnchor(blockHash, () => + ): Promise> { + const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () => this.aztecNode.getNoteHashMembershipWitness(blockHash, noteHash), ); + if (!witness) { + throw new Error( + `Note hash ${noteHash} not found in the note hash tree at anchor block hash ${blockHash.toString()}.`, + ); + } + return witness; } /** @@ -239,13 +245,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra * @param nullifier - Nullifier we try to find witness for. * @returns The nullifier membership witness (if found). */ - public getNullifierMembershipWitness( - blockHash: BlockHash, - nullifier: Fr, - ): Promise { - return this.#queryWithBlockHashNotAfterAnchor(blockHash, () => + public async getNullifierMembershipWitness(blockHash: BlockHash, nullifier: Fr): Promise { + const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () => this.aztecNode.getNullifierMembershipWitness(blockHash, nullifier), ); + if (!witness) { + throw new Error(`Nullifier witness not found for nullifier ${nullifier} at block hash ${blockHash.toString()}.`); + } + return witness; } /** @@ -257,13 +264,19 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra * list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier * we are trying to prove non-inclusion for. */ - public getLowNullifierMembershipWitness( + public async getLowNullifierMembershipWitness( blockHash: BlockHash, nullifier: Fr, - ): Promise { - return this.#queryWithBlockHashNotAfterAnchor(blockHash, () => + ): Promise { + const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () => this.aztecNode.getLowNullifierMembershipWitness(blockHash, nullifier), ); + if (!witness) { + throw new Error( + `Low nullifier witness not found for nullifier ${nullifier} at block hash ${blockHash.toString()}.`, + ); + } + return witness; } /** @@ -272,10 +285,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra * @param leafSlot - The slot of the public data tree to get the witness for. * @returns - The witness */ - public getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise { - return this.#queryWithBlockHashNotAfterAnchor(blockHash, () => + public async getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise { + const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () => this.aztecNode.getPublicDataWitness(blockHash, leafSlot), ); + if (!witness) { + throw new Error(`Public data witness not found for slot ${leafSlot} at block hash ${blockHash.toString()}.`); + } + return witness; } /** @@ -283,7 +300,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra * @param blockNumber - The number of a block of which to get the block header. * @returns Block extracted from a block with block number `blockNumber`. */ - public async getBlockHeader(blockNumber: BlockNumber): Promise { + public async getBlockHeader(blockNumber: BlockNumber): Promise { const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber(); if (blockNumber > anchorBlockNumber) { throw new Error(`Block number ${blockNumber} is higher than current block ${anchorBlockNumber}`); @@ -295,7 +312,10 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra } const block = await this.aztecNode.getBlock(blockNumber); - return block?.header; + if (!block?.header) { + throw new Error(`Block header not found for block ${blockNumber}.`); + } + return block.header; } /** @@ -342,8 +362,12 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra * @param messageHash - Hash of the message to authenticate. * @returns Authentication witness for the requested message hash, or undefined if not found. */ - public getAuthWitness(messageHash: Fr): Promise { - return Promise.resolve(this.authWitnesses.find(w => w.requestHash.equals(messageHash))?.witness); + public getAuthWitness(messageHash: Fr): Promise { + const witness = this.authWitnesses.find(w => w.requestHash.equals(messageHash))?.witness; + if (!witness) { + throw new Error(`Unknown auth witness for message hash ${messageHash}`); + } + return Promise.resolve(witness); } /** @@ -671,9 +695,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra } // TODO(#11849): consider replacing this oracle with a pure Noir implementation of aes decryption. - public decryptAes128(ciphertext: Buffer, iv: Buffer, symKey: Buffer): Promise { - const aes128 = new Aes128(); - return aes128.decryptBufferCBC(ciphertext, iv, symKey); + public async decryptAes128(ciphertext: Buffer, iv: Buffer, symKey: Buffer): Promise { + try { + const aes128 = new Aes128(); + return await aes128.decryptBufferCBC(ciphertext, iv, symKey); + } catch { + return undefined; + } } /** diff --git a/yarn-project/txe/src/constants.ts b/yarn-project/txe/src/constants.ts index 24230b9217a4..49307f0e814a 100644 --- a/yarn-project/txe/src/constants.ts +++ b/yarn-project/txe/src/constants.ts @@ -1,3 +1,9 @@ +import { PRIVATE_LOG_CIPHERTEXT_LEN } from '@aztec/constants'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42); + +// Arbitrarily set at 64 because we need a bound. Nothing inherent about it. +export const MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY = 64; +// Must match MAX_OFFCHAIN_EFFECT_LEN in noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr. +export const MAX_OFFCHAIN_EFFECT_LEN = 2 + PRIVATE_LOG_CIPHERTEXT_LEN; diff --git a/yarn-project/txe/src/oracle/interfaces.ts b/yarn-project/txe/src/oracle/interfaces.ts index 0d0ecdc845cc..4ee05b93157b 100644 --- a/yarn-project/txe/src/oracle/interfaces.ts +++ b/yarn-project/txe/src/oracle/interfaces.ts @@ -38,6 +38,11 @@ export interface IAvmExecutionOracle { nullifierExists(siloedNullifier: Fr): Promise; storageWrite(slot: Fr, value: Fr): Promise; storageRead(slot: Fr, contractAddress: AztecAddress): Promise; + returndataSize(): Promise; + returndataCopy(rdOffset: number, copySize: number): Promise; + call(l2Gas: number, daGas: number, address: AztecAddress, argsLength: number, args: Fr[]): Promise; + staticCall(l2Gas: number, daGas: number, address: AztecAddress, argsLength: number, args: Fr[]): Promise; + successCopy(): Promise; } /** diff --git a/yarn-project/txe/src/oracle/txe_oracle_public_context.ts b/yarn-project/txe/src/oracle/txe_oracle_public_context.ts index 3631cc067d69..84e24a696896 100644 --- a/yarn-project/txe/src/oracle/txe_oracle_public_context.ts +++ b/yarn-project/txe/src/oracle/txe_oracle_public_context.ts @@ -122,6 +122,36 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle { return value; } + returndataSize(): Promise { + throw new Error( + 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', + ); + } + + returndataCopy(_rdOffset: number, _copySize: number): Promise { + throw new Error( + 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', + ); + } + + call(_l2Gas: number, _daGas: number, _address: AztecAddress, _argsLength: number, _args: Fr[]): Promise { + throw new Error( + 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', + ); + } + + staticCall(_l2Gas: number, _daGas: number, _address: AztecAddress, _argsLength: number, _args: Fr[]): Promise { + throw new Error( + 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', + ); + } + + successCopy(): Promise { + throw new Error( + 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', + ); + } + async close(): Promise { this.logger.debug('Exiting Public Context, building block with collected side effects', { blockNumber: this.globalVariables.blockNumber, diff --git a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts index 24c1ce0d3239..0b0bf3316f2f 100644 --- a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts +++ b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts @@ -1,4 +1,8 @@ -import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; +import { + CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, + MAX_PRIVATE_LOGS_PER_TX, + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, +} from '@aztec/constants'; import { BlockNumber } from '@aztec/foundation/branded-types'; import { Schnorr } from '@aztec/foundation/crypto/schnorr'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -175,11 +179,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl const txEffects = block!.body.txEffects[0]; + const privateLogs = txEffects.privateLogs; + if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) { + throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`); + } + return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers, - privateLogs: txEffects.privateLogs, + privateLogs, }; } diff --git a/yarn-project/txe/src/oracle/txe_private_execution_oracle.ts b/yarn-project/txe/src/oracle/txe_private_execution_oracle.ts new file mode 100644 index 000000000000..e0dc84d1a163 --- /dev/null +++ b/yarn-project/txe/src/oracle/txe_private_execution_oracle.ts @@ -0,0 +1,30 @@ +import type { Fr } from '@aztec/foundation/curves/bn254'; +import { PrivateExecutionOracle } from '@aztec/pxe/simulator'; +import type { FunctionSelector } from '@aztec/stdlib/abi'; +import type { AztecAddress } from '@aztec/stdlib/aztec-address'; + +/** + * TXE-specific subclass of PrivateExecutionOracle that forbids operations not supported in + * TestEnvironment::private_context. TXE uses dedicated oracle flows (e.g. private_call) instead. + */ +export class TXEPrivateExecutionOracle extends PrivateExecutionOracle { + override callPrivateFunction( + _targetContractAddress: AztecAddress, + _functionSelector: FunctionSelector, + _argsHash: Fr, + _sideEffectCounter: number, + _isStaticCall: boolean, + ): Promise<{ endSideEffectCounter: Fr; returnsHash: Fr }> { + throw new Error( + 'Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead', + ); + } + + override assertValidPublicCalldata(_calldataHash: Fr): Promise { + throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context'); + } + + override notifyRevertiblePhaseStart(_minRevertibleSideEffectCounter: number): Promise { + throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context'); + } +} diff --git a/yarn-project/txe/src/rpc_translator.ts b/yarn-project/txe/src/rpc_translator.ts index bb5fa4b8d356..bef1d2f19ce2 100644 --- a/yarn-project/txe/src/rpc_translator.ts +++ b/yarn-project/txe/src/rpc_translator.ts @@ -5,7 +5,6 @@ import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_LOGS_PER_TX, - PRIVATE_LOG_CIPHERTEXT_LEN, PRIVATE_LOG_SIZE_IN_FIELDS, } from '@aztec/constants'; import { BlockNumber } from '@aztec/foundation/branded-types'; @@ -21,8 +20,8 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { BlockHash } from '@aztec/stdlib/block'; import { GasSettings } from '@aztec/stdlib/gas'; +import { MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY, MAX_OFFCHAIN_EFFECT_LEN } from './constants.js'; import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js'; -import { TXE_ORACLE_VERSION_MAJOR } from './txe_oracle_version.js'; import type { TXESessionStateHandler } from './txe_session.js'; import { type ForeignCallArray, @@ -118,17 +117,7 @@ export class RPCTranslator { const major = fromSingle(foreignMajor).toNumber(); const minor = fromSingle(foreignMinor).toNumber(); - if (major !== TXE_ORACLE_VERSION_MAJOR) { - const hint = - major > TXE_ORACLE_VERSION_MAJOR - ? 'The test was compiled with a newer version of Aztec.nr than your test environment supports. Upgrade your test environment to a compatible version.' - : 'The test was compiled with an older version of Aztec.nr than your test environment supports. Recompile the test with a compatible version of Aztec.nr.'; - throw new Error( - `Incompatible test environment version: ${hint} See https://docs.aztec.network/errors/12 (expected test oracle major version ${TXE_ORACLE_VERSION_MAJOR}, got ${major})`, - ); - } - - this.stateHandler.setTxeOracleVersion({ major, minor }); + this.stateHandler.setTxeOracleVersion(major, minor); return toForeignCallResult([]); } @@ -329,10 +318,6 @@ export class RPCTranslator { async aztec_txe_getLastTxEffects() { const { txHash, noteHashes, nullifiers, privateLogs } = await this.handlerAsTxe().getLastTxEffects(); - if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) { - throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`); - } - // Same workaround as `aztec_txe_getPrivateEvents`: Noir cannot yet return nested structs with arrays, so we return // a flat multidimensional array plus per-log lengths and the total count, and reassemble into a // `BoundedVec>` on the Noir side. Each log contributes only its emitted fields. The rest @@ -364,21 +349,8 @@ export class RPCTranslator { // eslint-disable-next-line camelcase aztec_txe_getLastCallOffchainEffects() { - // This oracle returns all offchain effect payloads (messages, authwit requests, etc.) emitted by the last top-level call, - // MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY is arbitrarily set at 64 because we need a bound. Nothing inherent about it. - const MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY = 64; - // Must match MAX_OFFCHAIN_EFFECT_LEN in txe_oracles.nr. - const MAX_OFFCHAIN_EFFECT_LEN = 2 + PRIVATE_LOG_CIPHERTEXT_LEN; - const { effects } = this.stateHandler.getLastCallOffchainEffects(); - if (effects.length > MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY) { - throw new Error(`${effects.length} offchain effects exceed max ${MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY}`); - } - if (effects.some(e => e.length > MAX_OFFCHAIN_EFFECT_LEN)) { - throw new Error(`Some offchain effect has length larger than max ${MAX_OFFCHAIN_EFFECT_LEN}`); - } - const rawArrayStorage = effects .map(e => e.concat(Array(MAX_OFFCHAIN_EFFECT_LEN - e.length).fill(new Fr(0)))) .concat( @@ -510,10 +482,6 @@ export class RPCTranslator { const leafSlot = fromSingle(foreignLeafSlot); const witness = await this.handlerAsUtility().getPublicDataWitness(blockHash, leafSlot); - - if (!witness) { - throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockHash.toString()}.`); - } return toForeignCallResult(witness.toNoirRepresentation()); } @@ -589,12 +557,10 @@ export class RPCTranslator { }), ); - // Now we convert each sub-array to an array of ForeignCallSingles const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map(subArray => subArray.map(toSingle), ); - // At last we convert the array of arrays to a bounded vec of arrays return toForeignCallResult( arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength), ); @@ -716,16 +682,27 @@ export class RPCTranslator { } // eslint-disable-next-line camelcase - aztec_prv_callPrivateFunction( - _foreignTargetContractAddress: ForeignCallSingle, - _foreignFunctionSelector: ForeignCallSingle, - _foreignArgsHash: ForeignCallSingle, - _foreignSideEffectCounter: ForeignCallSingle, - _foreignIsStaticCall: ForeignCallSingle, + async aztec_prv_callPrivateFunction( + foreignTargetContractAddress: ForeignCallSingle, + foreignFunctionSelector: ForeignCallSingle, + foreignArgsHash: ForeignCallSingle, + foreignSideEffectCounter: ForeignCallSingle, + foreignIsStaticCall: ForeignCallSingle, ) { - throw new Error( - 'Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead', + const targetContractAddress = addressFromSingle(foreignTargetContractAddress); + const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector)); + const argsHash = fromSingle(foreignArgsHash); + const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber(); + const isStaticCall = fromSingle(foreignIsStaticCall).toBool(); + + const { endSideEffectCounter, returnsHash } = await this.handlerAsPrivate().callPrivateFunction( + targetContractAddress, + functionSelector, + argsHash, + sideEffectCounter, + isStaticCall, ); + return toForeignCallResult([[endSideEffectCounter, returnsHash].map(toSingle)]); } // eslint-disable-next-line camelcase @@ -737,10 +714,6 @@ export class RPCTranslator { const nullifier = fromSingle(foreignNullifier); const witness = await this.handlerAsUtility().getNullifierMembershipWitness(blockHash, nullifier); - - if (!witness) { - throw new Error(`Nullifier membership witness not found at block ${blockHash}.`); - } return toForeignCallResult(witness.toNoirRepresentation()); } @@ -749,21 +722,21 @@ export class RPCTranslator { const messageHash = fromSingle(foreignMessageHash); const authWitness = await this.handlerAsUtility().getAuthWitness(messageHash); - - if (!authWitness) { - throw new Error(`Auth witness not found for message hash ${messageHash}.`); - } return toForeignCallResult([toArray(authWitness)]); } // eslint-disable-next-line camelcase - public aztec_prv_assertValidPublicCalldata(_foreignCalldataHash: ForeignCallSingle) { - throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context'); + public async aztec_prv_assertValidPublicCalldata(foreignCalldataHash: ForeignCallSingle) { + const calldataHash = fromSingle(foreignCalldataHash); + await this.handlerAsPrivate().assertValidPublicCalldata(calldataHash); + return toForeignCallResult([]); } // eslint-disable-next-line camelcase - public aztec_prv_notifyRevertiblePhaseStart(_foreignMinRevertibleSideEffectCounter: ForeignCallSingle) { - throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context'); + public async aztec_prv_notifyRevertiblePhaseStart(foreignMinRevertibleSideEffectCounter: ForeignCallSingle) { + const minRevertibleSideEffectCounter = fromSingle(foreignMinRevertibleSideEffectCounter).toNumber(); + await this.handlerAsPrivate().notifyRevertiblePhaseStart(minRevertibleSideEffectCounter); + return toForeignCallResult([]); } // eslint-disable-next-line camelcase @@ -785,10 +758,6 @@ export class RPCTranslator { const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber()); const header = await this.handlerAsUtility().getBlockHeader(blockNumber); - - if (!header) { - throw new Error(`Block header not found for block ${blockNumber}.`); - } return toForeignCallResult(header.toFields().map(toSingle)); } @@ -801,10 +770,6 @@ export class RPCTranslator { const noteHash = fromSingle(foreignNoteHash); const witness = await this.handlerAsUtility().getNoteHashMembershipWitness(blockHash, noteHash); - - if (!witness) { - throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`); - } return toForeignCallResult(witness.toNoirRepresentation()); } @@ -830,10 +795,6 @@ export class RPCTranslator { const nullifier = fromSingle(foreignNullifier); const witness = await this.handlerAsUtility().getLowNullifierMembershipWitness(blockHash, nullifier); - - if (!witness) { - throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`); - } return toForeignCallResult(witness.toNoirRepresentation()); } @@ -1033,14 +994,14 @@ export class RPCTranslator { const symKey = fromUintArray(foreignSymKey, 8); // Noir Option is encoded as [is_some: Field, storage: Field[], length: Field]. - try { - const plaintextBuffer = await this.handlerAsUtility().decryptAes128(ciphertext, iv, symKey); + const plaintextBuffer = await this.handlerAsUtility().decryptAes128(ciphertext, iv, symKey); + if (plaintextBuffer) { const [storage, length] = arrayToBoundedVec( bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length, ); return toForeignCallResult([toSingle(new Fr(1)), storage, length]); - } catch { + } else { const zeroStorage = toArray(Array(foreignCiphertextBVecStorage.length).fill(new Fr(0))); return toForeignCallResult([toSingle(new Fr(0)), zeroStorage, toSingle(new Fr(0))]); } @@ -1232,52 +1193,60 @@ export class RPCTranslator { } // eslint-disable-next-line camelcase - aztec_avm_returndataSize() { - throw new Error( - 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', - ); + async aztec_avm_returndataSize() { + const result = await this.handlerAsAvm().returndataSize(); + return toForeignCallResult([toSingle(result)]); } // eslint-disable-next-line camelcase - aztec_avm_returndataCopy(_foreignRdOffset: ForeignCallSingle, _foreignCopySize: ForeignCallSingle) { - throw new Error( - 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', - ); + async aztec_avm_returndataCopy(foreignRdOffset: ForeignCallSingle, foreignCopySize: ForeignCallSingle) { + const rdOffset = fromSingle(foreignRdOffset).toNumber(); + const copySize = fromSingle(foreignCopySize).toNumber(); + const result = await this.handlerAsAvm().returndataCopy(rdOffset, copySize); + return toForeignCallResult([toArray(result)]); } // eslint-disable-next-line camelcase - aztec_avm_call( - _foreignL2Gas: ForeignCallSingle, - _foreignDaGas: ForeignCallSingle, - _foreignAddress: ForeignCallSingle, - _foreignLength: ForeignCallSingle, - _foreignArgs: ForeignCallArray, + async aztec_avm_call( + foreignL2Gas: ForeignCallSingle, + foreignDaGas: ForeignCallSingle, + foreignAddress: ForeignCallSingle, + foreignLength: ForeignCallSingle, + foreignArgs: ForeignCallArray, ) { - throw new Error( - 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', - ); + const l2Gas = fromSingle(foreignL2Gas).toNumber(); + const daGas = fromSingle(foreignDaGas).toNumber(); + const address = addressFromSingle(foreignAddress); + const argsLength = fromSingle(foreignLength).toNumber(); + const args = fromArray(foreignArgs); + const result = await this.handlerAsAvm().call(l2Gas, daGas, address, argsLength, args); + return toForeignCallResult([toArray(result)]); } // eslint-disable-next-line camelcase - aztec_avm_staticCall( - _foreignL2Gas: ForeignCallSingle, - _foreignDaGas: ForeignCallSingle, - _foreignAddress: ForeignCallSingle, - _foreignLength: ForeignCallSingle, - _foreignArgs: ForeignCallArray, + async aztec_avm_staticCall( + foreignL2Gas: ForeignCallSingle, + foreignDaGas: ForeignCallSingle, + foreignAddress: ForeignCallSingle, + foreignLength: ForeignCallSingle, + foreignArgs: ForeignCallArray, ) { - throw new Error( - 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', - ); + const l2Gas = fromSingle(foreignL2Gas).toNumber(); + const daGas = fromSingle(foreignDaGas).toNumber(); + const address = addressFromSingle(foreignAddress); + const argsLength = fromSingle(foreignLength).toNumber(); + const args = fromArray(foreignArgs); + const result = await this.handlerAsAvm().staticCall(l2Gas, daGas, address, argsLength, args); + return toForeignCallResult([toArray(result)]); } // eslint-disable-next-line camelcase - aztec_avm_successCopy() { - throw new Error( - 'Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead', - ); + async aztec_avm_successCopy() { + const result = await this.handlerAsAvm().successCopy(); + return toForeignCallResult([toSingle(result)]); } + // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize. // eslint-disable-next-line camelcase async aztec_txe_privateCallNewFlow( foreignFromIsSome: ForeignCallSingle, @@ -1341,6 +1310,7 @@ export class RPCTranslator { return toForeignCallResult([toArray(returnValues)]); } + // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize. // eslint-disable-next-line camelcase async aztec_txe_executeUtilityFunction( foreignTargetContractAddress: ForeignCallSingle, @@ -1373,6 +1343,7 @@ export class RPCTranslator { return toForeignCallResult([toArray(returnValues)]); } + // TODO(F-674): Move orchestration logic into the handler so the transport layer is pure serialize→delegate→deserialize. // eslint-disable-next-line camelcase async aztec_txe_publicCallNewFlow( foreignFromIsSome: ForeignCallSingle, diff --git a/yarn-project/txe/src/txe_session.ts b/yarn-project/txe/src/txe_session.ts index 2c7c7fd493fb..32f674eeab30 100644 --- a/yarn-project/txe/src/txe_session.ts +++ b/yarn-project/txe/src/txe_session.ts @@ -24,7 +24,6 @@ import { type IPrivateExecutionOracle, type IUtilityExecutionOracle, Oracle, - PrivateExecutionOracle, UtilityExecutionOracle, } from '@aztec/pxe/simulator'; import { @@ -46,10 +45,11 @@ import { CallContext, GlobalVariables, OFFCHAIN_MESSAGE_IDENTIFIER, TxContext } import { z } from 'zod'; -import { DEFAULT_ADDRESS } from './constants.js'; +import { DEFAULT_ADDRESS, MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY, MAX_OFFCHAIN_EFFECT_LEN } from './constants.js'; import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js'; import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js'; import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js'; +import { TXEPrivateExecutionOracle } from './oracle/txe_private_execution_oracle.js'; import { RPCTranslator } from './rpc_translator.js'; import { TXEArchiver } from './state_machine/archiver.js'; import { TXEStateMachine } from './state_machine/index.js'; @@ -111,7 +111,7 @@ export type TXEOracleFunctionName = Exclude< export interface TXESessionStateHandler { /** Records the TXE oracle version reported by the Noir test code for diagnostics. */ - setTxeOracleVersion(version: { major: number; minor: number }): void; + setTxeOracleVersion(major: number, minor: number): void; enterTopLevelState(): Promise; enterPublicState(contractAddress?: AztecAddress): Promise; @@ -397,7 +397,16 @@ export class TXESession implements TXESessionStateHandler { getLastCallOffchainEffects(): { effects: Fr[][] } { this.lastCallInfo.queried = true; - return { effects: this.lastCallInfo.offchainEffects }; + const effects = this.lastCallInfo.offchainEffects; + + if (effects.length > MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY) { + throw new Error(`${effects.length} offchain effects exceed max ${MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY}`); + } + if (effects.some(e => e.length > MAX_OFFCHAIN_EFFECT_LEN)) { + throw new Error(`Some offchain effect has length larger than max ${MAX_OFFCHAIN_EFFECT_LEN}`); + } + + return { effects }; } getLastCallContext(): { txHash: Fr; anchorBlockTimestamp: bigint } { @@ -405,9 +414,19 @@ export class TXESession implements TXESessionStateHandler { return { txHash, anchorBlockTimestamp }; } - setTxeOracleVersion(version: { major: number; minor: number }): void { - this.txeOracleVersion = version; - this.logger.debug(`Test compiled with test oracle version ${version.major}.${version.minor}`); + setTxeOracleVersion(major: number, minor: number): void { + if (major !== TXE_ORACLE_VERSION_MAJOR) { + const hint = + major > TXE_ORACLE_VERSION_MAJOR + ? 'The test was compiled with a newer version of Aztec.nr than your test environment supports. Upgrade your test environment to a compatible version.' + : 'The test was compiled with an older version of Aztec.nr than your test environment supports. Recompile the test with a compatible version of Aztec.nr.'; + throw new Error( + `Incompatible test environment version: ${hint} See https://docs.aztec.network/errors/12 (expected test oracle major version ${TXE_ORACLE_VERSION_MAJOR}, got ${major})`, + ); + } + + this.txeOracleVersion = { major, minor }; + this.logger.debug(`Test compiled with test oracle version ${major}.${minor}`); } async enterTopLevelState() { @@ -489,7 +508,7 @@ export class TXESession implements TXESessionStateHandler { const taggingIndexCache = new ExecutionTaggingIndexCache(); const utilityExecutor = this.utilityExecutorForContractSync(anchorBlock); - this.oracleHandler = new PrivateExecutionOracle({ + this.oracleHandler = new TXEPrivateExecutionOracle({ argsHash: Fr.ZERO, txContext: new TxContext(this.chainId, this.version, gasSettings), callContext: new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false), @@ -530,7 +549,7 @@ export class TXESession implements TXESessionStateHandler { // via `anchorBlockNumber`, "latest" would be the wrong anchor for offchain-message semantics. this.setLastCallContext(Fr.ZERO, anchorBlock!.globalVariables.timestamp); - return (this.oracleHandler as PrivateExecutionOracle).getPrivateContextInputs(); + return (this.oracleHandler as TXEPrivateExecutionOracle).getPrivateContextInputs(); } async enterPublicState(contractAddress?: AztecAddress) { From ede2dec932d999525a96c4529d3976cd6b775eb2 Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Thu, 21 May 2026 14:42:48 +0100 Subject: [PATCH 05/13] feat(pxe)!: add source and block-range filtering to get_logs_by_tag (#23326) --- .../docs/resources/migration_notes.md | 23 ++ .../src/messages/discovery/partial_notes.nr | 22 +- .../processing/log_retrieval_request.nr | 81 ++++++- .../aztec/src/messages/processing/mod.nr | 26 +-- .../aztec/src/oracle/message_processing.nr | 9 +- .../log_retrieval_request.test.ts | 73 ++++++- .../noir-structs/log_retrieval_request.ts | 37 +++- .../oracle/utility_execution_oracle.ts | 10 +- yarn-project/pxe/src/logs/log_service.test.ts | 198 ++++++++++++++---- yarn-project/pxe/src/logs/log_service.ts | 106 ++++++---- 10 files changed, 461 insertions(+), 124 deletions(-) diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 077d386681f6..91f0802af2c6 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -9,6 +9,29 @@ Aztec is in active development. Each version may introduce breaking changes that ## TBD +### [Aztec.nr] `LogRetrievalRequest` now includes `source`, `from_block`, and `to_block` fields + +`LogRetrievalRequest` has been extended with three new fields to support filtering logs by source and block range. The `get_logs_by_tag` oracle now also returns all matching logs per tag instead of only the first match. + +A `LogRetrievalRequest::new(contract_address, tag)` constructor is provided that defaults to querying both public and private logs with no block range filter: + +```rust +LogRetrievalRequest::new(contract_address, my_tag) +``` + +If you need to customize source or block range, construct the struct manually with the new fields: + +```diff + LogRetrievalRequest { + tag: my_tag, ++ source: LogSource.PUBLIC_AND_PRIVATE, ++ from_block: Option::none(), ++ to_block: Option::none(), + } +``` + +`source` controls which RPCs are queried: `LogSource.PRIVATE`, `LogSource.PUBLIC`, or `LogSource.PUBLIC_AND_PRIVATE`. `from_block` and `to_block` define a half-open `[from, to)` block range filter. Both are `Option` and default to `Option::none()` (no filtering). + ### [Aztec.nr] `emit_private_log_unsafe` / `emit_raw_note_log_unsafe` now take `BoundedVec` The old array-based `emit_private_log_unsafe(tag, log: [Field; N], length)` and `emit_raw_note_log_unsafe(tag, log: [Field; N], length, note_hash_counter)` have been removed. The temporary `_vec_unsafe` variants introduced in a prior release have been renamed to take their place. diff --git a/noir-projects/aztec-nr/aztec/src/messages/discovery/partial_notes.nr b/noir-projects/aztec-nr/aztec/src/messages/discovery/partial_notes.nr index ff61bfc6b69b..63548b99f117 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/discovery/partial_notes.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/discovery/partial_notes.nr @@ -1,5 +1,6 @@ use crate::{ capsules::CapsuleArray, + ephemeral::EphemeralArray, messages::{ discovery::{ComputeNoteHash, ComputeNoteNullifier, nonce_discovery::attempt_note_nonce_discovery}, encoding::MAX_MESSAGE_CONTENT_LEN, @@ -88,17 +89,17 @@ pub(crate) unconstrained fn fetch_and_process_partial_note_completion_logs( // Each of the pending partial notes might get completed by a log containing its public values. For performance // reasons, we fetch all of these logs concurrently and then process them one by one, minimizing the amount of time // waiting for the node roundtrip. - let maybe_completion_logs = get_pending_partial_notes_completion_logs(contract_address, pending_partial_notes); + let completion_logs = get_pending_partial_notes_completion_logs(contract_address, pending_partial_notes); - // Each entry in the maybe completion logs array corresponds to the entry in the pending partial notes array at the - // same index. This means we can use the same index as we iterate through the responses to get both the partial - // note and the log that might complete it. - assert_eq(maybe_completion_logs.len(), pending_partial_notes.len()); + // Each entry in the completion logs array corresponds to the entry in the pending partial notes array at the same + // index. Each inner array contains all matching LogRetrievalResponses. + assert_eq(completion_logs.len(), pending_partial_notes.len()); - maybe_completion_logs.for_each(|i, maybe_log: Option| { + completion_logs.for_each(|i, logs_for_tag: EphemeralArray| { let pending_partial_note = pending_partial_notes.get(i); + let num_logs = logs_for_tag.len(); - if maybe_log.is_none() { + if num_logs == 0 { aztecnr_debug_log_format!("Found no completion logs for partial note with tag {}")( [pending_partial_note.note_completion_log_tag], ); @@ -107,10 +108,15 @@ pub(crate) unconstrained fn fetch_and_process_partial_note_completion_logs( // searching for this tagged log when performing message discovery in the future until we either find it or // the entry is somehow removed from the array. } else { + assert( + num_logs == 1, + f"Expected at most 1 completion log per partial note, got {num_logs}", + ); + aztecnr_debug_log_format!("Completion log found for partial note with tag {}")([ pending_partial_note.note_completion_log_tag, ]); - let log = maybe_log.unwrap(); + let log = logs_for_tag.get(0); // The first field in the completion log payload is the storage slot, followed by the public note // content fields. diff --git a/noir-projects/aztec-nr/aztec/src/messages/processing/log_retrieval_request.nr b/noir-projects/aztec-nr/aztec/src/messages/processing/log_retrieval_request.nr index c303df34e850..e853beda9ab3 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/processing/log_retrieval_request.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/processing/log_retrieval_request.nr @@ -1,30 +1,89 @@ use crate::protocol::{address::AztecAddress, traits::Serialize}; -/// A request for the `bulk_retrieve_logs` oracle to fetch either: -/// - a public log emitted by `contract_address` with `unsiloed_tag` -/// - a private log with tag equal to `compute_siloed_private_log_first_field(contract_address, unsiloed_tag)`. +pub(crate) struct LogSourceEnum { + pub PRIVATE: Field, + pub PUBLIC: Field, + pub PUBLIC_AND_PRIVATE: Field, +} + +pub(crate) global LogSource: LogSourceEnum = + LogSourceEnum { PRIVATE: 0, PUBLIC: 1, PUBLIC_AND_PRIVATE: 2 }; + +/// A request for the `bulk_retrieve_logs` oracle to fetch all logs matching a tag. #[derive(Serialize)] pub(crate) struct LogRetrievalRequest { pub contract_address: AztecAddress, pub unsiloed_tag: Field, - // TODO(#15052): choose source: public, private or either (current behavior) + /// Which log source to query: public, private, or both (the default). See [`LogSource`]. + pub source: Field, + /// Inclusive lower bound on block number. When unset, logs from the first block are included. + pub from_block: Option, + /// Exclusive upper bound on block number. When unset, logs up to the anchor block are included. + pub to_block: Option, +} + +impl LogRetrievalRequest { + /// Creates a request that queries both public and private logs with no block range filter. + pub(crate) fn new(contract_address: AztecAddress, unsiloed_tag: Field) -> Self { + LogRetrievalRequest { + contract_address, + unsiloed_tag, + source: LogSource.PUBLIC_AND_PRIVATE, + from_block: Option::none(), + to_block: Option::none(), + } + } } mod test { use crate::protocol::{address::AztecAddress, traits::{FromField, Serialize}}; - use super::LogRetrievalRequest; + use super::{LogRetrievalRequest, LogSource}; + + #[test] + fn serialization_of_defaults_matches_typescript() { + let request = LogRetrievalRequest { + contract_address: AztecAddress::from_field(1), + unsiloed_tag: 2, + source: LogSource.PUBLIC_AND_PRIVATE, + from_block: Option::none(), + to_block: Option::none(), + }; + + // We define the serialization in Noir and the deserialization in TS. If the deserialization changes from + // the snapshot value below, then log_retrieval_request.test.ts must be updated with the same value. + // Ideally we'd autogenerate this, but for now we only have single-sided snapshot generation, from TS to + // Noir, which is not what we need here. + let expected_serialization = [ + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000002, + 0x0000000000000000000000000000000000000000000000000000000000000002, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000, + ]; + + assert_eq(request.serialize(), expected_serialization); + } #[test] - fn serialization_matches_typescript() { - let request = LogRetrievalRequest { contract_address: AztecAddress::from_field(1), unsiloed_tag: 2 }; + fn serialization_with_values_matches_typescript() { + let request = LogRetrievalRequest { + contract_address: AztecAddress::from_field(1), + unsiloed_tag: 2, + source: LogSource.PUBLIC, + from_block: Option::some(10), + to_block: Option::some(20), + }; - // We define the serialization in Noir and the deserialization in TS. If the deserialization changes from the - // snapshot value below, then log_retrieval_request.test.ts must be updated with the same value. Ideally we'd - // autogenerate this, but for now we only have single-sided snapshot generation, from TS to Noir, which is not - // what we need here. let expected_serialization = [ 0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x000000000000000000000000000000000000000000000000000000000000000a, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000014, ]; assert_eq(request.serialize(), expected_serialization); diff --git a/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr b/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr index df716e43ccbe..f94d2cb539c5 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr @@ -19,7 +19,10 @@ use crate::{ discovery::partial_notes::DeliveredPendingPartialNote, encoding::MESSAGE_CIPHERTEXT_LEN, logs::{event::MAX_EVENT_SERIALIZED_LEN, note::MAX_NOTE_PACKED_LEN}, - processing::{log_retrieval_request::LogRetrievalRequest, log_retrieval_response::LogRetrievalResponse}, + processing::{ + log_retrieval_request::LogRetrievalRequest, + log_retrieval_response::LogRetrievalResponse, + }, }, oracle::message_processing, }; @@ -151,22 +154,19 @@ pub unconstrained fn validate_and_store_enqueued_notes_and_events(scope: AztecAd } /// Efficiently queries the node for logs that result in the completion of all `DeliveredPendingPartialNote`s stored in -/// a `CapsuleArray` by performing all node communication concurrently. Returns an `EphemeralArray` with Options -/// for the responses that correspond to the pending partial notes at the same index. -/// -/// For example, given an array with pending partial notes `[ p1, p2, p3 ]`, where `p1` and `p3` have corresponding -/// completion logs but `p2` does not, the returned `EphemeralArray` will have contents `[some(p1_log), none(), -/// some(p3_log)]`. +/// a `CapsuleArray` by performing all node communication concurrently. Returns a nested `EphemeralArray`, one inner +/// array per pending partial note, each containing all matching `LogRetrievalResponse`s (which may be empty if no +/// logs were found). pub(crate) unconstrained fn get_pending_partial_notes_completion_logs( contract_address: AztecAddress, pending_partial_notes: CapsuleArray, -) -> EphemeralArray> { +) -> EphemeralArray> { let log_retrieval_requests = EphemeralArray::at(LOG_RETRIEVAL_REQUESTS_ARRAY_BASE_SLOT); - // We create a LogRetrievalRequest for each PendingPartialNote in the EphemeralArray. Because we need the indices in - // the request array to match the indices in the partial note array, we can't use EphemeralArray::for_each, as that - // function has arbitrary iteration order. Instead, we manually iterate the array from the beginning and push into - // the requests array, which we expect to be empty. + // We create a LogRetrievalRequest for each PendingPartialNote in the EphemeralArray. Because we need the indices + // in the request array to match the indices in the partial note array, we can't use EphemeralArray::for_each, as + // that function has arbitrary iteration order. Instead, we manually iterate the array from the beginning and push + // into the requests array, which we expect to be empty. let mut i = 0; let pending_partial_notes_count = pending_partial_notes.len(); while i < pending_partial_notes_count { @@ -177,7 +177,7 @@ pub(crate) unconstrained fn get_pending_partial_notes_completion_logs( pending_partial_note.note_completion_log_tag, DOM_SEP__NOTE_COMPLETION_LOG_TAG, ); - log_retrieval_requests.push(LogRetrievalRequest { contract_address, unsiloed_tag: log_tag }); + log_retrieval_requests.push(LogRetrievalRequest::new(contract_address, log_tag)); i += 1; } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr b/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr index 876f55dd9e96..156c3b89dbc2 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr @@ -42,17 +42,20 @@ unconstrained fn validate_and_store_enqueued_notes_and_events_oracle( scope: AztecAddress, ) {} -/// Fetches logs by tag from an ephemeral request array and returns a response ephemeral array. +/// Fetches all logs matching each request's tag and returns a nested ephemeral array. +/// +/// Each element in the outer array is an inner `EphemeralArray` containing all matching logs for +/// the request at the same index (which may be empty if no logs were found). pub(crate) unconstrained fn get_logs_by_tag( requests: EphemeralArray, -) -> EphemeralArray> { +) -> EphemeralArray> { get_logs_by_tag_oracle(requests) } #[oracle(aztec_utl_getLogsByTag)] unconstrained fn get_logs_by_tag_oracle( requests: EphemeralArray, -) -> EphemeralArray> {} +) -> EphemeralArray> {} /// Resolves message contexts for tx hashes in an ephemeral request array and returns a response ephemeral array. pub(crate) unconstrained fn get_message_contexts_by_tx_hash( diff --git a/yarn-project/pxe/src/contract_function_simulator/noir-structs/log_retrieval_request.test.ts b/yarn-project/pxe/src/contract_function_simulator/noir-structs/log_retrieval_request.test.ts index d33ba2470a10..175f7f906bcb 100644 --- a/yarn-project/pxe/src/contract_function_simulator/noir-structs/log_retrieval_request.test.ts +++ b/yarn-project/pxe/src/contract_function_simulator/noir-structs/log_retrieval_request.test.ts @@ -1,19 +1,88 @@ +import { BlockNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { Tag } from '@aztec/stdlib/logs'; -import { LogRetrievalRequest } from './log_retrieval_request.js'; +import { LogRetrievalRequest, LogSource } from './log_retrieval_request.js'; describe('LogRetrievalRequest', () => { - it('output of Noir serialization deserializes as expected', () => { + it('output of Noir serialization with defaults deserializes as expected', () => { const serialized = [ '0x0000000000000000000000000000000000000000000000000000000000000001', '0x0000000000000000000000000000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + ].map(Fr.fromHexString); + + const request = LogRetrievalRequest.fromFields(serialized); + + expect(request.contractAddress).toEqual(AztecAddress.fromBigInt(1n)); + expect(request.tag).toEqual(new Tag(new Fr(2))); + expect(request.source).toEqual(LogSource.PUBLIC_AND_PRIVATE); + expect(request.fromBlock).toBeUndefined(); + expect(request.toBlock).toBeUndefined(); + }); + + it('output of Noir serialization with values deserializes as expected', () => { + const serialized = [ + '0x0000000000000000000000000000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000000000000000000000000000001', + '0x000000000000000000000000000000000000000000000000000000000000000a', + '0x0000000000000000000000000000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000000000000000000000000000014', ].map(Fr.fromHexString); const request = LogRetrievalRequest.fromFields(serialized); expect(request.contractAddress).toEqual(AztecAddress.fromBigInt(1n)); expect(request.tag).toEqual(new Tag(new Fr(2))); + expect(request.source).toEqual(LogSource.PUBLIC); + expect(request.fromBlock).toEqual(BlockNumber(10)); + expect(request.toBlock).toEqual(BlockNumber(20)); + }); + + it('rejects an invalid LogSource value', () => { + const serialized = [ + '0x0000000000000000000000000000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000000000000000000000000000002', + '0x000000000000000000000000000000000000000000000000000000000000002a', // 42 — invalid + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + ].map(Fr.fromHexString); + + expect(() => LogRetrievalRequest.fromFields(serialized)).toThrow(/Invalid LogSource value 42/); + }); + + it('accepts all valid LogSource values', () => { + for (const source of [LogSource.PRIVATE, LogSource.PUBLIC, LogSource.PUBLIC_AND_PRIVATE]) { + const fields = new LogRetrievalRequest(AztecAddress.fromBigInt(1n), new Tag(new Fr(2)), source).toFields(); + const restored = LogRetrievalRequest.fromFields(fields); + expect(restored.source).toEqual(source); + } + }); + + it('round-trips through toFields and fromFields', () => { + const original = new LogRetrievalRequest( + AztecAddress.fromBigInt(42n), + new Tag(new Fr(99)), + LogSource.PRIVATE, + BlockNumber(5), + BlockNumber(100), + ); + + const restored = LogRetrievalRequest.fromFields(original.toFields()); + + expect(restored.contractAddress).toEqual(original.contractAddress); + expect(restored.tag).toEqual(original.tag); + expect(restored.source).toEqual(original.source); + expect(restored.fromBlock).toEqual(original.fromBlock); + expect(restored.toBlock).toEqual(original.toBlock); }); }); diff --git a/yarn-project/pxe/src/contract_function_simulator/noir-structs/log_retrieval_request.ts b/yarn-project/pxe/src/contract_function_simulator/noir-structs/log_retrieval_request.ts index 377213a23106..549b452d2d39 100644 --- a/yarn-project/pxe/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +++ b/yarn-project/pxe/src/contract_function_simulator/noir-structs/log_retrieval_request.ts @@ -1,8 +1,16 @@ +import { BlockNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; import { FieldReader } from '@aztec/foundation/serialize'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { Tag } from '@aztec/stdlib/logs'; +/** Discriminant for which log source to query. */ +export enum LogSource { + PRIVATE = 0, + PUBLIC = 1, + PUBLIC_AND_PRIVATE = 2, +} + /** * Intermediate struct used to perform batch log retrieval by PXE. The `utilityBulkRetrieveLogs` oracle expects values of this * type to be stored in a `EphemeralArray`. @@ -11,10 +19,21 @@ export class LogRetrievalRequest { constructor( public contractAddress: AztecAddress, public tag: Tag, + public source: LogSource = LogSource.PUBLIC_AND_PRIVATE, + public fromBlock?: BlockNumber, + public toBlock?: BlockNumber, ) {} toFields(): Fr[] { - return [this.contractAddress.toField(), this.tag.value]; + return [ + this.contractAddress.toField(), + this.tag.value, + new Fr(this.source), + new Fr(this.fromBlock !== undefined ? 1 : 0), + new Fr(this.fromBlock ?? 0), + new Fr(this.toBlock !== undefined ? 1 : 0), + new Fr(this.toBlock ?? 0), + ]; } static fromFields(fields: Fr[] | FieldReader): LogRetrievalRequest { @@ -22,7 +41,21 @@ export class LogRetrievalRequest { const contractAddress = AztecAddress.fromField(reader.readField()); const tag = new Tag(reader.readField()); + const sourceNum = reader.readField().toNumber(); + if (!(sourceNum in LogSource)) { + const validNames = Object.keys(LogSource).filter(k => isNaN(Number(k))); + throw new Error(`Invalid LogSource value ${sourceNum}, expected one of ${validNames.join(', ')}`); + } + const source = sourceNum as LogSource; + + const fromBlockIsSome = reader.readBoolean(); + const fromBlockValue = reader.readField(); + const fromBlock = fromBlockIsSome ? BlockNumber(fromBlockValue.toNumber()) : undefined; + + const toBlockIsSome = reader.readBoolean(); + const toBlockValue = reader.readField(); + const toBlock = toBlockIsSome ? BlockNumber(toBlockValue.toNumber()) : undefined; - return new LogRetrievalRequest(contractAddress, tag); + return new LogRetrievalRequest(contractAddress, tag, source, fromBlock, toBlock); } } diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts index 27f789b4dff9..5fef884bff1a 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts @@ -48,7 +48,6 @@ import type { SenderAddressBookStore } from '../../storage/tagging_store/sender_ import { EphemeralArrayService } from '../ephemeral_array_service.js'; import { EventValidationRequest } from '../noir-structs/event_validation_request.js'; import { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js'; -import { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js'; import { NoteValidationRequest } from '../noir-structs/note_validation_request.js'; import { UtilityContext } from '../noir-structs/utility_context.js'; import { pickNotes } from '../pick_notes.js'; @@ -602,9 +601,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra .map(LogRetrievalRequest.fromFields); const logService = this.#createLogService(); - const maybeLogRetrievalResponses = await logService.fetchLogsByTag(this.contractAddress, logRetrievalRequests); + const logRetrievalResponses = await logService.fetchLogsByTag(this.contractAddress, logRetrievalRequests); - return this.ephemeralArrayService.newArray(maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption)); + // Create an inner ephemeral array for each request's matching logs, then wrap all slots in an outer array. + const innerSlots = logRetrievalResponses.map(responses => + this.ephemeralArrayService.newArray(responses.map(r => r.toFields())), + ); + + return this.ephemeralArrayService.newArray(innerSlots.map(slot => [slot])); } /** Reads tx hash requests from an ephemeral array, resolves their contexts, and returns the response slot. */ diff --git a/yarn-project/pxe/src/logs/log_service.test.ts b/yarn-project/pxe/src/logs/log_service.test.ts index fbaef16f94d9..7eb33274d934 100644 --- a/yarn-project/pxe/src/logs/log_service.test.ts +++ b/yarn-project/pxe/src/logs/log_service.test.ts @@ -6,12 +6,12 @@ import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { L2TipsProvider } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { Tag } from '@aztec/stdlib/logs'; +import { SiloedTag, Tag } from '@aztec/stdlib/logs'; import { makeBlockHeader, randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; import { type MockProxy, mock } from 'jest-mock-extended'; -import { LogRetrievalRequest } from '../contract_function_simulator/noir-structs/log_retrieval_request.js'; +import { LogRetrievalRequest, LogSource } from '../contract_function_simulator/noir-structs/log_retrieval_request.js'; import { AddressStore } from '../storage/address_store/address_store.js'; import { RecipientTaggingStore } from '../storage/tagging_store/recipient_tagging_store.js'; import { SenderAddressBookStore } from '../storage/tagging_store/sender_address_book_store.js'; @@ -26,7 +26,7 @@ describe('LogService', () => { let senderAddressBookStore: SenderAddressBookStore; let logService: LogService; - describe('bulkRetrieveLogs', () => { + describe('fetchLogsByTag', () => { const tag = Tag.random(); beforeEach(async () => { @@ -58,30 +58,15 @@ describe('LogService', () => { ); }); - it('returns no logs if none are found', async () => { + it('returns empty arrays if no logs are found', async () => { aztecNode.getPrivateLogsByTags.mockResolvedValue([[]]); aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[]]); const request = new LogRetrievalRequest(contractAddress, tag); const responses = await logService.fetchLogsByTag(contractAddress, [request]); - expect(responses.length).toEqual(1); - expect(responses[0]).toBeNull(); + expect(responses).toEqual([[]]); }); - it('returns a public log if one is found', async () => { - const scopedLog = randomTxScopedPrivateL2Log(); - - aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[scopedLog]]); - aztecNode.getPrivateLogsByTags.mockResolvedValue([[]]); - - const request = new LogRetrievalRequest(contractAddress, new Tag(scopedLog.logData[0])); - - const responses = await logService.fetchLogsByTag(contractAddress, [request]); - - expect(responses.length).toEqual(1); - expect(responses[0]).not.toBeNull(); - }); - - it('returns first log when multiple public logs are found for a single tag', async () => { + it('returns all logs when multiple public logs exist for a single tag', async () => { const scopedLog1 = randomTxScopedPrivateL2Log(); const scopedLog2 = randomTxScopedPrivateL2Log(); @@ -91,11 +76,12 @@ describe('LogService', () => { const request = new LogRetrievalRequest(contractAddress, tag); const responses = await logService.fetchLogsByTag(contractAddress, [request]); - expect(responses.length).toEqual(1); - expect(responses[0]).not.toBeNull(); + expect(responses[0]).toHaveLength(2); + expect(responses[0][0].txHash).toEqual(scopedLog1.txHash); + expect(responses[0][1].txHash).toEqual(scopedLog2.txHash); }); - it('returns first log when multiple private logs are found for a single tag', async () => { + it('returns all logs when multiple private logs exist for a single tag', async () => { const scopedLog1 = randomTxScopedPrivateL2Log(); const scopedLog2 = randomTxScopedPrivateL2Log(); @@ -105,11 +91,12 @@ describe('LogService', () => { const request = new LogRetrievalRequest(contractAddress, tag); const responses = await logService.fetchLogsByTag(contractAddress, [request]); - expect(responses.length).toEqual(1); - expect(responses[0]).not.toBeNull(); + expect(responses[0]).toHaveLength(2); + expect(responses[0][0].txHash).toEqual(scopedLog1.txHash); + expect(responses[0][1].txHash).toEqual(scopedLog2.txHash); }); - it('returns first log when both a public and private log are found for a single tag', async () => { + it('returns combined public and private logs for a single tag', async () => { const publicLog = randomTxScopedPrivateL2Log(); const privateLog = randomTxScopedPrivateL2Log(); @@ -119,22 +106,9 @@ describe('LogService', () => { const request = new LogRetrievalRequest(contractAddress, tag); const responses = await logService.fetchLogsByTag(contractAddress, [request]); - expect(responses.length).toEqual(1); - expect(responses[0]).not.toBeNull(); - }); - - it('returns a private log if one is found', async () => { - const scopedLog = randomTxScopedPrivateL2Log(); - - aztecNode.getPrivateLogsByTags.mockResolvedValue([[scopedLog]]); - aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[]]); - - const request = new LogRetrievalRequest(contractAddress, new Tag(scopedLog.logData[0])); - - const responses = await logService.fetchLogsByTag(contractAddress, [request]); - - expect(responses.length).toEqual(1); - expect(responses[0]).not.toBeNull(); + expect(responses[0]).toHaveLength(2); + expect(responses[0][0].txHash).toEqual(publicLog.txHash); + expect(responses[0][1].txHash).toEqual(privateLog.txHash); }); it('rejects a batch where at least one request targets a different contract', async () => { @@ -167,9 +141,11 @@ describe('LogService', () => { const responses = await logService.fetchLogsByTag(contractAddress, requests); expect(responses).toHaveLength(3); - expect(responses[0]).toEqual(expect.objectContaining({ txHash: publicLog1.txHash })); - expect(responses[1]).toEqual(expect.objectContaining({ txHash: privateLog2.txHash })); - expect(responses[2]).toBeNull(); + expect(responses[0]).toHaveLength(1); + expect(responses[0][0].txHash).toEqual(publicLog1.txHash); + expect(responses[1]).toHaveLength(1); + expect(responses[1][0].txHash).toEqual(privateLog2.txHash); + expect(responses[2]).toEqual([]); expect(aztecNode.getPublicLogsByTagsFromContract).toHaveBeenCalledTimes(1); expect(aztecNode.getPrivateLogsByTags).toHaveBeenCalledTimes(1); @@ -181,5 +157,135 @@ describe('LogService', () => { expect(aztecNode.getPublicLogsByTagsFromContract).not.toHaveBeenCalled(); expect(aztecNode.getPrivateLogsByTags).not.toHaveBeenCalled(); }); + + describe('block range filtering', () => { + it('fromBlock is inclusive', async () => { + const logBefore = randomTxScopedPrivateL2Log({ blockNumber: 9 }); + const logAtBoundary = randomTxScopedPrivateL2Log({ blockNumber: 10 }); + + aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[logBefore, logAtBoundary]]); + aztecNode.getPrivateLogsByTags.mockResolvedValue([[]]); + + const request = new LogRetrievalRequest(contractAddress, tag, LogSource.PUBLIC_AND_PRIVATE, BlockNumber(10)); + const responses = await logService.fetchLogsByTag(contractAddress, [request]); + + expect(responses[0]).toHaveLength(1); + expect(responses[0][0].txHash).toEqual(logAtBoundary.txHash); + }); + + it('toBlock is exclusive', async () => { + const logBeforeBoundary = randomTxScopedPrivateL2Log({ blockNumber: 9 }); + const logAtBoundary = randomTxScopedPrivateL2Log({ blockNumber: 10 }); + + aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[logBeforeBoundary, logAtBoundary]]); + aztecNode.getPrivateLogsByTags.mockResolvedValue([[]]); + + const request = new LogRetrievalRequest( + contractAddress, + tag, + LogSource.PUBLIC_AND_PRIVATE, + undefined, + BlockNumber(10), + ); + const responses = await logService.fetchLogsByTag(contractAddress, [request]); + + expect(responses[0]).toHaveLength(1); + expect(responses[0][0].txHash).toEqual(logBeforeBoundary.txHash); + }); + + it('filters with both fromBlock and toBlock', async () => { + const logBefore = randomTxScopedPrivateL2Log({ blockNumber: 3 }); + const logInRange = randomTxScopedPrivateL2Log({ blockNumber: 15 }); + const logAfter = randomTxScopedPrivateL2Log({ blockNumber: 25 }); + + aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[logBefore, logInRange, logAfter]]); + aztecNode.getPrivateLogsByTags.mockResolvedValue([[]]); + + const request = new LogRetrievalRequest( + contractAddress, + tag, + LogSource.PUBLIC_AND_PRIVATE, + BlockNumber(10), + BlockNumber(20), + ); + const responses = await logService.fetchLogsByTag(contractAddress, [request]); + + expect(responses[0]).toHaveLength(1); + expect(responses[0][0].txHash).toEqual(logInRange.txHash); + }); + }); + + describe('source filtering', () => { + it('returns only public logs and skips private RPC when source is PUBLIC', async () => { + const publicLog = randomTxScopedPrivateL2Log(); + + aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[publicLog]]); + + const request = new LogRetrievalRequest(contractAddress, tag, LogSource.PUBLIC); + const responses = await logService.fetchLogsByTag(contractAddress, [request]); + + expect(responses[0]).toHaveLength(1); + expect(responses[0][0].txHash).toEqual(publicLog.txHash); + expect(aztecNode.getPrivateLogsByTags).not.toHaveBeenCalled(); + }); + + it('returns only private logs and skips public RPC when source is PRIVATE', async () => { + const privateLog = randomTxScopedPrivateL2Log(); + + aztecNode.getPrivateLogsByTags.mockResolvedValue([[privateLog]]); + + const request = new LogRetrievalRequest(contractAddress, tag, LogSource.PRIVATE); + const responses = await logService.fetchLogsByTag(contractAddress, [request]); + + expect(responses[0]).toHaveLength(1); + expect(responses[0][0].txHash).toEqual(privateLog.txHash); + expect(aztecNode.getPublicLogsByTagsFromContract).not.toHaveBeenCalled(); + }); + + it('only sends relevant tags per source in a mixed batch', async () => { + const tag1 = Tag.random(); + const tag2 = Tag.random(); + const tag3 = Tag.random(); + + const publicLog1 = randomTxScopedPrivateL2Log(); + const privateLog2 = randomTxScopedPrivateL2Log(); + const publicLog3 = randomTxScopedPrivateL2Log(); + const privateLog3 = randomTxScopedPrivateL2Log(); + + aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[publicLog1], [publicLog3]]); + aztecNode.getPrivateLogsByTags.mockResolvedValue([[privateLog2], [privateLog3]]); + + const requests = [ + new LogRetrievalRequest(contractAddress, tag1, LogSource.PUBLIC), + new LogRetrievalRequest(contractAddress, tag2, LogSource.PRIVATE), + new LogRetrievalRequest(contractAddress, tag3, LogSource.PUBLIC_AND_PRIVATE), + ]; + + const responses = await logService.fetchLogsByTag(contractAddress, requests); + + // Public RPC receives tag1 and tag3, private RPC receives tag2 and tag3 + expect(aztecNode.getPublicLogsByTagsFromContract).toHaveBeenCalledTimes(1); + const publicCallTags = aztecNode.getPublicLogsByTagsFromContract.mock.calls[0][1]; + expect(publicCallTags).toHaveLength(2); + expect(publicCallTags[0]).toEqual(tag1); + expect(publicCallTags[1]).toEqual(tag3); + + expect(aztecNode.getPrivateLogsByTags).toHaveBeenCalledTimes(1); + const privateCallTags = aztecNode.getPrivateLogsByTags.mock.calls[0][0]; + expect(privateCallTags).toHaveLength(2); + const expectedSiloedTag2 = await SiloedTag.computeFromTagAndApp(tag2, contractAddress); + const expectedSiloedTag3 = await SiloedTag.computeFromTagAndApp(tag3, contractAddress); + expect(privateCallTags[0]).toEqual(expectedSiloedTag2); + expect(privateCallTags[1]).toEqual(expectedSiloedTag3); + + expect(responses[0]).toHaveLength(1); + expect(responses[0][0].txHash).toEqual(publicLog1.txHash); + expect(responses[1]).toHaveLength(1); + expect(responses[1][0].txHash).toEqual(privateLog2.txHash); + expect(responses[2]).toHaveLength(2); + expect(responses[2][0].txHash).toEqual(publicLog3.txHash); + expect(responses[2][1].txHash).toEqual(privateLog3.txHash); + }); + }); }); }); diff --git a/yarn-project/pxe/src/logs/log_service.ts b/yarn-project/pxe/src/logs/log_service.ts index 6edd28fae40f..27bb8093deba 100644 --- a/yarn-project/pxe/src/logs/log_service.ts +++ b/yarn-project/pxe/src/logs/log_service.ts @@ -1,7 +1,8 @@ +import type { BlockNumber } from '@aztec/foundation/branded-types'; import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log'; import type { KeyStore } from '@aztec/key-store'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; -import type { L2TipsProvider } from '@aztec/stdlib/block'; +import type { BlockHash, L2TipsProvider } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; import { ExtendedDirectionalAppTaggingSecret, @@ -11,7 +12,10 @@ import { } from '@aztec/stdlib/logs'; import type { BlockHeader } from '@aztec/stdlib/tx'; -import type { LogRetrievalRequest } from '../contract_function_simulator/noir-structs/log_retrieval_request.js'; +import { + type LogRetrievalRequest, + LogSource, +} from '../contract_function_simulator/noir-structs/log_retrieval_request.js'; import { LogRetrievalResponse } from '../contract_function_simulator/noir-structs/log_retrieval_response.js'; import { AddressStore } from '../storage/address_store/address_store.js'; import type { RecipientTaggingStore } from '../storage/tagging_store/recipient_tagging_store.js'; @@ -39,10 +43,11 @@ export class LogService { this.log = createLogger('pxe:log_service', bindings); } + /** Fetches all logs matching each request's tag, returning an array of log arrays (one per request). */ public async fetchLogsByTag( contractAddress: AztecAddress, logRetrievalRequests: LogRetrievalRequest[], - ): Promise<(LogRetrievalResponse | null)[]> { + ): Promise { for (const request of logRetrievalRequests) { if (!contractAddress.equals(request.contractAddress)) { throw new Error(`Got a log retrieval request from ${request.contractAddress}, expected ${contractAddress}`); @@ -54,51 +59,80 @@ export class LogService { } const anchorBlockHash = await this.anchorBlockHeader.hash(); - const tags = logRetrievalRequests.map(r => r.tag); - const siloedTags = await Promise.all( - logRetrievalRequests.map(r => SiloedTag.computeFromTagAndApp(r.tag, r.contractAddress)), - ); - const [allPublicLogsPerTag, allPrivateLogsPerTag] = await Promise.all([ - getAllPublicLogsByTagsFromContract(this.aztecNode, contractAddress, tags, anchorBlockHash), - getAllPrivateLogsByTags(this.aztecNode, siloedTags, anchorBlockHash), + const [publicLogsPerTag, privateLogsPerTag] = await Promise.all([ + this.#fetchPublicLogs(contractAddress, logRetrievalRequests, anchorBlockHash), + this.#fetchPrivateLogs(logRetrievalRequests, anchorBlockHash), ]); - return logRetrievalRequests.map((request, i) => { - const publicLog = this.#extractSingleLog( - allPublicLogsPerTag[i], - `public log for tag ${request.tag} and contract ${request.contractAddress.toString()}`, - ); - const privateLog = this.#extractSingleLog(allPrivateLogsPerTag[i], `private log for tag ${siloedTags[i]}`); + return logRetrievalRequests.map((request, i) => [ + ...this.#extractLogs(publicLogsPerTag[i], request.fromBlock, request.toBlock), + ...this.#extractLogs(privateLogsPerTag[i], request.fromBlock, request.toBlock), + ]); + } - if (publicLog !== null && privateLog !== null) { - this.log.warn( - `Found both a public and private log for tag ${request.tag} from contract ${request.contractAddress}. This may indicate a contract bug. Returning the public log.`, - ); - } + async #fetchPublicLogs( + contractAddress: AztecAddress, + requests: LogRetrievalRequest[], + anchorBlockHash: BlockHash, + ): Promise { + const indices = requests.flatMap((r, i) => (r.source !== LogSource.PRIVATE ? [i] : [])); + if (indices.length === 0) { + return requests.map(() => []); + } - return publicLog ?? privateLog; + const results = await getAllPublicLogsByTagsFromContract( + this.aztecNode, + contractAddress, + indices.map(i => requests[i].tag), + anchorBlockHash, + ); + + const logsPerTag: TxScopedL2Log[][] = requests.map(() => []); + indices.forEach((originalIdx, resultIdx) => { + logsPerTag[originalIdx] = results[resultIdx]; }); + return logsPerTag; } - #extractSingleLog(logsForTag: TxScopedL2Log[], description: string): LogRetrievalResponse | null { - if (logsForTag.length === 0) { - return null; + async #fetchPrivateLogs(requests: LogRetrievalRequest[], anchorBlockHash: BlockHash): Promise { + const indices = requests.flatMap((r, i) => (r.source !== LogSource.PUBLIC ? [i] : [])); + if (indices.length === 0) { + return requests.map(() => []); } - if (logsForTag.length > 1) { - this.log.warn( - `Expected at most 1 ${description}, got ${logsForTag.length}. This may indicate a contract bug. Returning the first log.`, - ); - } + const siloedTags = await Promise.all( + indices.map(i => SiloedTag.computeFromTagAndApp(requests[i].tag, requests[i].contractAddress)), + ); - const scopedLog = logsForTag[0]; + const results = await getAllPrivateLogsByTags(this.aztecNode, siloedTags, anchorBlockHash); - return new LogRetrievalResponse( - scopedLog.logData.slice(1), // Skip the tag - scopedLog.txHash, - scopedLog.noteHashes, - scopedLog.firstNullifier, + const logsPerTag: TxScopedL2Log[][] = requests.map(() => []); + indices.forEach((originalIdx, resultIdx) => { + logsPerTag[originalIdx] = results[resultIdx]; + }); + return logsPerTag; + } + + #extractLogs(logsForTag: TxScopedL2Log[], fromBlock?: BlockNumber, toBlock?: BlockNumber): LogRetrievalResponse[] { + // TODO(F-650): push the block range filter down to the node query instead of filtering in memory. + const filtered = + fromBlock !== undefined || toBlock !== undefined + ? logsForTag.filter( + log => + (fromBlock === undefined || log.blockNumber >= fromBlock) && + (toBlock === undefined || log.blockNumber < toBlock), + ) + : logsForTag; + + return filtered.map( + scopedLog => + new LogRetrievalResponse( + scopedLog.logData.slice(1), // Skip the tag + scopedLog.txHash, + scopedLog.noteHashes, + scopedLog.firstNullifier, + ), ); } From 49a4d219ccecdd4078be8ba52afaa230cd24b21d Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Fri, 22 May 2026 13:52:56 +0100 Subject: [PATCH 06/13] fix(txe): update TXE oracle interface hash for new AVM oracle methods (#23492) --- .../oracle/utility_execution_oracle.ts | 6 ++---- yarn-project/txe/src/txe_oracle_version.ts | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts index 5fef884bff1a..e03a4ee93c19 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts @@ -208,9 +208,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra this.aztecNode.getNoteHashMembershipWitness(blockHash, noteHash), ); if (!witness) { - throw new Error( - `Note hash ${noteHash} not found in the note hash tree at anchor block hash ${blockHash.toString()}.`, - ); + throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`); } return witness; } @@ -249,7 +247,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra this.aztecNode.getNullifierMembershipWitness(blockHash, nullifier), ); if (!witness) { - throw new Error(`Nullifier witness not found for nullifier ${nullifier} at block hash ${blockHash.toString()}.`); + throw new Error(`Nullifier membership witness not found at block ${blockHash.toString()}.`); } return witness; } diff --git a/yarn-project/txe/src/txe_oracle_version.ts b/yarn-project/txe/src/txe_oracle_version.ts index 4c3b67b711c9..015357f412f8 100644 --- a/yarn-project/txe/src/txe_oracle_version.ts +++ b/yarn-project/txe/src/txe_oracle_version.ts @@ -6,7 +6,7 @@ * The Noir counterparts are in `noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr`. */ export const TXE_ORACLE_VERSION_MAJOR = 1; -export const TXE_ORACLE_VERSION_MINOR = 0; +export const TXE_ORACLE_VERSION_MINOR = 1; /** * This hash is computed from the TXE oracle interfaces (IAvmExecutionOracle and ITxeExecutionOracle) and is used to @@ -14,4 +14,4 @@ export const TXE_ORACLE_VERSION_MINOR = 0; * - TXE_ORACLE_VERSION_MAJOR (and reset MINOR to 0) for breaking changes, or * - TXE_ORACLE_VERSION_MINOR for additive changes (new oracle method added). */ -export const TXE_ORACLE_INTERFACE_HASH = 'c5e3567b08790c8181254c0831de6b5af49e221e14d36dded3fc5d8787fba482'; +export const TXE_ORACLE_INTERFACE_HASH = '833b77ccdba925b1ed129028432c7d4b116867fb426cee40f9d6104c5aa31e42'; From f753e4b3ec2bd70191977ae8f2c365eb73676e28 Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Fri, 22 May 2026 09:08:56 -0400 Subject: [PATCH 07/13] chore(ci): capture sandbox diagnostics on acceptance test failure (#23495) --- .../workflows/aztec-cli-acceptance-test.yml | 9 +++++ .../aztec-cli-acceptance-test.ts | 34 ++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/.github/workflows/aztec-cli-acceptance-test.yml b/.github/workflows/aztec-cli-acceptance-test.yml index ef9da15b4b45..1a1de972c320 100644 --- a/.github/workflows/aztec-cli-acceptance-test.yml +++ b/.github/workflows/aztec-cli-acceptance-test.yml @@ -40,6 +40,15 @@ jobs: timeout-minutes: 30 run: ./aztec-up/test/aztec-cli-acceptance-test/run-test.sh + - name: Upload diagnostics on failure + if: failure() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: acceptance-test-diagnostics-${{ matrix.os }} + path: ${{ runner.temp }}/aztec-cli-acceptance-test-*/** + if-no-files-found: warn + retention-days: 7 + notify: needs: release-acceptance if: always() && github.event_name != 'workflow_dispatch' diff --git a/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts b/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts index d207f90f9679..4f58deb6615a 100644 --- a/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts +++ b/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts @@ -49,7 +49,10 @@ if (!existsSync(join(AZTEC_INSTALL_DIR, "package.json"))) { process.exit(2); } -const TMP_DIR = mkdtempSync(join(tmpdir(), "aztec-cli-acceptance-test-")); +// Prefer RUNNER_TEMP so the GitHub Actions upload-artifact step can find the diagnostic +// tree on failure under a predictable parent path. Falls back to the system tmpdir locally. +const TMP_DIR_PARENT = process.env.RUNNER_TEMP ?? tmpdir(); +const TMP_DIR = mkdtempSync(join(TMP_DIR_PARENT, "aztec-cli-acceptance-test-")); const WORKSPACE_DIR = join(TMP_DIR, "my_workspace"); // Exit codes follow the Unix 128+signal convention for signal terminations. @@ -188,13 +191,32 @@ function locateArtifact(): string { async function startLocalNetwork(): Promise { const logPath = join(TMP_DIR, "local_network.log"); const logFd = openSync(logPath, "a"); + // LOG_LEVEL defaults to "debug" so failed CI runs leave useful traces in local_network.log; + // override with LOCAL_NETWORK_LOG_LEVEL=silent when running locally and the volume is noisy. + const logLevel = process.env.LOCAL_NETWORK_LOG_LEVEL ?? "debug"; + const reportDir = join(TMP_DIR, "node-reports"); + mkdirSync(reportDir, { recursive: true }); + const nodeOptions = [ + process.env.NODE_OPTIONS, + `--report-on-signal`, + `--report-directory=${reportDir}`, + ] + .filter(Boolean) + .join(" "); const proc = spawn("aztec", ["start", "--local-network"], { cwd: TMP_DIR, stdio: ["ignore", logFd, logFd], - env: { ...process.env, LOG_LEVEL: "silent", PXE_PROVER: "none" }, + env: { + ...process.env, + LOG_LEVEL: logLevel, + PXE_PROVER: "none", + NODE_OPTIONS: nodeOptions, + }, }); closeSync(logFd); - log(` local-network pid=${proc.pid}, log=${logPath}`); + log( + ` local-network pid=${proc.pid}, log=${logPath}, LOG_LEVEL=${logLevel}`, + ); // Kill the network on process exit (including SIGINT/SIGTERM via the signal handlers). process.on("exit", () => { @@ -214,6 +236,10 @@ async function startLocalNetwork(): Promise { ); } if (Date.now() > deadline) { + try { + process.kill(proc.pid!, "SIGUSR2"); + await delay(2000); + } catch {} dumpTail(logPath); fail( `timed out after ${msToSecs(LOCAL_NETWORK_READY_TIMEOUT_MS)}s waiting for local-network /status (see ${logPath})`, @@ -306,7 +332,7 @@ function leaveTmpDirForInspection() { console.error(`>>> Left tmp dir at ${TMP_DIR} for inspection`); } -function dumpTail(path: string, lines = 100) { +function dumpTail(path: string, lines = 400) { if (!existsSync(path)) { return; } From 174de72f5d0ab79b98217da44b9c37a14583b765 Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Fri, 22 May 2026 14:25:14 +0100 Subject: [PATCH 08/13] feat(aztec-nr)!: rename push_nullifier to push_nullifier_unsafe (#23488) --- .../docs/aztec-nr/standards/aip-721.md | 2 +- .../docs/foundational-topics/advanced/authwit.md | 2 +- .../docs/resources/migration_notes.md | 13 +++++++++++++ .../aztec-nr/aztec/src/authwit/account.nr | 2 +- noir-projects/aztec-nr/aztec/src/authwit/auth.nr | 2 +- .../aztec-nr/aztec/src/context/private_context.nr | 15 ++++++++------- .../aztec-nr/aztec/src/context/public_context.nr | 4 ++-- .../aztec-nr/aztec/src/event/event_emission.nr | 2 +- .../aztec-nr/aztec/src/history/nullifier.nr | 14 ++++++++------ .../src/macros/functions/initialization_utils.nr | 6 +++--- noir-projects/aztec-nr/aztec/src/nullifier/mod.nr | 4 ++-- .../aztec/src/state_vars/private_immutable.nr | 2 +- .../aztec/src/state_vars/private_mutable.nr | 2 +- .../aztec/src/state_vars/public_immutable.nr | 2 +- .../src/state_vars/single_private_immutable.nr | 2 +- .../src/state_vars/single_private_mutable.nr | 2 +- .../aztec/src/state_vars/single_use_claim.nr | 2 +- .../test_environment/test/private_context.nr | 12 ++++++------ .../test_environment/test/public_context.nr | 14 +++++++------- .../test_environment/test/utility_context.nr | 2 +- noir-projects/aztec-nr/uint-note/src/uint_note.nr | 2 +- .../simulated_ecdsa_account_contract/src/main.nr | 4 ++-- .../src/main.nr | 4 ++-- .../contracts/app/nft_contract/src/main.nr | 2 +- .../app/nft_contract/src/types/nft_note.nr | 2 +- .../contracts/app/orderbook_contract/src/main.nr | 2 +- .../app/simple_token_contract/src/main.nr | 2 +- .../contracts/app/token_contract/src/main.nr | 2 +- .../contracts/test/avm_test_contract/src/main.nr | 14 +++++++------- .../test/benchmarking_contract/src/main.nr | 2 +- .../test/custom_message_contract/src/main.nr | 2 +- .../test/private_init_test_contract/src/main.nr | 2 +- .../contracts/test/spam_contract/src/main.nr | 2 +- .../contracts/test/test_contract/src/main.nr | 4 ++-- .../contracts/side_effect_contract/src/main.nr | 2 +- 35 files changed, 85 insertions(+), 69 deletions(-) diff --git a/docs/docs-developers/docs/aztec-nr/standards/aip-721.md b/docs/docs-developers/docs/aztec-nr/standards/aip-721.md index 7d307265a034..d661cde80af9 100644 --- a/docs/docs-developers/docs/aztec-nr/standards/aip-721.md +++ b/docs/docs-developers/docs/aztec-nr/standards/aip-721.md @@ -49,7 +49,7 @@ impl NFTNote { // ... creates encrypted log and validity commitment let partial_note = PartialNFTNote { commitment }; let validity_commitment = partial_note.compute_validity_commitment(completer); - context.push_nullifier(validity_commitment); + context.push_nullifier_unsafe(validity_commitment); partial_note } } diff --git a/docs/docs-developers/docs/foundational-topics/advanced/authwit.md b/docs/docs-developers/docs/foundational-topics/advanced/authwit.md index 664d2b5fe99f..d9cf8880def3 100644 --- a/docs/docs-developers/docs/foundational-topics/advanced/authwit.md +++ b/docs/docs-developers/docs/foundational-topics/advanced/authwit.md @@ -144,7 +144,7 @@ You can cancel an authwit before it's used by emitting its nullifier directly. T fn cancel_authwit(inner_hash: Field) { let on_behalf_of = self.msg_sender(); let nullifier = compute_authwit_nullifier(on_behalf_of, inner_hash); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } ``` diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 91f0802af2c6..25f2795a901a 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -9,6 +9,19 @@ Aztec is in active development. Each version may introduce breaking changes that ## TBD +### [Aztec.nr] `push_nullifier` renamed to `push_nullifier_unsafe` + +`PrivateContext::push_nullifier` and `PublicContext::push_nullifier` have been renamed to `push_nullifier_unsafe` to +make it clear that they are low-level functions that require careful domain separation. This is consistent with the +`_unsafe` suffix already used by `emit_private_log_unsafe`, `emit_raw_note_log_unsafe`, and `emit_public_log_unsafe`. + +```diff +- context.push_nullifier(nullifier); ++ context.push_nullifier_unsafe(nullifier); +``` + +Prefer higher-level abstractions like `SingleUseClaim` or `destroy_note` which handle domain separation automatically. + ### [Aztec.nr] `LogRetrievalRequest` now includes `source`, `from_block`, and `to_block` fields `LogRetrievalRequest` has been extended with three new fields to support filtering logs by source and block range. The `get_logs_by_tag` oracle now also returns all matching logs per tag instead of only the first match. diff --git a/noir-projects/aztec-nr/aztec/src/authwit/account.nr b/noir-projects/aztec-nr/aztec/src/authwit/account.nr index e35a5378ac05..72f5607f1392 100644 --- a/noir-projects/aztec-nr/aztec/src/authwit/account.nr +++ b/noir-projects/aztec-nr/aztec/src/authwit/account.nr @@ -74,7 +74,7 @@ impl AccountActions<&mut PrivateContext> { if cancellable { let tx_nullifier = poseidon2_hash_with_separator([app_payload.tx_nonce], DOM_SEP__TX_NULLIFIER); - self.context.push_nullifier(tx_nullifier); + self.context.push_nullifier_unsafe(tx_nullifier); } } diff --git a/noir-projects/aztec-nr/aztec/src/authwit/auth.nr b/noir-projects/aztec-nr/aztec/src/authwit/auth.nr index c62d4c5172e6..9fe5abad3d66 100644 --- a/noir-projects/aztec-nr/aztec/src/authwit/auth.nr +++ b/noir-projects/aztec-nr/aztec/src/authwit/auth.nr @@ -282,7 +282,7 @@ pub fn assert_inner_hash_valid_authwit(context: &mut PrivateContext, on_behalf_o // already be handled in the verification, so we just need something to nullify, that allows the same inner_hash // for multiple actors. let nullifier = compute_authwit_nullifier(on_behalf_of, inner_hash); - context.push_nullifier(nullifier); + context.push_nullifier_unsafe(nullifier); } /// Assert that `on_behalf_of` has authorized the current call in the authentication registry diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 32f57b6aac67..7631593cefb5 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -366,16 +366,17 @@ impl PrivateContext { /// The raw `nullifier` is not what is inserted into the Aztec state tree: it will be first siloed by contract /// address via [`crate::protocol::hash::compute_siloed_nullifier`] in order to prevent accidental or malicious /// interference of nullifiers from different contracts. - pub fn push_nullifier(&mut self, nullifier: Field) { + pub fn push_nullifier_unsafe(&mut self, nullifier: Field) { notify_created_nullifier(nullifier); self.nullifiers.push(Nullifier { value: nullifier, note_hash: 0 }.count(self.next_counter())); } /// Creates a new [nullifier](crate::nullifier) associated with a note. /// - /// This is a variant of [`PrivateContext::push_nullifier`] that is used for note nullifiers, i.e. nullifiers that - /// correspond to a note. If a note and its nullifier are created in the same transaction, then the private kernels - /// will 'squash' these values, deleting them both as if they never existed and reducing transaction fees. + /// This is a variant of [`PrivateContext::push_nullifier_unsafe`] that is used for note nullifiers, i.e. + /// nullifiers that correspond to a note. If a note and its nullifier are created in the same transaction, then + /// the private kernels will 'squash' these values, deleting them both as if they never existed and reducing + /// transaction fees. /// /// The `nullification_note_hash` must be the result of calling /// [`crate::note::utils::compute_confirmed_note_hash_for_nullification`] for pending notes, and `0` for settled @@ -386,10 +387,10 @@ impl PrivateContext { /// This is a low-level function that must be used with great care to avoid subtle corruption of contract state. /// Instead of calling this function, consider using the higher-level [`crate::note::lifecycle::destroy_note`]. /// - /// The precautions listed for [`PrivateContext::push_nullifier`] apply here as well, and callers should + /// The precautions listed for [`PrivateContext::push_nullifier_unsafe`] apply here as well, and callers should /// additionally ensure `nullification_note_hash` corresponds to a note emitted by this contract, with its hash /// computed in the same transaction execution phase as the call to this function. Finally, only this function - /// should be used for note nullifiers, never [`PrivateContext::push_nullifier`]. + /// should be used for note nullifiers, never [`PrivateContext::push_nullifier_unsafe`]. /// /// Failure to do these things can result in unprovable contexts, accidental deletion of notes, or double-spend /// attacks. @@ -858,7 +859,7 @@ impl PrivateContext { ); // Push nullifier (and the "commitment" corresponding to this can be "empty") - self.push_nullifier(nullifier) + self.push_nullifier_unsafe(nullifier) } /// Emits a private log (an array of Fields) that will be published to an Ethereum blob. diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index 33b87501cb7c..49189174e051 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -253,7 +253,7 @@ impl PublicContext { assert(!self.nullifier_exists_unsafe(nullifier, self.this_address()), "L1-to-L2 message is already nullified"); assert(self.l1_to_l2_msg_exists(message_hash, leaf_index), "Tried to consume nonexistent L1-to-L2 message"); - self.push_nullifier(nullifier); + self.push_nullifier_unsafe(nullifier); } /// Sends an "L2 -> L1 message" from this function (Aztec, L2) to a smart contract on Ethereum (L1). L1 contracts @@ -406,7 +406,7 @@ impl PublicContext { /// The raw `nullifier` is not what is inserted into the Aztec state tree: it will be first siloed by contract /// address via [`crate::protocol::hash::compute_siloed_nullifier`] in order to prevent accidental or malicious /// interference of nullifiers from different contracts. - pub fn push_nullifier(_self: Self, nullifier: Field) { + pub fn push_nullifier_unsafe(_self: Self, nullifier: Field) { // Safety: AVM opcodes are constrained by the AVM itself unsafe { avm::emit_nullifier(nullifier) }; } diff --git a/noir-projects/aztec-nr/aztec/src/event/event_emission.nr b/noir-projects/aztec-nr/aztec/src/event/event_emission.nr index b24c06992d5d..192fcfb99cf8 100644 --- a/noir-projects/aztec-nr/aztec/src/event/event_emission.nr +++ b/noir-projects/aztec-nr/aztec/src/event/event_emission.nr @@ -29,7 +29,7 @@ where // The event commitment is emitted as a nullifier instead of as a note because these are simpler: nullifiers cannot // be squashed, making kernel processing simpler, and they have no nonce that recipients need to discover. let commitment = compute_private_event_commitment(event, randomness); - context.push_nullifier(commitment); + context.push_nullifier_unsafe(commitment); EventMessage::new(NewEvent { event, randomness }, context) } diff --git a/noir-projects/aztec-nr/aztec/src/history/nullifier.nr b/noir-projects/aztec-nr/aztec/src/history/nullifier.nr index 47ae008258b9..1ec2b4dd9e09 100644 --- a/noir-projects/aztec-nr/aztec/src/history/nullifier.nr +++ b/noir-projects/aztec-nr/aztec/src/history/nullifier.nr @@ -15,8 +15,9 @@ mod test; /// Asserts that a nullifier existed by the time a block was mined. /// /// This function takes a _siloed_ nullifier, i.e. the value that is actually stored in the tree. Use -/// [`crate::protocol::hash::compute_siloed_nullifier`] to convert an inner nullifier (what -/// [`PrivateContext::push_nullifier`](crate::context::PrivateContext::push_nullifier) takes) into a siloed one. +/// [`crate::protocol::hash::compute_siloed_nullifier`] to convert an inner nullifier +/// (what [`PrivateContext::push_nullifier_unsafe`](crate::context::PrivateContext::push_nullifier_unsafe) +/// takes) into a siloed one. /// /// Note that this does not mean that the nullifier was created **at** `block_header`, only that it was present in the /// tree once all transactions from `block_header` were executed. @@ -56,8 +57,9 @@ pub fn assert_nullifier_existed_by(block_header: BlockHeader, siloed_nullifier: /// Asserts that a nullifier did not exist by the time a block was mined. /// /// This function takes a _siloed_ nullifier, i.e. the value that is actually stored in the tree. Use -/// [`crate::protocol::hash::compute_siloed_nullifier`] to convert an inner nullifier (what -/// [`PrivateContext::push_nullifier`](crate::context::PrivateContext::push_nullifier) takes) into a siloed one. +/// [`crate::protocol::hash::compute_siloed_nullifier`] to convert an inner nullifier +/// (what [`PrivateContext::push_nullifier_unsafe`](crate::context::PrivateContext::push_nullifier_unsafe) +/// takes) into a siloed one. /// /// In order to prove that a nullifier **did** exist by `block_header`, use [`assert_nullifier_existed_by`]. /// @@ -69,8 +71,8 @@ pub fn assert_nullifier_existed_by(block_header: BlockHeader, siloed_nullifier: /// /// If you **must** prove that a nullifier does not exist by the time a transaction is executed, there only two ways to /// do this: by actually emitting the nullifier via -/// [`PrivateContext::push_nullifier`](crate::context::PrivateContext::push_nullifier) (which can of course can be done -/// once), or by calling a public contract function that calls +/// [`PrivateContext::push_nullifier_unsafe`](crate::context::PrivateContext::push_nullifier_unsafe) +/// (which can of course only be done once), or by calling a public contract function that calls /// [`PublicContext::nullifier_exists_unsafe`](crate::context::PublicContext::nullifier_exists_unsafe) (which leaks /// that this nullifier is being checked): /// diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr index a406af070329..d4634b4cf0a2 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr @@ -54,14 +54,14 @@ global EMIT_PUBLIC_INIT_NULLIFIER_SELECTOR: FunctionSelector = comptime { /// emitting the public nullifier without the private one). The macro-generated code handles this automatically. pub fn mark_as_initialized_public(context: PublicContext) { let init_nullifier = compute_public_initialization_nullifier(context.this_address()); - context.push_nullifier(init_nullifier); + context.push_nullifier_unsafe(init_nullifier); } fn mark_as_initialized_private(context: &mut PrivateContext) { let address = (*context).this_address(); let instance = get_contract_instance(address); let init_nullifier = compute_private_initialization_nullifier(address, instance.initialization_hash); - context.push_nullifier(init_nullifier); + context.push_nullifier_unsafe(init_nullifier); } /// Emits the private initialization nullifier and, if relevant, enqueues the emission of the public one. @@ -88,7 +88,7 @@ pub fn mark_as_initialized_from_public_initializer(context: PublicContext) { // currently executing, which by definition must have been deployed. let init_hash = get_contract_instance_initialization_hash_avm(address).unwrap(); let private_nullifier = compute_private_initialization_nullifier(address, init_hash); - context.push_nullifier(private_nullifier); + context.push_nullifier_unsafe(private_nullifier); mark_as_initialized_public(context); } diff --git a/noir-projects/aztec-nr/aztec/src/nullifier/mod.nr b/noir-projects/aztec-nr/aztec/src/nullifier/mod.nr index 68b1453f5260..e0c6d0cdba45 100644 --- a/noir-projects/aztec-nr/aztec/src/nullifier/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/nullifier/mod.nr @@ -31,8 +31,8 @@ //! //! ## Nullifier Creation //! -//! The low-level mechanisms to create new nullifiers are [`crate::context::PrivateContext::push_nullifier`] and -//! [`crate::context::PublicContext::push_nullifier`], but these require care and can be hard to use correctly. +//! The low-level mechanisms to create new nullifiers are [`crate::context::PrivateContext::push_nullifier_unsafe`] and +//! [`crate::context::PublicContext::push_nullifier_unsafe`], but these require care and can be hard to use correctly. //! Higher-level abstractions exist which safely create nullifiers, such as [`crate::note::lifecycle::destroy_note`] //! and //! [`crate::state_vars::SingleUseClaim`]. diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr index ef84849f3ebb..019b8219cabc 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr @@ -104,7 +104,7 @@ impl PrivateImmutable { // We emit an initialization nullifier to indicate that the struct is initialized. This also prevents the value // from being initialized again as a nullifier can be included only once. let nullifier = self.get_initialization_nullifier(); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); create_note(self.context, self.owner, self.storage_slot, note) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr index cc1bbade6d6e..81a61aade5d9 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr @@ -145,7 +145,7 @@ where { // Nullify the storage slot. let nullifier = self.get_initialization_nullifier(); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); create_note(self.context, self.owner, self.storage_slot, note) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr index da21ab7d3a1c..d7f7e99b4754 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -154,7 +154,7 @@ impl PublicImmutable { // We emit an initialization nullifier to indicate that the struct is initialized. This also prevents the value // from being initialized again as each nullifier can be emitted only once. let nullifier = self.compute_initialization_inner_nullifier(); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); self.context.storage_write(self.storage_slot, WithHash::new(value)); } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr index 326a4843110d..6ae7103ee469 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr @@ -103,7 +103,7 @@ impl SinglePrivateImmutable { Note: NoteType + NoteHash + Packable, { let nullifier = self.get_initialization_nullifier(); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); // The note owner is set to the contract's address. Strictly speaking, specifying a note owner is not required // here, as this note is never intended to be nullified. However, we must provide an owner because Aztec.nr diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr index d286aa346b78..14feab03af3c 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr @@ -139,7 +139,7 @@ where { // Nullify the storage slot. let nullifier = self.get_initialization_nullifier(); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); create_note(self.context, owner, self.storage_slot, note) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr index 28f0ac6f860d..a97301415b21 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr @@ -105,7 +105,7 @@ impl SingleUseClaim<&mut PrivateContext> { /// storage slot of the underlying state variable. pub fn claim(self) { let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m.hash()); - self.context.push_nullifier(self.compute_nullifier(owner_nhk_app)); + self.context.push_nullifier_unsafe(self.compute_nullifier(owner_nhk_app)); } /// Asserts that the owner has already claimed this single use claim (i.e. that [`SingleUseClaim::claim`] has been diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/private_context.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/private_context.nr index 0feac8ded02d..812334f4a8e2 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/private_context.nr @@ -145,8 +145,8 @@ unconstrained fn rejects_duplicate_transient_nullifiers() { let env = TestEnvironment::new(); env.private_context(|context| { - context.push_nullifier(1); - context.push_nullifier(1); + context.push_nullifier_unsafe(1); + context.push_nullifier_unsafe(1); }); } @@ -154,9 +154,9 @@ unconstrained fn rejects_duplicate_transient_nullifiers() { unconstrained fn rejects_duplicate_settled_nullifiers() { let env = TestEnvironment::new(); - env.private_context(|context| { context.push_nullifier(1); }); + env.private_context(|context| { context.push_nullifier_unsafe(1); }); - env.private_context(|context| { context.push_nullifier(1); }); + env.private_context(|context| { context.push_nullifier_unsafe(1); }); } #[test] @@ -207,7 +207,7 @@ unconstrained fn check_nullifier_exists_nonexistent() { unconstrained fn check_nullifier_exists_settled() { let env = TestEnvironment::new(); - env.private_context(|context| { context.push_nullifier(1); }); + env.private_context(|context| { context.push_nullifier_unsafe(1); }); env.private_context(|_| { assert(check_nullifier_exists(1)); }); } @@ -217,7 +217,7 @@ unconstrained fn check_nullifier_exists_pending() { let env = TestEnvironment::new(); env.private_context(|context| { - context.push_nullifier(1); + context.push_nullifier_unsafe(1); assert(check_nullifier_exists(1)); }); } diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/public_context.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/public_context.nr index 5fd8f6dc4d4f..e7d926c16abd 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/public_context.nr @@ -119,7 +119,7 @@ unconstrained fn read_public_nullifier_same_context() { let env = TestEnvironment::new(); env.public_context(|context| { - context.push_nullifier(nullifier); + context.push_nullifier_unsafe(nullifier); assert(context.nullifier_exists_unsafe(nullifier, context.this_address())); }); } @@ -128,7 +128,7 @@ unconstrained fn read_public_nullifier_same_context() { unconstrained fn read_public_nullifier_other_context() { let env = TestEnvironment::new(); - env.public_context(|context| { context.push_nullifier(nullifier); }); + env.public_context(|context| { context.push_nullifier_unsafe(nullifier); }); env.public_context(|context| { assert(context.nullifier_exists_unsafe(nullifier, context.this_address())); }); } @@ -137,7 +137,7 @@ unconstrained fn read_public_nullifier_other_context() { unconstrained fn read_private_nullifier() { let env = TestEnvironment::new(); - env.private_context(|context| { context.push_nullifier(nullifier); }); + env.private_context(|context| { context.push_nullifier_unsafe(nullifier); }); env.public_context(|context| { assert(context.nullifier_exists_unsafe(nullifier, context.this_address())); }); } @@ -147,8 +147,8 @@ unconstrained fn rejects_duplicate_transient_nullifiers() { let env = TestEnvironment::new(); env.public_context(|context| { - context.push_nullifier(1); - context.push_nullifier(1); + context.push_nullifier_unsafe(1); + context.push_nullifier_unsafe(1); }); } @@ -156,9 +156,9 @@ unconstrained fn rejects_duplicate_transient_nullifiers() { unconstrained fn rejects_duplicate_settled_nullifiers() { let env = TestEnvironment::new(); - env.public_context(|context| { context.push_nullifier(1); }); + env.public_context(|context| { context.push_nullifier_unsafe(1); }); - env.public_context(|context| { context.push_nullifier(1); }); + env.public_context(|context| { context.push_nullifier_unsafe(1); }); } #[test(should_fail_with = "Contract calls are forbidden")] diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/utility_context.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/utility_context.nr index 8c48bfc9defc..487665e4dc9c 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/utility_context.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/utility_context.nr @@ -75,7 +75,7 @@ unconstrained fn check_nullifier_exists_nonexistent() { unconstrained fn check_nullifier_exists_settled() { let env = TestEnvironment::new(); - env.private_context(|context| { context.push_nullifier(1); }); + env.private_context(|context| { context.push_nullifier_unsafe(1); }); env.utility_context(|_| { assert(check_nullifier_exists(1)); }); } diff --git a/noir-projects/aztec-nr/uint-note/src/uint_note.nr b/noir-projects/aztec-nr/uint-note/src/uint_note.nr index 979f3934775c..00583d1e7d73 100644 --- a/noir-projects/aztec-nr/uint-note/src/uint_note.nr +++ b/noir-projects/aztec-nr/uint-note/src/uint_note.nr @@ -135,7 +135,7 @@ impl UintNote { // nullifier tree since it uses its own separator, making collisions with actual note nullifiers practically // impossible. let validity_commitment = partial_note.compute_validity_commitment(completer); - context.push_nullifier(validity_commitment); + context.push_nullifier_unsafe(validity_commitment); partial_note } diff --git a/noir-projects/noir-contracts/contracts/account/simulated_ecdsa_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/account/simulated_ecdsa_account_contract/src/main.nr index af4511c9ec29..0544820909ac 100644 --- a/noir-projects/noir-contracts/contracts/account/simulated_ecdsa_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/account/simulated_ecdsa_account_contract/src/main.nr @@ -38,10 +38,10 @@ pub contract SimulatedEcdsaAccount { let seed = unsafe { random() }; // Emit the initialization nullifier for the contract itself. - self.context.push_nullifier(seed); + self.context.push_nullifier_unsafe(seed); // Emit the initialization nullifier for the signing_public_key SinglePrivateImmutable. - self.context.push_nullifier(seed + 1); + self.context.push_nullifier_unsafe(seed + 1); // Emit the note hash for the signing key note. self.context.push_note_hash(seed + 2); diff --git a/noir-projects/noir-contracts/contracts/account/simulated_schnorr_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/account/simulated_schnorr_account_contract/src/main.nr index cfbdea31d4dc..9d3959ed947f 100644 --- a/noir-projects/noir-contracts/contracts/account/simulated_schnorr_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/account/simulated_schnorr_account_contract/src/main.nr @@ -40,10 +40,10 @@ pub contract SimulatedSchnorrAccount { let seed = unsafe { random() }; // Emit the initialization nullifier for the contract itself. - self.context.push_nullifier(seed); + self.context.push_nullifier_unsafe(seed); // Emit the initialization nullifier for the signing_public_key SinglePrivateImmutable. - self.context.push_nullifier(seed + 1); + self.context.push_nullifier_unsafe(seed + 1); // Emit the note hash for the signing key note. self.context.push_note_hash(seed + 2); diff --git a/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr index f8c5a2f4b816..90189549f536 100644 --- a/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr @@ -204,7 +204,7 @@ pub contract NFT { fn cancel_authwit(inner_hash: Field) { let on_behalf_of = self.msg_sender(); let nullifier = compute_authwit_nullifier(on_behalf_of, inner_hash); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } #[authorize_once("from", "authwit_nonce")] diff --git a/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr b/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr index 4b52fc52d803..6f0e47db7085 100644 --- a/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr +++ b/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr @@ -131,7 +131,7 @@ impl NFTNote { // the nullifier tree since it uses its own separator, making collisions with actual note nullifiers // practically impossible. let validity_commitment = partial_note.compute_validity_commitment(completer); - context.push_nullifier(validity_commitment); + context.push_nullifier_unsafe(validity_commitment); partial_note } diff --git a/noir-projects/noir-contracts/contracts/app/orderbook_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/orderbook_contract/src/main.nr index 9da0106f0064..1032473e2dba 100644 --- a/noir-projects/noir-contracts/contracts/app/orderbook_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/orderbook_contract/src/main.nr @@ -141,7 +141,7 @@ pub contract Orderbook { // a nullifier is cheaper (1 Field in DA instead of multiple Fields for the order). // TODO(F-399): pushing a raw nullifier with no domain separator like we do here is unsafe: we should instead // use something like a singleton `SingleUseClaim`. - self.context.push_nullifier(order_id); + self.context.push_nullifier_unsafe(order_id); // Enqueue the fulfillment to finalize both partial notes self.enqueue_self._fulfill_order(order_id, taker_partial_note, bid_token, order.bid_amount); diff --git a/noir-projects/noir-contracts/contracts/app/simple_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/simple_token_contract/src/main.nr index bb2da32153ad..06c66a0df8fc 100644 --- a/noir-projects/noir-contracts/contracts/app/simple_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/simple_token_contract/src/main.nr @@ -247,7 +247,7 @@ pub contract SimpleToken { fn cancel_authwit(inner_hash: Field) { let on_behalf_of = self.msg_sender(); let nullifier = compute_authwit_nullifier(on_behalf_of, inner_hash); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } #[internal("private")] diff --git a/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr index 9805be627732..8afb7bdd16c9 100644 --- a/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr @@ -276,7 +276,7 @@ pub contract Token { fn cancel_authwit(inner_hash: Field) { let on_behalf_of = self.msg_sender(); let nullifier = compute_authwit_nullifier(on_behalf_of, inner_hash); - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } // docs:end:cancel_authwit diff --git a/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr index 6ae17f9c7354..91e52f588160 100644 --- a/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr @@ -610,7 +610,7 @@ pub contract AvmTest { #[contract_library_method] fn _new_nullifier(context: PublicContext, nullifier: Field) { - context.push_nullifier(nullifier); + context.push_nullifier_unsafe(nullifier); } #[external("public")] @@ -630,7 +630,7 @@ pub contract AvmTest { #[external("public")] fn n_new_nullifiers(num: u32) { for i in 0..num { - self.context.push_nullifier(i as Field); + self.context.push_nullifier_unsafe(i as Field); } } @@ -672,7 +672,7 @@ pub contract AvmTest { // Use the standard context interface to emit a new nullifier #[external("public")] fn emit_nullifier_and_check(nullifier: Field) { - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); let exists = self.context.nullifier_exists_unsafe(nullifier, self.address); assert(exists, "Nullifier was just created, but its existence wasn't detected!"); } @@ -680,9 +680,9 @@ pub contract AvmTest { // Create the same nullifier twice (shouldn't work!) #[external("public")] fn nullifier_collision(nullifier: Field) { - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); // Can't do this twice! - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } #[external("public")] @@ -780,13 +780,13 @@ pub contract AvmTest { #[external("public")] fn create_same_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) { - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); self.call(AvmTest::at(nestedAddress).new_nullifier(nullifier)); } #[external("public")] fn create_different_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) { - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); self.call(AvmTest::at(nestedAddress).new_nullifier(nullifier + 1)); } diff --git a/noir-projects/noir-contracts/contracts/test/benchmarking_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/benchmarking_contract/src/main.nr index 0596a0b081c8..7f77d9c3e57f 100644 --- a/noir-projects/noir-contracts/contracts/test/benchmarking_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/benchmarking_contract/src/main.nr @@ -78,7 +78,7 @@ pub contract Benchmarking { // Safety: Benchmarking code let random_seed = unsafe { random() }; for i in 0..MAX_NULLIFIERS_PER_CALL { - self.context.push_nullifier(random_seed + (i as Field)); + self.context.push_nullifier_unsafe(random_seed + (i as Field)); } } diff --git a/noir-projects/noir-contracts/contracts/test/custom_message_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/custom_message_contract/src/main.nr index 31305cf716f8..b31163f2336c 100644 --- a/noir-projects/noir-contracts/contracts/test/custom_message_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/custom_message_contract/src/main.nr @@ -147,7 +147,7 @@ contract CustomMessage { // Emit commitment as nullifier computed from FULL event (same as standard events) let commitment = compute_private_event_commitment(event, randomness); - self.context.push_nullifier(commitment); + self.context.push_nullifier_unsafe(commitment); let event_type_id = MultiLogEvent::get_event_type_id().to_field(); diff --git a/noir-projects/noir-contracts/contracts/test/private_init_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/private_init_test_contract/src/main.nr index f4eadfc6292f..914301a00aba 100644 --- a/noir-projects/noir-contracts/contracts/test/private_init_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/private_init_test_contract/src/main.nr @@ -37,7 +37,7 @@ pub contract PrivateInitTest { #[external("private")] #[noinitcheck] fn private_no_init_check_emit_nullifier(nullifier: Field) { - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } #[external("utility")] diff --git a/noir-projects/noir-contracts/contracts/test/spam_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/spam_contract/src/main.nr index 7610fa0180b6..7de11f2d7754 100644 --- a/noir-projects/noir-contracts/contracts/test/spam_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/spam_contract/src/main.nr @@ -31,7 +31,7 @@ pub contract Spam { for i in 0..MAX_NULLIFIERS_PER_CALL { if (i < nullifier_count) { - self.context.push_nullifier(compute_note_nullifier(nullifier_seed, [i as Field])); + self.context.push_nullifier_unsafe(compute_note_nullifier(nullifier_seed, [i as Field])); } } diff --git a/noir-projects/noir-contracts/contracts/test/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/test_contract/src/main.nr index 674bcb767c3d..10084a241a8b 100644 --- a/noir-projects/noir-contracts/contracts/test/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/test_contract/src/main.nr @@ -287,13 +287,13 @@ pub contract Test { #[external("public")] fn emit_nullifier_public(nullifier: Field) { - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } #[external("private")] #[noinitcheck] fn emit_nullifier(nullifier: Field) { - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } // For testing non-note encrypted logs diff --git a/noir-projects/protocol-fuzzer/contracts/side_effect_contract/src/main.nr b/noir-projects/protocol-fuzzer/contracts/side_effect_contract/src/main.nr index 2b9b29f171b5..db015882abb0 100644 --- a/noir-projects/protocol-fuzzer/contracts/side_effect_contract/src/main.nr +++ b/noir-projects/protocol-fuzzer/contracts/side_effect_contract/src/main.nr @@ -165,7 +165,7 @@ pub contract SideEffect { #[external("private")] #[noinitcheck] fn emit_nullifier(nullifier: Field) { - self.context.push_nullifier(nullifier); + self.context.push_nullifier_unsafe(nullifier); } #[external("private")] From a15c6efac5735994dcd4bfa7f18167cb69ed27bb Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Fri, 22 May 2026 14:58:29 +0100 Subject: [PATCH 09/13] feat(aztec-nr)!: add explicit custom_sync_state hook to AztecConfig (#23446) --- .../docs/resources/migration_notes.md | 34 ++++ .../aztec-nr/aztec/src/macros/aztec.nr | 90 +++++++-- .../aztec/src/messages/discovery/mod.nr | 26 ++- .../src/messages/discovery/process_message.nr | 8 +- .../aztec/src/messages/processing/offchain.nr | 2 +- .../src/test/helpers/test_environment.nr | 8 +- .../user_defined_sync_state/Nargo.toml | 7 + .../user_defined_sync_state/src/main.nr | 12 ++ .../snapshots__stderr.snap | 4 +- .../snapshots__stderr.snap | 4 +- .../snapshots__stderr.snap | 4 +- .../snapshots__stderr.snap | 4 +- .../snapshots__stderr.snap | 2 +- .../bob_token/snapshots__stderr.snap | 4 +- .../invalid_note/snapshots__stderr.snap | 6 +- .../snapshots__stderr.snap | 2 +- .../snapshots__stderr.snap | 4 +- .../snapshots__stderr.snap | 2 +- .../snapshots__stderr.snap | 17 ++ .../amm_contract/snapshots__expanded.snap | 18 +- .../snapshots__expanded.snap | 2 +- .../snapshots__expanded.snap | 184 +++++++++--------- .../snapshots__expanded.snap | 2 +- .../snapshots__expanded.snap | 2 +- .../token_contract/snapshots__expanded.snap | 120 ++++++------ noir-projects/noir-contracts/Nargo.toml | 1 + .../custom_sync_state_contract/Nargo.toml | 9 + .../custom_sync_state_contract/src/main.nr | 70 +++++++ .../custom_sync_state_contract/src/test.nr | 42 ++++ 29 files changed, 472 insertions(+), 218 deletions(-) create mode 100644 noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_sync_state/Nargo.toml create mode 100644 noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_sync_state/src/main.nr create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_sync_state/snapshots__stderr.snap create mode 100644 noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/Nargo.toml create mode 100644 noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/src/main.nr create mode 100644 noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/src/test.nr diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 25f2795a901a..42e923dd34ef 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -9,6 +9,40 @@ Aztec is in active development. Each version may introduce breaking changes that ## TBD +### [Aztec.nr] Defining a custom `sync_state` function now requires `AztecConfig` + +Contracts that previously overrode the default `sync_state` by defining their own function with that name will now get a compile error. Use `AztecConfig::custom_sync_state()` instead. + +The custom hook receives the same parameters as `do_sync_state` and is responsible for calling it if default behavior is also desired. You can perform work before and/or after the default `do_sync_state` call, or skip it entirely. + +```diff ++ unconstrained fn my_custom_sync( ++ contract_address: AztecAddress, ++ compute_note_hash: ComputeNoteHash, ++ compute_note_nullifier: ComputeNoteNullifier, ++ process_custom_message: Option, ++ offchain_inbox_sync: Option, ++ scope: AztecAddress, ++ ) { ++ // optional: work before default sync ++ do_sync_state(contract_address, compute_note_hash, compute_note_nullifier, process_custom_message, offchain_inbox_sync, scope); ++ // optional: work after default sync ++ } + +- #[aztec] ++ #[aztec(::aztec::macros::AztecConfig::new().custom_sync_state(crate::my_custom_sync))] + contract MyContract { +- use aztec::macros::functions::external; +- +- #[external("utility")] +- unconstrained fn sync_state(scope: AztecAddress) { +- // custom sync logic +- } + } +``` + +**Impact**: Only contracts that manually defined a `sync_state` function are affected. Contracts using the default macro-generated `sync_state` require no changes. + ### [Aztec.nr] `push_nullifier` renamed to `push_nullifier_unsafe` `PrivateContext::push_nullifier` and `PublicContext::push_nullifier` have been renamed to `push_nullifier_unsafe` to diff --git a/noir-projects/aztec-nr/aztec/src/macros/aztec.nr b/noir-projects/aztec-nr/aztec/src/macros/aztec.nr index 84ee1bf2812b..dd6c11a96241 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/aztec.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/aztec.nr @@ -16,7 +16,7 @@ use crate::{ storage::STORAGE_LAYOUT_NAME, utils::{is_fn_contract_library_method, is_fn_external, is_fn_internal, is_fn_test, module_has_storage}, }, - messages::discovery::CustomMessageHandler, + messages::discovery::{CustomMessageHandler, CustomSyncHandler}, }; use compute_note_hash_and_nullifier::generate_contract_library_methods_compute_note_hash_and_nullifier; @@ -24,8 +24,8 @@ use compute_note_hash_and_nullifier::generate_contract_library_methods_compute_n /// Configuration for the [`aztec`] macro. /// /// This type lets users override different parts of the default aztec-nr contract behavior, such -/// as message handling. These are advanced features that require careful understanding of -/// the behavior of these systems. +/// as message handling and state synchronization. These are advanced features that require careful +/// understanding of the behavior of these systems. /// /// ## Examples /// @@ -34,7 +34,8 @@ use compute_note_hash_and_nullifier::generate_contract_library_methods_compute_n /// contract MyContract { ... } /// ``` pub struct AztecConfig { - custom_message_handler: Option>, + custom_message_handler: Option, + custom_sync_state: Option, } impl AztecConfig { @@ -43,7 +44,7 @@ impl AztecConfig { /// Calling `new` is equivalent to invoking the [`aztec`] macro with no parameters. The different methods /// (e.g. [`AztecConfig::custom_message_handler`]) can then be used to change the default behavior. pub comptime fn new() -> Self { - Self { custom_message_handler: Option::none() } + Self { custom_message_handler: Option::none(), custom_sync_state: Option::none() } } /// Sets a handler for custom messages. @@ -53,8 +54,23 @@ impl AztecConfig { /// /// `handler` must be a function that conforms to the /// [`crate::messages::discovery::CustomMessageHandler`] type signature. - pub comptime fn custom_message_handler(_self: Self, handler: CustomMessageHandler<()>) -> Self { - Self { custom_message_handler: Option::some(handler) } + pub comptime fn custom_message_handler(&mut self, handler: CustomMessageHandler) -> Self { + self.custom_message_handler = Option::some(handler); + *self + } + + /// Overrides the default state synchronization logic. + /// + /// The generated `sync_state` function will call `handler` instead of + /// [`crate::messages::discovery::do_sync_state`]. The handler receives all of the same parameters, so it can + /// run custom logic (e.g. fetching and decrypting custom logs) before, after, or instead of calling + /// `do_sync_state`. + /// + /// `handler` must be a function that conforms to the + /// [`crate::messages::discovery::CustomSyncHandler`] type signature. + pub comptime fn custom_sync_state(&mut self, handler: CustomSyncHandler) -> Self { + self.custom_sync_state = Option::some(handler); + *self } } @@ -105,7 +121,7 @@ pub comptime fn aztec(m: Module, args: [AztecConfig]) -> Quoted { let fn_abi_exports = create_fn_abi_exports(m); // We generate `_compute_note_hash`, `_compute_note_nullifier` (and the deprecated - // `_compute_note_hash_and_nullifier` wrapper) and `sync_state` functions only if they are not already implemented. + // `_compute_note_hash_and_nullifier` wrapper) only if they are not already implemented. // If they are implemented we just insert empty quotes. let contract_library_method_compute_note_hash_and_nullifier = if !m.functions().any(|f| { // Note that we don't test for `_compute_note_hash` or `_compute_note_nullifier` in order to make this simpler @@ -121,19 +137,29 @@ pub comptime fn aztec(m: Module, args: [AztecConfig]) -> Quoted { let handler = config.custom_message_handler.unwrap(); quote { Option::some($handler) } } else { - quote { Option::>::none() } + quote { Option::::none() } }; let offchain_inbox_sync_option = quote { Option::some(aztec::messages::processing::offchain::sync_inbox) }; - let sync_state_fn_and_abi_export = if !m.functions().any(|f| f.name() == quote { sync_state }) { - generate_sync_state(process_custom_message_option, offchain_inbox_sync_option) + if m.functions().any(|f| f.name() == quote { sync_state }) { + panic( + "User-defined 'sync_state' is not allowed. Use AztecConfig::custom_sync_state() to customize sync behavior.", + ); + } + + let custom_sync_handler = if config.custom_sync_state.is_some() { + let handler = config.custom_sync_state.unwrap(); + Option::some(quote { $handler }) } else { - quote {} + Option::none() }; + let sync_state_fn_and_abi_export = + generate_sync_state(process_custom_message_option, offchain_inbox_sync_option, custom_sync_handler); + if m.functions().any(|f| f.name() == quote { offchain_receive }) { panic( "User-defined 'offchain_receive' is not allowed. The function is auto-injected by the #[aztec] macro. See https://docs.aztec.network/errors/7", @@ -223,7 +249,36 @@ comptime fn generate_contract_interface(m: Module) -> Quoted { } /// Generates the `sync_state` utility function that performs message discovery. -comptime fn generate_sync_state(process_custom_message_option: Quoted, offchain_inbox_sync_option: Quoted) -> Quoted { +comptime fn generate_sync_state( + process_custom_message_option: Quoted, + offchain_inbox_sync_option: Quoted, + custom_sync_handler: Option, +) -> Quoted { + let body = if custom_sync_handler.is_some() { + let handler = custom_sync_handler.unwrap(); + quote { + $handler( + address, + _compute_note_hash, + _compute_note_nullifier, + $process_custom_message_option, + $offchain_inbox_sync_option, + scope, + ); + } + } else { + quote { + aztec::messages::discovery::do_sync_state( + address, + _compute_note_hash, + _compute_note_nullifier, + $process_custom_message_option, + $offchain_inbox_sync_option, + scope, + ); + } + }; + quote { pub struct sync_state_parameters { pub scope: aztec::protocol::address::AztecAddress, @@ -237,14 +292,7 @@ comptime fn generate_sync_state(process_custom_message_option: Quoted, offchain_ #[aztec::macros::internals_functions_generation::abi_attributes::abi_utility] unconstrained fn sync_state(scope: aztec::protocol::address::AztecAddress) { let address = aztec::context::UtilityContext::new().this_address(); - aztec::messages::discovery::do_sync_state( - address, - _compute_note_hash, - _compute_note_nullifier, - $process_custom_message_option, - $offchain_inbox_sync_option, - scope, - ); + $body } } } diff --git a/noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr b/noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr index bb51eb7755cc..a5651e627c49 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr @@ -98,7 +98,7 @@ pub type ComputeNoteHashAndNullifier = unconstrained fn[Env](/* packed_note /// Contracts that emit custom messages (i.e. any with a message type that is not in [`crate::messages::msg_type`]) /// need to use [`crate::macros::AztecConfig::custom_message_handler`] with a function of this type in order to /// process them. They will otherwise be **silently ignored**. -pub type CustomMessageHandler = unconstrained fn[Env]( +pub type CustomMessageHandler = unconstrained fn( /* contract_address */AztecAddress, /* msg_type_id */ u64, /* msg_metadata */ u64, @@ -106,6 +106,20 @@ pub type CustomMessageHandler = unconstrained fn[Env]( /* message_context */ MessageContext, /* scope */ AztecAddress); +/// Custom state synchronization handler. +/// +/// When set via [`crate::macros::AztecConfig::custom_sync_state`], the generated `sync_state` function will call +/// this handler instead of [`do_sync_state`]. It receives all of the same parameters, so it can run custom logic +/// (e.g. fetching and decrypting custom logs) before, after, or instead of calling [`do_sync_state`]. +pub type CustomSyncHandler = unconstrained fn( + /* contract_address */ AztecAddress, + /* compute_note_hash */ ComputeNoteHash, + /* compute_note_nullifier */ ComputeNoteNullifier, + /* process_custom_message */ Option, + /* offchain_inbox_sync */ Option, + /* scope */ AztecAddress, +); + /// Synchronizes the contract's private state with the network. /// /// As blocks are mined, it is possible for a contract's private state to change (e.g. with new notes being created), @@ -114,12 +128,12 @@ pub type CustomMessageHandler = unconstrained fn[Env]( /// /// The private state will be synchronized up to the block that will be used for private transactions (i.e. the anchor /// block. This will typically be close to the tip of the chain. -pub unconstrained fn do_sync_state( +pub unconstrained fn do_sync_state( contract_address: AztecAddress, compute_note_hash: ComputeNoteHash, compute_note_nullifier: ComputeNoteNullifier, - process_custom_message: Option>, - offchain_inbox_sync: Option>, + process_custom_message: Option, + offchain_inbox_sync: Option, scope: AztecAddress, ) { aztecnr_debug_log!("Performing state synchronization"); @@ -205,8 +219,8 @@ mod test { logs.push(PendingTaggedLog { log: BoundedVec::new(), context: std::mem::zeroed() }); assert_eq(logs.len(), 1); - let no_handler: Option> = Option::none(); - let no_inbox_sync: Option> = Option::none(); + let no_handler: Option = Option::none(); + let no_inbox_sync: Option = Option::none(); do_sync_state( contract_address, dummy_compute_note_hash, diff --git a/noir-projects/aztec-nr/aztec/src/messages/discovery/process_message.nr b/noir-projects/aztec-nr/aztec/src/messages/discovery/process_message.nr index 55937a9ec6ea..96726873e4dc 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/discovery/process_message.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/discovery/process_message.nr @@ -26,11 +26,11 @@ use crate::protocol::address::AztecAddress; /// /// Events are processed by computing an event commitment from the serialized event data and its randomness field, then /// enqueueing the event data and commitment for validation. -pub unconstrained fn process_message_ciphertext( +pub unconstrained fn process_message_ciphertext( contract_address: AztecAddress, compute_note_hash: ComputeNoteHash, compute_note_nullifier: ComputeNoteNullifier, - process_custom_message: Option>, + process_custom_message: Option, message_ciphertext: BoundedVec, message_context: MessageContext, recipient: AztecAddress, @@ -52,11 +52,11 @@ pub unconstrained fn process_message_ciphertext( } } -pub(crate) unconstrained fn process_message_plaintext( +pub(crate) unconstrained fn process_message_plaintext( contract_address: AztecAddress, compute_note_hash: ComputeNoteHash, compute_note_nullifier: ComputeNoteNullifier, - process_custom_message: Option>, + process_custom_message: Option, message_plaintext: BoundedVec, message_context: MessageContext, recipient: AztecAddress, diff --git a/noir-projects/aztec-nr/aztec/src/messages/processing/offchain.nr b/noir-projects/aztec-nr/aztec/src/messages/processing/offchain.nr index 066586b5955c..4775b95a6c74 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/processing/offchain.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/processing/offchain.nr @@ -48,7 +48,7 @@ global MAX_MSG_TTL: u64 = MAX_TX_LIFETIME + TX_EXPIRATION_TOLERANCE; /// /// The only current implementation of an `OffchainInboxSync` is [`sync_inbox`], which manages an inbox with expiration /// based eviction and automatic transaction context resolution. -pub(crate) type OffchainInboxSync = unconstrained fn[Env]( +pub type OffchainInboxSync = unconstrained fn( /* contract_address */AztecAddress, /* scope */ AztecAddress) -> EphemeralArray; /// A message delivered via the `offchain_receive` utility function. diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr index bb853bbfc1e7..561956ac8cfd 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr @@ -1318,7 +1318,7 @@ impl TestEnvironment { note.compute_nullifier_unconstrained(owner, unique_note_hash) }; - let process_custom_message: Option> = Option::none(); + let process_custom_message: Option = Option::none(); self.discover_data_in_message_plaintext( message_plaintext, opts.contract_address, @@ -1433,7 +1433,7 @@ impl TestEnvironment { ) }; - let process_custom_message: Option> = Option::none(); + let process_custom_message: Option = Option::none(); self.discover_data_in_message_plaintext( message_plaintext, opts.contract_address, @@ -1444,14 +1444,14 @@ impl TestEnvironment { ); } - unconstrained fn discover_data_in_message_plaintext( + unconstrained fn discover_data_in_message_plaintext( self, message_plaintext: BoundedVec, contract_address: Option, recipient: Option, compute_note_hash: ComputeNoteHash, compute_note_nullifier: ComputeNoteNullifier, - process_custom_message: Option>, + process_custom_message: Option, ) { // This function will emulate the message discovery and processing that would happen in a real contract, based // on a message plaintext. diff --git a/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_sync_state/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_sync_state/Nargo.toml new file mode 100644 index 000000000000..43c0fecda407 --- /dev/null +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_sync_state/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "user_defined_sync_state" +type = "contract" +authors = [""] + +[dependencies] +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_sync_state/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_sync_state/src/main.nr new file mode 100644 index 000000000000..f57905c0fddf --- /dev/null +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_sync_state/src/main.nr @@ -0,0 +1,12 @@ +/// The name `sync_state` is reserved for the function auto-injected by the #[aztec] macro. +/// Use AztecConfig::custom_sync_state() to customize sync behavior. +use aztec::macros::aztec; + +#[aztec] +contract UserDefinedSyncState { + use aztec::macros::functions::external; + use aztec::protocol::address::AztecAddress; + + #[external("private")] + fn sync_state(_scope: AztecAddress) {} +} diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap index a65ed2dba256..b2230482ea2f 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap @@ -12,7 +12,7 @@ error: Argument from in function foo must be of type AztecAddress, but is of typ 1: #[aztec] at src/main.nr:4:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:111:21 3: process_functions at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:9 4: [T]::map @@ -20,7 +20,7 @@ error: Argument from in function foo must be of type AztecAddress, but is of typ 5: process_functions at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41 6: generate_public_external - at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:134:9 + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:131:9 7: create_authorize_once_check at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:72:9 diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap index 57f6c20570f6..1d0d83a4885f 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap @@ -12,7 +12,7 @@ error: Function foo does not have a from parameter. Please specify which one to 1: #[aztec] at src/main.nr:4:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:111:21 3: process_functions at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:9 4: [T]::map @@ -20,7 +20,7 @@ error: Function foo does not have a from parameter. Please specify which one to 5: process_functions at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41 6: generate_public_external - at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:134:9 + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:131:9 7: create_authorize_once_check at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:67:9 diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap index a70f07d8bcc7..a2373050d810 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap @@ -12,7 +12,7 @@ error: Function foo does not have a authwit_nonce. Please specify which one to u 1: #[aztec] at src/main.nr:4:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:111:21 3: process_functions at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:9 4: [T]::map @@ -20,7 +20,7 @@ error: Function foo does not have a authwit_nonce. Please specify which one to u 5: process_functions at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41 6: generate_public_external - at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:134:9 + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:131:9 7: create_authorize_once_check at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:81:9 diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap index 6a4a3efa9cd0..0a20fe9e7d8d 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap @@ -12,7 +12,7 @@ error: Argument authwit_nonce in function foo must be of type Field, but is of t 1: #[aztec] at src/main.nr:4:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:111:21 3: process_functions at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:9 4: [T]::map @@ -20,7 +20,7 @@ error: Argument authwit_nonce in function foo must be of type Field, but is of t 5: process_functions at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41 6: generate_public_external - at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:134:9 + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:131:9 7: create_authorize_once_check at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:86:9 diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/aztec_macro_too_many_args/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/aztec_macro_too_many_args/snapshots__stderr.snap index e7043b21b324..94af4f9fb2a5 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/aztec_macro_too_many_args/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/aztec_macro_too_many_args/snapshots__stderr.snap @@ -12,6 +12,6 @@ error: #[aztec] expects 0 or 1 arguments, got 2 1: #[aztec] at src/main.nr:4:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:89:9 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:103:9 Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/bob_token/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/bob_token/snapshots__stderr.snap index 48141769333e..423a820781ee 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/bob_token/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/bob_token/snapshots__stderr.snap @@ -64,9 +64,9 @@ error: Function _assert_is_owner must be marked as either #[external(...)], #[in 1: #[aztec] at src/main.nr:18:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:93:5 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:107:5 3: check_each_fn_macroified - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:295:13 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:341:13 error: cannot find `self` in this scope ┌─ src/main.nr:41:9 diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_note/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_note/snapshots__stderr.snap index c8727783a33e..63957a4a7ed0 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_note/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_note/snapshots__stderr.snap @@ -10,13 +10,13 @@ error: InvalidNote has a packed length of 9 fields, which exceeds the maximum al │ = Call stack: 1: generate_sync_state - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:240:13 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:269:13 2: do_sync_state - at /noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr:130:5 + at /noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr:144:5 3: EphemeralArray::for_each at /noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr:99:13 4: do_sync_state - at /noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr:139:13 + at /noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr:153:13 5: process_message_ciphertext at /noir-projects/aztec-nr/aztec/src/messages/discovery/process_message.nr:41:9 6: process_message_plaintext diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_function_selector_collision/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_function_selector_collision/snapshots__stderr.snap index 5e1f5985c358..ffa6b777f47a 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_function_selector_collision/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_function_selector_collision/snapshots__stderr.snap @@ -12,7 +12,7 @@ error: Public function selector collision detected between functions 'fn_selecto 1: #[aztec] at src/main.nr:4:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:145:27 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:169:27 3: generate_public_dispatch at /noir-projects/aztec-nr/aztec/src/macros/dispatch.nr:20:19 4: [T]::map diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/unmacroified_function_in_contract/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/unmacroified_function_in_contract/snapshots__stderr.snap index d96287947c14..d86875453f24 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/unmacroified_function_in_contract/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/unmacroified_function_in_contract/snapshots__stderr.snap @@ -12,8 +12,8 @@ error: Function foo must be marked as either #[external(...)], #[internal(...)], 1: #[aztec] at src/main.nr:4:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:93:5 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:107:5 3: check_each_fn_macroified - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:295:13 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:341:13 Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_offchain_receive/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_offchain_receive/snapshots__stderr.snap index 75565319fd2a..f884b397a38d 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_offchain_receive/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_offchain_receive/snapshots__stderr.snap @@ -12,6 +12,6 @@ error: User-defined 'offchain_receive' is not allowed. The function is auto-inje 1: #[aztec] at src/main.nr:4:1 2: aztec - at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:138:9 + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:162:9 Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_sync_state/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_sync_state/snapshots__stderr.snap new file mode 100644 index 000000000000..3a3e1bf8ea88 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_sync_state/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: User-defined 'sync_state' is not allowed. Use AztecConfig::custom_sync_state() to customize sync behavior. + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:5:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:146:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap index e671b64900c1..8d76a72665ad 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap @@ -1001,7 +1001,7 @@ pub contract AMM { unconstrained fn sync_state(scope: AztecAddress) { let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); - aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::, aztec::messages::processing::MessageContext, AztecAddress)>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); } pub struct offchain_receive_parameters { @@ -1424,7 +1424,7 @@ pub contract AMM { returns_hash.get_preimage() } - pub fn swap_tokens_for_exact_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_out: u128, amount_in_max: u128, authwit_nonce: Field) { + pub fn swap_exact_tokens_for_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, authwit_nonce: Field) { let mut serialized_params: [Field; 5] = [0_Field; 5]; let mut offset: u32 = 0_u32; let serialized_member: [Field; 1] = ::serialize(token_in); @@ -1445,7 +1445,7 @@ pub contract AMM { } }; offset = offset + serialized_member_len; - let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member: [Field; 1] = ::serialize(amount_in); let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { @@ -1454,7 +1454,7 @@ pub contract AMM { } }; offset = offset + serialized_member_len; - let serialized_member: [Field; 1] = ::serialize(amount_in_max); + let serialized_member: [Field; 1] = ::serialize(amount_out_min); let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { @@ -1472,14 +1472,14 @@ pub contract AMM { } }; offset = offset + serialized_member_len; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2620890703_Field); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2960373586_Field); let args_hash: Field = aztec::hash::hash_args(serialized_params); aztec::oracle::execution_cache::store(serialized_params, args_hash); let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); returns_hash.get_preimage() } - pub fn swap_exact_tokens_for_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, authwit_nonce: Field) { + pub fn swap_tokens_for_exact_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_out: u128, amount_in_max: u128, authwit_nonce: Field) { let mut serialized_params: [Field; 5] = [0_Field; 5]; let mut offset: u32 = 0_u32; let serialized_member: [Field; 1] = ::serialize(token_in); @@ -1500,7 +1500,7 @@ pub contract AMM { } }; offset = offset + serialized_member_len; - let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member: [Field; 1] = ::serialize(amount_out); let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { @@ -1509,7 +1509,7 @@ pub contract AMM { } }; offset = offset + serialized_member_len; - let serialized_member: [Field; 1] = ::serialize(amount_out_min); + let serialized_member: [Field; 1] = ::serialize(amount_in_max); let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { @@ -1527,7 +1527,7 @@ pub contract AMM { } }; offset = offset + serialized_member_len; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2960373586_Field); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2620890703_Field); let args_hash: Field = aztec::hash::hash_args(serialized_params); aztec::oracle::execution_cache::store(serialized_params, args_hash); let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap index e1341d2cba98..c7f2843131a6 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap @@ -332,7 +332,7 @@ contract AvmGadgetsTest { unconstrained fn sync_state(scope: aztec::protocol::address::AztecAddress) { let address: aztec::protocol::address::AztecAddress = aztec::context::UtilityContext::new().this_address(); - aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::, aztec::messages::processing::MessageContext, aztec::protocol::address::AztecAddress)>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); } pub struct offchain_receive_parameters { diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap index 2ec9f691f21c..7fc55e104f8f 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap @@ -1492,10 +1492,10 @@ pub contract AvmTest { aztec::context::calls::PublicCall::<41, 2, ()>::new(self.target_contract, selector, "create_different_nullifier_in_nested_call", serialized_params) } - pub fn call_fee_juice(self) -> aztec::context::calls::PublicCall<14, 0, ()> { - let serialized_params: [Field; 0] = []; - let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); - aztec::context::calls::PublicCall::<14, 0, ()>::new(self.target_contract, selector, "call_fee_juice", serialized_params) + pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> aztec::context::calls::PublicCall<26, 300, Field> { + let serialized_params: [Field; 300] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); + aztec::context::calls::PublicCall::<26, 300, Field>::new(self.target_contract, selector, "nested_call_large_calldata", serialized_params) } pub fn get_transaction_fee(self) -> aztec::context::calls::PublicCall<19, 0, Field> { @@ -1522,6 +1522,12 @@ pub contract AvmTest { aztec::context::calls::PublicStaticCall::<18, 0, u8>::new(self.target_contract, selector, "set_opcode_u8_view", serialized_params) } + pub fn call_fee_juice(self) -> aztec::context::calls::PublicCall<14, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); + aztec::context::calls::PublicCall::<14, 0, ()>::new(self.target_contract, selector, "call_fee_juice", serialized_params) + } + pub fn assert_nullifier_exists(self, nullifier: Field) -> aztec::context::calls::PublicCall<23, 1, ()> { let serialized_params: [Field; 1] = nullifier.serialize(); let selector: FunctionSelector = FunctionSelector::from_field(2810255355_Field); @@ -1540,12 +1546,6 @@ pub contract AvmTest { aztec::context::calls::PublicCall::<13, 0, ()>::new(self.target_contract, selector, "debug_logging", serialized_params) } - pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> aztec::context::calls::PublicCall<26, 300, Field> { - let serialized_params: [Field; 300] = arr.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); - aztec::context::calls::PublicCall::<26, 300, Field>::new(self.target_contract, selector, "nested_call_large_calldata", serialized_params) - } - pub fn external_call_to_divide_by_zero_recovers(self) -> aztec::context::calls::PublicCall<40, 0, ()> { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); @@ -1874,7 +1874,7 @@ pub contract AvmTest { unconstrained fn sync_state(scope: AztecAddress) { let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); - aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::, aztec::messages::processing::MessageContext, AztecAddress)>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); } pub struct offchain_receive_parameters { @@ -2131,34 +2131,6 @@ pub contract AvmTest { } } - pub fn add_args_return(self, arg_a: Field, arg_b: Field) -> Field { - let mut serialized_params: [Field; 2] = [0_Field; 2]; - let mut offset: u32 = 0_u32; - let serialized_member: [Field; 1] = arg_a.serialize(); - let serialized_member_len: u32 = ::N; - for i in 0_u32..serialized_member_len { - { - let i_0: u32 = i + offset; - serialized_params[i_0] = serialized_member[i]; - } - }; - offset = offset + serialized_member_len; - let serialized_member: [Field; 1] = arg_b.serialize(); - let serialized_member_len: u32 = ::N; - for i in 0_u32..serialized_member_len { - { - let i_1: u32 = i + offset; - serialized_params[i_1] = serialized_member[i]; - } - }; - offset = offset + serialized_member_len; - let selector: FunctionSelector = FunctionSelector::from_field(2858633377_Field); - // Safety: comment added by `nargo expand` - unsafe { - aztec::context::calls::PublicCall::<15, 2, Field>::new(self.address, selector, "add_args_return", serialized_params).call(self.context) - } - } - pub fn variable_base_msm(self, scalar_lo: Field, scalar_hi: Field, scalar2_lo: Field, scalar2_hi: Field) -> Point { let mut serialized_params: [Field; 4] = [0_Field; 4]; let mut offset: u32 = 0_u32; @@ -2205,6 +2177,34 @@ pub contract AvmTest { } } + pub fn add_args_return(self, arg_a: Field, arg_b: Field) -> Field { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2858633377_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 2, Field>::new(self.address, selector, "add_args_return", serialized_params).call(self.context) + } + } + pub fn test_get_contract_instance_matches(self, address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field) { let mut serialized_params: [Field; 4] = [0_Field; 4]; let mut offset: u32 = 0_u32; @@ -2498,15 +2498,6 @@ pub contract AvmTest { } } - pub fn new_nullifier(self, nullifier: Field) { - let serialized_params: [Field; 1] = nullifier.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); - // Safety: comment added by `nargo expand` - unsafe { - aztec::context::calls::PublicCall::<13, 1, ()>::new(self.address, selector, "new_nullifier", serialized_params).call(self.context) - } - } - pub fn divide_by_zero(self, denominator: u8) -> u8 { let serialized_params: [Field; 1] = denominator.serialize(); let selector: FunctionSelector = FunctionSelector::from_field(815932481_Field); @@ -2525,6 +2516,15 @@ pub contract AvmTest { } } + pub fn new_nullifier(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 1, ()>::new(self.address, selector, "new_nullifier", serialized_params).call(self.context) + } + } + pub fn raw_l2_to_l1_msg(self, recipient: EthAddress, content: Field) { let mut serialized_params: [Field; 2] = [0_Field; 2]; let mut offset: u32 = 0_u32; @@ -2627,15 +2627,6 @@ pub contract AvmTest { } } - pub fn returndata_copy_oracle(self) { - let serialized_params: [Field; 0] = []; - let selector: FunctionSelector = FunctionSelector::from_field(4172530660_Field); - // Safety: comment added by `nargo expand` - unsafe { - aztec::context::calls::PublicCall::<22, 0, ()>::new(self.address, selector, "returndata_copy_oracle", serialized_params).call(self.context) - } - } - pub fn set_read_storage_single(self, a: Field) -> Field { let serialized_params: [Field; 1] = a.serialize(); let selector: FunctionSelector = FunctionSelector::from_field(1932358992_Field); @@ -2645,12 +2636,12 @@ pub contract AvmTest { } } - pub fn n_new_public_logs(self, num: u32) { - let serialized_params: [Field; 1] = num.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(2907114368_Field); + pub fn returndata_copy_oracle(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4172530660_Field); // Safety: comment added by `nargo expand` unsafe { - aztec::context::calls::PublicCall::<17, 1, ()>::new(self.address, selector, "n_new_public_logs", serialized_params).call(self.context) + aztec::context::calls::PublicCall::<22, 0, ()>::new(self.address, selector, "returndata_copy_oracle", serialized_params).call(self.context) } } @@ -2700,6 +2691,15 @@ pub contract AvmTest { } } + pub fn n_new_public_logs(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2907114368_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<17, 1, ()>::new(self.address, selector, "n_new_public_logs", serialized_params).call(self.context) + } + } + pub fn nested_call_to_nothing(self) { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(1183868090_Field); @@ -2783,12 +2783,12 @@ pub contract AvmTest { } } - pub fn call_fee_juice(self) { - let serialized_params: [Field; 0] = []; - let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); + pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> Field { + let serialized_params: [Field; 300 * 1] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); // Safety: comment added by `nargo expand` unsafe { - aztec::context::calls::PublicCall::<14, 0, ()>::new(self.address, selector, "call_fee_juice", serialized_params).call(self.context) + aztec::context::calls::PublicCall::<26, 300 * 1, Field>::new(self.address, selector, "nested_call_large_calldata", serialized_params).call(self.context) } } @@ -2819,6 +2819,15 @@ pub contract AvmTest { } } + pub fn call_fee_juice(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 0, ()>::new(self.address, selector, "call_fee_juice", serialized_params).call(self.context) + } + } + pub fn assert_nullifier_exists(self, nullifier: Field) { let serialized_params: [Field; 1] = nullifier.serialize(); let selector: FunctionSelector = FunctionSelector::from_field(2810255355_Field); @@ -2846,15 +2855,6 @@ pub contract AvmTest { } } - pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> Field { - let serialized_params: [Field; 300 * 1] = arr.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); - // Safety: comment added by `nargo expand` - unsafe { - aztec::context::calls::PublicCall::<26, 300 * 1, Field>::new(self.address, selector, "nested_call_large_calldata", serialized_params).call(self.context) - } - } - pub fn external_call_to_divide_by_zero_recovers(self) { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); @@ -3871,15 +3871,6 @@ pub contract AvmTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } - pub fn new_nullifier(self, nullifier: Field) { - let serialized_params: [Field; 1] = nullifier.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); - let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); - let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); - aztec::oracle::execution_cache::store(calldata, calldata_hash); - self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); - } - pub fn divide_by_zero(self, denominator: u8) { let serialized_params: [Field; 1] = denominator.serialize(); let selector: FunctionSelector = FunctionSelector::from_field(815932481_Field); @@ -3898,6 +3889,15 @@ pub contract AvmTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } + pub fn new_nullifier(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + pub fn raw_l2_to_l1_msg(self, recipient: EthAddress, content: Field) { let mut serialized_params: [Field; 2] = [0_Field; 2]; let mut offset: u32 = 0_u32; @@ -4156,6 +4156,15 @@ pub contract AvmTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } + pub fn nested_call_large_calldata(self, arr: [Field; 300]) { + let serialized_params: [Field; 300 * 1] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); + let calldata: [Field; 1 + (300 * 1)] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + pub fn call_fee_juice(self) { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); @@ -4219,15 +4228,6 @@ pub contract AvmTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } - pub fn nested_call_large_calldata(self, arr: [Field; 300]) { - let serialized_params: [Field; 300 * 1] = arr.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); - let calldata: [Field; 1 + (300 * 1)] = [selector.to_field()].concat(serialized_params); - let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); - aztec::oracle::execution_cache::store(calldata, calldata_hash); - self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); - } - pub fn external_call_to_divide_by_zero_recovers(self) { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap index 7bd15a82795d..c863124e5be8 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap @@ -308,7 +308,7 @@ pub contract PublicFnsWithEmitRepro { unconstrained fn sync_state(scope: aztec::protocol::address::AztecAddress) { let address: aztec::protocol::address::AztecAddress = aztec::context::UtilityContext::new().this_address(); - aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::, aztec::messages::processing::MessageContext, aztec::protocol::address::AztecAddress)>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); } pub struct offchain_receive_parameters { diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/storage_proof_test_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/storage_proof_test_contract/snapshots__expanded.snap index e08b63d47b43..c864347061c9 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/expand/storage_proof_test_contract/snapshots__expanded.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/storage_proof_test_contract/snapshots__expanded.snap @@ -309,7 +309,7 @@ contract StorageProofTest { unconstrained fn sync_state(scope: AztecAddress) { let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); - aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::, aztec::messages::processing::MessageContext, AztecAddress)>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); } pub struct offchain_receive_parameters { diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap index e7bc147862b9..075c453dacba 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap @@ -1217,7 +1217,7 @@ pub contract Token { unconstrained fn sync_state(scope: AztecAddress) { let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); - aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::, aztec::messages::processing::MessageContext, AztecAddress)>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); } pub struct offchain_receive_parameters { @@ -1309,10 +1309,10 @@ pub contract Token { } } - pub fn constructor(self, admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8) { - let mut serialized_params: [Field; 64] = [0_Field; 64]; + pub fn mint_to_public(self, to: AztecAddress, amount: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; let mut offset: u32 = 0_u32; - let serialized_member: [Field; 1] = ::serialize(admin); + let serialized_member: [Field; 1] = ::serialize(to); let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { @@ -1321,8 +1321,8 @@ pub contract Token { } }; offset = offset + serialized_member_len; - let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(name); - let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { let i_1: u32 = i + offset; @@ -1330,36 +1330,18 @@ pub contract Token { } }; offset = offset + serialized_member_len; - let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(symbol); - let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; - for i in 0_u32..serialized_member_len { - { - let i_2: u32 = i + offset; - serialized_params[i_2] = serialized_member[i]; - } - }; - offset = offset + serialized_member_len; - let serialized_member: [Field; 1] = ::serialize(decimals); - let serialized_member_len: u32 = ::N; - for i in 0_u32..serialized_member_len { - { - let i_3: u32 = i + offset; - serialized_params[i_3] = serialized_member[i]; - } - }; - offset = offset + serialized_member_len; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1578322623_Field); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1159421870_Field); // Safety: comment added by `nargo expand` unsafe { - aztec::context::calls::PublicCall::<11, 64, ()>::new(self.address, selector, "constructor", serialized_params).call(self.context) + aztec::context::calls::PublicCall::<14, 2, ()>::new(self.address, selector, "mint_to_public", serialized_params).call(self.context) } } - pub fn mint_to_public(self, to: AztecAddress, amount: u128) { + pub fn finalize_transfer_to_private(self, amount: u128, partial_note: PartialUintNote) { let mut serialized_params: [Field; 2] = [0_Field; 2]; let mut offset: u32 = 0_u32; - let serialized_member: [Field; 1] = ::serialize(to); - let serialized_member_len: u32 = ::N; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { let i_0: u32 = i + offset; @@ -1367,8 +1349,8 @@ pub contract Token { } }; offset = offset + serialized_member_len; - let serialized_member: [Field; 1] = ::serialize(amount); - let serialized_member_len: u32 = ::N; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { let i_1: u32 = i + offset; @@ -1376,18 +1358,18 @@ pub contract Token { } }; offset = offset + serialized_member_len; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1159421870_Field); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2599745508_Field); // Safety: comment added by `nargo expand` unsafe { - aztec::context::calls::PublicCall::<14, 2, ()>::new(self.address, selector, "mint_to_public", serialized_params).call(self.context) + aztec::context::calls::PublicCall::<28, 2, ()>::new(self.address, selector, "finalize_transfer_to_private", serialized_params).call(self.context) } } - pub fn finalize_transfer_to_private(self, amount: u128, partial_note: PartialUintNote) { - let mut serialized_params: [Field; 2] = [0_Field; 2]; + pub fn constructor(self, admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8) { + let mut serialized_params: [Field; 64] = [0_Field; 64]; let mut offset: u32 = 0_u32; - let serialized_member: [Field; 1] = ::serialize(amount); - let serialized_member_len: u32 = ::N; + let serialized_member: [Field; 1] = ::serialize(admin); + let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { let i_0: u32 = i + offset; @@ -1395,8 +1377,8 @@ pub contract Token { } }; offset = offset + serialized_member_len; - let serialized_member: [Field; 1] = ::serialize(partial_note); - let serialized_member_len: u32 = ::N; + let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(name); + let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; for i in 0_u32..serialized_member_len { { let i_1: u32 = i + offset; @@ -1404,10 +1386,28 @@ pub contract Token { } }; offset = offset + serialized_member_len; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2599745508_Field); + let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(symbol); + let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(decimals); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1578322623_Field); // Safety: comment added by `nargo expand` unsafe { - aztec::context::calls::PublicCall::<28, 2, ()>::new(self.address, selector, "finalize_transfer_to_private", serialized_params).call(self.context) + aztec::context::calls::PublicCall::<11, 64, ()>::new(self.address, selector, "constructor", serialized_params).call(self.context) } } @@ -1439,6 +1439,15 @@ pub contract Token { } } + pub fn _reduce_total_supply(self, amount: u128) { + let serialized_params: [Field; 1] = ::serialize(amount); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2253390209_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<20, 1, ()>::new(self.address, selector, "_reduce_total_supply", serialized_params).call(self.context) + } + } + pub fn transfer_in_public(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { let mut serialized_params: [Field; 4] = [0_Field; 4]; let mut offset: u32 = 0_u32; @@ -1485,15 +1494,6 @@ pub contract Token { } } - pub fn _reduce_total_supply(self, amount: u128) { - let serialized_params: [Field; 1] = ::serialize(amount); - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2253390209_Field); - // Safety: comment added by `nargo expand` - unsafe { - aztec::context::calls::PublicCall::<20, 1, ()>::new(self.address, selector, "_reduce_total_supply", serialized_params).call(self.context) - } - } - pub fn set_admin(self, new_admin: AztecAddress) { let serialized_params: [Field; 1] = ::serialize(new_admin); let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2519591682_Field); @@ -1598,10 +1598,10 @@ pub contract Token { } impl CallSelf<&mut PrivateContext> { - pub fn _recurse_subtract_balance(self, account: AztecAddress, amount: u128) -> u128 { + pub fn transfer(self, to: AztecAddress, amount: u128) { let mut serialized_params: [Field; 2] = [0_Field; 2]; let mut offset: u32 = 0_u32; - let serialized_member: [Field; 1] = ::serialize(account); + let serialized_member: [Field; 1] = ::serialize(to); let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { @@ -1619,17 +1619,17 @@ pub contract Token { } }; offset = offset + serialized_member_len; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1536394406_Field); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1968158567_Field); let args_hash: Field = aztec::hash::hash_args(serialized_params); aztec::oracle::execution_cache::store(serialized_params, args_hash); let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); returns_hash.get_preimage() } - pub fn transfer(self, to: AztecAddress, amount: u128) { + pub fn _recurse_subtract_balance(self, account: AztecAddress, amount: u128) -> u128 { let mut serialized_params: [Field; 2] = [0_Field; 2]; let mut offset: u32 = 0_u32; - let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member: [Field; 1] = ::serialize(account); let serialized_member_len: u32 = ::N; for i in 0_u32..serialized_member_len { { @@ -1647,7 +1647,7 @@ pub contract Token { } }; offset = offset + serialized_member_len; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1968158567_Field); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1536394406_Field); let args_hash: Field = aztec::hash::hash_args(serialized_params); aztec::oracle::execution_cache::store(serialized_params, args_hash); let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); @@ -2067,18 +2067,18 @@ pub contract Token { } impl CallSelfStatic<&mut PrivateContext> { - pub fn private_get_name(self) -> FieldCompressedString { + pub fn private_get_symbol(self) -> FieldCompressedString { let serialized_params: [Field; 0] = []; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3516522363_Field); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1295669651_Field); let args_hash: Field = aztec::hash::hash_args(serialized_params); aztec::oracle::execution_cache::store(serialized_params, args_hash); let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, true); returns_hash.get_preimage() } - pub fn private_get_symbol(self) -> FieldCompressedString { + pub fn private_get_name(self) -> FieldCompressedString { let serialized_params: [Field; 0] = []; - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1295669651_Field); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3516522363_Field); let args_hash: Field = aztec::hash::hash_args(serialized_params); aztec::oracle::execution_cache::store(serialized_params, args_hash); let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, true); diff --git a/noir-projects/noir-contracts/Nargo.toml b/noir-projects/noir-contracts/Nargo.toml index d0a2168911fe..25247903ccb1 100644 --- a/noir-projects/noir-contracts/Nargo.toml +++ b/noir-projects/noir-contracts/Nargo.toml @@ -47,6 +47,7 @@ members = [ "contracts/test/child_contract", "contracts/test/counter/counter_contract", "contracts/test/custom_message_contract", + "contracts/test/custom_sync_state_contract", "contracts/test/ephemeral_child_contract", "contracts/test/ephemeral_parent_contract", "contracts/test/event_only_contract", diff --git a/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/Nargo.toml new file mode 100644 index 000000000000..e48264fbe26b --- /dev/null +++ b/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "custom_sync_state_contract" +authors = [""] +compiler_version = ">=0.25.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../../aztec-nr/aztec" } +field_note = { path = "../../../../aztec-nr/field-note" } diff --git a/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/src/main.nr new file mode 100644 index 000000000000..87b1215db425 --- /dev/null +++ b/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/src/main.nr @@ -0,0 +1,70 @@ +// Tests the custom_sync_state AztecConfig option by registering a hook that counts how many times +// sync_state is called and then forwards to do_sync_state. +mod test; + +use ::aztec::{ + messages::discovery::{ + ComputeNoteHash, ComputeNoteNullifier, CustomMessageHandler, do_sync_state, + }, + messages::processing::offchain::OffchainInboxSync, + oracle::capsules, + protocol::{address::AztecAddress, hash::sha256_to_field}, +}; +use ::aztec::macros::aztec; + +global SYNC_COUNTER_SLOT: Field = sha256_to_field("SYNC_COUNTER".as_bytes()); + +#[aztec(::aztec::macros::AztecConfig::new().custom_sync_state(crate::my_custom_sync))] +contract CustomSyncState { + use aztec::macros::{ + functions::{external, initializer}, + storage::storage, + }; + use aztec::messages::message_delivery::MessageDelivery; + use aztec::protocol::address::AztecAddress; + use aztec::state_vars::{Owned, PrivateImmutable}; + use field_note::FieldNote; + + #[storage] + struct Storage { + value: Owned, Context>, + } + + #[external("private")] + #[initializer] + fn constructor(owner: AztecAddress, value: Field) { + let note = FieldNote { value }; + self.storage.value.at(owner).initialize(note).deliver( + MessageDelivery.ONCHAIN_UNCONSTRAINED, + ); + } + + #[external("utility")] + unconstrained fn read_value(owner: AztecAddress) -> pub Field { + self.storage.value.at(owner).view_note().value + } +} + +/// Counts how many times `sync_state` is invoked by incrementing a capsule counter, then forwards +/// to [`do_sync_state`] so that normal note discovery still happens. +unconstrained fn my_custom_sync( + contract_address: AztecAddress, + compute_note_hash: ComputeNoteHash, + compute_note_nullifier: ComputeNoteNullifier, + process_custom_message: Option, + offchain_inbox_sync: Option, + scope: AztecAddress, +) { + let current: Option = + capsules::load(contract_address, crate::SYNC_COUNTER_SLOT, scope); + let new_count = current.map(|c| c + 1).unwrap_or(1); + capsules::store(contract_address, crate::SYNC_COUNTER_SLOT, new_count, scope); + do_sync_state( + contract_address, + compute_note_hash, + compute_note_nullifier, + process_custom_message, + offchain_inbox_sync, + scope, + ); +} diff --git a/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/src/test.nr b/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/src/test.nr new file mode 100644 index 000000000000..949bf53535a9 --- /dev/null +++ b/noir-projects/noir-contracts/contracts/test/custom_sync_state_contract/src/test.nr @@ -0,0 +1,42 @@ +use crate::CustomSyncState; +use aztec::oracle::capsules; +use aztec::protocol::address::AztecAddress; +use aztec::test::helpers::test_environment::TestEnvironment; + +#[test] +unconstrained fn test_custom_sync_hook_is_called() { + let mut env = TestEnvironment::new(); + let owner = env.create_light_account(); + let value: Field = 42; + + let contract_address = env.deploy("CustomSyncState").with_private_initializer( + owner, + CustomSyncState::interface().constructor(owner, value), + ); + let target = CustomSyncState::at(contract_address); + + // After deploying and calling the private initializer, the hook should have been called once + let count = get_sync_count(env, contract_address, owner); + assert_eq(count, 1); + + // Reading the note via a utility function triggers another sync + let result = env.execute_utility(target.read_value(owner)); + + let count = get_sync_count(env, contract_address, owner); + assert_eq(count, 2); + + // The note was correctly discovered by do_sync_state (called by the hook) + assert_eq(result, value); +} + +unconstrained fn get_sync_count( + env: TestEnvironment, + contract_address: AztecAddress, + scope: AztecAddress, +) -> Field { + env.utility_context_at(contract_address, |_| { + let count: Option = + capsules::load(contract_address, crate::SYNC_COUNTER_SLOT, scope); + count.unwrap_or(0) + }) +} From c47e668342ded16d85692fe0173ac76078dbcc45 Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Sat, 23 May 2026 19:51:12 -0400 Subject: [PATCH 10/13] fix(ci): skip aztec-cli notify job when acceptance test is skipped (#23534) --- .github/workflows/aztec-cli-acceptance-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aztec-cli-acceptance-test.yml b/.github/workflows/aztec-cli-acceptance-test.yml index 1a1de972c320..acf4b5d98ff7 100644 --- a/.github/workflows/aztec-cli-acceptance-test.yml +++ b/.github/workflows/aztec-cli-acceptance-test.yml @@ -51,7 +51,7 @@ jobs: notify: needs: release-acceptance - if: always() && github.event_name != 'workflow_dispatch' + if: (success() || failure()) && github.event_name != 'workflow_dispatch' runs-on: ubuntu-latest env: VERSION: ${{ github.event.inputs.version || github.event.workflow_run.head_branch }} From 90de996a598eab12f4ea527d0ba4dc8cb1b42e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Sun, 24 May 2026 09:27:07 +0100 Subject: [PATCH 11/13] fix: released contract artifact aztec version (forward port of #23470) (#23500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forward-port of #23470 (originally merged to `backport-to-v4-next-staging` for the v4 release line). > [!IMPORTANT] > Do not merge until we get a green v4 nightly release. ## Summary The v4.3.0 release shipped contract artifact JSONs with `aztec_version: "dev"` baked in, which caused ci-compat-e2e to fail because the artifact version did not match the expected tested version. The root cause is that `REF_NAME` is not reliably populated when the release artifacts are built, so `stamp_aztec_version` in `noir-projects/noir-contracts/bootstrap.sh` was falling back to `"dev"`. The fix re-stamps the version at the point in the release process where the actual version is known: - `ci3/release_prep_package_json` now stamps `aztec_version` into `artifacts/*.json` at npm-publish time using the authoritative `$version` arg. - `release-image/Dockerfile` now re-stamps `aztec_version` into all shipped contract artifacts (accounts, noir-contracts.js, noir-test-contracts.js) using `$VERSION` at image build time. - `noir-projects/noir-contracts/bootstrap.sh` is simplified to always stamp `"dev"` (renamed to `stamp_dev_aztec_version`) — the real version is now applied at publish time by whichever path owns it. The `stamp_dev_aztec_version` helper preserves the `cat`/`rm` pattern from #23174 so artifact file permissions aren't clobbered. The `assertContractArtifactsVersion()` bypass from the original PR is omitted here because v5 doesn't have the bad v4.3.0 artifact in its compat matrix. ## Verification (from the original PR) - **npm release**: `DRY_RUN=1 ../../ci3/deploy_npm latest 5.1.0-test` produced artifacts with `aztec_version: "5.1.0-test"`. - **docker release**: built the docker image and inspected the contract artifacts inside — `aztec_version` matches `$VERSION`. Co-authored-by: Claude Opus 4.7 (1M context) --- ci3/release_prep_package_json | 10 ++++++++++ noir-projects/noir-contracts/bootstrap.sh | 21 +++++++++------------ release-image/Dockerfile | 12 ++++++++++++ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/ci3/release_prep_package_json b/ci3/release_prep_package_json index b03d5fc83cb1..70a727502687 100755 --- a/ci3/release_prep_package_json +++ b/ci3/release_prep_package_json @@ -22,3 +22,13 @@ for deps in dependencies devDependencies peerDependencies; do mv tmp.json package.json done done + +# Stamp aztec_version into any published noir contract artifacts in artifacts/*.json. The build-time stamp in +# noir-projects/noir-contracts/bootstrap.sh writes "dev"; $version here is the authoritative release version about to +# be written to package.json. We cannot stamp real version in bootstrap because there we don't have access to it. +if [ -d artifacts ]; then + for f in artifacts/*.json; do + [ -e "$f" ] || continue + jq --arg v "$version" '.aztec_version = $v' "$f" >$tmp && mv $tmp "$f" + done +fi diff --git a/noir-projects/noir-contracts/bootstrap.sh b/noir-projects/noir-contracts/bootstrap.sh index 5cf30927ae65..d5f5ca2cf90d 100755 --- a/noir-projects/noir-contracts/bootstrap.sh +++ b/noir-projects/noir-contracts/bootstrap.sh @@ -93,20 +93,17 @@ function get_contract_path { } export -f get_contract_path -# Stamps the aztec version into a contract artifact JSON in place. Mirrors stampAztecVersion in -# yarn-project/aztec/src/cli/cmds/compile.ts so monorepo-built artifacts match those produced by `aztec compile`. -# On release builds (REF_NAME is valid semver) the tag without the leading "v" is used; otherwise "dev". -function stamp_aztec_version { +# Stamps "dev" (DEV_VERSION) as the artifact's aztec_version - that is the expected version of a locally checked out +# monorepo. The real release version is applied at publish time by whichever path owns it: +# ci3/release_prep_package_json for npm packages, release-image/Dockerfile for the docker image. +function stamp_dev_aztec_version { local json_path=$1 - # "dev" here corresponds to DEV_VERSION in yarn-project/stdlib/src/update-checker/dev_version.ts. - local version="dev" - semver check "$REF_NAME" 2>/dev/null && version="${REF_NAME#v}" local tmp=$(mktemp) - jq --arg v "$version" '.aztec_version = $v' "$json_path" > "$tmp" + jq '.aztec_version = "dev"' "$json_path" > "$tmp" cat "$tmp" > "$json_path" rm "$tmp" } -export -f stamp_aztec_version +export -f stamp_dev_aztec_version # This compiles a noir contract, transpiles public functions, strips internal prefixes, # and generates verification keys for private functions via 'bb aztec_process'. @@ -128,9 +125,9 @@ function compile { $BB aztec_process -i $json_path cache_upload contract-$contract_hash.tar.gz $json_path fi - # Stamp the current version after the cache block so the field always matches the build's version, whether - # the artifact came from a fresh compile or a cache hit. - stamp_aztec_version "$json_path" + # Stamp the version after the cache block so the field is always present, whether the artifact came from a fresh + # compile or a cache hit. + stamp_dev_aztec_version "$json_path" } export -f compile diff --git a/release-image/Dockerfile b/release-image/Dockerfile index 4a4c329b3ff7..49378744b0b0 100644 --- a/release-image/Dockerfile +++ b/release-image/Dockerfile @@ -19,4 +19,16 @@ WORKDIR "/usr/src/yarn-project" ARG VERSION RUN echo '{".": "'$VERSION'"}' > /usr/src/.release-please-manifest.json +# Stamp aztec_version into the shipped contract artifacts. The build-time stamp in +# noir-projects/noir-contracts/bootstrap.sh writes "dev" unconditionally; $VERSION here is the authoritative release +# version for this image. +RUN for dir in \ + /usr/src/yarn-project/accounts/artifacts \ + /usr/src/yarn-project/noir-contracts.js/artifacts \ + /usr/src/yarn-project/noir-test-contracts.js/artifacts; do \ + for f in "$dir"/*.json; do \ + jq --arg v "$VERSION" '.aztec_version = $v' "$f" > /tmp/a.json && mv /tmp/a.json "$f"; \ + done; \ + done + ENTRYPOINT ["node", "--no-warnings", "/usr/src/yarn-project/aztec/dest/bin/index.js"] From d542c9b6d7e54aa378a35bad1f7754e3d5ee0956 Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 25 May 2026 09:14:00 +0000 Subject: [PATCH 12/13] fix --- .github/workflows/deploy-irm.yml | 4 +- .github/workflows/deploy-network.yml | 14 +- .github/workflows/deploy-staging-public.yml | 4 - .../workflows/ensure-funded-environment.yml | 3 +- .github/workflows/metrics-deploy.yml | 3 - .github/workflows/nightly-bench-10tps.yml | 122 +- .github/workflows/nightly-spartan-bench.yml | 375 +- .github/workflows/weekly-proving-bench.yml | 121 +- .test_patterns.yml | 73 +- avm-transpiler/src/procedures/compiler.rs | 2 - avm-transpiler/src/procedures/msm.rs | 24 +- avm-transpiler/src/transpile.rs | 21 +- aztec-up/bootstrap.sh | 19 + aztec-up/test/amm_flow.sh | 2 + aztec-up/test/basic_install.sh | 1 + aztec-up/test/bridge_and_claim.sh | 2 + .../pil/vm2/bytecode/address_derivation.pil | 201 +- .../bytecode/contract_instance_retrieval.pil | 44 +- barretenberg/cpp/pil/vm2/constants_gen.pil | 3 +- barretenberg/cpp/pil/vm2/ecc.pil | 39 +- barretenberg/cpp/pil/vm2/ecc_mem.pil | 122 +- barretenberg/cpp/pil/vm2/execution.pil | 14 +- barretenberg/cpp/pil/vm2/memory.pil | 5 +- .../pil/vm2/opcodes/get_contract_instance.pil | 39 +- barretenberg/cpp/pil/vm2/precomputed.pil | 3 +- barretenberg/cpp/pil/vm2/scalar_mul.pil | 14 +- barretenberg/cpp/scripts/chonk-inputs.hash | 2 +- .../avm_fuzzer/common/interfaces/dbs.cpp | 6 +- .../avm_fuzzer/fuzz_lib/fuzzer_context.cpp | 6 +- .../avm_fuzzer/fuzz_lib/instruction.hpp | 8 +- .../avm_fuzzer/fuzz_lib/program_block.cpp | 12 +- .../barretenberg/avm_fuzzer/fuzzer_lib.cpp | 6 +- .../avm_fuzzer/harness/ecc.fuzzer.cpp | 38 +- .../avm_fuzzer/mutations/bytecode.cpp | 6 +- .../mutations/instructions/instruction.cpp | 37 +- .../barretenberg/aztec/aztec_constants.hpp | 5 +- .../cpp/src/barretenberg/bbapi/bbapi_ecc.cpp | 12 +- .../src/barretenberg/bbapi/bbapi_ecdsa.cpp | 8 +- .../src/barretenberg/bbapi/bbapi_schnorr.cpp | 5 +- .../barretenberg/crypto/ecdsa/ecdsa_impl.hpp | 4 +- .../barretenberg/crypto/schnorr/schnorr.tcc | 2 +- .../acir_format/acir_to_constraint_buf.cpp | 45 +- .../dsl/acir_format/block_constraint.test.cpp | 43 +- .../dsl/acir_format/ec_operations.cpp | 19 +- .../dsl/acir_format/ec_operations.hpp | 13 +- .../dsl/acir_format/ec_operations.test.cpp | 81 +- .../dsl/acir_format/gate_count_constants.hpp | 4 +- .../dsl/acir_format/multi_scalar_mul.cpp | 20 +- .../dsl/acir_format/multi_scalar_mul.hpp | 1 - .../dsl/acir_format/multi_scalar_mul.test.cpp | 75 +- .../acir_format/opcode_gate_count.test.cpp | 46 +- .../dsl/acir_format/serde/acir.hpp | 73 +- .../dsl/acir_format/test_class.hpp | 48 +- .../barretenberg/dsl/acir_format/utils.hpp | 2 - .../dsl/acir_format/witness_constant.cpp | 27 +- .../dsl/acir_format/witness_constant.hpp | 1 - .../ecc/curves/invert_differential.fuzzer.cpp | 240 + .../ecc/fields/bernstein_yang_inverse.hpp | 369 + .../ecc/fields/bernstein_yang_inverse.md | 392 + .../fields/bernstein_yang_inverse.test.cpp | 150 + .../fields/bernstein_yang_inverse_wasm.hpp | 280 + .../ecc/fields/field_declarations.hpp | 1 + .../barretenberg/ecc/fields/field_impl.hpp | 25 + .../src/barretenberg/ecc/groups/element.hpp | 2 + .../barretenberg/ecc/groups/element_impl.hpp | 29 + .../nodejs_module/util/async_op.hpp | 52 +- .../src/barretenberg/vm2/common/avm_io.hpp | 16 +- .../barretenberg/vm2/common/aztec_types.hpp | 37 +- .../vm2/common/instruction_spec.cpp | 10 +- .../vm2/common/standard_affine_point.hpp | 35 +- .../vm2/common/standard_affine_point.test.cpp | 37 +- .../vm2/constraining/avm_fixed_vk.hpp | 62 +- .../relations/address_derivation.test.cpp | 67 +- .../contract_instance_retrieval.test.cpp | 117 +- .../vm2/constraining/relations/ecc.test.cpp | 184 +- .../relations/get_contract_instance.test.cpp | 11 +- .../relations/instr_fetching.test.cpp | 4 +- .../barretenberg/vm2/generated/columns.hpp | 18 +- .../vm2/generated/flavor_variables.hpp | 13 +- .../relations/address_derivation.hpp | 4 +- .../relations/address_derivation_impl.hpp | 40 +- .../relations/contract_instance_retrieval.hpp | 7 +- .../contract_instance_retrieval_impl.hpp | 11 +- .../vm2/generated/relations/ecc.hpp | 21 +- .../vm2/generated/relations/ecc_impl.hpp | 57 +- .../vm2/generated/relations/ecc_mem.hpp | 25 +- .../vm2/generated/relations/ecc_mem_impl.hpp | 81 +- .../relations/get_contract_instance_impl.hpp | 4 +- .../relations/lookups_address_derivation.cpp | 4 +- .../relations/lookups_address_derivation.hpp | 151 +- .../lookups_contract_instance_retrieval.hpp | 22 +- .../generated/relations/lookups_ecc_mem.hpp | 12 +- .../lookups_get_contract_instance.hpp | 21 +- .../relations/lookups_scalar_mul.hpp | 4 +- .../vm2/generated/relations/memory.hpp | 32 +- .../vm2/generated/relations/memory_impl.hpp | 73 +- .../vm2/generated/relations/perms_ecc_mem.hpp | 24 - .../generated/relations/perms_execution.hpp | 8 +- .../events/address_derivation_event.hpp | 1 + .../events/get_contract_instance_event.hpp | 3 +- .../simulation/gadgets/address_derivation.cpp | 58 +- .../gadgets/address_derivation.test.cpp | 24 +- .../vm2/simulation/gadgets/ecc.cpp | 46 +- .../vm2/simulation/gadgets/ecc.test.cpp | 42 +- .../vm2/simulation/gadgets/execution.cpp | 14 +- .../vm2/simulation/gadgets/execution.hpp | 2 - .../vm2/simulation/gadgets/execution.test.cpp | 11 +- .../gadgets/get_contract_instance.cpp | 30 +- .../vm2/simulation/lib/contract_crypto.cpp | 24 +- .../vm2/simulation/lib/hinting_dbs.cpp | 10 +- .../vm2/simulation/lib/raw_data_dbs.cpp | 9 +- .../vm2/simulation/lib/serialization.cpp | 2 - .../vm2/testing/avm_inputs.testdata.bin | Bin 2084088 -> 2081088 bytes .../src/barretenberg/vm2/testing/fixtures.cpp | 7 +- .../vm2/testing/minimal_tx.testdata.bin | Bin 189007 -> 190583 bytes .../vm2/tracegen/address_derivation_trace.cpp | 43 +- .../address_derivation_trace.test.cpp | 21 +- .../contract_instance_retrieval_trace.cpp | 18 +- ...contract_instance_retrieval_trace.test.cpp | 19 +- .../barretenberg/vm2/tracegen/ecc_trace.cpp | 27 +- .../vm2/tracegen/ecc_trace.test.cpp | 31 +- .../lib/get_contract_instance_spec.cpp | 7 +- .../lib/get_contract_instance_spec.hpp | 1 + .../vm2/tracegen/lib/interaction_builder.cpp | 19 +- .../vm2/tracegen/lib/interaction_builder.hpp | 21 +- .../vm2/tracegen/lib/interaction_def.hpp | 11 +- ...clk.hpp => lookup_into_indexed_by_row.hpp} | 0 .../lib/multi_permutation_builder.hpp | 10 +- .../vm2/tracegen/lib/shared_index_cache.hpp | 16 +- .../tracegen/lib/test_interaction_builder.hpp | 16 +- .../vm2/tracegen/memory_trace.cpp | 1 - .../opcodes/get_contract_instance_trace.cpp | 13 +- .../get_contract_instance_trace.test.cpp | 74 + .../vm2/tracegen/precomputed_trace.cpp | 3 +- bootstrap.sh | 84 +- ci.sh | 23 +- ci3/bootstrap_ec2 | 1 + .../version-v4.3.0/docs/aztec-nr/debugging.md | 2 +- .../docs/aztec-js/how_to_read_data.md | 4 + .../how_to_simulate_without_signing.md | 112 + .../framework-description/custom_notes.md | 6 +- .../docs/foundational-topics/accounts/keys.md | 18 +- .../docs/foundational-topics/pxe/index.md | 6 +- .../pxe/kernelless_simulations.md | 98 + .../docs/foundational-topics/wallets.md | 2 +- .../docs/resources/migration_notes.md | 92 +- .../reference/ethereum-rpc-reference.md | 2 +- .../slashing-configuration.md | 2 +- .../operators/setup/registering-sequencer.md | 6 +- docs/docs-words.txt | 2 + docs/examples/bootstrap.sh | 5 +- .../aztecjs_kernelless_simulation/config.yaml | 16 + .../ts/aztecjs_kernelless_simulation/index.ts | 167 + .../aztecjs_kernelless_simulation/yarn.lock | 0 docs/examples/ts/aztecjs_runner/run.sh | 26 +- docs/examples/ts/docker-compose.yml | 1 + .../reference/ethereum-rpc-reference.md | 2 +- .../operators/setup/registering-sequencer.md | 6 +- .../typescript-api/mainnet/foundation.md | 2 +- l1-contracts/bootstrap.sh | 7 +- .../src/core/slashing/SlashingProposer.sol | 11 +- .../aztec/src/context/private_context.nr | 45 +- .../aztec/src/keys/ecdh_shared_secret.nr | 26 +- .../aztec-nr/aztec/src/keys/ephemeral.nr | 14 +- .../aztec-nr/aztec/src/keys/getters/mod.nr | 29 +- .../aztec-nr/aztec/src/macros/notes.nr | 10 +- .../src/messages/encryption/poseidon2.nr | 17 +- .../aztec/src/oracle/get_contract_instance.nr | 19 + .../aztec-nr/aztec/src/oracle/keys.nr | 26 +- .../aztec/src/oracle/shared_secret.nr | 24 +- .../aztec/src/publish_contract_instance.nr | 20 +- .../aztec/src/state_vars/private_immutable.nr | 12 +- .../aztec/src/state_vars/private_mutable.nr | 12 +- .../state_vars/single_private_immutable.nr | 10 +- .../src/state_vars/single_private_mutable.nr | 12 +- .../aztec/src/state_vars/single_use_claim.nr | 7 +- .../helpers/test_environment/test/misc.nr | 5 +- .../aztec-nr/aztec/src/utils/point.nr | 30 +- .../aztec-nr/uint-note/src/uint_note.nr | 8 +- noir-projects/bootstrap.sh | 11 +- .../app/card_game_contract/src/cards.nr | 4 +- .../app/nft_contract/src/types/nft_note.nr | 8 +- .../src/handshake_note.nr | 6 +- .../src/main.nr | 57 +- .../src/main.nr | 1 + .../test/avm_test_contract/Nargo.toml | 1 + .../test/avm_test_contract/src/main.nr | 100 +- .../test/returning_tuple_contract/src/main.nr | 10 +- .../test/scope_test_contract/src/main.nr | 6 +- .../crates/private-kernel-init-2/Prover.toml | 4016 ++++++ .../crates/private-kernel-init-3/Prover.toml | 5989 ++++++++ .../crates/private-kernel-init/Prover.toml | 496 +- .../crates/private-kernel-inner-2/Prover.toml | 10000 +++++++++++++ .../crates/private-kernel-inner-3/Prover.toml | 11973 ++++++++++++++++ .../crates/private-kernel-inner/Prover.toml | 1326 +- .../key_validation_request_validator_tests.nr | 7 +- .../reset/key_validation_request/tests/mod.nr | 8 +- .../validate_key_validation_request.nr | 46 +- .../validate_contract_address_tests.nr | 2 +- .../output_composition_tests.nr | 3 +- .../key_validation_tests.nr | 2 +- .../src/tests/private_kernel_reset/mod.nr | 12 +- .../previous_kernel_validation_tests.nr | 7 +- .../previous_kernel_validation_tests.nr | 7 +- .../crates/private-kernel-reset/Prover.toml | 796 +- .../private-kernel-tail-to-public/Prover.toml | 702 +- .../crates/private-kernel-tail/Prover.toml | 838 +- .../src/fixture_builder.nr | 10 +- .../src/fixtures/contracts.nr | 18 +- .../crates/rollup-block-merge/Prover.toml | 518 +- .../Prover.toml | 246 +- .../Prover.toml | 284 +- .../rollup-block-root-first/Prover.toml | 360 +- .../rollup-block-root-single-tx/Prover.toml | 266 +- .../crates/rollup-block-root/Prover.toml | 516 +- .../rollup-checkpoint-merge/Prover.toml | 214 +- .../Prover.toml | 464 +- .../crates/rollup-checkpoint-root/Prover.toml | 562 +- .../crates/rollup-root/Prover.toml | 430 +- .../crates/rollup-tx-base-private/Prover.toml | 2444 ++-- .../crates/rollup-tx-base-public/Prover.toml | 338 +- .../crates/rollup-tx-merge/Prover.toml | 516 +- .../key_validation_request.nr | 16 +- .../key_validation_request_and_separator.nr | 3 +- .../crates/types/src/address/aztec_address.nr | 100 +- .../types/src/address/partial_address.nr | 3 +- .../src/address/salted_initialization_hash.nr | 9 +- .../crates/types/src/constants.nr | 19 +- .../crates/types/src/constants_tests.nr | 18 +- .../crates/types/src/contract_instance.nr | 3 + .../crates/types/src/point.nr | 172 +- .../crates/types/src/public_keys.nr | 209 +- .../crates/types/src/type_packing.nr | 14 +- noir/noir-repo | 2 +- playground/docker-compose.yml | 1 + .../aztec-node/templates/_pod-template.yaml | 18 +- spartan/aztec-node/values.yaml | 5 +- spartan/bootstrap.sh | 16 +- spartan/environments/alpha-net.env | 91 - spartan/environments/bench-10tps.env | 7 +- spartan/environments/block-capacity.env | 3 +- spartan/environments/devnet.env | 1 + spartan/environments/five-tps-long-epoch.env | 75 - spartan/environments/five-tps-short-epoch.env | 75 - spartan/environments/kind-minimal.env | 1 + spartan/environments/kind-provers.env | 1 + spartan/environments/mainnet.env | 7 +- spartan/environments/mbps-net.env | 68 - spartan/environments/mbps-pipeline.env | 69 - spartan/environments/network-defaults.yml | 22 +- spartan/environments/next-net-clone.env | 79 - spartan/environments/next-net.env | 5 +- spartan/environments/next-scenario.env | 3 +- spartan/environments/prove-n-tps-fake.env | 3 +- spartan/environments/prove-n-tps-real.env | 1 + spartan/environments/scenario.local.env | 1 + spartan/environments/staging-ignition.env | 42 - spartan/environments/staging-public.env | 3 +- spartan/environments/staging.local.env | 21 - spartan/environments/ten-tps-long-epoch.env | 76 - spartan/environments/ten-tps-short-epoch.env | 76 - spartan/environments/testnet.env | 3 +- spartan/environments/tps-scenario.env | 7 +- spartan/metrics/grafana/alerts/policies.yaml | 12 - .../grafana/dashboards/aztec_network.json | 185 +- .../metrics/grafana/dashboards/bootnodes.json | 4 +- .../irm-monitor/alerting/alert-rules.yml | 4 +- spartan/metrics/values.yaml | 3 +- .../bench_10tps/bench_output.schema.json | 545 +- spartan/scripts/bench_10tps/bench_scrape.ts | 186 +- spartan/scripts/check_env_vars.sh | 1 - spartan/scripts/deploy_network.sh | 7 +- spartan/scripts/network_pause.sh | 2 +- spartan/scripts/wait_for_l2_block.sh | 48 +- spartan/terraform/deploy-aztec-infra/main.tf | 21 +- .../values/blob-sink-resources-mainnet.yaml | 41 - .../values/bot-resources-dev.yaml | 21 +- .../values/bot-resources-prod.yaml | 10 +- .../full-node-resources-2-core-spot.yaml | 52 - .../values/full-node-resources-prod.yaml | 13 - ....yaml => prover-resources-dev-hi-tps.yaml} | 13 - .../values/prover-resources-mainnet.yaml | 83 - .../values/prover-resources-prod-hi-tps.yaml | 43 +- .../values/prover-resources-prod.yaml | 13 +- .../values/rpc-resources-mainnet.yaml | 39 - .../validator-resources-2-core-dedicated.yaml | 22 - .../values/validator-resources-ha.yaml | 10 + .../validator-resources-prod-hi-tps.yaml | 23 - ...pot.yaml => validator-resources-spot.yaml} | 19 - .../terraform/deploy-aztec-infra/variables.tf | 26 +- spartan/terraform/deploy-metrics/main.tf | 1 - spartan/terraform/deploy-metrics/variables.tf | 6 - spartan/testnet-runbook.md | 2 +- yarn-project/BRANCHING.md | 3 +- yarn-project/CLAUDE.md | 4 +- yarn-project/archiver/src/index.ts | 1 + .../src/modules/data_store_updater.test.ts | 129 + .../src/modules/data_store_updater.ts | 47 +- .../archiver/src/modules/l1_synchronizer.ts | 13 + .../archiver/src/store/block_store.ts | 203 +- .../archiver/src/store/l2_tips_cache.ts | 125 +- .../aztec-node/src/aztec-node/config.ts | 11 + .../aztec-node/src/aztec-node/server.test.ts | 75 + .../aztec-node/src/aztec-node/server.ts | 235 +- .../aztec-node/src/sentinel/README.md | 103 + .../aztec-node/src/sentinel/config.ts | 24 +- .../aztec-node/src/sentinel/factory.ts | 8 +- .../aztec-node/src/sentinel/sentinel.test.ts | 221 +- .../aztec-node/src/sentinel/sentinel.ts | 275 +- .../aztec-node/src/sentinel/store.test.ts | 66 +- yarn-project/aztec-node/src/sentinel/store.ts | 44 +- yarn-project/aztec-node/src/test/index.ts | 4 +- .../src/deployment/publish_instance.ts | 1 + yarn-project/aztec.js/src/utils/node.test.ts | 4 +- .../aztec.js/src/wallet/wallet.test.ts | 12 +- .../aztec/src/cli/aztec_start_action.ts | 4 +- yarn-project/aztec/src/cli/util.ts | 14 +- .../aztec/src/local-network/local-network.ts | 15 + .../aztec/src/testing/anvil_test_watcher.ts | 32 + yarn-project/aztec/src/testing/cheat_codes.ts | 21 +- yarn-project/bootstrap.sh | 6 +- yarn-project/cli-wallet/package.json | 2 +- yarn-project/constants/src/constants.gen.ts | 22 +- .../constants/src/scripts/constants.in.ts | 6 +- yarn-project/end-to-end/bootstrap.sh | 18 +- .../end-to-end/scripts/docker-compose.yml | 1 + .../end-to-end/scripts/test_simple.sh | 2 +- .../src/bench/tx_stats_bench.test.ts | 2 +- .../src/composed/e2e_cheat_codes.test.ts | 32 +- .../e2e_local_network_example.test.ts | 4 +- .../src/composed/e2e_persistence.test.ts | 38 +- .../e2e_token_bridge_tutorial_test.test.ts | 2 +- .../src/composed/ha/e2e_ha_full.test.ts | 230 +- .../uniswap_trade_on_l1_from_l2.test.ts | 3 +- ...e2e_multi_validator_node_key_store.test.ts | 7 +- .../end-to-end/src/e2e_2_pxes.test.ts | 3 +- .../end-to-end/src/e2e_abi_types.test.ts | 5 +- .../src/e2e_account_contracts.test.ts | 6 +- yarn-project/end-to-end/src/e2e_amm.test.ts | 10 +- .../end-to-end/src/e2e_authwit.test.ts | 6 +- .../end-to-end/src/e2e_automine_smoke.test.ts | 137 + .../end-to-end/src/e2e_avm_simulator.test.ts | 400 +- .../access_control.test.ts | 3 +- .../blacklist_token_contract_test.ts | 23 +- .../e2e_blacklist_token_contract/burn.test.ts | 6 +- .../minting.test.ts | 6 +- .../shielding.test.ts | 6 +- .../transfer_private.test.ts | 7 +- .../transfer_public.test.ts | 6 +- .../unshielding.test.ts | 7 +- .../end-to-end/src/e2e_block_building.test.ts | 133 +- yarn-project/end-to-end/src/e2e_bot.test.ts | 14 +- .../end-to-end/src/e2e_card_game.test.ts | 3 +- .../src/e2e_circuit_recorder.test.ts | 5 +- .../src/e2e_contract_updates.test.ts | 15 +- .../cross_chain_messaging_test.ts | 51 +- .../l1_to_l2.parallel.test.ts | 324 + .../l1_to_l2.test.ts | 288 - .../l2_to_l1.test.ts | 38 +- .../token_bridge_failure_cases.test.ts | 8 +- .../token_bridge_private.test.ts | 9 +- .../token_bridge_public.test.ts | 12 +- .../src/e2e_crowdfunding_and_claim.test.ts | 16 +- .../end-to-end/src/e2e_custom_message.test.ts | 5 +- .../end-to-end/src/e2e_debug_trace.test.ts | 11 +- .../contract_class_registration.test.ts | 53 +- .../e2e_deploy_contract/deploy_method.test.ts | 3 +- .../src/e2e_deploy_contract/deploy_test.ts | 5 +- .../src/e2e_deploy_contract/legacy.test.ts | 5 +- .../private_initialization.test.ts | 3 +- .../end-to-end/src/e2e_double_spend.test.ts | 5 +- .../e2e_epochs/epochs_equivocation.test.ts | 49 +- .../epochs_invalidate_block.parallel.test.ts | 13 +- .../e2e_epochs/epochs_mbps.parallel.test.ts | 4 +- .../e2e_epochs/epochs_missed_l1_slot.test.ts | 6 +- .../epochs_proof_at_boundary.parallel.test.ts | 30 +- .../epochs_proof_public_cross_chain.test.ts | 2 +- .../end-to-end/src/e2e_epochs/epochs_test.ts | 8 + .../src/e2e_escrow_contract.test.ts | 3 +- .../end-to-end/src/e2e_event_logs.test.ts | 5 +- .../end-to-end/src/e2e_event_only.test.ts | 5 +- .../src/e2e_expiration_timestamp.test.ts | 70 +- .../src/e2e_fee_asset_price_oracle.test.ts | 6 +- .../src/e2e_fees/account_init.test.ts | 8 +- .../end-to-end/src/e2e_fees/failures.test.ts | 42 +- .../src/e2e_fees/fee_juice_payments.test.ts | 9 +- .../src/e2e_fees/fee_settings.test.ts | 170 +- .../end-to-end/src/e2e_fees/fees_test.ts | 26 +- .../src/e2e_fees/gas_estimation.test.ts | 17 +- .../src/e2e_fees/private_payments.test.ts | 27 +- .../src/e2e_fees/public_payments.test.ts | 11 +- .../src/e2e_fees/sponsored_payments.test.ts | 11 +- .../src/e2e_genesis_timestamp.test.ts | 37 +- .../src/e2e_kernelless_simulation.test.ts | 3 +- yarn-project/end-to-end/src/e2e_keys.test.ts | 14 +- .../e2e_l1_publisher/e2e_l1_publisher.test.ts | 134 +- .../src/e2e_l1_with_wall_time.test.ts | 14 +- .../src/e2e_large_public_event.test.ts | 5 +- .../src/e2e_lending_contract.test.ts | 90 +- .../end-to-end/src/e2e_mempool_limit.test.ts | 7 +- .../end-to-end/src/e2e_multi_eoa.test.ts | 33 +- .../e2e_multi_validator_node.test.ts | 87 +- .../e2e_multiple_accounts_1_enc_key.test.ts | 8 +- .../end-to-end/src/e2e_multiple_blobs.test.ts | 3 +- .../src/e2e_nested_contract/importer.test.ts | 3 +- .../manual_private_call.test.ts | 3 +- .../manual_private_enqueue.test.ts | 3 +- .../e2e_nested_contract/manual_public.test.ts | 3 +- .../nested_contract_test.ts | 4 +- .../src/e2e_nested_utility_calls.test.ts | 6 +- yarn-project/end-to-end/src/e2e_nft.test.ts | 5 +- .../end-to-end/src/e2e_note_getter.test.ts | 3 +- .../src/e2e_offchain_effect.test.ts | 5 +- .../src/e2e_offchain_payment.test.ts | 80 +- .../end-to-end/src/e2e_option_params.test.ts | 5 +- .../end-to-end/src/e2e_orderbook.test.ts | 5 +- .../end-to-end/src/e2e_ordering.test.ts | 14 +- .../end-to-end/src/e2e_p2p/add_rollup.test.ts | 7 +- ...asted_invalid_block_proposal_slash.test.ts | 93 +- .../e2e_p2p/data_withholding_slash.test.ts | 291 +- .../duplicate_attestation_slash.test.ts | 12 + .../fee_asset_price_oracle_gossip.test.ts | 2 + ...tiple_validators_sentinel.parallel.test.ts | 4 +- .../src/e2e_p2p/reqresp/reqresp.test.ts | 6 + .../reqresp/reqresp_no_handshake.test.ts | 6 + .../end-to-end/src/e2e_p2p/reqresp/utils.ts | 27 +- .../sentinel_status_slash.parallel.test.ts | 414 + .../e2e_p2p/valid_epoch_pruned_slash.test.ts | 193 - .../end-to-end/src/e2e_partial_notes.test.ts | 5 +- .../e2e_pending_note_hashes_contract.test.ts | 24 +- .../end-to-end/src/e2e_phase_check.test.ts | 3 +- .../src/e2e_private_voting_contract.test.ts | 3 +- .../end-to-end/src/e2e_prover/client.test.ts | 42 +- .../end-to-end/src/e2e_prover/full.test.ts | 56 +- .../end-to-end/src/e2e_pruned_blocks.test.ts | 42 +- .../e2e_public_testnet_transfer.test.ts | 2 + .../src/e2e_publisher_funding_multi.test.ts | 10 +- yarn-project/end-to-end/src/e2e_pxe.test.ts | 3 +- .../src/e2e_scope_isolation.test.ts | 3 +- .../escape_hatch_vote_only.test.ts | 83 +- .../gov_proposal.parallel.test.ts | 59 +- .../src/e2e_sequencer/reload_keystore.test.ts | 2 + .../src/e2e_sequencer/slasher_config.test.ts | 2 + .../src/e2e_sequencer_config.test.ts | 7 +- .../end-to-end/src/e2e_simple.test.ts | 4 +- .../attested_invalid_proposal.test.ts | 574 + ..._invalid_checkpoint_proposal_slash.test.ts | 489 + .../end-to-end/src/e2e_snapshot_sync.test.ts | 3 +- .../end-to-end/src/e2e_state_vars.test.ts | 56 +- .../end-to-end/src/e2e_static_calls.test.ts | 8 +- .../e2e_storage_proof.test.ts | 3 +- .../end-to-end/src/e2e_synching.test.ts | 3 + .../e2e_token_contract/access_control.test.ts | 3 +- .../src/e2e_token_contract/burn.test.ts | 4 +- .../src/e2e_token_contract/minting.test.ts | 4 +- .../private_transfer_recursion.test.ts | 3 +- .../reading_constants.test.ts | 3 +- .../e2e_token_contract/token_contract_test.ts | 12 +- .../src/e2e_token_contract/transfer.test.ts | 3 +- .../transfer_in_private.test.ts | 4 +- .../transfer_in_public.test.ts | 4 +- .../transfer_to_private.test.ts | 4 +- .../transfer_to_public.test.ts | 4 +- .../src/e2e_tx_effect_oracle.test.ts | 3 +- .../src/fixtures/e2e_prover_test.ts | 4 +- .../end-to-end/src/fixtures/fixtures.ts | 64 + yarn-project/end-to-end/src/fixtures/setup.ts | 39 +- .../end-to-end/src/fixtures/setup_p2p_test.ts | 4 + .../writing_an_account_contract.test.ts | 3 +- .../end-to-end/src/shared/uniswap_l1_l2.ts | 2 +- .../src/simulators/lending_simulator.ts | 40 +- .../src/spartan/invalidate_blocks.test.ts | 10 +- .../end-to-end/src/spartan/n_tps.test.ts | 52 +- .../end-to-end/src/spartan/tx_metrics.ts | 98 +- .../end-to-end/src/test-wallet/utils.ts | 3 +- .../contracts/chain_state_override.test.ts | 24 + .../src/contracts/chain_state_override.ts | 35 +- .../src/contracts/governance_proposer.ts | 30 + .../ethereum/src/contracts/multicall.test.ts | 82 +- .../ethereum/src/contracts/multicall.ts | 284 +- .../ethereum/src/l1_tx_utils/l1_tx_utils.ts | 41 +- .../ethereum/src/test/eth_cheat_codes.ts | 10 + .../ethereum/src/test/rollup_cheat_codes.ts | 15 + yarn-project/ethereum/src/utils.ts | 18 + yarn-project/foundation/package.json | 1 + yarn-project/foundation/src/config/env_var.ts | 13 +- .../foundation/src/config/network_name.ts | 3 - .../src/curves/grumpkin/point.test.ts | 5 +- .../foundation/src/curves/grumpkin/point.ts | 68 +- .../foundation/src/fifo_set/fifo_set.test.ts | 62 + .../foundation/src/fifo_set/fifo_set.ts | 52 + yarn-project/foundation/src/fifo_set/index.ts | 1 + .../server/safe_json_rpc_server.test.ts | 58 + .../json-rpc/server/safe_json_rpc_server.ts | 34 +- yarn-project/foundation/src/timer/index.ts | 2 +- .../foundation/src/timer/timeout.test.ts | 30 +- yarn-project/foundation/src/timer/timeout.ts | 31 + yarn-project/key-store/src/key_store.test.ts | 56 +- yarn-project/key-store/src/key_store.ts | 62 +- .../__snapshots__/noir_test_gen.test.ts.snap | 24 +- .../src/conversion/client.ts | 19 +- .../src/conversion/common.ts | 5 +- .../src/conversion/type_conversion.test.ts | 2 +- .../src/noir_test_gen.test.ts | 7 +- yarn-project/p2p/src/client/interface.ts | 12 +- .../p2p/src/client/p2p_client.test.ts | 2 +- yarn-project/p2p/src/client/p2p_client.ts | 48 +- ...client.batch_tx_requester.bench.README.md} | 76 +- ...p_client.batch_tx_requester.bench.test.ts} | 8 +- .../p2p_client.integration_batch_txs.test.ts | 13 +- .../p2p_client.integration_reqresp.test.ts | 70 - .../proposal_tx_collector_worker.ts | 345 - .../proposal_tx_collector_worker_protocol.ts | 40 - yarn-project/p2p/src/config.ts | 37 +- yarn-project/p2p/src/errors/reqresp.error.ts | 25 - .../attestation_pool/attestation_pool.ts | 240 +- .../attestation_pool_test_suite.ts | 79 +- .../mem_pools/tx_pool_v2/tx_pool_v2_impl.ts | 16 +- .../block_proposal_validator.ts | 1 + .../checkpoint_proposal_validator.ts | 1 + .../proposal_validator/proposal_validator.ts | 5 +- .../contract_instance_validator.test.ts | 14 +- .../p2p/src/services/dummy_service.ts | 54 +- .../services/libp2p/libp2p_service.test.ts | 64 +- .../p2p/src/services/libp2p/libp2p_service.ts | 114 +- .../p2p/src/services/reqresp/README.md | 14 - .../batch_tx_requester.test.ts | 109 +- .../batch-tx-requester/batch_tx_requester.ts | 27 +- .../reqresp/batch-tx-requester/interface.ts | 13 +- .../batch-tx-requester/tx_validator.ts | 32 +- .../batch_connection_sampler.test.ts | 256 - .../batch_connection_sampler.ts | 161 - .../p2p/src/services/reqresp/interface.ts | 40 +- .../p2p/src/services/reqresp/reqresp.test.ts | 130 +- .../p2p/src/services/reqresp/reqresp.ts | 262 +- yarn-project/p2p/src/services/service.ts | 29 +- .../p2p/src/services/tx_collection/config.ts | 4 +- .../tx_collection/fast_tx_collection.ts | 379 - .../file_store_tx_collection.test.ts | 166 +- .../tx_collection/file_store_tx_collection.ts | 157 +- .../p2p/src/services/tx_collection/index.ts | 3 +- .../tx_collection/tx_collection.test.ts | 87 +- .../services/tx_collection/tx_collection.ts | 395 +- .../services/tx_file_store/tx_file_store.ts | 22 +- yarn-project/p2p/src/services/tx_provider.ts | 5 + .../p2p/src/test-helpers/mock-pubsub.ts | 70 +- .../p2p/src/test-helpers/reqresp-nodes.ts | 21 +- .../p2p/src/test-helpers/test_tx_provider.ts | 5 + .../p2p/src/test-helpers/testbench-utils.ts | 30 +- .../testbench/p2p_client_testbench_worker.ts | 9 +- .../ContractClassPublishedEventData.hex | 2 +- .../ContractInstancePublishedEventData.hex | 2 +- ...ontract_class_published_event.test.ts.snap | 8 +- ...ract_instance_published_event.test.ts.snap | 19 +- .../contract_instance_published_event.ts | 6 +- .../src/make_protocol_contract.ts | 4 +- .../src/scripts/generate_data.ts | 3 +- yarn-project/prover-client/package.json | 2 +- .../src/orchestrator/orchestrator.ts | 2 +- .../src/proving_broker/proving_broker.test.ts | 19 +- .../src/proving_broker/proving_broker.ts | 8 +- .../src/job/epoch-proving-job.test.ts | 100 +- .../prover-node/src/job/epoch-proving-job.ts | 98 +- .../src/prover-node-publisher.test.ts | 76 + .../prover-node/src/prover-node-publisher.ts | 54 + yarn-project/prover-node/src/prover-node.ts | 4 +- .../oracle/oracle.ts | 21 +- .../oracle/private_execution.test.ts | 24 +- .../oracle/utility_execution.test.ts | 17 +- .../oracle/utility_execution_oracle.ts | 10 +- ...ate_kernel_reset_private_inputs_builder.ts | 2 +- .../src/private_kernel/hints/test_utils.ts | 11 +- .../private_kernel_execution_prover.test.ts | 3 +- .../private_kernel/private_kernel_oracle.ts | 12 +- .../address_store/address_store.test.ts | 3 +- .../__snapshots__/AddressStore.json | 12 +- .../__snapshots__/ContractStore.json | 2 +- .../__snapshots__/KeyStore.json | 32 +- .../__snapshots__/opened_stores.json | 2 +- .../schema_tests.ts | 16 +- yarn-project/pxe/src/storage/metadata.ts | 2 +- .../sender_tagging_store.test.ts | 2 +- .../sync_sender_tagging_indexes.test.ts | 6 +- .../get_status_change_of_pending.test.ts | 6 +- yarn-project/sequencer-client/README.md | 98 +- yarn-project/sequencer-client/src/config.ts | 10 + yarn-project/sequencer-client/src/index.ts | 11 +- .../publisher/sequencer-bundle-simulator.ts | 253 + .../src/publisher/sequencer-publisher.test.ts | 389 +- .../src/publisher/sequencer-publisher.ts | 755 +- .../sequencer-client/src/sequencer/README.md | 10 +- .../src/sequencer/automine/README.md | 46 + .../sequencer/automine/automine_factory.ts | 145 + .../sequencer/automine/automine_sequencer.ts | 592 + .../src/sequencer/chain_state_overrides.ts | 213 +- .../sequencer/checkpoint_proposal_job.test.ts | 234 +- .../checkpoint_proposal_job.timing.test.ts | 4 +- .../src/sequencer/checkpoint_proposal_job.ts | 97 +- .../checkpoint_voter.ha.integration.test.ts | 7 +- .../sequencer-client/src/sequencer/events.ts | 35 +- .../sequencer-client/src/sequencer/index.ts | 2 + .../src/sequencer/sequencer.test.ts | 100 +- .../src/sequencer/sequencer.ts | 140 +- .../docs/avm/avm-isa-quick-reference.md | 6 +- .../docs/avm/opcodes/getcontractinstance.md | 3 +- .../docs/avm/public-tx-simulation.md | 2 +- .../public/avm/apps_tests/avm_test.test.ts | 15 + .../src/public/avm/avm_simulator.test.ts | 34 +- .../src/public/avm/fixtures/utils.ts | 3 + .../src/public/avm/opcodes/contract.test.ts | 6 +- .../src/public/avm/opcodes/contract.ts | 6 +- .../src/public/avm/opcodes/ec_add.test.ts | 268 +- .../src/public/avm/opcodes/ec_add.ts | 43 +- .../src/public/fixtures/bulk_test.ts | 26 + .../src/public/fixtures/opcode_spammer.ts | 12 +- .../simulator/src/public/fixtures/utils.ts | 17 +- .../src/public/hinting_db_sources.ts | 1 + .../apps_tests/deployments.test.ts | 2 +- .../public_processor/public_processor.test.ts | 34 +- .../public_processor/public_processor.ts | 68 +- .../public_tx_simulator.test.ts | 12 +- yarn-project/slasher/README.md | 80 +- yarn-project/slasher/src/config.ts | 31 +- yarn-project/slasher/src/index.ts | 4 +- .../src/slash_offenses_collector.test.ts | 4 +- .../slasher/src/stores/offenses_store.test.ts | 13 +- .../attestations_block_watcher.test.ts | 8 +- .../watchers/attestations_block_watcher.ts | 29 +- ...nvalid_checkpoint_proposal_watcher.test.ts | 290 + ...ted_invalid_checkpoint_proposal_watcher.ts | 199 + .../checkpoint_equivocation_watcher.test.ts | 120 + .../checkpoint_equivocation_watcher.ts | 98 + .../watchers/data_withholding_watcher.test.ts | 340 + .../src/watchers/data_withholding_watcher.ts | 227 + .../src/watchers/epoch_prune_watcher.test.ts | 260 - .../src/watchers/epoch_prune_watcher.ts | 256 - yarn-project/sqlite3mc-wasm/scripts/vendor.sh | 6 +- yarn-project/stdlib/src/abi/decoder.test.ts | 17 +- yarn-project/stdlib/src/abi/utils.ts | 6 +- yarn-project/stdlib/src/avm/avm.ts | 5 + yarn-project/stdlib/src/avm/message_pack.ts | 15 +- yarn-project/stdlib/src/avm/revert_code.ts | 6 - .../src/aztec-address/aztec-address.test.ts | 2 +- .../stdlib/src/block/l2_block_source.ts | 14 + .../l2_block_stream/l2_tips_store_base.ts | 25 +- .../checkpoint_reexecution_tracker.test.ts | 168 + .../checkpoint_reexecution_tracker.ts | 167 + yarn-project/stdlib/src/checkpoint/index.ts | 1 + .../src/contract/complete_address.test.ts | 8 +- .../stdlib/src/contract/complete_address.ts | 10 +- .../src/contract/contract_address.test.ts | 14 +- .../stdlib/src/contract/contract_address.ts | 10 +- .../stdlib/src/contract/contract_instance.ts | 13 +- .../contract/interfaces/contract_instance.ts | 8 +- .../stdlib/src/interfaces/archiver.test.ts | 6 +- .../src/interfaces/aztec-node-admin.test.ts | 19 +- .../stdlib/src/interfaces/aztec-node-admin.ts | 11 + .../stdlib/src/interfaces/aztec-node.test.ts | 10 +- .../stdlib/src/interfaces/block-builder.ts | 2 + yarn-project/stdlib/src/interfaces/configs.ts | 11 + yarn-project/stdlib/src/interfaces/p2p.ts | 8 + yarn-project/stdlib/src/interfaces/slasher.ts | 19 +- .../stdlib/src/interfaces/tx_provider.ts | 6 + .../stdlib/src/interfaces/validator.ts | 6 + .../kernel/hints/key_validation_request.ts | 34 +- .../stdlib/src/keys/derivation.test.ts | 40 +- yarn-project/stdlib/src/keys/derivation.ts | 23 +- yarn-project/stdlib/src/keys/public_key.ts | 28 +- .../stdlib/src/keys/public_keys.test.ts | 13 +- yarn-project/stdlib/src/keys/public_keys.ts | 196 +- .../stdlib/src/p2p/checkpoint_proposal.ts | 22 +- .../stdlib/src/slashing/helpers.test.ts | 25 +- yarn-project/stdlib/src/slashing/helpers.ts | 18 +- .../stdlib/src/slashing/serialization.test.ts | 10 +- yarn-project/stdlib/src/slashing/types.ts | 28 +- .../stdlib/src/slashing/votes.test.ts | 10 +- yarn-project/stdlib/src/tests/factories.ts | 30 +- yarn-project/stdlib/src/tx/tx_receipt.test.ts | 14 +- yarn-project/stdlib/src/tx/tx_receipt.ts | 9 - yarn-project/stdlib/src/validators/schemas.ts | 6 +- yarn-project/stdlib/src/validators/types.ts | 23 +- .../telemetry-client/src/attributes.ts | 1 - yarn-project/telemetry-client/src/config.ts | 12 + .../monitored_batch_span_processor.test.ts | 76 + .../src/monitored_batch_span_processor.ts | 25 +- yarn-project/telemetry-client/src/otel.ts | 7 +- .../telemetry-client/src/otel_propagation.ts | 43 +- yarn-project/telemetry-client/src/start.ts | 7 +- .../telemetry-client/src/telemetry.ts | 1 - yarn-project/txe/src/index.ts | 5 +- .../oracle/txe_oracle_top_level_context.ts | 4 +- yarn-project/txe/src/rpc_translator.ts | 33 +- .../txe/src/state_machine/dummy_p2p_client.ts | 22 +- yarn-project/validator-client/README.md | 19 +- yarn-project/validator-client/src/config.ts | 4 + .../src/duties/validation_service.ts | 13 +- yarn-project/validator-client/src/factory.ts | 5 + .../src/proposal_handler.test.ts | 20 +- .../validator-client/src/proposal_handler.ts | 245 +- .../src/validator.ha.integration.test.ts | 5 + .../src/validator.integration.test.ts | 4 +- .../validator-client/src/validator.test.ts | 352 +- .../validator-client/src/validator.ts | 136 +- .../src/native/ipc_world_state_instance.ts | 47 +- .../src/native/merkle_trees_facade.ts | 21 +- .../src/native/native_world_state.test.ts | 28 + .../src/native/native_world_state_instance.ts | 49 +- 707 files changed, 56066 insertions(+), 17732 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/ecc/curves/invert_differential.fuzzer.cpp create mode 100644 barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.hpp create mode 100644 barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.md create mode 100644 barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.test.cpp create mode 100644 barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp rename barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/{lookup_into_indexed_by_clk.hpp => lookup_into_indexed_by_row.hpp} (100%) create mode 100644 docs/docs-developers/docs/aztec-js/how_to_simulate_without_signing.md create mode 100644 docs/docs-developers/docs/foundational-topics/pxe/kernelless_simulations.md create mode 100644 docs/examples/ts/aztecjs_kernelless_simulation/config.yaml create mode 100644 docs/examples/ts/aztecjs_kernelless_simulation/index.ts create mode 100644 docs/examples/ts/aztecjs_kernelless_simulation/yarn.lock create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-init-2/Prover.toml create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-init-3/Prover.toml create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-inner-2/Prover.toml create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-inner-3/Prover.toml delete mode 100644 spartan/environments/alpha-net.env delete mode 100644 spartan/environments/five-tps-long-epoch.env delete mode 100644 spartan/environments/five-tps-short-epoch.env delete mode 100644 spartan/environments/mbps-net.env delete mode 100644 spartan/environments/mbps-pipeline.env delete mode 100644 spartan/environments/next-net-clone.env delete mode 100644 spartan/environments/staging-ignition.env delete mode 100644 spartan/environments/staging.local.env delete mode 100644 spartan/environments/ten-tps-long-epoch.env delete mode 100644 spartan/environments/ten-tps-short-epoch.env delete mode 100644 spartan/terraform/deploy-aztec-infra/values/blob-sink-resources-mainnet.yaml delete mode 100644 spartan/terraform/deploy-aztec-infra/values/full-node-resources-2-core-spot.yaml rename spartan/terraform/deploy-aztec-infra/values/{prover-resources-hi-tps.yaml => prover-resources-dev-hi-tps.yaml} (82%) delete mode 100644 spartan/terraform/deploy-aztec-infra/values/prover-resources-mainnet.yaml delete mode 100644 spartan/terraform/deploy-aztec-infra/values/rpc-resources-mainnet.yaml delete mode 100644 spartan/terraform/deploy-aztec-infra/values/validator-resources-2-core-dedicated.yaml create mode 100644 spartan/terraform/deploy-aztec-infra/values/validator-resources-ha.yaml delete mode 100644 spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-hi-tps.yaml rename spartan/terraform/deploy-aztec-infra/values/{validator-resources-prod-spot.yaml => validator-resources-spot.yaml} (57%) create mode 100644 yarn-project/aztec-node/src/sentinel/README.md create mode 100644 yarn-project/end-to-end/src/e2e_automine_smoke.test.ts create mode 100644 yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.parallel.test.ts delete mode 100644 yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts create mode 100644 yarn-project/end-to-end/src/e2e_p2p/sentinel_status_slash.parallel.test.ts delete mode 100644 yarn-project/end-to-end/src/e2e_p2p/valid_epoch_pruned_slash.test.ts create mode 100644 yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts create mode 100644 yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts create mode 100644 yarn-project/foundation/src/fifo_set/fifo_set.test.ts create mode 100644 yarn-project/foundation/src/fifo_set/fifo_set.ts create mode 100644 yarn-project/foundation/src/fifo_set/index.ts rename yarn-project/p2p/src/client/test/{tx_proposal_collector/README.md => p2p_client.batch_tx_requester.bench.README.md} (71%) rename yarn-project/p2p/src/client/test/{tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts => p2p_client.batch_tx_requester.bench.test.ts} (96%) delete mode 100644 yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts delete mode 100644 yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts delete mode 100644 yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.test.ts delete mode 100644 yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.ts delete mode 100644 yarn-project/p2p/src/services/tx_collection/fast_tx_collection.ts create mode 100644 yarn-project/sequencer-client/src/publisher/sequencer-bundle-simulator.ts create mode 100644 yarn-project/sequencer-client/src/sequencer/automine/README.md create mode 100644 yarn-project/sequencer-client/src/sequencer/automine/automine_factory.ts create mode 100644 yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts create mode 100644 yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.test.ts create mode 100644 yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts create mode 100644 yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.test.ts create mode 100644 yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.ts create mode 100644 yarn-project/slasher/src/watchers/data_withholding_watcher.test.ts create mode 100644 yarn-project/slasher/src/watchers/data_withholding_watcher.ts delete mode 100644 yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts delete mode 100644 yarn-project/slasher/src/watchers/epoch_prune_watcher.ts create mode 100644 yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.test.ts create mode 100644 yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.ts create mode 100644 yarn-project/telemetry-client/src/monitored_batch_span_processor.test.ts diff --git a/.github/workflows/deploy-irm.yml b/.github/workflows/deploy-irm.yml index b9f18c59cb93..873ed74dcb51 100644 --- a/.github/workflows/deploy-irm.yml +++ b/.github/workflows/deploy-irm.yml @@ -6,7 +6,7 @@ on: workflow_call: inputs: network: - description: "Network that IRM will be monitoring e.g. testnet, staging-ignition..." + description: "Network that IRM will be monitoring e.g. testnet..." required: true type: string default: "testnet" @@ -41,7 +41,7 @@ on: workflow_dispatch: inputs: network: - description: "Network that IRM will be monitoring e.g. testnet, staging-ignition..." + description: "Network that IRM will be monitoring e.g. testnet..." required: true type: string default: "testnet" diff --git a/.github/workflows/deploy-network.yml b/.github/workflows/deploy-network.yml index d25e6a76d04c..0a278740d88d 100644 --- a/.github/workflows/deploy-network.yml +++ b/.github/workflows/deploy-network.yml @@ -38,10 +38,15 @@ on: description: "Source tag that triggered this deploy" required: false type: string + notify_on_failure: + description: "Whether this workflow should send its own failure notification" + required: false + type: boolean + default: true workflow_dispatch: inputs: network: - description: "Network to deploy (e.g., staging-public, staging-ignition, testnet, next-net)" + description: "Network to deploy (e.g., staging-public, testnet, next-net)" required: true type: choice options: @@ -74,6 +79,11 @@ on: description: "Source tag that triggered this deploy" required: false type: string + notify_on_failure: + description: "Whether this workflow should send its own failure notification" + required: false + type: boolean + default: true concurrency: group: deploy-network-${{ inputs.network }}-${{ inputs.namespace || inputs.network }}-${{ inputs.aztec_docker_image || inputs.semver }}-${{ github.ref || github.ref_name }} @@ -242,7 +252,7 @@ jobs: } >> "$GITHUB_STEP_SUMMARY" - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() + if: failure() && inputs.notify_on_failure env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} diff --git a/.github/workflows/deploy-staging-public.yml b/.github/workflows/deploy-staging-public.yml index f7252194354c..a22aa33d054a 100644 --- a/.github/workflows/deploy-staging-public.yml +++ b/.github/workflows/deploy-staging-public.yml @@ -1,10 +1,6 @@ name: Deploy to staging-public on: - workflow_run: - workflows: ["Nightly Release Tag (v4-next)"] - types: - - completed workflow_dispatch: inputs: tag: diff --git a/.github/workflows/ensure-funded-environment.yml b/.github/workflows/ensure-funded-environment.yml index de5a20cec116..e06fef5b7039 100644 --- a/.github/workflows/ensure-funded-environment.yml +++ b/.github/workflows/ensure-funded-environment.yml @@ -6,7 +6,7 @@ on: workflow_call: inputs: environment: - description: 'Environment to fund (e.g., staging-public, next-net, staging-ignition, testnet)' + description: 'Environment to fund (e.g., staging-public, next-net, testnet)' required: true type: string low_watermark: @@ -32,7 +32,6 @@ on: options: - staging-public - next-net - - staging-ignition - testnet - devnet - tps-scenario diff --git a/.github/workflows/metrics-deploy.yml b/.github/workflows/metrics-deploy.yml index b8774a1a7e96..4350f6fb7054 100644 --- a/.github/workflows/metrics-deploy.yml +++ b/.github/workflows/metrics-deploy.yml @@ -100,7 +100,6 @@ jobs: GRAFANA_DASHBOARD_PASSWORD_SECRET_NAME: ${{ inputs.grafana_dashboard_password_secret_name }} SLACK_WEBHOOK_URL_SECRET_NAME: slack-webhook-url SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME: slack-webhook-staging-public-url - SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME: slack-webhook-staging-ignition-url SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME: slack-webhook-next-scenario-url SLACK_WEBHOOK_NEXT_NET_SECRET_NAME: slack-webhook-next-net-url SLACK_WEBHOOK_TESTNET_SECRET_NAME: slack-webhook-testnet-url @@ -164,7 +163,6 @@ jobs: -var="GRAFANA_PASSWORD_SECRET_NAME=${{ env.GRAFANA_DASHBOARD_PASSWORD_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_SECRET_NAME=${{ env.SLACK_WEBHOOK_URL_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME=${{ env.SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME }}" \ - -var="SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME=${{ env.SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME=${{ env.SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_NEXT_NET_SECRET_NAME=${{ env.SLACK_WEBHOOK_NEXT_NET_SECRET_NAME }}" \ -lock=${{ inputs.respect_tf_lock }} @@ -179,7 +177,6 @@ jobs: -var="GRAFANA_PASSWORD_SECRET_NAME=${{ env.GRAFANA_DASHBOARD_PASSWORD_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_SECRET_NAME=${{ env.SLACK_WEBHOOK_URL_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME=${{ env.SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME }}" \ - -var="SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME=${{ env.SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME=${{ env.SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_NEXT_NET_SECRET_NAME=${{ env.SLACK_WEBHOOK_NEXT_NET_SECRET_NAME }}" \ -out=tfplan \ diff --git a/.github/workflows/nightly-bench-10tps.yml b/.github/workflows/nightly-bench-10tps.yml index 89675dc16e65..68d79cb190cb 100644 --- a/.github/workflows/nightly-bench-10tps.yml +++ b/.github/workflows/nightly-bench-10tps.yml @@ -5,8 +5,12 @@ on: - cron: "30 6 * * *" workflow_dispatch: inputs: + docker_image: + description: "Full Docker image (e.g., aztecprotocol/aztec:my-tag). Takes precedence over nightly_tag." + required: false + type: string nightly_tag: - description: "Nightly tag to use (e.g., 2.3.4-nightly.20251209). Leave empty to auto-detect." + description: "Nightly tag to use (e.g., 2.3.4-nightly.20251209). Ignored if docker_image is set. Leave empty to auto-detect." required: false type: string @@ -15,29 +19,40 @@ concurrency: cancel-in-progress: true jobs: - benchmark: + select-image: runs-on: ubuntu-latest + outputs: + docker_image: ${{ steps.docker-image.outputs.docker_image }} + image_label: ${{ steps.docker-image.outputs.image_label }} steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: ref: next - - name: Determine nightly tag - id: nightly-tag + - name: Determine docker image + id: docker-image run: | - if [[ -n "${{ inputs.nightly_tag }}" ]]; then + if [[ -n "${{ inputs.docker_image }}" ]]; then + docker_image="${{ inputs.docker_image }}" + image_label="${{ inputs.docker_image }}" + elif [[ -n "${{ inputs.nightly_tag }}" ]]; then nightly_tag="${{ inputs.nightly_tag }}" + docker_image="aztecprotocol/aztec:${nightly_tag}" + image_label="${nightly_tag}" else current_version=$(jq -r '."."' .release-please-manifest.json) nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" + docker_image="aztecprotocol/aztec:${nightly_tag}" + image_label="${nightly_tag}" fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT - echo "Using nightly tag: $nightly_tag" + echo "docker_image=$docker_image" >> "$GITHUB_OUTPUT" + echo "image_label=$image_label" >> "$GITHUB_OUTPUT" + echo "Using docker image: $docker_image" - name: Check if Docker image exists run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" + DOCKER_IMAGE="${{ steps.docker-image.outputs.docker_image }}" echo "Checking if Docker image exists: $DOCKER_IMAGE" if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then echo "Docker image exists: $DOCKER_IMAGE" @@ -46,7 +61,56 @@ jobs: exit 1 fi - - name: Deploy and run 10 TPS benchmark + deploy-bench-10tps-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: bench-10tps + namespace: bench-10tps + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-for-first-l2-block: + needs: deploy-bench-10tps-network + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} + + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + run: | + cd spartan + ./bootstrap.sh wait_for_l2_block bench-10tps + + benchmark: + needs: + - select-image + - wait-for-first-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Run 10 TPS benchmark timeout-minutes: 240 env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} @@ -59,11 +123,25 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 240 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | - ./.github/ci3.sh network-bench-10tps bench-10tps bench-10tps "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" + ./.github/ci3.sh network-bench-10tps bench-10tps bench-10tps "${{ needs.select-image.outputs.docker_image }}" + + cleanup: + if: always() + needs: + - select-image + - deploy-bench-10tps-network + - wait-for-first-l2-block + - benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next - name: Cleanup network resources - if: always() env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -74,15 +152,29 @@ jobs: NO_SPOT: 1 run: ./.github/ci3.sh network-teardown bench-10tps bench-10tps + notify-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-bench-10tps-network + - wait-for-first-l2-block + - benchmark + - cleanup + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + IMAGE="${{ needs.select-image.outputs.image_label || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ - "Nightly 10 TPS benchmark FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ - "Nightly 10 TPS benchmark failed (nightly tag ${TAG}). CI run: ${RUN_URL}. Investigate the benchmark failure and identify the root cause." \ + "Nightly 10 TPS benchmark FAILED (image ${IMAGE}): <${RUN_URL}|View Run> (🤖)" \ + "Nightly 10 TPS benchmark failed (image ${IMAGE}). CI run: ${RUN_URL}. Investigate the benchmark failure and identify the root cause." \ --link "$RUN_URL" diff --git a/.github/workflows/nightly-spartan-bench.yml b/.github/workflows/nightly-spartan-bench.yml index 61d6f43abaf7..8b2c83f487d3 100644 --- a/.github/workflows/nightly-spartan-bench.yml +++ b/.github/workflows/nightly-spartan-bench.yml @@ -15,8 +15,11 @@ concurrency: cancel-in-progress: true jobs: - benchmark: + select-image: runs-on: ubuntu-latest + outputs: + nightly_tag: ${{ steps.nightly-tag.outputs.nightly_tag }} + docker_image: ${{ steps.nightly-tag.outputs.docker_image }} steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd @@ -32,12 +35,14 @@ jobs: current_version=$(jq -r '."."' .release-please-manifest.json) nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT + docker_image="aztecprotocol/aztec:${nightly_tag}" + echo "nightly_tag=$nightly_tag" >> "$GITHUB_OUTPUT" + echo "docker_image=$docker_image" >> "$GITHUB_OUTPUT" echo "Using nightly tag: $nightly_tag" - name: Check if Docker image exists run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" + DOCKER_IMAGE="${{ steps.nightly-tag.outputs.docker_image }}" echo "Checking if Docker image exists: $DOCKER_IMAGE" if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then echo "Docker image exists: $DOCKER_IMAGE" @@ -46,6 +51,59 @@ jobs: exit 1 fi + # --------------------------------------------------------------------------- + # TPS benchmark (env tps-scenario, namespace nightly-bench) + # --------------------------------------------------------------------------- + deploy-bench-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: tps-scenario + namespace: nightly-bench + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-bench-l2-block: + needs: deploy-bench-network + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} + + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NAMESPACE: nightly-bench + run: | + cd spartan + ./bootstrap.sh wait_for_l2_block tps-scenario + + benchmark: + needs: + - select-image + - wait-bench-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Run benchmarks timeout-minutes: 240 env: @@ -59,21 +117,10 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 240 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | # Pass the arguments expected in ./bootstrap.sh ci-network-bench - ./.github/ci3.sh network-bench tps-scenario nightly-bench "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - - - name: Cleanup network resources - if: always() - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} - BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} - GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - NO_SPOT: 1 - run: ./.github/ci3.sh network-teardown tps-scenario nightly-bench + ./.github/ci3.sh network-bench tps-scenario nightly-bench "${{ needs.select-image.outputs.docker_image }}" - name: Download benchmarks if: always() @@ -82,7 +129,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | if ./ci.sh gh-spartan-bench; then - echo "ENABLE_DEPLOY_BENCH=1" >> $GITHUB_ENV + echo "ENABLE_DEPLOY_BENCH=1" >> "$GITHUB_ENV" fi - name: Upload benchmarks @@ -102,49 +149,109 @@ jobs: fail-on-alert: false max-items-in-chart: 100 + cleanup-bench: + if: always() + needs: + - deploy-bench-network + - wait-bench-l2-block + - benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Cleanup network resources + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NO_SPOT: 1 + run: ./.github/ci3.sh network-teardown tps-scenario nightly-bench + + notify-bench-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-bench-network + - wait-bench-l2-block + - benchmark + - cleanup-bench + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + TAG="${{ needs.select-image.outputs.nightly_tag || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ "Nightly Spartan Benchmarks FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ "Nightly Spartan benchmarks failed (nightly tag ${TAG}). CI run: ${RUN_URL}. Investigate the benchmark failure and identify the root cause." \ --link "$RUN_URL" - proving-benchmark: + # --------------------------------------------------------------------------- + # Proving benchmark (env prove-n-tps-fake, namespace prove-n-tps-fake) + # --------------------------------------------------------------------------- + deploy-proving-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: prove-n-tps-fake + namespace: prove-n-tps-fake + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-proving-l2-block: + needs: deploy-proving-network runs-on: ubuntu-latest + timeout-minutes: 120 steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: ref: next - - name: Determine nightly tag - id: nightly-tag - run: | - if [[ -n "${{ inputs.nightly_tag }}" ]]; then - nightly_tag="${{ inputs.nightly_tag }}" - else - current_version=$(jq -r '."."' .release-please-manifest.json) - nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" - fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT - echo "Using nightly tag: $nightly_tag" + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} - - name: Check if Docker image exists + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NAMESPACE: prove-n-tps-fake run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - echo "Checking if Docker image exists: $DOCKER_IMAGE" - if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then - echo "Docker image exists: $DOCKER_IMAGE" - else - echo "Docker image does not exist: $DOCKER_IMAGE" - exit 1 - fi + cd spartan + ./bootstrap.sh wait_for_l2_block prove-n-tps-fake + + proving-benchmark: + needs: + - select-image + - wait-proving-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next - name: Run proving benchmarks timeout-minutes: 180 @@ -159,20 +266,9 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 180 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | - ./.github/ci3.sh network-proving-bench prove-n-tps-fake prove-n-tps-fake "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - - - name: Cleanup network resources - if: always() - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} - BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} - GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - NO_SPOT: 1 - run: ./.github/ci3.sh network-teardown prove-n-tps-fake prove-n-tps-fake + ./.github/ci3.sh network-proving-bench prove-n-tps-fake prove-n-tps-fake "${{ needs.select-image.outputs.docker_image }}" - name: Download benchmarks if: always() @@ -181,7 +277,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | if ./ci.sh gh-spartan-proving-bench; then - echo "ENABLE_DEPLOY_BENCH=1" >> $GITHUB_ENV + echo "ENABLE_DEPLOY_BENCH=1" >> "$GITHUB_ENV" fi - name: Upload benchmarks @@ -200,49 +296,109 @@ jobs: fail-on-alert: false max-items-in-chart: 100 + cleanup-proving: + if: always() + needs: + - deploy-proving-network + - wait-proving-l2-block + - proving-benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Cleanup network resources + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NO_SPOT: 1 + run: ./.github/ci3.sh network-teardown prove-n-tps-fake prove-n-tps-fake + + notify-proving-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-proving-network + - wait-proving-l2-block + - proving-benchmark + - cleanup-proving + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + TAG="${{ needs.select-image.outputs.nightly_tag || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ "Nightly Proving Benchmarks FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ "Nightly proving benchmarks failed (nightly tag ${TAG}). CI run: ${RUN_URL}. Investigate the benchmark failure and identify the root cause." \ --link "$RUN_URL" - block-capacity-benchmark: + # --------------------------------------------------------------------------- + # Block capacity benchmark (env block-capacity, namespace nightly-block-capacity) + # --------------------------------------------------------------------------- + deploy-block-capacity-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: block-capacity + namespace: nightly-block-capacity + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-block-capacity-l2-block: + needs: deploy-block-capacity-network runs-on: ubuntu-latest + timeout-minutes: 120 steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: - ref: merge-train/spartan + ref: next - - name: Determine nightly tag - id: nightly-tag - run: | - if [[ -n "${{ inputs.nightly_tag }}" ]]; then - nightly_tag="${{ inputs.nightly_tag }}" - else - current_version=$(jq -r '."."' .release-please-manifest.json) - nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" - fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT - echo "Using nightly tag: $nightly_tag" + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} - - name: Check if Docker image exists + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NAMESPACE: nightly-block-capacity run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - echo "Checking if Docker image exists: $DOCKER_IMAGE" - if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then - echo "Docker image exists: $DOCKER_IMAGE" - else - echo "Docker image does not exist: $DOCKER_IMAGE" - exit 1 - fi + cd spartan + ./bootstrap.sh wait_for_l2_block block-capacity + + block-capacity-benchmark: + needs: + - select-image + - wait-block-capacity-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next - name: Run block capacity benchmarks timeout-minutes: 240 @@ -257,20 +413,9 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 240 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | - ./.github/ci3.sh network-block-capacity-bench block-capacity nightly-block-capacity "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - - - name: Cleanup network resources - if: always() - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} - BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} - GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - NO_SPOT: 1 - run: ./.github/ci3.sh network-teardown block-capacity nightly-block-capacity + ./.github/ci3.sh network-block-capacity-bench block-capacity nightly-block-capacity "${{ needs.select-image.outputs.docker_image }}" - name: Download benchmarks if: always() @@ -279,7 +424,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | if ./ci.sh gh-spartan-block-capacity-bench; then - echo "ENABLE_DEPLOY_BENCH=1" >> $GITHUB_ENV + echo "ENABLE_DEPLOY_BENCH=1" >> "$GITHUB_ENV" fi - name: Upload benchmarks @@ -299,13 +444,51 @@ jobs: fail-on-alert: false max-items-in-chart: 100 + cleanup-block-capacity: + if: always() + needs: + - deploy-block-capacity-network + - wait-block-capacity-l2-block + - block-capacity-benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Cleanup network resources + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NO_SPOT: 1 + run: ./.github/ci3.sh network-teardown block-capacity nightly-block-capacity + + notify-block-capacity-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-block-capacity-network + - wait-block-capacity-l2-block + - block-capacity-benchmark + - cleanup-block-capacity + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + TAG="${{ needs.select-image.outputs.nightly_tag || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ "Nightly Block Capacity Benchmarks FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ diff --git a/.github/workflows/weekly-proving-bench.yml b/.github/workflows/weekly-proving-bench.yml index b8b383a23022..654a38c610a5 100644 --- a/.github/workflows/weekly-proving-bench.yml +++ b/.github/workflows/weekly-proving-bench.yml @@ -2,7 +2,7 @@ name: Weekly Real Proving Benchmark on: schedule: - - cron: "0 6 * * 1" # Every Monday at 6 AM UTC + - cron: "0 6 * * 1" # Every Monday at 6 AM UTC workflow_dispatch: inputs: nightly_tag: @@ -15,8 +15,11 @@ concurrency: cancel-in-progress: true jobs: - real-proving-benchmark: + select-image: runs-on: ubuntu-latest + outputs: + nightly_tag: ${{ steps.nightly-tag.outputs.nightly_tag }} + docker_image: ${{ steps.nightly-tag.outputs.docker_image }} steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd @@ -32,12 +35,15 @@ jobs: current_version=$(jq -r '."."' .release-please-manifest.json) nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT + + docker_image="aztecprotocol/aztec:${nightly_tag}" + echo "nightly_tag=$nightly_tag" >> "$GITHUB_OUTPUT" + echo "docker_image=$docker_image" >> "$GITHUB_OUTPUT" echo "Using nightly tag: $nightly_tag" - name: Check if Docker image exists run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" + DOCKER_IMAGE="${{ steps.nightly-tag.outputs.docker_image }}" echo "Checking if Docker image exists: $DOCKER_IMAGE" if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then echo "Docker image exists: $DOCKER_IMAGE" @@ -46,6 +52,53 @@ jobs: exit 1 fi + deploy-real-proving-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: prove-n-tps-real + namespace: prove-n-tps-real + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-for-first-l2-block: + needs: deploy-real-proving-network + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} + + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + run: | + cd spartan + ./bootstrap.sh wait_for_l2_block prove-n-tps-real + + benchmark: + needs: wait-for-first-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Run real proving benchmarks timeout-minutes: 180 env: @@ -59,20 +112,9 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 180 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | - ./.github/ci3.sh network-proving-bench prove-n-tps-real prove-n-tps-real "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - - - name: Cleanup network resources - if: always() - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} - BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} - GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - NO_SPOT: 1 - run: ./.github/ci3.sh network-teardown prove-n-tps-real prove-n-tps-real + ./.github/ci3.sh network-proving-bench prove-n-tps-real prove-n-tps-real - name: Download benchmarks if: always() @@ -81,7 +123,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | if ./ci.sh gh-spartan-proving-bench; then - echo "ENABLE_DEPLOY_BENCH=1" >> $GITHUB_ENV + echo "ENABLE_DEPLOY_BENCH=1" >> "$GITHUB_ENV" fi - name: Upload benchmarks @@ -100,13 +142,52 @@ jobs: fail-on-alert: false max-items-in-chart: 100 + cleanup: + if: always() + needs: + - select-image + - deploy-real-proving-network + - wait-for-first-l2-block + - benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Cleanup network resources + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NO_SPOT: 1 + run: ./.github/ci3.sh network-teardown prove-n-tps-real prove-n-tps-real + + notify-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-real-proving-network + - wait-for-first-l2-block + - benchmark + - cleanup + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + TAG="${{ needs.select-image.outputs.nightly_tag || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ "Weekly Real Proving Benchmark FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ diff --git a/.test_patterns.yml b/.test_patterns.yml index aaa4e6dadca2..299706444e55 100644 --- a/.test_patterns.yml +++ b/.test_patterns.yml @@ -116,9 +116,7 @@ tests: error_regex: "✕ Repay" owners: - *lasse - # http://ci.aztec-labs.com/e85ff6c5da65a1e7 - - regex: "src/e2e_cross_chain_messaging/l1_to_l2.test.ts" - error_regex: "Failed to advance block" + - regex: "src/e2e_cross_chain_messaging/l1_to_l2" owners: - *palla - regex: "src/e2e_cross_chain_messaging/token_bridge_private" @@ -141,6 +139,10 @@ tests: error_regex: "Anvil failed to stop in time|Cannot read properties of undefined" owners: - *palla + - regex: "src/e2e_bot.test.ts" + error_regex: "Tx dropped" + owners: + - *palla # yarn-project tests # Attempt to catch all kv-store browser test failures (consider them quarantined for now) @@ -164,6 +166,10 @@ tests: error_regex: "Error: Timeout of 2000ms exceeded" owners: - *martin + - regex: "kv-store/.*store\\.test" + error_regex: "guards against too many cursors" + owners: + - *palla - regex: "ethereum/src/test/tx_delayer.test.ts" error_regex: "delays a transaction until a given L1 timestamp" owners: @@ -172,6 +178,18 @@ tests: error_regex: "ContractFunctionExecutionError: The contract function" owners: - *mitch + # Under proposer pipelining each validator votes in its own slot and the votes + # don't aggregate into the same round, so the slashing quorum (3) is never + # reached within the 414s budget; the test consistently times out at the docker + # outer 600s (exit 124). The publisher refactor lands all vote-offenses tx's + # on L1 successfully — voteCount on the slasher proposer simply stays at 1 + # per round. This is a slashing-payload aggregation issue independent of + # publisher work; skip until the slashing team addresses it separately. + - regex: "e2e_p2p/valid_epoch_pruned_slash.test.ts" + skip: true + owners: + - *mitch + - *palla - regex: "archiver/src/archiver/archiver.test.ts" error_regex: "Received number of calls: 1" owners: @@ -185,14 +203,6 @@ tests: - *phil - *palla - # http://ci.aztec-labs.com/64a972aafaa40dd0 - # ProvingBroker › Retries › does not retry if job is stale — kv-store closes - # before the broker's final reportProvingJobError write lands. - - regex: "prover-client/src/proving_broker/proving_broker.test.ts" - error_regex: "does not retry if job is stale|Store is closed" - owners: - - *alex - # Nightly GKE tests - regex: "spartan/bootstrap.sh" owners: @@ -347,11 +357,42 @@ tests: owners: - *esau + # http://ci.aztec-labs.com/6db6103599cb22e6 + # Under pipelining, the lazy validator's attestation can arrive after the + # p2p checkpoint-attestation-validator's acceptance window, getting rejected + # before the slasher's gossip callback fires. The slasher then never records + # ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL and the test times out. + - regex: "src/e2e_slashing/attested_invalid_proposal.test.ts" + error_regex: "Timeout awaiting honest validator slash offenses for invalid proposal attestation" + owners: + - *palla + + # HA full suite is unstable under HA pipelining: multiple distinct failure + # modes (governance vote coord, work distribution, afterAll teardown hook + # timeouts, peer races on checkpoint proposals — see #23344, #23541, + # ci.aztec-labs.com/136431da99834194). Flagging individual error_regex + # entries and even the whole-suite flake match still let it dequeue PRs + # because ci3 retries once and the suite fails both attempts. Skip + # outright on merge-train/spartan until HA pipelining stabilises. - regex: "yarn-project/end-to-end/scripts/run_test.sh ha src/composed/ha/e2e_ha_full.test.ts" - error_regex: "✕ should coordinate governance voting across HA nodes" + skip: true owners: - *spyros + # Multi-validator web3signer suite is unstable under proposer pipelining: + # two distinct failure modes have been seen in the same "should build blocks + # & attest with multiple validator keys" case — Promise.all index-0 + # waitForTx aborting with "Tx dropped by P2P node" + # (ci.aztec-labs.com/9a5fa90aa18f62e7), and the proposer missing the slot's + # 5-attestation deadline ("AttestationTimeoutError" / "Block .* not found .* + # reorg") on PR #23344 run 26370196367 (ci.aztec-labs.com/b91d3218b5e88ae4). + # Error-regex flake matches still let ci3 retry-and-fail both attempts. Skip + # outright on merge-train/spartan until proposer pipelining stabilises. + - regex: "yarn-project/end-to-end/scripts/run_test.sh web3signer src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts" + skip: true + owners: + - *palla + # http://ci.aztec-labs.com/98d59d04f85223f8 # Build-cache flake: module not found during Jest startup - regex: "src/e2e_sequencer/gov_proposal.parallel.test.ts" @@ -374,3 +415,11 @@ tests: error_regex: "✕ verifies transactions at 10 TPS" owners: - *phil + + # http://ci.aztec-labs.com/930ddc9ede87059f + # Pipelining race: slasher doesn't record the duplicate proposal offense before + # the test's wait timeout — same family as #23501. + - regex: "src/e2e_p2p/duplicate_proposal_slash.test.ts" + error_regex: "TimeoutError: Timeout awaiting duplicate proposal offense" + owners: + - *palla diff --git a/avm-transpiler/src/procedures/compiler.rs b/avm-transpiler/src/procedures/compiler.rs index c3789e48b221..8cd6091881d6 100644 --- a/avm-transpiler/src/procedures/compiler.rs +++ b/avm-transpiler/src/procedures/compiler.rs @@ -233,10 +233,8 @@ fn compile_opcode( Mnemonic::ECADD => { collector.memory_address_operand()?; // p1 x collector.memory_address_operand()?; // p1 y - collector.memory_address_operand()?; // p1 is_infinite collector.memory_address_operand()?; // p2 x collector.memory_address_operand()?; // p2 y - collector.memory_address_operand()?; // p2 is_infinite collector.memory_address_operand()?; // result let collection = collector.finish()?; result.add_instruction( diff --git a/avm-transpiler/src/procedures/msm.rs b/avm-transpiler/src/procedures/msm.rs index f00f3504bb46..f952ae0ddac3 100644 --- a/avm-transpiler/src/procedures/msm.rs +++ b/avm-transpiler/src/procedures/msm.rs @@ -1,15 +1,13 @@ pub(crate) const MSM_ASSEMBLY: &str = " ; We are passed three pointers and one usize. - ; d0 points to the points. Points are represented by (x: Field, y: Field, is_infinite: bool) + ; d0 points to the points. Points are represented by (x: Field, y: Field). ; d1 points to the scalars. Scalars are represented by (lo: Field, hi: Field) both range checked to 128 bits. ; d2 contains the number of points. ; d3 points to the result. The result is a point. ADD d3, /*the reserved register 'one_usize'*/ $2, d4; Compute the pointer to the result y. - ADD d4, $2, d5; Compute the pointer to the result is_infinite ; Initialize the msm result: point at infinity SET i3, 0 ff SET i4, 0 ff - SET i5, 1 u1 ; Loop globals SET d6, 0 u32; Initialize the outer loop variable, ranging from 0 to the number of points SET d8, 0 ff; Initialize a 0 FF @@ -18,13 +16,12 @@ pub(crate) const MSM_ASSEMBLY: &str = " SET d10, 128 u32; Initialize a constant 128 SET d11, 1 u1; Initialize a constant true SET d12, 0 u1; Initialize a constant false - SET d13, 2 u32; Initialize a constant 2 - SET d14, 3 u32; Initialize a constant 3 for computing pointers to the point components + SET d13, 2 u32; Initialize a constant 2 for computing pointers to point and scalar components ; Main loop: iterate over the points/scalars OUTER_HEAD: LT d6, d2, d15 ; Check if we are done with the outer loop JUMPI d15, OUTER_BODY JUMP OUTER_END -OUTER_BODY: MUL d6, d14, d16; Compute the pointer to the point +OUTER_BODY: MUL d6, d13, d16; Compute the pointer to the point ADD d16, d0, d16; MUL d6, d13, d17; Compute the pointer to the scalar lo ADD d17, d1, d17 @@ -51,16 +48,13 @@ FIND_MSB_BODY: JUMPI i19, FIND_MSB_END; Check if the current bit is one JUMP FIND_MSB_BODY ; Now we have the pointer of the MSB in d19 - ; Now store the result of the scalar multiplication in d22, d23, d24 + ; Now store the result of the scalar multiplication in d22, d23 FIND_MSB_END: MOV i16, d22; x ADD d16, $2, d25; pointer to y MOV i25, d23; y - ADD d25, $2, d25; pointer to is_infinite - MOV i25, d24; is_infinite - ; Also store the original point in d25, d26, d27 + ; Also store the original point in d25, d26 MOV d22, d25; x MOV d23, d26; y - MOV d24, d27; is_infinite ; Now we need to do the inner loop, that will do double then add ; We need to iterate from the pointer of the MSB + 1 to the end pointer (d21) @@ -68,18 +62,18 @@ FIND_MSB_END: MOV i16, d22; x INNER_HEAD: LT d19, d21, d28; Check if we are done with the loop JUMPI d28, INNER_BODY JUMP INNER_END -INNER_BODY: ECADD d22, d23, d24, d22, d23, d24, /*not indirect, so the result is stored in d22, d23, d24*/ d22; Double the current result. +INNER_BODY: ECADD d22, d23, d22, d23, /*not indirect, so the result is stored in d22, d23*/ d22; Double the current result. EQ i19, d12, d28; Check if the current bit is zero JUMPI d28, INNER_INC; If the current bit is zero, continue - ECADD d25, d26, d27, d22, d23, d24, /*not indirect, so the result is stored in d22, d23, d24*/ d22; Add the original point to the result + ECADD d25, d26, d22, d23, /*not indirect, so the result is stored in d22, d23*/ d22; Add the original point to the result INNER_INC: ADD d19, $2, d19; Increment the pointer JUMP INNER_HEAD ; After the inner loop we have computed the scalar multiplication. Add it to the msm result -INNER_END: ECADD i3, i4, i5, d22, d23, d24, i3; Add the result to the msm result +INNER_END: ECADD i3, i4, d22, d23, i3; Add the result to the msm result OUTER_INC: ADD d6, $2, d6; Increment the outer loop variable JUMP OUTER_HEAD - ; After the outer loop we have computed the msm. We can return since we wrote the result in i3, i4, i5 + ; After the outer loop we have computed the msm. We can return since we wrote the result in i3, i4 OUTER_END: INTERNALRETURN "; diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 40e3a6f0bb4f..2380c95ce34e 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -1280,32 +1280,26 @@ fn handle_black_box_function( BlackBoxOp::EmbeddedCurveAdd { input1_x: p1_x_offset, input1_y: p1_y_offset, - input1_infinite: p1_infinite_offset, input2_x: p2_x_offset, input2_y: p2_y_offset, - input2_infinite: p2_infinite_offset, result, } => avm_instrs.push(AvmInstruction { opcode: AvmOpcode::ECADD, - // The result (SIXTH operand) is indirect (addressing mode). + // The result (FOURTH operand) is indirect (addressing mode). addressing_mode: Some( AddressingModeBuilder::default() .direct_operand(p1_x_offset) .direct_operand(p1_y_offset) - .direct_operand(p1_infinite_offset) .direct_operand(p2_x_offset) .direct_operand(p2_y_offset) - .direct_operand(p2_infinite_offset) .indirect_operand(&result.pointer) .build(), ), operands: vec![ AvmOperand::U16 { value: p1_x_offset.to_u32() as u16 }, AvmOperand::U16 { value: p1_y_offset.to_u32() as u16 }, - AvmOperand::U16 { value: p1_infinite_offset.to_u32() as u16 }, AvmOperand::U16 { value: p2_x_offset.to_u32() as u16 }, AvmOperand::U16 { value: p2_y_offset.to_u32() as u16 }, - AvmOperand::U16 { value: p2_infinite_offset.to_u32() as u16 }, AvmOperand::U16 { value: result.pointer.to_u32() as u16 }, ], ..Default::default() @@ -1313,20 +1307,19 @@ fn handle_black_box_function( BlackBoxOp::MultiScalarMul { points, scalars, outputs } => { // The length of the scalars vector is 2x the length of the points vector due to limb - // decomposition - // Output array is fixed to 3 + // decomposition. Points are (x, y); the point at infinity is encoded as (0, 0). assert_eq!( outputs.size, - SemiFlattenedLength(3), - "Output array size must be equal to 3" + SemiFlattenedLength(2), + "Output array size must be equal to 2" ); - assert_eq!(points.size.0 % 3, 0, "Points array size must be divisible by 3"); + assert_eq!(points.size.0 % 2, 0, "Points array size must be divisible by 2"); avm_instrs.push(generate_mov_to_procedure(&points.pointer, 0)); avm_instrs.push(generate_mov_to_procedure(&scalars.pointer, 1)); avm_instrs.push(generate_set_to_procedure( AvmTypeTag::UINT32, - &FieldElement::from(points.size.0 / 3), + &FieldElement::from(points.size.0 / 2), 2, )); avm_instrs.push(generate_mov_to_procedure(&outputs.pointer, 3)); @@ -1634,6 +1627,7 @@ fn handle_get_contract_instance( DEPLOYER, CLASS_ID, INIT_HASH, + IMMUTABLES_HASH, } assert_eq!(inputs.len(), 1); @@ -1643,6 +1637,7 @@ fn handle_get_contract_instance( "aztec_avm_getContractInstanceDeployer" => ContractInstanceMember::DEPLOYER, "aztec_avm_getContractInstanceClassId" => ContractInstanceMember::CLASS_ID, "aztec_avm_getContractInstanceInitializationHash" => ContractInstanceMember::INIT_HASH, + "aztec_avm_getContractInstanceImmutablesHash" => ContractInstanceMember::IMMUTABLES_HASH, _ => panic!("Transpiler doesn't know how to process function {:?}", function), }; diff --git a/aztec-up/bootstrap.sh b/aztec-up/bootstrap.sh index dad8802868d8..4618253bca97 100755 --- a/aztec-up/bootstrap.sh +++ b/aztec-up/bootstrap.sh @@ -20,6 +20,9 @@ function build { echo # Create Verdaccio config. + # publish.allow_offline lets verdaccio accept publishes when the npmjs + # uplink is briefly unreachable, instead of returning 503. We never want + # the upstream existence check to gate these local fake-publishes. cat > /tmp/verdaccio-config.yaml < P == -Q (INVERSE_PRED == true): // R := O // If P == O: - // R := Q (r_x := q_x, r_y := q_y, r_is_inf = q_is_inf) + // R := Q (r_x := q_x, r_y := q_y) // Vice versa, if Q == O: - // R := P (r_x := p_x, r_y := p_y, r_is_inf = p_is_inf) + // R := P (r_x := p_x, r_y := p_y) // pol INVERSE_PRED = x_match * (1 - y_match); @@ -182,6 +191,4 @@ namespace ecc; sel * (r_x - (EITHER_INF * (p_is_inf * q_x + q_is_inf * p_x)) - result_infinity * INFINITY_X - use_computed_result * COMPUTED_R_X) = 0; #[OUTPUT_Y_COORD] sel * (r_y - (EITHER_INF * (p_is_inf * q_y + q_is_inf * p_y)) - result_infinity * INFINITY_Y - use_computed_result * COMPUTED_R_Y) = 0; - #[OUTPUT_INF_FLAG] - sel * (r_is_inf - result_infinity) = 0; diff --git a/barretenberg/cpp/pil/vm2/ecc_mem.pil b/barretenberg/cpp/pil/vm2/ecc_mem.pil index efd63ca6814c..e7d6d41e01e1 100644 --- a/barretenberg/cpp/pil/vm2/ecc_mem.pil +++ b/barretenberg/cpp/pil/vm2/ecc_mem.pil @@ -8,28 +8,29 @@ include "precomputed.pil"; * This handles the memory writes when the ECADD opcode is executed by user code. * Given two points, P & Q, this trace constrains that both exist on the Grumpkin curve * and the claimed result point, R = P + Q, is written to memory addresses within range. + * A point exists on the curve if it satisfies the curve equation (SW form: Y^2 = X^3 − 17) + * or is the point at infinity, represented by (X, Y) = (INFINITY_X, INFINITY_Y) = (0, 0). * The reads of P and Q are handled by the registers in the execution trace. The correctness * of point addition is handled by the ECC subtrace. * * This trace writes the resulting embedded curve point to the addresses {dst, - * dst + 1, and dst + 2 }. Embedded curve points consist of the tuple of types - * {x: FF, y: FF, is_inf: U1 }. + * dst + 1 }. Embedded curve points consist of the tuple of types {x: FF, y: FF }. * - * PRECONDITIONS: Input point coordinates have tag checked FF coordinates and U1 is_inf - * flag (see Memory I/O below for details). + * PRECONDITIONS: Input point coordinates have tag checked FF coordinates (see Memory I/O + * below for details). * * USAGE: Dispatching lookup defined in execution.pil: * #[DISPATCH_TO_ECC_ADD] * sel_exec_dispatch_ecc_add { * clk, context_id, - * register[0], register[1], register[2], // Point P - * register[3], register[4], register[5], // Point Q - * rop[6], // Dst address + * register[0], register[1], // Point P + * register[2], register[3], // Point Q + * rop[4], // Dst address * sel_opcode_error // Error * } is ecc_add_mem.sel { * ecc_add_mem.execution_clk, ecc_add_mem.space_id, - * ecc_add_mem.p_x, ecc_add_mem.p_y, ecc_add_mem.p_is_inf, // Point P - * ecc_add_mem.q_x, ecc_add_mem.q_y, ecc_add_mem.q_is_inf, // Point Q + * ecc_add_mem.p_x, ecc_add_mem.p_y, // Point P + * ecc_add_mem.q_x, ecc_add_mem.q_y, // Point Q * ecc_add_mem.dst_addr[0], // Dst address * ecc_add_mem.err // Error * }; @@ -37,38 +38,30 @@ include "precomputed.pil"; * Opcode operands (relevant in EXECUTION when interacting with this gadget): * - rop[0]: p_x_addr * - rop[1]: p_y_addr - * - rop[2]: p_is_inf_addr - * - rop[3]: q_x_addr - * - rop[4]: q_y_addr - * - rop[5]: q_is_inf_addr - * - rop[6]: dst_addr + * - rop[2]: q_x_addr + * - rop[3]: q_y_addr + * - rop[4]: dst_addr * * Memory I/O: * - register[0]: M[p_x_addr] aka p_x (x coordinate of point P - read from memory by EXECUTION) * - p_x is tagged-checked by execution/registers to be FF based on instruction spec. * - register[1]: M[p_y_addr] aka p_y (y coordinate of point P - read from memory by EXECUTION) * - p_y is tagged-checked by execution/registers to be FF based on instruction spec. - * - register[2]: M[p_is_inf_addr] aka p_is_inf (boolean flag if P is the point at infinity - read from memory by EXECUTION) - * - p_is_inf is tagged-checked by execution/registers to be U1 based on instruction spec. - * - register[3]: M[q_x_addr] aka q_x (x coordinate of point Q - read from memory by EXECUTION) + * - register[2]: M[q_x_addr] aka q_x (x coordinate of point Q - read from memory by EXECUTION) * - q_x is tagged-checked by execution/registers to be FF based on instruction spec. - * - register[4]: M[q_y_addr] aka q_y (y coordinate of point Q - read from memory by EXECUTION) + * - register[3]: M[q_y_addr] aka q_y (y coordinate of point Q - read from memory by EXECUTION) * - q_y is tagged-checked by execution/registers to be FF based on instruction spec. - * - register[5]: M[q_is_inf_addr] aka q_is_inf (boolean flag if Q is the point at infinity - read from memory by EXECUTION) - * - q_is_inf is tagged-checked by execution/registers to be U1 based on instruction spec. - * - M[rop[6]]: M[dst_addr] aka res_x (x coordinate of the resulting point RES - written by this gadget) + * - M[rop[4]]: M[dst_addr] aka res_x (x coordinate of the resulting point RES - written by this gadget) * - guaranteed by this gadget to be FF. - * - M[rop[6]+1]: M[dst_offset+1] aka res_y (y coordinate of the resulting point RES - written by this gadget) + * - M[rop[4]+1]: M[dst_offset+1] aka res_y (y coordinate of the resulting point RES - written by this gadget) * - guaranteed by this gadget to be FF. - * - M[rop[6]+2]: M[dst_offset+2] aka res_is_inf (boolean flag if RES is the point at infinity - written by this gadget) - * - guaranteed by this gadget to be U1. * * ERROR HANDLING: * Two errors need to be handled as part of this trace, * (1) DST_OUT_OF_BOUNDS_ACCESS: If the writes would access a memory address outside * of the max AVM memory address (AVM_HIGHEST_MEM_ADDRESS). * (2) POINT_NOT_ON_CURVE: If either of the inputs (embedded curve points) do not - * satisfy the Grumpkin curve equation (SW form: Y^2 = X^3 − 17) + * exist on the Grumpkin curve. * * TRACE SHAPE: This subtrace writes the values within 1 single row (i.e. 3 output columns) * @@ -78,19 +71,27 @@ include "precomputed.pil"; * --> gt.pil * This subtrace is looked up by: * - execution.pil: To constrain the dispatch permutation for the ECADD opcode (#[DISPATCH_TO_ECC_ADD]). Includes memory - * reads (register[0] to register[5]), the initial write address (rop[6]), and error flag (sel_opcode_error). + * reads (register[0] to register[3]), the initial write address (rop[4]), and error flag (sel_opcode_error). * * This subtrace looks up: - * - memory.pil: To write the output point values (res_x, res_y, res_is_inf) to memory with standard write permutations - * (#[WRITE_MEM_i] for i = 0, 1, 2). + * - memory.pil: To write the output point values (res_x, res_y) to memory with standard write permutations + * (#[WRITE_MEM_i] for i = 0, 1). * - ecc.pil: To retrieve the output point R as the result of adding the points P and Q read from memory * (#[INPUT_OUTPUT_ECC_ADD]). See below for details on infinity points. * - gt.pil: To constrain that the maximum written memory address is within range (#[CHECK_DST_ADDR_IN_RANGE]). * - * This subtrace is connected to the ECC subtrace via a lookup. ECC is used by - * other subtraces internally (e.g., address derivation). We re-map any input infinity points to (0, 0) - * so ECC correctly manages edge cases. Resulting infinity points are guaranteed to be (0, 0) by the - * ECC subtrace (see #[OUTPUT_X_COORD] and #[OUTPUT_Y_COORD]). + * This subtrace is connected to the ECC subtrace via a lookup. ECC is used by other subtraces internally + * (e.g. address derivation). Now that the is_inf flag has been removed from noir (noir-lang/noir/#11926/) we consider + * a point to be infinity iff its coordinates are (0, 0); the noir standard representation (see relations #[P/Q_INF_X/Y_CHECK]). + * + * Note that the point at infinity, O, does not have valid coordinates (a property of SW curves like Grumpkin). We represent it + * as (0, 0) but any (ecc.INFINITY_X, ecc.INFINITY_Y) not satisfying the curve equation will be correctly handled in this trace. + * + * The ECC subtrace requires a correctly constrained is_inf flag for each point. We derive it within this circuit by enforcing + * (0, 0) <==> is_inf for input points P and Q: + * - (0, 0) ==> is_inf by #[P/Q_ON_CURVE_CHECK] (zero coordinates will fail this relation unless is_inf is set correctly). + * - is_inf ==> (0, 0) by #[P/Q_INF_X/Y_CHECK]. + * Resulting infinity points are guaranteed to be (0, 0) by the ECC subtrace (see #[OUTPUT_X_COORD] and #[OUTPUT_Y_COORD]). */ namespace ecc_add_mem; @@ -103,16 +104,17 @@ namespace ecc_add_mem; pol commit execution_clk; pol commit space_id; - pol commit dst_addr[3]; + pol commit dst_addr[2]; // dst_addr[0] constrained by the permutation to execution #[WRITE_INCR_DST_ADDR] dst_addr[1] = sel * (dst_addr[0] + 1); - dst_addr[2] = sel * (dst_addr[0] + 2); - // p_is_inf, q_is_inf are constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD]) - pol commit p_x, p_y, p_is_inf; - pol commit q_x, q_y, q_is_inf; + pol commit p_x, p_y; + pol commit q_x, q_y; + + // Needs to be committed columns as they are used in the lookups + pol commit p_is_inf, q_is_inf; // constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD]) //////////////////////////////////////////////// // Error Handling - Out of Range Memory Access @@ -121,15 +123,15 @@ namespace ecc_add_mem; // Use the comparison gadget to check that the max addresses are within range // The comparison gadget provides the ability to test GreaterThan so we check - // dst_addr[2] > max_mem_addr + // dst_addr[1] > max_mem_addr pol commit max_mem_addr; // Column needed until we support constants in lookups sel * (max_mem_addr - constants.AVM_HIGHEST_MEM_ADDRESS) = 0; // Preconditions to `gt` gadget require both inputs to be bounded by 2^128. - // `dst_addr[2]` = dst_addr[0] + 2 where dst_addr[0] is an address (< 2^32), so dst_addr[2] < 2^33. + // `dst_addr[1]` = dst_addr[0] + 1 where dst_addr[0] is an address (< 2^32), so dst_addr[1] < 2^33. // `max_mem_addr` = AVM_HIGHEST_MEM_ADDRESS which is < 2^32. #[CHECK_DST_ADDR_IN_RANGE] - sel { dst_addr[2], max_mem_addr, sel_dst_out_of_range_err } + sel { dst_addr[1], max_mem_addr, sel_dst_out_of_range_err } in gt.sel_others { gt.input_a, gt.input_b, gt.res }; @@ -142,6 +144,8 @@ namespace ecc_add_mem; pol commit sel_q_not_on_curve_err; // @boolean sel_q_not_on_curve_err * (1 - sel_q_not_on_curve_err) = 0; + // Note: The below additionally constrains that (X, Y) == (INFINITY_X, INFINITY_Y) ==> is_inf. See above description. + // Y^2 = X^3 − 17, re-formulate to Y^2 - (X^3 - 17) = 0 pol commit p_is_on_curve_eqn; // Needs to be committed to reduce relation degrees pol P_X3 = p_x * p_x * p_x; @@ -170,32 +174,31 @@ namespace ecc_add_mem; /////////////////////////////////////////////////////////////////////// // Dispatch inputs to ecc add and retrieve outputs /////////////////////////////////////////////////////////////////////// - pol commit res_x, res_y, res_is_inf; // res_is_inf is constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD]) + pol commit res_x, res_y; pol commit sel_should_exec; // @boolean (by definition) sel_should_exec = sel * (1 - err); - // Needs to be committed columns as they are used in the lookups - pol commit p_x_n, p_y_n; - pol commit q_x_n, q_y_n; - - // We re-map input infinity points to (0, 0) for ecc.pil. Output infinities are already constrained to be (0, 0) in the subtrace. - // Note that we cannot use p_x, p_y, etc. because they are read from memory in execution's #[DISPATCH_TO_ECC_ADD]. - sel_should_exec * (p_x_n - (1 - p_is_inf) * p_x - p_is_inf * ecc.INFINITY_X) = 0; - sel_should_exec * (p_y_n - (1 - p_is_inf) * p_y - p_is_inf * ecc.INFINITY_Y) = 0; - sel_should_exec * (q_x_n - (1 - q_is_inf) * q_x - q_is_inf * ecc.INFINITY_X) = 0; - sel_should_exec * (q_y_n - (1 - q_is_inf) * q_y - q_is_inf * ecc.INFINITY_Y) = 0; + // Constrains that the infinity flags required for the ecc trace have been set correctly: + #[P_INF_X_CHECK] + sel * p_is_inf * (p_x - ecc.INFINITY_X) = 0; + #[P_INF_Y_CHECK] + sel * p_is_inf * (p_y - ecc.INFINITY_Y) = 0; + #[Q_INF_X_CHECK] + sel * q_is_inf * (q_x - ecc.INFINITY_X) = 0; + #[Q_INF_Y_CHECK] + sel * q_is_inf * (q_y - ecc.INFINITY_Y) = 0; #[INPUT_OUTPUT_ECC_ADD] sel_should_exec { - p_x_n, p_y_n, p_is_inf, - q_x_n, q_y_n, q_is_inf, - res_x, res_y, res_is_inf + p_x, p_y, p_is_inf, + q_x, q_y, q_is_inf, + res_x, res_y } in ecc.sel { ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.q_x, ecc.q_y, ecc.q_is_inf, - ecc.r_x, ecc.r_y, ecc.r_is_inf + ecc.r_x, ecc.r_y }; //////////////////////////////////////////////// @@ -216,12 +219,3 @@ namespace ecc_add_mem; memory.sel_ecc_write[1] { memory.clk, memory.space_id, memory.address, memory.value, memory.tag, memory.rw }; - - #[WRITE_MEM_2] - sel_should_exec { - execution_clk, space_id, dst_addr[2], res_is_inf, /*U1_mem_tag=1*/ sel_should_exec, /*rw=1*/ sel_should_exec - } is - memory.sel_ecc_write[2] { - memory.clk, memory.space_id, memory.address, memory.value, memory.tag, memory.rw - }; - diff --git a/barretenberg/cpp/pil/vm2/execution.pil b/barretenberg/cpp/pil/vm2/execution.pil index 98bffa729581..fd7f7a2e217f 100644 --- a/barretenberg/cpp/pil/vm2/execution.pil +++ b/barretenberg/cpp/pil/vm2/execution.pil @@ -1277,10 +1277,10 @@ sel_exec_dispatch_keccakf1600 { }; // ECADD DISPATCHING -// Each input point uses 3 registers: -// P = [x, y, is_inf] -> register[0..2], Q = [x, y, is_inf] -> register[3..5] +// Each input point uses 2 registers: +// P = [x, y] -> register[0..1], Q = [x, y] -> register[2..3] // The output point is written to memory internally inside the ecc_add_mem (ecc_mem.pil) trace, starting at: -// dst_addr[0] -> rop[6] +// dst_addr[0] -> rop[4] // Outputs (#[WRITE_MEM_x]) and memory write checks (#[CHECK_DST_ADDR_IN_RANGE]) are hence handled by the trace. #[DISPATCH_TO_ECC_ADD] @@ -1290,13 +1290,11 @@ sel_exec_dispatch_ecc_add { // Point P register[0], register[1], - register[2], // Point Q + register[2], register[3], - register[4], - register[5], // Dst address - rop[6], + rop[4], // Error sel_opcode_error } is ecc_add_mem.sel { @@ -1305,11 +1303,9 @@ sel_exec_dispatch_ecc_add { // Point P ecc_add_mem.p_x, ecc_add_mem.p_y, - ecc_add_mem.p_is_inf, // Point Q ecc_add_mem.q_x, ecc_add_mem.q_y, - ecc_add_mem.q_is_inf, // Dst address ecc_add_mem.dst_addr[0], // Error diff --git a/barretenberg/cpp/pil/vm2/memory.pil b/barretenberg/cpp/pil/vm2/memory.pil index ed27382c2dc5..be46a78734a9 100644 --- a/barretenberg/cpp/pil/vm2/memory.pil +++ b/barretenberg/cpp/pil/vm2/memory.pil @@ -175,10 +175,9 @@ sel_sha256_op[6] * (1 - sel_sha256_op[6]) = 0; sel_sha256_op[7] * (1 - sel_sha256_op[7]) = 0; // Permutation selectors (ecc_mem.pil). -pol commit sel_ecc_write[3]; // @boolean +pol commit sel_ecc_write[2]; // @boolean sel_ecc_write[0] * (1 - sel_ecc_write[0]) = 0; sel_ecc_write[1] * (1 - sel_ecc_write[1]) = 0; -sel_ecc_write[2] * (1 - sel_ecc_write[2]) = 0; // Permutation selectors (to_radix_mem.pil). pol commit sel_to_radix_write; // @boolean @@ -212,7 +211,7 @@ sel = // Addressing. + sel_sha256_op[0] + sel_sha256_op[1] + sel_sha256_op[2] + sel_sha256_op[3] + sel_sha256_op[4] + sel_sha256_op[5] + sel_sha256_op[6] + sel_sha256_op[7] // ECC. - + sel_ecc_write[0] + sel_ecc_write[1] + sel_ecc_write[2] + + sel_ecc_write[0] + sel_ecc_write[1] // To Radix. + sel_to_radix_write; diff --git a/barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil b/barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil index 0cea9409ff82..38bbbad882bb 100644 --- a/barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil +++ b/barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil @@ -11,16 +11,17 @@ include "../precomputed.pil"; * - Bounds-check dst_offset+1 via #[WRITE_OUT_OF_BOUNDS_CHECK]. If dst_offset is the * maximum valid address, dst_offset+1 would be out of bounds. * - Look up member_enum in the precomputed table (#[PRECOMPUTED_INFO]) to determine - * validity and which member is selected (deployer, class_id, or init_hash). + * validity and which member is selected (deployer, class_id, init_hash or immutables_hash). * The precomputed table covers the full 8-bit range: - * +-------+----------------------+-------------+-------------+--------------+ - * | idx | is_valid_member_enum | is_deployer | is_class_id | is_init_hash | - * +-------+----------------------+-------------+-------------+--------------+ - * | 0 | 1 | 1 | 0 | 0 | - * | 1 | 1 | 0 | 1 | 0 | - * | 2 | 1 | 0 | 0 | 1 | - * | 3+ | 0 | 0 | 0 | 0 | - * +-------+----------------------+-------------+-------------+--------------+ + * +-------+----------------------+-------------+-------------+--------------+--------------------+ + * | idx | is_valid_member_enum | is_deployer | is_class_id | is_init_hash | is_immutables_hash | + * +-------+----------------------+-------------+-------------+--------------+--------------------+ + * | 0 | 1 | 1 | 0 | 0 | 0 | + * | 1 | 1 | 0 | 1 | 0 | 0 | + * | 2 | 1 | 0 | 0 | 1 | 0 | + * | 3 | 1 | 0 | 0 | 0 | 1 | + * | 4+ | 0 | 0 | 0 | 0 | 0 | + * +-------+----------------------+-------------+-------------+--------------+--------------------+ * - Aggregate errors via #[ERROR_AGGREGATION]. sel_error is set when either * is_valid_writes_in_bounds or is_valid_member_enum is false. * - [no error only] Retrieve contract instance via the ContractInstanceRetrieval gadget @@ -72,7 +73,7 @@ include "../precomputed.pil"; * ERROR HANDLING: * Two error conditions, which are NOT mutually exclusive: * - Write out-of-bounds: dst_offset == AVM_HIGHEST_MEM_ADDRESS (dst_offset+1 overflows). - * - Invalid member enum: member_enum >= 3 (precomputed table returns is_valid_member_enum=0). + * - Invalid member enum: member_enum >= 4 (precomputed table returns is_valid_member_enum=0). * On error, the row has sel_error=1. The contract instance retrieval lookup and memory * write permutations are disabled (their selectors is_valid_member_enum / is_valid_writes_in_bounds * are 0), so no destination interactions fire for error rows. @@ -121,13 +122,14 @@ namespace get_contract_instance; // (from precomputed.pil's GETCONTRACTINSTANCE opcode precomputed columns) // These are constrained only via the #[PRECOMPUTED_INFO] lookup when is_valid_writes_in_bounds == 1. // When the lookup is disabled (writes out of bounds), is_valid_member_enum is forced to 0 by - // #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]. is_deployer/is_class_id/is_init_hash + // #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]. is_deployer/is_class_id/is_init_hash/is_immutables_hash // are free in that case, but safe: they are only consumed in #[SELECTED_MEMBER] and the memory // write permutations, all of which are gated on is_valid_member_enum (which is 0). pol commit is_valid_member_enum; // @boolean (by lookup when is_valid_writes_in_bounds == 1) pol commit is_deployer; // @boolean (by lookup when is_valid_writes_in_bounds == 1) pol commit is_class_id; // @boolean (by lookup when is_valid_writes_in_bounds == 1) pol commit is_init_hash; // @boolean (by lookup when is_valid_writes_in_bounds == 1) + pol commit is_immutables_hash; // @boolean (by lookup when is_valid_writes_in_bounds == 1) // Note: member_enum is guaranteed to be 8 bits by execution (as a U8 immediate operand), // and the precomputed table is populated for the entire 8-bit range (256 rows). #[PRECOMPUTED_INFO] @@ -138,7 +140,8 @@ namespace get_contract_instance; is_valid_member_enum, is_deployer, is_class_id, - is_init_hash + is_init_hash, + is_immutables_hash } in precomputed.sel_range_8 { // inputs precomputed.idx, @@ -146,7 +149,8 @@ namespace get_contract_instance; precomputed.is_valid_member_enum, precomputed.is_deployer, precomputed.is_class_id, - precomputed.is_init_hash + precomputed.is_init_hash, + precomputed.is_immutables_hash }; // Do not allow is_valid_member_enum to be 1 if the precomputed lookup is disabled. #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP] @@ -171,6 +175,7 @@ namespace get_contract_instance; pol commit retrieved_deployer_addr; pol commit retrieved_class_id; pol commit retrieved_init_hash; + pol commit retrieved_immutables_hash; #[CONTRACT_INSTANCE_RETRIEVAL] is_valid_member_enum { @@ -182,7 +187,8 @@ namespace get_contract_instance; instance_exists, retrieved_deployer_addr, retrieved_class_id, - retrieved_init_hash + retrieved_init_hash, + retrieved_immutables_hash } in contract_instance_retrieval.sel { // inputs contract_instance_retrieval.address, @@ -192,14 +198,15 @@ namespace get_contract_instance; contract_instance_retrieval.exists, contract_instance_retrieval.deployer_addr, contract_instance_retrieval.current_class_id, - contract_instance_retrieval.init_hash + contract_instance_retrieval.init_hash, + contract_instance_retrieval.immutables_hash }; // Select the member indicated by the enum for writing to memory // Note: is_* selectors are guaranteed to be mutually exclusive booleans by the precomputed table. pol commit selected_member; #[SELECTED_MEMBER] - selected_member = is_deployer * retrieved_deployer_addr + is_class_id * retrieved_class_id + is_init_hash * retrieved_init_hash; + selected_member = is_deployer * retrieved_deployer_addr + is_class_id * retrieved_class_id + is_init_hash * retrieved_init_hash + is_immutables_hash * retrieved_immutables_hash; // Compute memory offsets for writing to pol commit member_write_offset; diff --git a/barretenberg/cpp/pil/vm2/precomputed.pil b/barretenberg/cpp/pil/vm2/precomputed.pil index 734d6b761e46..0e03550ddc90 100644 --- a/barretenberg/cpp/pil/vm2/precomputed.pil +++ b/barretenberg/cpp/pil/vm2/precomputed.pil @@ -435,7 +435,7 @@ pol constant out_tag; // ===== Section 14: GETCONTRACTINSTANCE opcode columns ===== // Maps contract instance member enum values to selectors indicating which field -// (deployer, class_id, init_hash) is being accessed. +// (deployer, class_id, init_hash, immutables_hash) is being accessed. // Used by the GETCONTRACTINSTANCE opcode. // // see opcodes/get_contract_instance.pil for ascii table @@ -444,3 +444,4 @@ pol constant is_valid_member_enum; pol constant is_deployer; pol constant is_class_id; pol constant is_init_hash; +pol constant is_immutables_hash; diff --git a/barretenberg/cpp/pil/vm2/scalar_mul.pil b/barretenberg/cpp/pil/vm2/scalar_mul.pil index cac3cd20e2dd..f77e5d86ce94 100644 --- a/barretenberg/cpp/pil/vm2/scalar_mul.pil +++ b/barretenberg/cpp/pil/vm2/scalar_mul.pil @@ -17,12 +17,17 @@ include "precomputed.pil"; * * The correctness of point addition (res + temp and temp + temp above) is constrained by a lookup into ecc.pil. * - * PRECONDITIONS: Input P is a valid point on the Grumpkin curve, input s is FF (see below note). + * PRECONDITIONS: Input P is a valid point on the Grumpkin curve, either satisfying the curve equation or the point + * at infinity representation (such that is_inf <==> (X, Y) == (ecc.INFINITY_X, ecc.INFINITY_Y)), and input s is FF. * Note: Grumpkin forms a 2-cycle with BN254, i.e the base field of one is the scalar field of the other and vice-versa, * so the scalar is actually a Fq value. We treat it as a Fr (FF tagged) value in circuit. Since r < q, we cannot use an * invalid scalar here. * - * USAGE: This is a non-memory aware subtrace used to constrain scalar point multiplicationas defined above. Each point can + * Note that once TODO(#AVM-266) is complete, is_inf will no longer be part of our point representation and we must either: + * - continue to rely on the 'calling' trace to inject a constrained is_inf, or + * - derive is_inf (<==> (X, Y) == (ecc.INFINITY_X, ecc.INFINITY_Y)) within this trace. + * + * USAGE: This is a non-memory aware subtrace used to constrain scalar point multiplication as defined above. Each point can * be looked up by coordinates (lookup as defined in address_derivation.pil): * #[PREADDRESS_SCALAR_MUL] * sel { @@ -116,6 +121,7 @@ namespace scalar_mul; sel_not_end * (point_x - point_x') = 0; #[INPUT_CONSISTENCY_Y] sel_not_end * (point_y - point_y') = 0; + // TODO(MW): remove/rework below? only used at end #[INPUT_CONSISTENCY_INF] sel_not_end * (point_inf - point_inf') = 0; #[INPUT_CONSISTENCY_SCALAR] @@ -172,7 +178,7 @@ namespace scalar_mul; sel_not_end { temp_x, temp_y, temp_inf, temp_x', temp_y', temp_inf', sel_not_end /* = 1 */ } in ecc.sel - { ecc.r_x, ecc.r_y, ecc.r_is_inf, ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.double_op }; + { ecc.r_x, ecc.r_y, ecc.result_infinity, ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.double_op }; /////////////////////////////// // Result Computation @@ -200,7 +206,7 @@ namespace scalar_mul; should_add { res_x, res_y, res_inf, res_x', res_y', res_inf', temp_x, temp_y, temp_inf } in ecc.sel - { ecc.r_x, ecc.r_y, ecc.r_is_inf, ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.q_x, ecc.q_y, ecc.q_is_inf }; + { ecc.r_x, ecc.r_y, ecc.result_infinity, ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.q_x, ecc.q_y, ecc.q_is_inf }; diff --git a/barretenberg/cpp/scripts/chonk-inputs.hash b/barretenberg/cpp/scripts/chonk-inputs.hash index 36bfba515855..74d7f158b3e2 100644 --- a/barretenberg/cpp/scripts/chonk-inputs.hash +++ b/barretenberg/cpp/scripts/chonk-inputs.hash @@ -1 +1 @@ -5d17cc1cfa051b60 +209dde8e69a27c9f diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp index 3b1499cc35ce..d70fabc58e8f 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp @@ -136,10 +136,10 @@ ContractInstance FuzzerContractDB::from_logs(const PrivateLog& log) const FF contract_class_id = log.fields[offset++]; FF initialization_hash = log.fields[offset++]; PublicKeys public_keys = { - .nullifier_key = { log.fields[offset++], log.fields[offset++] }, + .nullifier_key_hash = log.fields[offset++], .incoming_viewing_key = { log.fields[offset++], log.fields[offset++] }, - .outgoing_viewing_key = { log.fields[offset++], log.fields[offset++] }, - .tagging_key = { log.fields[offset++], log.fields[offset++] }, + .outgoing_viewing_key_hash = log.fields[offset++], + .tagging_key_hash = log.fields[offset++], }; auto deployer = AztecAddress(log.fields[offset++]); return ContractInstance{ diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp index b69cccff3231..c31decf6f8a4 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp @@ -40,10 +40,10 @@ ContractInstance create_default_instance(const ContractClassId& class_id) .initialization_hash = 0, .public_keys = PublicKeys{ - .nullifier_key = affine_one, + .nullifier_key_hash = 0, .incoming_viewing_key = affine_one, - .outgoing_viewing_key = affine_one, - .tagging_key = affine_one, + .outgoing_viewing_key_hash = 0, + .tagging_key_hash = 0, }, }; } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp index fce2e07f1a28..35e70ed2ab05 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp @@ -573,12 +573,10 @@ struct SUCCESSCOPY_Instruction { struct ECADD_Instruction { ParamRef p1_x; ParamRef p1_y; - ParamRef p1_infinite; ParamRef p2_x; ParamRef p2_y; - ParamRef p2_infinite; AddressRef result; - SERIALIZATION_FIELDS(p1_x, p1_y, p1_infinite, p2_x, p2_y, p2_infinite, result); + SERIALIZATION_FIELDS(p1_x, p1_y, p2_x, p2_y, result); }; /// @brief POSEIDON2PERM: Perform Poseidon2 permutation on 4 FF values @@ -881,8 +879,8 @@ inline std::ostream& operator<<(std::ostream& os, const FuzzInstruction& instruc << arg.dst_address; }, [&](ECADD_Instruction arg) { - os << "ECADD_Instruction " << arg.p1_x << " " << arg.p1_y << " " << arg.p1_infinite << " " << arg.p2_x - << " " << arg.p2_y << " " << arg.p2_infinite << " " << arg.result; + os << "ECADD_Instruction " << arg.p1_x << " " << arg.p1_y << " " << arg.p2_x << " " << arg.p2_y << " " + << arg.result; }, [&](POSEIDON2PERM_Instruction arg) { os << "POSEIDON2PERM_Instruction " << arg.src_address << " " << arg.dst_address; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp index b719d65bca5d..7c98c29b05f3 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp @@ -1287,40 +1287,32 @@ void ProgramBlock::process_ecadd_instruction(ECADD_Instruction instruction) #endif auto p1_x = memory_manager.get_resolved_address_and_operand_16(instruction.p1_x); auto p1_y = memory_manager.get_resolved_address_and_operand_16(instruction.p1_y); - auto p1_inf = memory_manager.get_resolved_address_and_operand_16(instruction.p1_infinite); auto p2_x = memory_manager.get_resolved_address_and_operand_16(instruction.p2_x); auto p2_y = memory_manager.get_resolved_address_and_operand_16(instruction.p2_y); - auto p2_inf = memory_manager.get_resolved_address_and_operand_16(instruction.p2_infinite); auto result = memory_manager.get_resolved_address_and_operand_16(instruction.result); - if (!p1_x.has_value() || !p1_y.has_value() || !p1_inf.has_value() || !p2_x.has_value() || !p2_y.has_value() || - !p2_inf.has_value() || !result.has_value()) { + if (!p1_x.has_value() || !p1_y.has_value() || !p2_x.has_value() || !p2_y.has_value() || !result.has_value()) { return; } preprocess_memory_addresses(p1_x.value().first); preprocess_memory_addresses(p1_y.value().first); - preprocess_memory_addresses(p1_inf.value().first); preprocess_memory_addresses(p2_x.value().first); preprocess_memory_addresses(p2_y.value().first); - preprocess_memory_addresses(p2_inf.value().first); preprocess_memory_addresses(result.value().first); auto ecadd_instruction = bb::avm2::testing::InstructionBuilder(bb::avm2::WireOpCode::ECADD) .operand(p1_x.value().second) .operand(p1_y.value().second) - .operand(p1_inf.value().second) .operand(p2_x.value().second) .operand(p2_y.value().second) - .operand(p2_inf.value().second) .operand(result.value().second) .build(); instructions.push_back(ecadd_instruction); - // ECADD writes 3 consecutive memory locations: result_x (FF), result_y (FF), result_is_inf (U1) + // ECADD writes 2 consecutive memory locations: result_x (FF), result_y (FF) memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, result.value().first.absolute_address); memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, result.value().first.absolute_address + 1); - memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result.value().first.absolute_address + 2); } void ProgramBlock::process_poseidon2perm_instruction(POSEIDON2PERM_Instruction instruction) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp index ec53d8b7c769..b33fb95ba8e8 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp @@ -299,10 +299,10 @@ ContractArtifacts build_bytecode_and_artifacts(FuzzerData& fuzzer_data) .current_contract_class_id = class_id, // Initial and current are the same .original_contract_class_id = class_id, .public_keys = { - .nullifier_key = { 0, 0 }, + .nullifier_key_hash = 0, .incoming_viewing_key = grumpkin::g1::element::one(), - .outgoing_viewing_key = { 0, 0 }, - .tagging_key = { 0, 0 }, + .outgoing_viewing_key_hash = 0, + .tagging_key_hash = 0, }, }; return { bytecode, contract_class, contract_instance }; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/ecc.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/ecc.fuzzer.cpp index 19e79a8078ed..5237bc909014 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/ecc.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/ecc.fuzzer.cpp @@ -94,8 +94,8 @@ struct EccFuzzerInput { AffinePoint q = AffinePoint::one(); Fq scalar = Fq::zero(); // Addresses are organised as: - // p_x, p_y, p_inf, q_x, q_y, q_inf, output_addr - std::array addresses{}; + // p_x, p_y, q_x, q_y, output_addr + std::array addresses{}; EccFuzzerInput() = default; // Serialize to buffer @@ -109,7 +109,7 @@ struct EccFuzzerInput { Fq::serialize_to_buffer(scalar, buffer + offset); offset += sizeof(Fq); // Serialize memory addresses - std::memcpy(buffer + offset, &addresses[0], sizeof(MemoryAddress) * 7); + std::memcpy(buffer + offset, &addresses[0], sizeof(MemoryAddress) * 5); } static EccFuzzerInput from_buffer(const uint8_t* buffer) @@ -137,7 +137,7 @@ struct EccFuzzerInput { input.scalar = Fq::serialize_from_buffer(buffer + offset); offset += sizeof(Fq); // Deserialize memory addresses - std::memcpy(&input.addresses[0], buffer + offset, sizeof(MemoryAddress) * 7); + std::memcpy(&input.addresses[0], buffer + offset, sizeof(MemoryAddress) * 5); return input; } @@ -210,7 +210,7 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size, size_t max case 7: { // Mutate memory addresses // Select a random address to mutate - std::uniform_int_distribution addr_dist(0, 6); + std::uniform_int_distribution addr_dist(0, 4); size_t addr_index = addr_dist(rng); input.addresses[addr_index] = mutate_memory_address(input.addresses[addr_index], rng); break; @@ -268,15 +268,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) mem->set(/*p_x_addr*/ input.addresses[0], MemoryValue::from_tag(MemoryTag::FF, point_p.x())); mem->set(/*p_y_addr*/ input.addresses[1], MemoryValue::from_tag(MemoryTag::FF, point_p.y())); - mem->set(/*p_inf*/ input.addresses[2], MemoryValue::from_tag(MemoryTag::U1, point_p.is_infinity() ? FF(1) : FF(0))); - mem->set(/*q_x_addr*/ input.addresses[3], MemoryValue::from_tag(MemoryTag::FF, point_q.x())); - mem->set(/*q_y_addr*/ input.addresses[4], MemoryValue::from_tag(MemoryTag::FF, point_q.y())); - mem->set(/*q_inf*/ input.addresses[5], MemoryValue::from_tag(MemoryTag::U1, point_q.is_infinity() ? FF(1) : FF(0))); + mem->set(/*q_x_addr*/ input.addresses[2], MemoryValue::from_tag(MemoryTag::FF, point_q.x())); + mem->set(/*q_y_addr*/ input.addresses[3], MemoryValue::from_tag(MemoryTag::FF, point_q.y())); EmbeddedCurvePoint scalar_mul_result; try { - ecc.add(*mem, point_p, point_q, /* output_addr */ input.addresses[6]); + ecc.add(*mem, point_p, point_q, /* output_addr */ input.addresses[4]); scalar_mul_result = ecc.scalar_mul(input.p, FF(uint256_t(input.scalar))); } catch (std::exception& e) { // info("Caught exception during ECC add: {}", e.what()); @@ -286,15 +284,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) EmbeddedCurvePoint expected_result = point_p + point_q; // Verify output in memory - MemoryValue res_x = mem->get(input.addresses[6]); - MemoryValue res_y = mem->get(input.addresses[6] + 1); - MemoryValue res_inf = mem->get(input.addresses[6] + 2); + MemoryValue res_x = mem->get(input.addresses[4]); + MemoryValue res_y = mem->get(input.addresses[4] + 1); - EmbeddedCurvePoint result_point = EmbeddedCurvePoint(res_x.as_ff(), res_y.as_ff(), res_inf.as_ff() == FF(1)); + EmbeddedCurvePoint result_point = EmbeddedCurvePoint(res_x.as_ff(), res_y.as_ff()); BB_ASSERT(result_point.x() == expected_result.x(), "Result x-coordinate mismatch"); BB_ASSERT(result_point.y() == expected_result.y(), "Result y-coordinate mismatch"); - BB_ASSERT(result_point.is_infinity() == expected_result.is_infinity(), "Result infinity flag mismatch"); // Non mem-aware ecmul result: expected_result = point_p * input.scalar; @@ -309,15 +305,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) auto trace = TestTraceContainer({ { { Column::execution_context_id, 0 }, // Point P - { Column::execution_register_0_, point_p.x() }, // = px - { Column::execution_register_1_, point_p.y() }, // = py - { Column::execution_register_2_, point_p.is_infinity() ? FF(1) : FF(0) }, // = p_inf + { Column::execution_register_0_, point_p.x() }, // = px + { Column::execution_register_1_, point_p.y() }, // = py // Point Q - { Column::execution_register_3_, point_q.x() }, // = qx - { Column::execution_register_4_, point_q.y() }, // = qy - { Column::execution_register_5_, point_q.is_infinity() ? FF(1) : FF(0) }, // = q_inf + { Column::execution_register_2_, point_q.x() }, // = qx + { Column::execution_register_3_, point_q.y() }, // = qy // Dst address - { Column::execution_rop_6_, input.addresses[6] }, // = dst_addr + { Column::execution_rop_4_, input.addresses[4] }, // = dst_addr { Column::execution_sel_exec_dispatch_ecc_add, 1 }, // = sel { Column::execution_sel_opcode_error, error ? 1 : 0 }, // = sel_err } }); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp index a4dddc705162..45ef5d2e1975 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp @@ -206,7 +206,7 @@ void mutate_contract_instances(std::vector& contract_instances break; case 3: // Mutate nullifier key - mutate_point(instance.public_keys.nullifier_key, rng); + mutate_field(instance.public_keys.nullifier_key_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION); break; case 4: // Mutate incoming viewing key @@ -214,11 +214,11 @@ void mutate_contract_instances(std::vector& contract_instances break; case 5: // Mutate outgoing viewing key - mutate_point(instance.public_keys.outgoing_viewing_key, rng); + mutate_field(instance.public_keys.outgoing_viewing_key_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION); break; case 6: // Mutate tagging key - mutate_point(instance.public_keys.tagging_key, rng); + mutate_field(instance.public_keys.tagging_key_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION); break; default: break; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp index 02b2278f658d..6801ee5ff5d3 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp @@ -428,17 +428,15 @@ std::vector InstructionMutator::generate_ecadd_instruction(std: // Random mode: use existing memory values (may fail if not valid points on curve) return { ECADD_Instruction{ .p1_x = generate_variable_ref(rng), .p1_y = generate_variable_ref(rng), - .p1_infinite = generate_variable_ref(rng), .p2_x = generate_variable_ref(rng), .p2_y = generate_variable_ref(rng), - .p2_infinite = generate_variable_ref(rng), .result = generate_address_ref(rng, MAX_16BIT_OPERAND) } }; } // Backfill mode: generate valid points on the Grumpkin curve and SET them - // 6 SET instructions (2 points * 3 fields each) + 1 ECADD = 7 instructions + // 4 SET instructions (2 points * 4 fields each) + 1 ECADD = 5 instructions std::vector instructions; - instructions.reserve(7); + instructions.reserve(5); // Generate a valid point via scalar multiplication of the generator (always on curve) auto generate_point = [&rng]() { @@ -447,17 +445,12 @@ std::vector InstructionMutator::generate_ecadd_instruction(std: }; // Generate SET instructions to backfill a point at the given addresses - auto backfill_point = [&instructions](const bb::avm2::EmbeddedCurvePoint& point, - AddressRef x_addr, - AddressRef y_addr, - AddressRef inf_addr) { + auto backfill_point = [&instructions]( + const bb::avm2::EmbeddedCurvePoint& point, AddressRef x_addr, AddressRef y_addr) { instructions.push_back( SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, .result_address = x_addr, .value = point.x() }); instructions.push_back( SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, .result_address = y_addr, .value = point.y() }); - instructions.push_back(SET_8_Instruction{ .value_tag = bb::avm2::MemoryTag::U1, - .result_address = inf_addr, - .value = static_cast(point.is_infinity() ? 1 : 0) }); }; auto p1 = generate_point(); @@ -466,20 +459,16 @@ std::vector InstructionMutator::generate_ecadd_instruction(std: // Generate addresses (SET_FF uses 16-bit, SET_8 uses 8-bit operands) AddressRef p1_x_addr = generate_address_ref(rng, MAX_16BIT_OPERAND); AddressRef p1_y_addr = generate_address_ref(rng, MAX_16BIT_OPERAND); - AddressRef p1_inf_addr = generate_address_ref(rng, MAX_8BIT_OPERAND); AddressRef p2_x_addr = generate_address_ref(rng, MAX_16BIT_OPERAND); AddressRef p2_y_addr = generate_address_ref(rng, MAX_16BIT_OPERAND); - AddressRef p2_inf_addr = generate_address_ref(rng, MAX_8BIT_OPERAND); - backfill_point(p1, p1_x_addr, p1_y_addr, p1_inf_addr); - backfill_point(p2, p2_x_addr, p2_y_addr, p2_inf_addr); + backfill_point(p1, p1_x_addr, p1_y_addr); + backfill_point(p2, p2_x_addr, p2_y_addr); instructions.push_back(ECADD_Instruction{ .p1_x = p1_x_addr, .p1_y = p1_y_addr, - .p1_infinite = p1_inf_addr, .p2_x = p2_x_addr, .p2_y = p2_y_addr, - .p2_infinite = p2_inf_addr, .result = generate_address_ref(rng, MAX_16BIT_OPERAND) }); return instructions; @@ -1476,8 +1465,8 @@ void InstructionMutator::mutate_successcopy_instruction(SUCCESSCOPY_Instruction& void InstructionMutator::mutate_ecadd_instruction(ECADD_Instruction& instruction, std::mt19937_64& rng) { - // ECADD has 7 operands, select one to mutate - int choice = std::uniform_int_distribution(0, 6)(rng); + // ECADD has 5 operands, select one to mutate + int choice = std::uniform_int_distribution(0, 4)(rng); switch (choice) { case 0: mutate_param_ref(instruction.p1_x, rng, MemoryTag::FF, MAX_16BIT_OPERAND); @@ -1486,18 +1475,12 @@ void InstructionMutator::mutate_ecadd_instruction(ECADD_Instruction& instruction mutate_param_ref(instruction.p1_y, rng, MemoryTag::FF, MAX_16BIT_OPERAND); break; case 2: - mutate_param_ref(instruction.p1_infinite, rng, MemoryTag::U1, MAX_16BIT_OPERAND); - break; - case 3: mutate_param_ref(instruction.p2_x, rng, MemoryTag::FF, MAX_16BIT_OPERAND); break; - case 4: + case 3: mutate_param_ref(instruction.p2_y, rng, MemoryTag::FF, MAX_16BIT_OPERAND); break; - case 5: - mutate_param_ref(instruction.p2_infinite, rng, MemoryTag::U1, MAX_16BIT_OPERAND); - break; - case 6: + case 4: mutate_address_ref(instruction.result, rng, MAX_16BIT_OPERAND); break; } diff --git a/barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp index 070d5bbc80ef..e63b9d7e3615 100644 --- a/barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp @@ -233,7 +233,7 @@ #define AVM_POSEIDON2_BASE_L2_GAS 360 #define AVM_SHA256COMPRESSION_BASE_L2_GAS 12288 #define AVM_KECCAKF1600_BASE_L2_GAS 58176 -#define AVM_ECADD_BASE_L2_GAS 270 +#define AVM_ECADD_BASE_L2_GAS 180 #define AVM_TORADIXBE_BASE_L2_GAS 24 #define AVM_CALLDATACOPY_DYN_L2_GAS 3 #define AVM_RETURNDATACOPY_DYN_L2_GAS 3 @@ -272,7 +272,8 @@ #define DOM_SEP__CONTRACT_CLASS_ID 3923495515UL #define DOM_SEP__SALTED_INITIALIZATION_HASH 2763052992UL #define DOM_SEP__PUBLIC_KEYS_HASH 777457226UL +#define DOM_SEP__SINGLE_PUBLIC_KEY_HASH 3452068255UL #define DOM_SEP__PARTIAL_ADDRESS 2103633018UL -#define DOM_SEP__CONTRACT_ADDRESS_V1 1788365517UL +#define DOM_SEP__CONTRACT_ADDRESS_V2 4099338721UL #define DOM_SEP__BLOCK_HEADER_HASH 4195546849UL #define DOM_SEP__PUBLIC_CALLDATA 2760353947UL diff --git a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp index 7bcc3fc2edfc..571ca7804e27 100644 --- a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp +++ b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp @@ -11,7 +11,7 @@ GrumpkinMul::Response GrumpkinMul::execute(BBApiRequest& request) && if (!point.on_curve()) { BBAPI_ERROR(request, "Input point must be on the curve"); } - return { point * scalar }; + return { grumpkin::g1::element(point).mul_const_time(scalar).to_affine_const_time() }; } GrumpkinAdd::Response GrumpkinAdd::execute(BBApiRequest& request) && @@ -32,7 +32,11 @@ GrumpkinBatchMul::Response GrumpkinBatchMul::execute(BBApiRequest& request) && BBAPI_ERROR(request, "Input point must be on the curve"); } } - auto output = grumpkin::g1::element::batch_mul_with_endomorphism(points, scalar); + std::vector output; + output.reserve(points.size()); + for (const auto& p : points) { + output.emplace_back(grumpkin::g1::element(p).mul_const_time(scalar).to_affine_const_time()); + } return { std::move(output) }; } @@ -54,7 +58,7 @@ Secp256k1Mul::Response Secp256k1Mul::execute(BBApiRequest& request) && if (!point.on_curve()) { BBAPI_ERROR(request, "Input point must be on the curve"); } - return { point * scalar }; + return { secp256k1::g1::element(point).mul_const_time(scalar).to_affine_const_time() }; } Secp256k1GetRandomFr::Response Secp256k1GetRandomFr::execute(BB_UNUSED BBApiRequest& request) && @@ -87,7 +91,7 @@ Bn254G1Mul::Response Bn254G1Mul::execute(BBApiRequest& request) && if (!point.on_curve()) { BBAPI_ERROR(request, "Input point must be on the curve"); } - auto result = point * scalar; + auto result = bb::g1::element(point).mul_const_time(scalar).to_affine_const_time(); if (!result.on_curve()) { BBAPI_ERROR(request, "Output point must be on the curve"); } diff --git a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecdsa.cpp b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecdsa.cpp index c664e74d65a5..e2f351a302f1 100644 --- a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecdsa.cpp +++ b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecdsa.cpp @@ -10,12 +10,12 @@ namespace bb::bbapi { // Secp256k1 implementations EcdsaSecp256k1ComputePublicKey::Response EcdsaSecp256k1ComputePublicKey::execute(BB_UNUSED BBApiRequest& request) && { - return { secp256k1::g1::one * private_key }; + return { secp256k1::g1::element(secp256k1::g1::one).mul_const_time(private_key).to_affine_const_time() }; } EcdsaSecp256k1ConstructSignature::Response EcdsaSecp256k1ConstructSignature::execute(BB_UNUSED BBApiRequest& request) && { - auto pub_key = secp256k1::g1::one * private_key; + auto pub_key = secp256k1::g1::element(secp256k1::g1::one).mul_const_time(private_key).to_affine_const_time(); crypto::ecdsa_key_pair key_pair = { private_key, pub_key }; std::string message_str(reinterpret_cast(message.data()), message.size()); @@ -44,12 +44,12 @@ EcdsaSecp256k1VerifySignature::Response EcdsaSecp256k1VerifySignature::execute(B // Secp256r1 implementations EcdsaSecp256r1ComputePublicKey::Response EcdsaSecp256r1ComputePublicKey::execute(BB_UNUSED BBApiRequest& request) && { - return { secp256r1::g1::one * private_key }; + return { secp256r1::g1::element(secp256r1::g1::one).mul_const_time(private_key).to_affine_const_time() }; } EcdsaSecp256r1ConstructSignature::Response EcdsaSecp256r1ConstructSignature::execute(BB_UNUSED BBApiRequest& request) && { - auto pub_key = secp256r1::g1::one * private_key; + auto pub_key = secp256r1::g1::element(secp256r1::g1::one).mul_const_time(private_key).to_affine_const_time(); crypto::ecdsa_key_pair key_pair = { private_key, pub_key }; std::string message_str(reinterpret_cast(message.data()), message.size()); diff --git a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp index 68b51ea2cd8e..f5c365a23479 100644 --- a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp +++ b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp @@ -8,12 +8,13 @@ namespace bb::bbapi { SchnorrComputePublicKey::Response SchnorrComputePublicKey::execute(BB_UNUSED BBApiRequest& request) && { - return { grumpkin::g1::one * private_key }; + return { grumpkin::g1::element(grumpkin::g1::one).mul_const_time(private_key).to_affine_const_time() }; } SchnorrConstructSignature::Response SchnorrConstructSignature::execute(BB_UNUSED BBApiRequest& request) && { - grumpkin::g1::affine_element pub_key = grumpkin::g1::one * private_key; + grumpkin::g1::affine_element pub_key = + grumpkin::g1::element(grumpkin::g1::one).mul_const_time(private_key).to_affine_const_time(); crypto::schnorr_key_pair key_pair = { private_key, pub_key }; auto sig = crypto::schnorr_construct_signature(message_field, key_pair); diff --git a/barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp b/barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp index 8588ffae6876..a028e787fb9b 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp @@ -31,11 +31,11 @@ ecdsa_signature ecdsa_construct_signature(const std::string& message, const ecds // Compute R = k * G. k is the secret RFC6979 nonce, so use the constant-time multiplication // to defend against the Hamming-weight / bit-length timing leak in operator*. - typename G1::affine_element R(typename G1::element(G1::one).mul_const_time(k)); + typename G1::affine_element R(typename G1::element(G1::one).mul_const_time(k).to_affine_const_time()); // Compute the signature Fr r = Fr(R.x); - Fr s = (z + r * account.private_key) / k; + Fr s = (z + r * account.private_key) * k.invert_const_time(); secure_erase_bytes(&k, sizeof(k)); // Ensure that the value of s is "low", i.e. s := min{ s, (|Fr| - s) } diff --git a/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc b/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc index 847608a53244..16fe624c72dc 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc +++ b/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc @@ -86,7 +86,7 @@ schnorr_signature schnorr_construct_signature(const typename G1::Fq& message_fie // k is a secret nonce; use the constant-time multiplication to defend against the // Hamming-weight / bit-length timing leak in operator*. - typename G1::affine_element R(typename G1::element(G1::one).mul_const_time(k)); + typename G1::affine_element R(typename G1::element(G1::one).mul_const_time(k).to_affine_const_time()); using Fq = typename G1::Fq; Fq e = schnorr_generate_challenge(message_field, public_key, R); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp index a60ce0cedaf0..e00b57168858 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp @@ -252,9 +252,8 @@ void update_max_witness_index_from_opcode(Acir::Opcode const& opcode, AcirFormat } }, [&](const Acir::Opcode::MemoryOp& arg) { - update_max_witness_index_from_expression(arg.op.index, af); - update_max_witness_index_from_expression(arg.op.value, af); - update_max_witness_index_from_expression(arg.op.operation, af); + update_max_witness_index_from_witness(arg.op.index); + update_max_witness_index_from_witness(arg.op.value); }, [&](const Acir::Opcode::BrilligCall& arg) { for (const auto& input : arg.inputs) { @@ -703,7 +702,6 @@ void add_blackbox_func_call_to_acir_format(Acir::Opcode::BlackBoxFuncCall const& .predicate = parse_input(arg.predicate), .out_point_x = to_witness((*arg.outputs)[0]), .out_point_y = to_witness((*arg.outputs)[1]), - .out_point_is_infinite = to_witness((*arg.outputs)[2]), }); af.original_opcode_indices.multi_scalar_mul_constraints.push_back(opcode_index); }, @@ -711,14 +709,11 @@ void add_blackbox_func_call_to_acir_format(Acir::Opcode::BlackBoxFuncCall const& af.ec_add_constraints.push_back(EcAdd{ .input1_x = parse_input((*arg.input1)[0]), .input1_y = parse_input((*arg.input1)[1]), - .input1_infinite = parse_input((*arg.input1)[2]), .input2_x = parse_input((*arg.input2)[0]), .input2_y = parse_input((*arg.input2)[1]), - .input2_infinite = parse_input((*arg.input2)[2]), .predicate = parse_input(arg.predicate), .result_x = to_witness((*arg.outputs)[0]), .result_y = to_witness((*arg.outputs)[1]), - .result_infinite = to_witness((*arg.outputs)[2]), }); af.original_opcode_indices.ec_add_constraints.push_back(opcode_index); }, @@ -817,36 +812,8 @@ BlockConstraint memory_init_to_block_constraint(Acir::Opcode::MemoryInit const& void add_memory_op_to_block_constraint(Acir::Opcode::MemoryOp const& mem_op, BlockConstraint& block) { - // Lambda to convert an Acir::Expression to a witness index. Noir always emits a single unscaled witness term for - // memory op indices and values, so anything else is a malformed input. - auto acir_expression_to_witness = [](const Acir::Expression& expr) -> uint32_t { - BB_ASSERT(expr.mul_terms.empty(), "MemoryOp should not have multiplication terms"); - BB_ASSERT_EQ(expr.linear_combinations.size(), 1U, "MemoryOp expression must be a single witness"); - - const fr a_scaling = from_buffer_with_bound_checks(std::get<0>(expr.linear_combinations[0])); - const fr constant_term = from_buffer_with_bound_checks(expr.q_c); - - BB_ASSERT(a_scaling == fr::one() && constant_term == fr::zero(), - "MemoryOp expression must be a single unscaled witness with no constant term"); - - return std::get<1>(expr.linear_combinations[0]).value; - }; - - // Lambda to determine whether a memory operation is a read or write operation - auto is_read_operation = [](const Acir::Expression& expr) { - BB_ASSERT(expr.mul_terms.empty(), "MemoryOp expression should not have multiplication terms"); - BB_ASSERT(expr.linear_combinations.empty(), "MemoryOp expression should not have linear terms"); - - const fr const_term = from_buffer_with_bound_checks(expr.q_c); - - BB_ASSERT((const_term == fr::one()) || (const_term == fr::zero()), - "MemoryOp expression should be either zero or one"); - - // A read operation is given by a zero Expression - return const_term == fr::zero(); - }; - - AccessType access_type = is_read_operation(mem_op.op.operation) ? AccessType::Read : AccessType::Write; + // Acir::MemOp::read is the serialized MemOpKind bool: false = Read, true = Write. + AccessType access_type = mem_op.op.read ? AccessType::Write : AccessType::Read; if (access_type == AccessType::Write) { // We are not allowed to write on the databus BB_ASSERT((block.type != BlockType::CallData) && (block.type != BlockType::ReturnData)); @@ -856,8 +823,8 @@ void add_memory_op_to_block_constraint(Acir::Opcode::MemoryOp const& mem_op, Blo MemOp acir_mem_op = MemOp{ .access_type = access_type, - .index = acir_expression_to_witness(mem_op.op.index), - .value = acir_expression_to_witness(mem_op.op.value), + .index = mem_op.op.index.value, + .value = mem_op.op.value.value, }; block.trace.push_back(acir_mem_op); } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 12b15b737f0e..7b619640e656 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -20,6 +20,45 @@ namespace { auto& engine = numeric::get_debug_randomness(); } // namespace +TEST(BlockConstraintMemOpEncoding, ReadFlagFalseDecodesAsRead) +{ + Acir::Opcode::MemoryInit mem_init{ + .block_id = Acir::BlockId{ .value = 0 }, + .init = { Acir::Witness{ .value = 0 } }, + .block_type = Acir::BlockType{ .value = Acir::BlockType::CallData{ .value = 0 } }, + }; + BlockConstraint block = memory_init_to_block_constraint(mem_init); + + Acir::Opcode::MemoryOp mem_op{ + .block_id = Acir::BlockId{ .value = 0 }, + .op = Acir::MemOp{ .read = false, .index = Acir::Witness{ .value = 1 }, .value = Acir::Witness{ .value = 2 } }, + }; + + EXPECT_NO_THROW(add_memory_op_to_block_constraint(mem_op, block)); + + ASSERT_EQ(block.trace.size(), 1); + EXPECT_EQ(block.trace[0].access_type, AccessType::Read); + EXPECT_EQ(block.trace[0].index, 1); + EXPECT_EQ(block.trace[0].value, 2); +} + +TEST(BlockConstraintMemOpEncoding, AccessTypeEncodesToReadFlag) +{ + const MemOp read_op{ + .access_type = AccessType::Read, + .index = 1, + .value = 2, + }; + const MemOp write_op{ + .access_type = AccessType::Write, + .index = 3, + .value = 4, + }; + + EXPECT_FALSE(mem_op_to_acir_mem_op(read_op).read); + EXPECT_TRUE(mem_op_to_acir_mem_op(write_op).read); +} + template struct ROMTestParams { using Builder = Builder_; static constexpr size_t table_size = TableSize_; @@ -304,12 +343,10 @@ using RAMTestConfigs = testing::Types, RAMTestParams, RAMTestParams, - RAMTestParams, RAMTestParams, RAMTestParams, RAMTestParams, - RAMTestParams, - RAMTestParams>; + RAMTestParams>; TYPED_TEST_SUITE(RAMTest, RAMTestConfigs); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp index 66d4b8b382c2..8ad5b8595e4d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp @@ -46,38 +46,25 @@ template void create_ec_add_constraint(Builder& builder, cons field_ct input_result_x = field_ct::from_witness_index(&builder, input.result_x); field_ct input_result_y = field_ct::from_witness_index(&builder, input.result_y); - bool_ct input_result_infinite = bool_ct(field_ct::from_witness_index(&builder, input.result_infinite)); if (builder.is_write_vk_mode()) { builder.set_variable(input_result_x.get_witness_index(), bb::grumpkin::g1::affine_one.x); builder.set_variable(input_result_y.get_witness_index(), bb::grumpkin::g1::affine_one.y); - builder.set_variable(input_result_infinite.get_witness_index(), bb::fr(0)); // generator is finite } - cycle_group_ct input1_point = - to_grumpkin_point(input.input1_x, input.input1_y, input.input1_infinite, predicate, builder); - cycle_group_ct input2_point = - to_grumpkin_point(input.input2_x, input.input2_y, input.input2_infinite, predicate, builder); + cycle_group_ct input1_point = to_grumpkin_point(input.input1_x, input.input1_y, predicate, builder); + cycle_group_ct input2_point = to_grumpkin_point(input.input2_x, input.input2_y, predicate, builder); // Use public constructor which auto-detects infinity from (0,0) coordinates. // Note that input_result is computed by Noir and passed to bb via ACIR. Hence, it is always a valid point on // Grumpkin, so we don't need to assert on curve. cycle_group_ct input_result(input_result_x, input_result_y, /*assert_on_curve=*/false); - // Constrain the result_infinite witness against the auto-detected infinity from coordinates. - // Use conditional_assign so the constraint is inactive when predicate is false. - bool_ct expected_infinite = - bool_ct::conditional_assign(predicate, input_result.is_point_at_infinity(), input_result_infinite); - input_result_infinite.assert_equal(expected_infinite); - // Step 2. cycle_group_ct result = input1_point + input2_point; // The assert_equal method standardizes both points before comparing, so if either of them is the point at - // infinity, the coordinates will be assigned to be (0,0). This is OK as long as Noir developers do not use the - // coordinates of a point at infinity (otherwise input_result might be the point at infinity different from (0, - // 0, true), and the fact that assert_equal passes doesn't imply anything for the original coordinates of - // input_result). + // infinity, the coordinates will be assigned to be (0,0). cycle_group_ct to_be_asserted_equal = cycle_group_ct::conditional_assign(predicate, input_result, result); result.assert_equal(to_be_asserted_equal); } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.hpp index b1c9bee4dfff..e7969be3fcf5 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.hpp @@ -13,35 +13,30 @@ namespace acir_format { /** * @brief Constraints for addition of two points on the Grumpkin curve. * - * @details EcAdd constraints have 10 components: + * @details EcAdd constraints have 7 components: * - input1_x: x-coordinate of the first input point * - input1_y: y-coordinate of the first input point - * - input1_infinite: flag indicating if the first input point is the point at infinity * - input2_x: x-coordinate of the second input point * - input2_y: y-coordinate of the second input point - * - input2_infinite: flag indicating if the second input point is the point at infinity * - predicate: flag indicating whether the constraint is active * - result_x: witness index for the x-coordinate of the resulting point * - result_y: witness index for the y-coordinate of the resulting point - * - result_infinite: witness index for the flag indicating if the result is the point at infinity * - * The data related to input1 and input2 can either be given by witnesses or constants. However, x and y coordinates - * pertaining to the same input must be either all witnesses or all constants. + * The point at infinity is represented by the coordinates (0, 0). The data related to input1 and input2 can either be + * given by witnesses or constants. However, x and y coordinates pertaining to the same input must be either all + * witnesses or all constants. */ struct EcAdd { WitnessOrConstant input1_x; WitnessOrConstant input1_y; - WitnessOrConstant input1_infinite; WitnessOrConstant input2_x; WitnessOrConstant input2_y; - WitnessOrConstant input2_infinite; // Predicate indicating whether the constraint should be disabled: // - true: the constraint is valid // - false: the constraint is disabled, i.e it must not fail and can return whatever. WitnessOrConstant predicate; uint32_t result_x; uint32_t result_y; - uint32_t result_infinite; friend bool operator==(EcAdd const& lhs, EcAdd const& rhs) = default; }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp index 27f80a89566c..848b5a80c5d9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp @@ -60,15 +60,12 @@ template class EcOperationsTesting auto construct_point = [&](const GrumpkinPoint& point, bool as_constant) -> std::vector> { if (as_constant) { // Point is constant - return { WitnessOrConstant::from_constant(point.x), - WitnessOrConstant::from_constant(point.y), - WitnessOrConstant::from_constant(point.is_point_at_infinity() ? FF(1) : FF(0)) }; + return { WitnessOrConstant::from_constant(point.x), WitnessOrConstant::from_constant(point.y) }; } // Point is witness std::vector point_indices = add_to_witness_and_track_indices(witness_values, point); return { WitnessOrConstant::from_index(point_indices[0]), - WitnessOrConstant::from_index(point_indices[1]), - WitnessOrConstant::from_index(point_indices[2]) }; + WitnessOrConstant::from_index(point_indices[1]) }; }; // Determine which inputs are constants based on the Constancy template parameter @@ -87,14 +84,11 @@ template class EcOperationsTesting ec_add_constraint = EcAdd{ .input1_x = input1_fields[0], .input1_y = input1_fields[1], - .input1_infinite = input1_fields[2], .input2_x = input2_fields[0], .input2_y = input2_fields[1], - .input2_infinite = input2_fields[2], .predicate = WitnessOrConstant::from_index(predicate_index), .result_x = result_indices[0], .result_y = result_indices[1], - .result_infinite = result_indices[2], }; } @@ -124,7 +118,6 @@ template class EcOperationsTesting // Tamper with the result (always a witness) by setting it to the generator point witness_values[constraint.result_x] = GrumpkinPoint::one().x; witness_values[constraint.result_y] = GrumpkinPoint::one().y; - witness_values[constraint.result_infinite] = FF::zero(); break; } case InvalidWitness::Target::None: @@ -296,34 +289,29 @@ TYPED_TEST(EcOperationsTestsBothConstant, InvalidWitnesses) } // ============================================================ -// Infinity flag tests +// Infinity tests: the point at infinity is encoded as (0, 0). // ============================================================ using GrumpkinPoint = bb::grumpkin::g1::affine_element; using FF = bb::fr; struct AcirPoint { - FF x, y, inf; - static AcirPoint from_native(const GrumpkinPoint& p) - { - return { p.x, p.y, p.is_point_at_infinity() ? FF(1) : FF(0) }; - } - static AcirPoint infinity() { return { FF(0), FF(0), FF(1) }; } + FF x, y; + static AcirPoint from_native(const GrumpkinPoint& p) { return { p.x, p.y }; } + static AcirPoint infinity() { return { FF(0), FF(0) }; } }; template class EcOperationsInfinityTests : public ::testing::Test { protected: static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } - // Push an AcirPoint to the witness vector and return the [x, y, inf] indices. - static std::array push_point(WitnessVector& witness, const AcirPoint& pt) + // Push an AcirPoint to the witness vector and return the [x, y] indices. + static std::array push_point(WitnessVector& witness, const AcirPoint& pt) { uint32_t xi = static_cast(witness.size()); witness.emplace_back(pt.x); uint32_t yi = static_cast(witness.size()); witness.emplace_back(pt.y); - uint32_t ii = static_cast(witness.size()); - witness.emplace_back(pt.inf); - return { xi, yi, ii }; + return { xi, yi }; } // Build an EcAdd constraint (predicate=1) from three ACIR points. @@ -340,14 +328,11 @@ template class EcOperationsInfinityTests : public ::testing:: EcAdd c{ .input1_x = WitnessOrConstant::from_index(i1[0]), .input1_y = WitnessOrConstant::from_index(i1[1]), - .input1_infinite = WitnessOrConstant::from_index(i1[2]), .input2_x = WitnessOrConstant::from_index(i2[0]), .input2_y = WitnessOrConstant::from_index(i2[1]), - .input2_infinite = WitnessOrConstant::from_index(i2[2]), .predicate = WitnessOrConstant::from_index(pred_idx), .result_x = r[0], .result_y = r[1], - .result_infinite = r[2], }; return { c, witness }; } @@ -365,7 +350,7 @@ template class EcOperationsInfinityTests : public ::testing:: TYPED_TEST_SUITE(EcOperationsInfinityTests, BuilderTypes); -// P + (-P) = point_at_infinity: valid proof with result_infinite=1, result_x=0, result_y=0. +// P + (-P) = (0, 0): valid circuit. TYPED_TEST(EcOperationsInfinityTests, ResultIsInfinity) { BB_DISABLE_ASSERTS(); @@ -376,37 +361,7 @@ TYPED_TEST(EcOperationsInfinityTests, ResultIsInfinity) EXPECT_TRUE(ok) << "P + (-P) = infinity should produce a valid circuit"; } -// A finite result with result_infinite=1 (forged) must fail. -TYPED_TEST(EcOperationsInfinityTests, ForgedInfinityFlagOnFiniteResultFails) -{ - BB_DISABLE_ASSERTS(); - GrumpkinPoint p = GrumpkinPoint::random_element(); - GrumpkinPoint q = GrumpkinPoint::random_element(); - ASSERT_FALSE((p + q).is_point_at_infinity()); - auto [constraint, witness] = - TestFixture::make_ec_add(AcirPoint::from_native(p), AcirPoint::from_native(q), AcirPoint::from_native(p + q)); - witness[constraint.result_infinite] = FF(1); // forge: finite result claimed as infinite - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) - << "Forged infinity flag on finite result should fail"; -} - -// An infinity result with result_infinite=0 (forged) must fail. -TYPED_TEST(EcOperationsInfinityTests, ForgedFiniteFlagOnInfinityResultFails) -{ - BB_DISABLE_ASSERTS(); - GrumpkinPoint p = GrumpkinPoint::random_element(); - // Forge result: (0,0) coordinates but is_infinite=0 (should be 1) - auto [constraint, witness] = TestFixture::make_ec_add( - AcirPoint::from_native(p), AcirPoint::from_native(-p), AcirPoint{ FF(0), FF(0), FF(0) }); - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) - << "Forged finite flag on infinity result should fail"; -} - -// Input point at infinity (∞ + P = P): should produce a valid circuit. +// Input point at infinity (∞ + P = P): valid circuit. TYPED_TEST(EcOperationsInfinityTests, Input1IsInfinity) { BB_DISABLE_ASSERTS(); @@ -417,17 +372,3 @@ TYPED_TEST(EcOperationsInfinityTests, Input1IsInfinity) auto [ok, err] = TestFixture::run_circuit(constraint, witness); EXPECT_TRUE(ok) << "infinity + P = P should produce a valid circuit"; } - -// Input point with forged input_infinite=1 (non-zero coordinates) must fail. -TYPED_TEST(EcOperationsInfinityTests, ForgedInputInfinityFlagFails) -{ - BB_DISABLE_ASSERTS(); - GrumpkinPoint p = GrumpkinPoint::random_element(); - GrumpkinPoint q = GrumpkinPoint::random_element(); - auto [constraint, witness] = - TestFixture::make_ec_add(AcirPoint::from_native(p), AcirPoint::from_native(q), AcirPoint::from_native(p + q)); - witness[constraint.input1_infinite.index] = FF(1); // forge: finite input1 claimed as infinite - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) << "Forged input infinity flag should fail"; -} diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp index e4f6adb5cc71..8f9febf543bc 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp @@ -43,8 +43,8 @@ template inline constexpr size_t BLAKE3 = 2158 + ZERO_GATE + template inline constexpr size_t KECCAK_PERMUTATION = 17387 + ZERO_GATE + MEGA_OFFSET; template inline constexpr size_t POSEIDON2_PERMUTATION = (IsMegaBuilder ? 27 : 73) + ZERO_GATE + MEGA_OFFSET; -template inline constexpr size_t MULTI_SCALAR_MUL = 3563 + ZERO_GATE; -template inline constexpr size_t EC_ADD = 84 + ZERO_GATE + MEGA_OFFSET; +template inline constexpr size_t MULTI_SCALAR_MUL = 3557 + ZERO_GATE; +template inline constexpr size_t EC_ADD = 76 + ZERO_GATE + MEGA_OFFSET; template inline constexpr size_t BLOCK_ROM_READ = 9 + ZERO_GATE + MEGA_OFFSET; template inline constexpr size_t BLOCK_RAM_READ = 9 + ZERO_GATE + MEGA_OFFSET; template inline constexpr size_t BLOCK_RAM_WRITE = 18 + ZERO_GATE + MEGA_OFFSET; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp index 6be1896928f5..dca9f880c246 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp @@ -83,13 +83,11 @@ static MsmInputs reconstruct_msm_inputs(Builder& builder, const MultiSc // Reconstruct expected result field_ct input_result_x = field_ct::from_witness_index(&builder, input.out_point_x); field_ct input_result_y = field_ct::from_witness_index(&builder, input.out_point_y); - bool_ct input_result_infinite = bool_ct(field_ct::from_witness_index(&builder, input.out_point_is_infinite)); // If no valid witness assignments, set result to generator point to avoid errors during circuit construction if (builder.is_write_vk_mode()) { builder.set_variable(input_result_x.get_witness_index(), bb::grumpkin::g1::affine_one.x); builder.set_variable(input_result_y.get_witness_index(), bb::grumpkin::g1::affine_one.y); - builder.set_variable(input_result_infinite.get_witness_index(), bb::fr(0)); // generator is finite } // Use public constructor which auto-detects infinity from (0,0) coordinates. @@ -97,25 +95,17 @@ static MsmInputs reconstruct_msm_inputs(Builder& builder, const MultiSc // Grumpkin, so we don't need to assert on curve. cycle_group_ct input_result(input_result_x, input_result_y, /*assert_on_curve=*/false); - // Constrain the out_point_is_infinite witness against the auto-detected infinity from coordinates. - // Use conditional_assign so the constraint is inactive when predicate is false. - bool_ct expected_infinite = - bool_ct::conditional_assign(predicate, input_result.is_point_at_infinity(), input_result_infinite); - input_result_infinite.assert_equal(expected_infinite); - // Reconstruct points and scalars std::vector points; std::vector scalars; - // Ensure that the number of points and scalars are consistent (3 field elements per point, 2 per scalar) - BB_ASSERT(input.points.size() * 2 == input.scalars.size() * 3, "MultiScalarMul input size mismatch"); + // Ensure that the number of points and scalars are consistent (2 field elements per point, 2 per scalar) + BB_ASSERT_EQ(input.points.size(), input.scalars.size(), "MultiScalarMul input size mismatch"); - for (size_t i = 0; i < input.points.size(); i += 3) { - cycle_group_ct input_point = - to_grumpkin_point(input.points[i], input.points[i + 1], input.points[i + 2], predicate, builder); + for (size_t i = 0; i < input.points.size(); i += 2) { + cycle_group_ct input_point = to_grumpkin_point(input.points[i], input.points[i + 1], predicate, builder); - cycle_scalar_ct scalar = - to_grumpkin_scalar(input.scalars[2 * (i / 3)], input.scalars[2 * (i / 3) + 1], predicate, builder); + cycle_scalar_ct scalar = to_grumpkin_scalar(input.scalars[i], input.scalars[i + 1], predicate, builder); points.push_back(input_point); scalars.push_back(scalar); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.hpp index 8c9d051e4dd9..fbb3a12f47c8 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.hpp @@ -23,7 +23,6 @@ struct MultiScalarMul { uint32_t out_point_x; uint32_t out_point_y; - uint32_t out_point_is_infinite; friend bool operator==(MultiScalarMul const& lhs, MultiScalarMul const& rhs) = default; }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp index a1e15b726336..408112454fe5 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp @@ -65,19 +65,15 @@ template class MultiScalarMulTesti constexpr bool scalars_are_constant = (Constancy == InputConstancy::Scalars || Constancy == InputConstancy::Both); - // Helper to add points: either as witnesses or constants based on Constancy + // Helper to add points: either as witnesses or constants based on Constancy. + // Points are encoded as (x, y); the point at infinity is encoded as (0, 0). auto construct_points = [&]() -> std::vector> { if constexpr (points_are_constant) { - // Points are constants - return { WitnessOrConstant::from_constant(point.x), - WitnessOrConstant::from_constant(point.y), - WitnessOrConstant::from_constant(point.is_point_at_infinity() ? FF(1) : FF(0)) }; + return { WitnessOrConstant::from_constant(point.x), WitnessOrConstant::from_constant(point.y) }; } - // Points are witnesses std::vector point_indices = add_to_witness_and_track_indices(witness_values, point); return { WitnessOrConstant::from_index(point_indices[0]), - WitnessOrConstant::from_index(point_indices[1]), - WitnessOrConstant::from_index(point_indices[2]) }; + WitnessOrConstant::from_index(point_indices[1]) }; }; // Helper to add scalars: either as witnesses or constants based on Constancy @@ -112,7 +108,6 @@ template class MultiScalarMulTesti .predicate = WitnessOrConstant::from_index(predicate_index), .out_point_x = result_indices[0], .out_point_y = result_indices[1], - .out_point_is_infinite = result_indices[2], }; } @@ -142,7 +137,6 @@ template class MultiScalarMulTesti // Tamper with the result by setting it to the generator point witness_values[constraint.out_point_x] = GrumpkinPoint::one().x; witness_values[constraint.out_point_y] = GrumpkinPoint::one().y; - witness_values[constraint.out_point_is_infinite] = FF::zero(); break; } case InvalidWitness::Target::None: @@ -314,20 +308,16 @@ TYPED_TEST(MultiScalarMulTestsBothConstant, InvalidWitnesses) } // ============================================================ -// Infinity flag tests +// Infinity tests: the point at infinity is encoded as (0, 0). // ============================================================ -// ACIR convention for encoding a curve point: (x, y, is_infinite) as field values. using MsmGrumpkinPoint = bb::grumpkin::g1::affine_element; using MsmFF = bb::fr; struct MsmAcirPoint { - MsmFF x, y, inf; - static MsmAcirPoint from_native(const MsmGrumpkinPoint& p) - { - return { p.x, p.y, p.is_point_at_infinity() ? MsmFF(1) : MsmFF(0) }; - } - static MsmAcirPoint infinity() { return { MsmFF(0), MsmFF(0), MsmFF(1) }; } + MsmFF x, y; + static MsmAcirPoint from_native(const MsmGrumpkinPoint& p) { return { p.x, p.y }; } + static MsmAcirPoint infinity() { return { MsmFF(0), MsmFF(0) }; } }; // Grumpkin scalar split into low 128-bit and high 128-bit field limbs. @@ -347,16 +337,14 @@ template class MsmSingleTermFixture : public ::testing::Test protected: static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } - // Push an MsmAcirPoint to witness; return [x, y, inf] indices. - static std::array push_point(WitnessVector& witness, const MsmAcirPoint& pt) + // Push an MsmAcirPoint to witness; return [x, y] indices. + static std::array push_point(WitnessVector& witness, const MsmAcirPoint& pt) { uint32_t xi = static_cast(witness.size()); witness.emplace_back(pt.x); uint32_t yi = static_cast(witness.size()); witness.emplace_back(pt.y); - uint32_t ii = static_cast(witness.size()); - witness.emplace_back(pt.inf); - return { xi, yi, ii }; + return { xi, yi }; } // Push a scalar (lo, hi) to witness; return [lo_idx, hi_idx]. @@ -381,14 +369,11 @@ template class MsmSingleTermFixture : public ::testing::Test witness.emplace_back(MsmFF(1)); MultiScalarMul c{ - .points = { WitnessOrConstant::from_index(p[0]), - WitnessOrConstant::from_index(p[1]), - WitnessOrConstant::from_index(p[2]) }, + .points = { WitnessOrConstant::from_index(p[0]), WitnessOrConstant::from_index(p[1]) }, .scalars = { WitnessOrConstant::from_index(s[0]), WitnessOrConstant::from_index(s[1]) }, .predicate = WitnessOrConstant::from_index(pred_idx), .out_point_x = r[0], .out_point_y = r[1], - .out_point_is_infinite = r[2], }; return { c, witness }; } @@ -408,7 +393,7 @@ template class MultiScalarMulInfinityTests : public MsmSingle TYPED_TEST_SUITE(MultiScalarMulInfinityTests, BuilderTypes); -// scalar=0 → result = ∞: valid proof with out_point_is_infinite=1. +// scalar=0 → result = (0, 0): valid circuit. TYPED_TEST(MultiScalarMulInfinityTests, ResultIsInfinity) { BB_DISABLE_ASSERTS(); @@ -420,40 +405,6 @@ TYPED_TEST(MultiScalarMulInfinityTests, ResultIsInfinity) EXPECT_TRUE(ok) << "0 * P = infinity should produce a valid circuit"; } -// A finite result with out_point_is_infinite=1 (forged) must fail. -TYPED_TEST(MultiScalarMulInfinityTests, ForgedInfinityFlagOnFiniteResultFails) -{ - BB_DISABLE_ASSERTS(); - MsmGrumpkinPoint point = MsmGrumpkinPoint::random_element(); - bb::fq scalar_native = bb::fq::random_element(); - while (scalar_native.is_zero()) { - scalar_native = bb::fq::random_element(); - } - MsmGrumpkinPoint result = point * scalar_native; - ASSERT_FALSE(result.is_point_at_infinity()); - auto [constraint, witness] = TestFixture::make_msm( - MsmAcirPoint::from_native(point), MsmScalar::from_native(scalar_native), MsmAcirPoint::from_native(result)); - witness[constraint.out_point_is_infinite] = MsmFF(1); // forge: finite result claimed as infinite - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) - << "Forged infinity flag on finite result should fail"; -} - -// An infinity result with out_point_is_infinite=0 (forged) must fail. -TYPED_TEST(MultiScalarMulInfinityTests, ForgedFiniteFlagOnInfinityResultFails) -{ - BB_DISABLE_ASSERTS(); - MsmGrumpkinPoint point = MsmGrumpkinPoint::random_element(); - // Forge result: (0,0) coordinates but is_infinite=0 (should be 1) - auto [constraint, witness] = TestFixture::make_msm( - MsmAcirPoint::from_native(point), MsmScalar::zero(), MsmAcirPoint{ MsmFF(0), MsmFF(0), MsmFF(0) }); - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) - << "Forged finite flag on infinity result should fail"; -} - // ============================================================ // Scalar field-bounds tests // ============================================================ diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/opcode_gate_count.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/opcode_gate_count.test.cpp index 73c722bd6c1a..43876202a8cb 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/opcode_gate_count.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/opcode_gate_count.test.cpp @@ -391,25 +391,21 @@ TYPED_TEST(OpcodeGateCountTests, MultiScalarMul) // Create a minimal MSM with one point and one scalar msm_constraint.points.push_back(WitnessOrConstant::from_index(0)); // x msm_constraint.points.push_back(WitnessOrConstant::from_index(1)); // y - msm_constraint.points.push_back(WitnessOrConstant::from_index(2)); // is_infinite - msm_constraint.scalars.push_back(WitnessOrConstant::from_index(3)); // scalar_lo - msm_constraint.scalars.push_back(WitnessOrConstant::from_index(4)); // scalar_hi + msm_constraint.scalars.push_back(WitnessOrConstant::from_index(2)); // scalar_lo + msm_constraint.scalars.push_back(WitnessOrConstant::from_index(3)); // scalar_hi - msm_constraint.predicate = WitnessOrConstant::from_index(5); + msm_constraint.predicate = WitnessOrConstant::from_index(4); - msm_constraint.out_point_x = 6; - msm_constraint.out_point_y = 7; - msm_constraint.out_point_is_infinite = 8; + msm_constraint.out_point_x = 5; + msm_constraint.out_point_y = 6; - WitnessVector witness(9, fr(0)); + WitnessVector witness(7, fr(0)); // Set valid point coordinates witness[0] = point.x; witness[1] = point.y; - witness[2] = fr(0); - witness[6] = point.x; - witness[7] = point.y; - witness[8] = fr(0); + witness[5] = point.x; + witness[6] = point.y; AcirFormat constraint_system = constraint_to_acir_format(msm_constraint); @@ -431,29 +427,23 @@ TYPED_TEST(OpcodeGateCountTests, EcAdd) EcAdd ec_add_constraint{ .input1_x = WitnessOrConstant::from_index(0), .input1_y = WitnessOrConstant::from_index(1), - .input1_infinite = WitnessOrConstant::from_index(2), - .input2_x = WitnessOrConstant::from_index(3), - .input2_y = WitnessOrConstant::from_index(4), - .input2_infinite = WitnessOrConstant::from_index(5), - .predicate = WitnessOrConstant::from_index(6), - .result_x = 7, - .result_y = 8, - .result_infinite = 9, + .input2_x = WitnessOrConstant::from_index(2), + .input2_y = WitnessOrConstant::from_index(3), + .predicate = WitnessOrConstant::from_index(4), + .result_x = 5, + .result_y = 6, }; - WitnessVector witness(10, fr(0)); + WitnessVector witness(7, fr(0)); // Set valid point1 coordinates witness[0] = point1.x; witness[1] = point1.y; - witness[2] = fr(0); // Set valid point2 coordinates - witness[3] = point2.x; - witness[4] = point2.y; - witness[5] = fr(0); + witness[2] = point2.x; + witness[3] = point2.y; // Set valid result coordinates - witness[7] = point1.x; - witness[8] = point1.y; - witness[9] = fr(0); + witness[5] = point1.x; + witness[6] = point1.y; AcirFormat constraint_system = constraint_to_acir_format(ec_add_constraint); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index cb20bb49b70b..d27238411e6f 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -1125,23 +1125,19 @@ struct BlackBoxOp { struct EmbeddedCurveAdd { Acir::MemoryAddress input1_x; Acir::MemoryAddress input1_y; - Acir::MemoryAddress input1_infinite; Acir::MemoryAddress input2_x; Acir::MemoryAddress input2_y; - Acir::MemoryAddress input2_infinite; Acir::HeapArray result; friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); void msgpack_pack(auto& packer) const { - packer.pack_array(7); + packer.pack_array(5); packer.pack(input1_x); packer.pack(input1_y); - packer.pack(input1_infinite); packer.pack(input2_x); packer.pack(input2_y); - packer.pack(input2_infinite); packer.pack(result); } @@ -1152,20 +1148,16 @@ struct BlackBoxOp { auto kvmap = Helpers::make_kvmap(o, name); Helpers::conv_fld_from_kvmap(kvmap, name, "input1_x", input1_x, false); Helpers::conv_fld_from_kvmap(kvmap, name, "input1_y", input1_y, false); - Helpers::conv_fld_from_kvmap(kvmap, name, "input1_infinite", input1_infinite, false); Helpers::conv_fld_from_kvmap(kvmap, name, "input2_x", input2_x, false); Helpers::conv_fld_from_kvmap(kvmap, name, "input2_y", input2_y, false); - Helpers::conv_fld_from_kvmap(kvmap, name, "input2_infinite", input2_infinite, false); Helpers::conv_fld_from_kvmap(kvmap, name, "result", result, false); } else if (o.type == msgpack::type::ARRAY) { auto array = o.via.array; Helpers::conv_fld_from_array(array, name, "input1_x", input1_x, 0); Helpers::conv_fld_from_array(array, name, "input1_y", input1_y, 1); - Helpers::conv_fld_from_array(array, name, "input1_infinite", input1_infinite, 2); - Helpers::conv_fld_from_array(array, name, "input2_x", input2_x, 3); - Helpers::conv_fld_from_array(array, name, "input2_y", input2_y, 4); - Helpers::conv_fld_from_array(array, name, "input2_infinite", input2_infinite, 5); - Helpers::conv_fld_from_array(array, name, "result", result, 6); + Helpers::conv_fld_from_array(array, name, "input2_x", input2_x, 2); + Helpers::conv_fld_from_array(array, name, "input2_y", input2_y, 3); + Helpers::conv_fld_from_array(array, name, "result", result, 4); } else { throw_or_abort("expected MAP or ARRAY for " + name); } @@ -3224,7 +3216,7 @@ struct BlackBoxFuncCall { std::vector points; std::vector scalars; Acir::FunctionInput predicate; - std::shared_ptr> outputs; + std::shared_ptr> outputs; friend bool operator==(const MultiScalarMul&, const MultiScalarMul&); @@ -3259,10 +3251,10 @@ struct BlackBoxFuncCall { }; struct EmbeddedCurveAdd { - std::shared_ptr> input1; - std::shared_ptr> input2; + std::shared_ptr> input1; + std::shared_ptr> input2; Acir::FunctionInput predicate; - std::shared_ptr> outputs; + std::shared_ptr> outputs; friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); @@ -4141,16 +4133,16 @@ struct BrilligOutputs { }; struct MemOp { - Acir::Expression operation; - Acir::Expression index; - Acir::Expression value; + bool read; + Acir::Witness index; + Acir::Witness value; friend bool operator==(const MemOp&, const MemOp&); void msgpack_pack(auto& packer) const { packer.pack_array(3); - packer.pack(operation); + packer.pack(read); packer.pack(index); packer.pack(value); } @@ -4160,12 +4152,12 @@ struct MemOp { std::string name = "MemOp"; if (o.type == msgpack::type::MAP) { auto kvmap = Helpers::make_kvmap(o, name); - Helpers::conv_fld_from_kvmap(kvmap, name, "operation", operation, false); + Helpers::conv_fld_from_kvmap(kvmap, name, "read", read, false); Helpers::conv_fld_from_kvmap(kvmap, name, "index", index, false); Helpers::conv_fld_from_kvmap(kvmap, name, "value", value, false); } else if (o.type == msgpack::type::ARRAY) { auto array = o.via.array; - Helpers::conv_fld_from_array(array, name, "operation", operation, 0); + Helpers::conv_fld_from_array(array, name, "read", read, 0); Helpers::conv_fld_from_array(array, name, "index", index, 1); Helpers::conv_fld_from_array(array, name, "value", value, 2); } else { @@ -4792,7 +4784,6 @@ struct PublicInputs { struct Circuit { std::string function_name; - uint32_t current_witness_index; std::vector opcodes; std::vector private_parameters; Acir::PublicInputs public_parameters; @@ -4803,9 +4794,8 @@ struct Circuit { void msgpack_pack(auto& packer) const { - packer.pack_array(7); + packer.pack_array(6); packer.pack(function_name); - packer.pack(current_witness_index); packer.pack(opcodes); packer.pack(private_parameters); packer.pack(public_parameters); @@ -4819,7 +4809,6 @@ struct Circuit { if (o.type == msgpack::type::MAP) { auto kvmap = Helpers::make_kvmap(o, name); Helpers::conv_fld_from_kvmap(kvmap, name, "function_name", function_name, false); - Helpers::conv_fld_from_kvmap(kvmap, name, "current_witness_index", current_witness_index, false); Helpers::conv_fld_from_kvmap(kvmap, name, "opcodes", opcodes, false); Helpers::conv_fld_from_kvmap(kvmap, name, "private_parameters", private_parameters, false); Helpers::conv_fld_from_kvmap(kvmap, name, "public_parameters", public_parameters, false); @@ -4828,12 +4817,11 @@ struct Circuit { } else if (o.type == msgpack::type::ARRAY) { auto array = o.via.array; Helpers::conv_fld_from_array(array, name, "function_name", function_name, 0); - Helpers::conv_fld_from_array(array, name, "current_witness_index", current_witness_index, 1); - Helpers::conv_fld_from_array(array, name, "opcodes", opcodes, 2); - Helpers::conv_fld_from_array(array, name, "private_parameters", private_parameters, 3); - Helpers::conv_fld_from_array(array, name, "public_parameters", public_parameters, 4); - Helpers::conv_fld_from_array(array, name, "return_values", return_values, 5); - Helpers::conv_fld_from_array(array, name, "assert_messages", assert_messages, 6); + Helpers::conv_fld_from_array(array, name, "opcodes", opcodes, 1); + Helpers::conv_fld_from_array(array, name, "private_parameters", private_parameters, 2); + Helpers::conv_fld_from_array(array, name, "public_parameters", public_parameters, 3); + Helpers::conv_fld_from_array(array, name, "return_values", return_values, 4); + Helpers::conv_fld_from_array(array, name, "assert_messages", assert_messages, 5); } else { throw_or_abort("expected MAP or ARRAY for " + name); } @@ -6535,18 +6523,12 @@ inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd& lhs, const BlackBoxOp if (!(lhs.input1_y == rhs.input1_y)) { return false; } - if (!(lhs.input1_infinite == rhs.input1_infinite)) { - return false; - } if (!(lhs.input2_x == rhs.input2_x)) { return false; } if (!(lhs.input2_y == rhs.input2_y)) { return false; } - if (!(lhs.input2_infinite == rhs.input2_infinite)) { - return false; - } if (!(lhs.result == rhs.result)) { return false; } @@ -6562,10 +6544,8 @@ void serde::Serializable::serialize(const Ac { serde::Serializable::serialize(obj.input1_x, serializer); serde::Serializable::serialize(obj.input1_y, serializer); - serde::Serializable::serialize(obj.input1_infinite, serializer); serde::Serializable::serialize(obj.input2_x, serializer); serde::Serializable::serialize(obj.input2_y, serializer); - serde::Serializable::serialize(obj.input2_infinite, serializer); serde::Serializable::serialize(obj.result, serializer); } @@ -6577,10 +6557,8 @@ Acir::BlackBoxOp::EmbeddedCurveAdd serde::Deserializable::deserialize(deserializer); obj.input1_y = serde::Deserializable::deserialize(deserializer); - obj.input1_infinite = serde::Deserializable::deserialize(deserializer); obj.input2_x = serde::Deserializable::deserialize(deserializer); obj.input2_y = serde::Deserializable::deserialize(deserializer); - obj.input2_infinite = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } @@ -7827,9 +7805,6 @@ inline bool operator==(const Circuit& lhs, const Circuit& rhs) if (!(lhs.function_name == rhs.function_name)) { return false; } - if (!(lhs.current_witness_index == rhs.current_witness_index)) { - return false; - } if (!(lhs.opcodes == rhs.opcodes)) { return false; } @@ -7856,7 +7831,6 @@ void serde::Serializable::serialize(const Acir::Circuit& obj, Ser { serializer.increase_container_depth(); serde::Serializable::serialize(obj.function_name, serializer); - serde::Serializable::serialize(obj.current_witness_index, serializer); serde::Serializable::serialize(obj.opcodes, serializer); serde::Serializable::serialize(obj.private_parameters, serializer); serde::Serializable::serialize(obj.public_parameters, serializer); @@ -7872,7 +7846,6 @@ Acir::Circuit serde::Deserializable::deserialize(Deserializer& de deserializer.increase_container_depth(); Acir::Circuit obj; obj.function_name = serde::Deserializable::deserialize(deserializer); - obj.current_witness_index = serde::Deserializable::deserialize(deserializer); obj.opcodes = serde::Deserializable::deserialize(deserializer); obj.private_parameters = serde::Deserializable::deserialize(deserializer); obj.public_parameters = serde::Deserializable::deserialize(deserializer); @@ -8481,7 +8454,7 @@ namespace Acir { inline bool operator==(const MemOp& lhs, const MemOp& rhs) { - if (!(lhs.operation == rhs.operation)) { + if (!(lhs.read == rhs.read)) { return false; } if (!(lhs.index == rhs.index)) { @@ -8500,7 +8473,7 @@ template void serde::Serializable::serialize(const Acir::MemOp& obj, Serializer& serializer) { serializer.increase_container_depth(); - serde::Serializable::serialize(obj.operation, serializer); + serde::Serializable::serialize(obj.read, serializer); serde::Serializable::serialize(obj.index, serializer); serde::Serializable::serialize(obj.value, serializer); serializer.decrease_container_depth(); @@ -8512,7 +8485,7 @@ Acir::MemOp serde::Deserializable::deserialize(Deserializer& deseri { deserializer.increase_container_depth(); Acir::MemOp obj; - obj.operation = serde::Deserializable::deserialize(deserializer); + obj.read = serde::Deserializable::deserialize(deserializer); obj.index = serde::Deserializable::deserialize(deserializer); obj.value = serde::Deserializable::deserialize(deserializer); deserializer.decrease_container_depth(); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/test_class.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/test_class.hpp index 46e28314aee8..8f3a1d1470e9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/test_class.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/test_class.hpp @@ -1,5 +1,6 @@ #pragma once +#include "barretenberg/common/assert.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp" #include "barretenberg/dsl/acir_format/serde/index.hpp" @@ -66,43 +67,16 @@ inline Acir::Expression witness_or_constant_to_expression(const WitnessOrConstan return expr; } -/** - * @brief Convert an AccessType to an Acir::Expression representing the operation type. - * - * @details Read operations are represented by Expression with constant 0, - * Write operations are represented by Expression with constant 1. - */ -inline Acir::Expression access_type_to_expression(AccessType access_type) -{ - bb::fr value = (access_type == AccessType::Write) ? bb::fr::one() : bb::fr::zero(); - return Acir::Expression{ - .mul_terms = {}, - .linear_combinations = {}, - .q_c = value.to_buffer(), - }; -} - -/** - * @brief Convert a witness index to an Acir::Expression representing a single unscaled witness term. - */ -inline Acir::Expression witness_to_expression(uint32_t witness_index) -{ - return Acir::Expression{ - .mul_terms = {}, - .linear_combinations = { std::make_tuple(bb::fr::one().to_buffer(), Acir::Witness{ .value = witness_index }) }, - .q_c = bb::fr::zero().to_buffer(), - }; -} - /** * @brief Convert an acir_format::MemOp to an Acir::MemOp. */ inline Acir::MemOp mem_op_to_acir_mem_op(const MemOp& mem_op) { return Acir::MemOp{ - .operation = access_type_to_expression(mem_op.access_type), - .index = witness_to_expression(mem_op.index), - .value = witness_to_expression(mem_op.value), + // Acir::MemOp::read is the serialized MemOpKind bool: false = Read, true = Write. + .read = (mem_op.access_type == AccessType::Write), + .index = Acir::Witness{ .value = mem_op.index }, + .value = Acir::Witness{ .value = mem_op.value }, }; } @@ -391,10 +365,9 @@ template std::vector constraint_to_acir_ for (const auto& sc : constraint.scalars) { scalars.push_back(witness_or_constant_to_function_input(sc)); } - auto outputs = std::make_shared>(); + auto outputs = std::make_shared>(); (*outputs)[0] = Acir::Witness{ .value = constraint.out_point_x }; (*outputs)[1] = Acir::Witness{ .value = constraint.out_point_y }; - (*outputs)[2] = Acir::Witness{ .value = constraint.out_point_is_infinite }; return { Acir::Opcode{ .value = Acir::Opcode::BlackBoxFuncCall{ .value = Acir::BlackBoxFuncCall{ .value = Acir::BlackBoxFuncCall::MultiScalarMul{ @@ -404,18 +377,15 @@ template std::vector constraint_to_acir_ .outputs = outputs, } } } } }; } else if constexpr (std::is_same_v) { - auto input1 = std::make_shared>(); + auto input1 = std::make_shared>(); (*input1)[0] = witness_or_constant_to_function_input(constraint.input1_x); (*input1)[1] = witness_or_constant_to_function_input(constraint.input1_y); - (*input1)[2] = witness_or_constant_to_function_input(constraint.input1_infinite); - auto input2 = std::make_shared>(); + auto input2 = std::make_shared>(); (*input2)[0] = witness_or_constant_to_function_input(constraint.input2_x); (*input2)[1] = witness_or_constant_to_function_input(constraint.input2_y); - (*input2)[2] = witness_or_constant_to_function_input(constraint.input2_infinite); - auto outputs = std::make_shared>(); + auto outputs = std::make_shared>(); (*outputs)[0] = Acir::Witness{ .value = constraint.result_x }; (*outputs)[1] = Acir::Witness{ .value = constraint.result_y }; - (*outputs)[2] = Acir::Witness{ .value = constraint.result_infinite }; return { Acir::Opcode{ .value = Acir::Opcode::BlackBoxFuncCall{ .value = Acir::BlackBoxFuncCall{ .value = Acir::BlackBoxFuncCall::EmbeddedCurveAdd{ diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/utils.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/utils.hpp index 505f4de368e9..904be8dbe27c 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/utils.hpp @@ -96,8 +96,6 @@ std::vector add_to_witness_and_track_indices(std::vector& witn witness.emplace_back(input.x); indices.emplace_back(witness.size()); witness.emplace_back(input.y); - indices.emplace_back(witness.size()); - witness.emplace_back(input.is_point_at_infinity() ? bb::fr(1) : bb::fr(0)); } else if constexpr (requires { input.data(); input.size(); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp index 3d94d525db72..8f4360f9e192 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp @@ -14,9 +14,8 @@ using namespace bb::stdlib; /** * @brief Convert inputs representing a Grumpkin point into a cycle_group element. - * @details Inputs x, y, and is_infinite are provided from the ACIR opcode. The cycle_group constructor - * auto-detects infinity from (0,0) coordinates; the is_infinite flag is constrained to agree with this - * auto-detected value, ensuring the external flag cannot be forged. + * @details Inputs x and y are provided from the ACIR opcode. The cycle_group constructor auto-detects + * infinity from (0,0) coordinates. * * We handle two special cases: * 1. write_vk scenario: we set the point to be the generator of Grumpkin to avoid circuit construction failures. @@ -26,70 +25,52 @@ using namespace bb::stdlib; * @tparam Builder * @param input_x x-coordinate of the point * @param input_y y-coordinate of the point - * @param input_infinite boolean from ACIR; constrained to agree with the infinity flag in cycle_group * @param predicate A relevant predicate used to conditionally assign the point to a valid value * @param builder * @return bb::stdlib::cycle_group - * - * TODO: remove input_infinite parameter once the ACIR format is updated to drop the is_infinite field for Grumpkin - * points. This requires a noir-side change. */ template bb::stdlib::cycle_group to_grumpkin_point(const WitnessOrConstant& input_x, const WitnessOrConstant& input_y, - const WitnessOrConstant& input_infinite, const bb::stdlib::bool_t& predicate, Builder& builder) { - using bool_ct = bb::stdlib::bool_t; using field_ct = bb::stdlib::field_t; bool constant_coordinates = input_x.is_constant && input_y.is_constant; auto point_x = to_field_ct(input_x, builder); auto point_y = to_field_ct(input_y, builder); - auto infinite = bool_ct(to_field_ct(input_infinite, builder)); // If a witness is not provided (we are in a write_vk scenario) we ensure the coordinates correspond to a valid // point to avoid erroneous failures during circuit construction. We set coordinates to the generator (a finite - // point) and the infinity flag to false for consistency. + // point). if (builder.is_write_vk_mode() && !constant_coordinates) { builder.set_variable(input_x.index, bb::grumpkin::g1::affine_one.x); builder.set_variable(input_y.index, bb::grumpkin::g1::affine_one.y); - if (!input_infinite.is_constant) { - builder.set_variable(input_infinite.index, bb::fr(0)); - } } // If the predicate is a non-constant witness, conditionally replace coordinates with a valid point. if (!predicate.is_constant()) { point_x = field_ct::conditional_assign(predicate, point_x, field_ct(bb::grumpkin::g1::affine_one.x)); point_y = field_ct::conditional_assign(predicate, point_y, field_ct(bb::grumpkin::g1::affine_one.y)); - infinite = bool_ct::conditional_assign(predicate, infinite, bool_ct(false)); } else { BB_ASSERT(predicate.get_value(), "Creating Grumpkin point with a constant predicate equal to false."); } // Use public constructor which auto-detects infinity from (0,0) coordinates. - cycle_group input_point(point_x, point_y, /*assert_on_curve=*/true); - - // The external infinity flag must agree with the auto-detected infinity from coordinates. - infinite.assert_equal(input_point.is_point_at_infinity()); - - return input_point; + return cycle_group(point_x, point_y, /*assert_on_curve=*/true); } template bb::stdlib::cycle_group to_grumpkin_point( const WitnessOrConstant& input_x, const WitnessOrConstant& input_y, - const WitnessOrConstant& input_infinite, const bb::stdlib::bool_t& predicate, UltraCircuitBuilder& builder); template bb::stdlib::cycle_group to_grumpkin_point( const WitnessOrConstant& input_x, const WitnessOrConstant& input_y, - const WitnessOrConstant& input_infinite, const bb::stdlib::bool_t& predicate, MegaCircuitBuilder& builder); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp index 32c033506634..eb9e78a48b6b 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp @@ -48,7 +48,6 @@ bb::stdlib::field_t to_field_ct(const WitnessOrConstant bb::stdlib::cycle_group to_grumpkin_point(const WitnessOrConstant& input_x, const WitnessOrConstant& input_y, - const WitnessOrConstant& input_infinite, const bb::stdlib::bool_t& predicate, Builder& builder); diff --git a/barretenberg/cpp/src/barretenberg/ecc/curves/invert_differential.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/invert_differential.fuzzer.cpp new file mode 100644 index 000000000000..6ef8c48599fb --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/curves/invert_differential.fuzzer.cpp @@ -0,0 +1,240 @@ +/** + * @file invert_differential.fuzzer.cpp + * @brief Differential fuzzer for Bernstein-Yang modular inverse vs Fermat (modexp). + * + * Reuses the FieldVM driver from `multi_field.fuzzer.cpp` to generate diverse + * field elements via sequences of arithmetic operations. After each VM phase + * it takes the last element produced (the highest-indexed non-zero slot in the + * VM's internal state, with a fallback to slot 0) and computes its inverse + * three different ways: + * + * - A: `pow(modulus_minus_two)` — Fermat's little theorem (modexp). + * - B: `invert_vartime` — safegcd, 5×64-bit limb kernel + * (selected on native targets, BATCH=62). + * - C: `invert_vartime` — safegcd, 9×29-bit limb kernel + * (selected on WASM targets, BATCH=58). + * + * All three are compared in canonical (non-Montgomery) form. Any discrepancy + * triggers an abort with full diagnostic output (field type, input, all three + * outputs, plus Montgomery checks `a * X ?= 1` for each). Cross-checking the + * WASM kernel here gives it libFuzzer coverage even though libFuzzer itself + * doesn't run under WASM — both kernels are plain C++ classes. + * + * Only 254-bit primes are tested (BN254 Fr/Fq, Grumpkin shares the BN254 + * curves), since the 5-limb signed BY state requires p < 2^255 and the + * production `field::invert()` dispatch also gates on this. 256-bit primes + * (secp256k1/r1) don't use BY and are skipped. + */ + +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/ecc/fields/bernstein_yang_inverse.hpp" +#include "barretenberg/ecc/fields/field.fuzzer.hpp" +#include +#include +#include +#include +#include +#include + +using namespace bb; +using numeric::uint256_t; + +// --------------------------------------------------------------- +// Phase header — same 2-byte layout as multi_field.fuzzer.cpp but restricted +// to the two 254-bit fields that actually use BY. +// --------------------------------------------------------------- +enum class FieldType : uint8_t { + BN254_FQ = 0, + BN254_FR = 1, +}; + +static constexpr size_t NUM_FIELD_TYPES = 2; +static constexpr size_t MAX_STEPS = 64; +static constexpr size_t PHASE_HEADER_SIZE = 2; + +struct VMPhaseHeader { + uint8_t field_type; + uint8_t steps; +}; +static_assert(sizeof(VMPhaseHeader) == 2, "VMPhaseHeader must be 2 bytes"); + +template static uint256_t reduce_to_modulus(const uint256_t& value) +{ + return (value < Field::modulus) ? value : (value % Field::modulus); +} + +template +static void import_state_with_reduction(FieldVM& vm, const std::vector& state) +{ + for (size_t i = 0; i < INTERNAL_STATE_SIZE && i < state.size(); i++) { + vm.uint_internal_state[i] = reduce_to_modulus(state[i]); + vm.field_internal_state[i] = Field(vm.uint_internal_state[i]); + } +} + +// --------------------------------------------------------------- +// Differential oracle. +// +// Fetches `a_raw` (the non-Montgomery integer) from the VM's uint state and +// computes a^{-1} two ways; aborts on mismatch. +// --------------------------------------------------------------- +template static Field raw_to_montgomery(const uint256_t& raw) +{ + Field f{ raw.data[0], raw.data[1], raw.data[2], raw.data[3] }; + f.self_to_montgomery_form(); + return f; +} + +static void print_limbs(const char* label, const uint256_t& v) +{ + std::fprintf(stderr, + " %s = 0x%016lx%016lx%016lx%016lx\n", + label, + (unsigned long)v.data[3], + (unsigned long)v.data[2], + (unsigned long)v.data[1], + (unsigned long)v.data[0]); +} + +template static void differential_check_inverse(const Field& a_mont, const uint256_t& a_raw) +{ + if (a_raw == 0) { + return; // 0 has no inverse — skip. + } + + // A: Fermat via pow. We bypass field::invert() (which now dispatches into + // BY) by calling pow(modulus_minus_two) directly, so the paths are + // genuinely independent implementations. + Field fermat_inv = a_mont.pow(Field::modulus_minus_two); + + // B, C: Bernstein-Yang safegcd, called with the raw (non-Montgomery) value + // on both the Native5x64 (BATCH=62) and Wasm9x29 (BATCH=58) kernels. + // Each kernel needs its own p_inv_mod_2^BATCH constant. + constexpr uint256_t p_uint = Field::modulus; + constexpr uint64_t p_inv_native = + bernstein_yang::Native5x64::p_inv_mod_2k_from_montgomery_r_inv(Field::Params::r_inv); + constexpr uint64_t p_inv_wasm = bernstein_yang::Wasm9x29::p_inv_mod_2k_from_montgomery_r_inv(Field::Params::r_inv); + + uint256_t native_inv_raw = bernstein_yang::invert_vartime(a_raw, p_uint, p_inv_native); + uint256_t wasm_inv_raw = bernstein_yang::invert_vartime(a_raw, p_uint, p_inv_wasm); + + Field native_inv = raw_to_montgomery(native_inv_raw); + Field wasm_inv = raw_to_montgomery(wasm_inv_raw); + + const bool native_ok = (fermat_inv == native_inv); + const bool wasm_ok = (fermat_inv == wasm_inv); + if (native_ok && wasm_ok) { + return; + } + + std::fprintf(stderr, "\n[invert_differential.fuzzer] MISMATCH\n"); + std::fprintf(stderr, " field: %s\n", typeid(Field).name()); + std::fprintf(stderr, " native_ok: %s\n", native_ok ? "yes" : "NO"); + std::fprintf(stderr, " wasm_ok: %s\n", wasm_ok ? "yes" : "NO"); + print_limbs("a_raw ", a_raw); + print_limbs("fermat ", static_cast(fermat_inv)); + print_limbs("BY native ", static_cast(native_inv)); + print_limbs("BY wasm ", static_cast(wasm_inv)); + print_limbs("a*fermat ", static_cast(a_mont * fermat_inv)); + print_limbs("a*native ", static_cast(a_mont * native_inv)); + print_limbs("a*wasm ", static_cast(a_mont * wasm_inv)); + std::fflush(stderr); + std::abort(); +} + +// Pick the last element produced: highest-indexed non-zero slot of the VM's +// uint state, with a fallback to slot 0 if all slots are zero. +static size_t last_element_index(const std::vector& state) +{ + for (size_t i = state.size(); i > 0; --i) { + if (state[i - 1] != uint256_t(0)) { + return i - 1; + } + } + return 0; +} + +template +static int run_phase_and_diff(const VMPhaseHeader& header, + const unsigned char* data, + size_t size, + size_t& data_offset, + std::vector& current_state) +{ + FieldVM vm(false, header.steps); + if (!current_state.empty()) { + import_state_with_reduction(vm, current_state); + } + vm.set_max_steps(header.steps); + size_t bytes_consumed = vm.run(data + data_offset, size - data_offset, true); + if (bytes_consumed == 0) { + return 0; + } + + if (!vm.check_internal_state()) { + // Internal VM invariant violation — not the inverse bug we're looking + // for, but still a failure of the driver. Report and stop. + std::fprintf(stderr, "[invert_differential.fuzzer] VM internal state check failed\n"); + return -1; + } + + // Differential inverse check on the last element produced this phase, + // plus every non-zero slot in the final state for extra coverage. + auto uint_state = vm.export_uint_state(); + size_t last_idx = last_element_index(uint_state); + differential_check_inverse(vm.field_internal_state[last_idx], uint_state[last_idx]); + + // Extra coverage: also diff every other non-zero slot. Same check on + // many more values per phase, virtually free CPU-wise. + for (size_t i = 0; i < uint_state.size(); ++i) { + if (i != last_idx && uint_state[i] != uint256_t(0)) { + differential_check_inverse(vm.field_internal_state[i], uint_state[i]); + } + } + + current_state = uint_state; + data_offset += bytes_consumed; + return 1; +} + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) +{ + if (size < PHASE_HEADER_SIZE) { + return 0; + } + + std::vector current_state; + size_t data_offset = 0; + + while (data_offset + PHASE_HEADER_SIZE <= size) { + const VMPhaseHeader* header_ptr = reinterpret_cast(data + data_offset); + VMPhaseHeader header = *header_ptr; + + FieldType selected_field_type = static_cast(header.field_type % NUM_FIELD_TYPES); + uint8_t selected_steps = header.steps % MAX_STEPS; + if (selected_steps == 0) { + selected_steps = 1; + } + header.field_type = static_cast(selected_field_type); + header.steps = selected_steps; + + int r = 0; + switch (selected_field_type) { + case FieldType::BN254_FQ: + r = run_phase_and_diff(header, data, size, data_offset, current_state); + break; + case FieldType::BN254_FR: + r = run_phase_and_diff(header, data, size, data_offset, current_state); + break; + } + + if (r < 0) { + return 1; + } + if (r == 0) { + break; + } + } + return 0; +} diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.hpp new file mode 100644 index 000000000000..4e4190d1bdf9 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.hpp @@ -0,0 +1,369 @@ +// Bernstein-Yang safegcd modular inverse. +// +// We want a⁻¹ mod p, where p is an odd prime. Run an extended binary GCD on +// the pair (f, g) starting at (p, a), with Bezout coefficients (d, e) +// satisfying invariants d·a ≡ f (mod p) and e·a ≡ g (mod p) at all times. +// When g reaches 0, gcd(p, a) = ±f = ±1 (since p is prime, a ≠ 0), so +// a⁻¹ = ±d. +// +// The cheap operation in a binary GCD is "if g is odd swap-and-subtract to +// make it even, then divide g by 2"; one such step is a "divstep" and +// shrinks |g| by ~1 bit. Doing each divstep on the full 256-bit state would +// be slow, so we use Pornin's trick: do BATCH divsteps purely on the low 64 +// bits of (f, g), accumulating the resulting linear transform as a 2×2 +// integer matrix M, then apply M to the full-precision (f, g, d, e) in one +// go (with an exact /2^BATCH at the end). The (d, e) side needs a 2-adic +// correction k·p added before dividing so the result stays integer-valued +// — k is determined by the low BATCH bits of M·(d, e) and p⁻¹ mod 2^BATCH. +// +// Native5x64 and Wasm9x29 wrap the platform-specific limb representation +// behind the same static interface so `invert_vartime` below is a +// single algorithm for both targets. + +#pragma once + +#include "barretenberg/numeric/uint256/uint256.hpp" +#include + +namespace bb::bernstein_yang { + +using numeric::uint256_t; +using u64 = uint64_t; +using i64 = int64_t; + +// The transition matrix produced by BATCH divsteps. With the implicit +// "/ 2^BATCH" at the end of apply_divstep_matrix, it represents the linear +// map (f, g) ↦ (M·(f, g) / 2^BATCH). Each divstep doubles one matrix entry, +// so after BATCH steps |u|, |v|, |q|, |r| ≤ 2^BATCH; they are signed (the +// swap-and-subtract case introduces negatives). +struct DivstepMatrix { + i64 u, v, q, r; +}; + +// 5 × 64-bit limbs, top limb two's-complement signed. Products via __int128. +class Native5x64 { + public: + // Number of divsteps folded into one matrix application. Bigger BATCH + // means fewer matrix applications per inversion but bigger matrix + // entries. Cap is set by the matrix-times-state product staying inside + // an __int128 accumulator: a single (i63 entry) × (u64 limb) is 127 bits, + // so BATCH ≤ 63; we use 62 to keep one bit of slack for the running sum. + static constexpr int BATCH = 62; + + // Worst-case number of matrix applications needed before g must have + // reached 0. The 735-divstep bound for 254-bit inputs is from the BY + // paper's convergence proof (rate ≈ 1 / 1.7 bits of g consumed per + // divstep). We pick the smallest NUM_ITERATIONS so NUM_ITERATIONS * + // BATCH ≥ 735; ⌈735 / 62⌉ = 12. The actual loop usually exits much + // earlier via the early break on g == 0. + static constexpr int NUM_ITERATIONS = 12; + + // The Bezout coefficients (d, e) live mod p but during the iteration we + // hold them as signed integers in the state. Each matrix application grows + // |d|, |e| by roughly a factor of 2 (matrix entry × value) plus an + // additive p (from the 2-adic correction k·p), so without bringing them + // back to [0, p) they would eventually overflow the state. + // reduce_to_canonical does that subtract-or-add-p reduction. Calling it + // every iter is wasteful — the 5×64-bit signed state has enough room to + // let |d|, |e| reach ~2^K · p before they no longer fit, so we only + // reduce every REDUCE_INTERVAL = 4 iters (|d|, |e| stay ≤ ~32p between + // reductions, plenty of headroom). + static constexpr int REDUCE_INTERVAL = 4; + + // Worst-case iteration cap inside reduce_to_canonical. After + // REDUCE_INTERVAL iters between reductions, |d|, |e| ≤ (2^(REDUCE_INTERVAL+1) - 1)·p, + // so reducing requires that many subtractions plus one break iter. + static constexpr int REDUCE_TO_CANONICAL_MAX_ITERS = 36; + static_assert((1U << (REDUCE_INTERVAL + 1)) <= REDUCE_TO_CANONICAL_MAX_ITERS, + "REDUCE_INTERVAL too large for reduce_to_canonical iteration bound"); + + Native5x64() noexcept + : l{} + {} + explicit Native5x64(const uint256_t& x) noexcept + : l{ x.data[0], x.data[1], x.data[2], x.data[3], 0 } + {} + static Native5x64 one() noexcept + { + Native5x64 r; + r.l[0] = 1; + return r; + } + + uint256_t to_uint256() const noexcept { return { l[0], l[1], l[2], l[3] }; } + u64 low_64() const noexcept { return l[0]; } + bool is_zero() const noexcept { return (l[0] | l[1] | l[2] | l[3] | l[4]) == 0; } + bool is_negative() const noexcept { return (i64)l[4] < 0; } + void neg() noexcept + { + u64 c = 1; + for (int i = 0; i < N; ++i) { + u64 v = (~l[i]) + c; + c = (c && v == 0) ? 1 : 0; + l[i] = v; + } + } + // Iter cap chosen by the REDUCE_TO_CANONICAL_MAX_ITERS / REDUCE_INTERVAL + // static_assert above; see those constants for the magnitude argument. + void reduce_to_canonical(const Native5x64& p) noexcept + { + for (int it = 0; it < REDUCE_TO_CANONICAL_MAX_ITERS; ++it) { + if (is_negative()) { + add_inplace(p); + } else if (ge(p)) { + sub_inplace(p); + } else { + break; + } + } + } + + // BATCH branchy divsteps on the low 64 bits of (f, g); returns the + // transition matrix M and updates δ. Variable-time over the inner + // branches — non-secret inputs only. + static DivstepMatrix compute_divstep_matrix(i64& delta, u64 f_lo, u64 g_lo) noexcept; + // (f, g) ← M·(f, g) / 2^BATCH and (d, e) ← (M·(d, e) + k·p) / 2^BATCH, + // where k_i = -((M·(d, e))_i · p⁻¹) mod 2^BATCH (the 2-adic correction + // that makes (M·(d, e))_i + k_i·p divisible by 2^BATCH). + static void apply_divstep_matrix(const DivstepMatrix& m, + Native5x64& f, + Native5x64& g, + Native5x64& d, + Native5x64& e, + const Native5x64& p, + u64 p_inv_mod_2k) noexcept; + // r_inv = -p⁻¹ mod 2^64 (barretenberg's Montgomery constant), so p⁻¹ mod + // 2^BATCH is the low BATCH bits of -r_inv. + static constexpr u64 p_inv_mod_2k_from_montgomery_r_inv(u64 r_inv) noexcept + { + // r_inv = -p^{-1} mod 2^64, so 0 - r_inv = p^{-1} mod 2^64. + return (0ULL - r_inv) & ((1ULL << BATCH) - 1); + } + + private: + static constexpr int N = 5; + u64 l[N]; + + void add_inplace(const Native5x64& b) noexcept + { + u64 c = 0; + for (int i = 0; i < N; ++i) { + __uint128_t s = (__uint128_t)l[i] + b.l[i] + c; + l[i] = (u64)s; + c = (u64)(s >> 64); + } + } + void sub_inplace(const Native5x64& b) noexcept + { + u64 borrow = 0; + for (int i = 0; i < N; ++i) { + __uint128_t s = (__uint128_t)l[i] - (__uint128_t)b.l[i] - borrow; + l[i] = (u64)s; + borrow = ((i64)(s >> 64) < 0) ? 1 : 0; + } + } + bool ge(const Native5x64& b) const noexcept + { + i64 a_top = (i64)l[N - 1], b_top = (i64)b.l[N - 1]; + if (a_top != b_top) { + return a_top > b_top; + } + for (int i = N - 2; i >= 0; --i) { + if (l[i] != b.l[i]) { + return l[i] > b.l[i]; + } + } + return true; + } + + friend struct NativeMatrix; +}; + +// 6-limb signed product helpers used by Native5x64::apply_divstep_matrix. +struct NativeMatrix { + static void signed_linear_combination(i64 a, const Native5x64& x, i64 b, const Native5x64& y, u64 out[6]) noexcept + { + __int128 c = 0; + for (int i = 0; i < 4; ++i) { + c += (__int128)a * (__int128)(u64)x.l[i] + (__int128)b * (__int128)(u64)y.l[i]; + out[i] = (u64)c; + c >>= 64; + } + c += (__int128)a * (__int128)(i64)x.l[4] + (__int128)b * (__int128)(i64)y.l[4]; + out[4] = (u64)c; + out[5] = (u64)(c >> 64); + } + // Sign-preserving exact /2^BATCH on the 6-limb signed `t`. Sign of the + // result lives in bit 63 of r.l[4], which is bit 61 of t[5]. This is the + // sign of t iff t[5] is just sign-extension of the actual magnitude — i.e., + // iff |t| < 2^319. BY guarantees this: |M·(x,y) + k·p| ≤ 2^324 in the + // (d,e) row and ≤ 2^319 in the (f,g) row, both with |result/2^62| < 2^263 < 2^319. + // A future change widening the matrix entries or state without re-running + // this analysis will silently corrupt the sign bit. + static Native5x64 arithmetic_shift_by_batch(const u64 t[6]) noexcept + { + Native5x64 r; + for (int i = 0; i < 4; ++i) { + r.l[i] = (t[i] >> 62) | (t[i + 1] << 2); + } + r.l[4] = (t[4] >> 62) | (t[5] << 2); + return r; + } +}; + +// Each inner step shrinks |g| by ~1 bit using a binary-GCD-style move. +// Three cases, depending on g's parity and the "δ" tracker (which decides +// whether |f| or |g| is currently smaller): +// g even : g ← g/2. +// g odd, δ ≤ 0 : g ← (g + f)/2 (adding f to make g+f even before /2). +// g odd, δ > 0 : swap roles — (f, g) ← (g, (g - f)/2). +// The matrix (u, v, q, r) tracks the same linear transform applied +// symbolically; doubling u, v (or q, r) corresponds to the implicit /2 each +// inner step performs. After BATCH steps the low BATCH bits of the +// transformed state are guaranteed zero, so apply_divstep_matrix's implicit +// "/ 2^BATCH" is an exact integer division. +inline DivstepMatrix Native5x64::compute_divstep_matrix(i64& delta, u64 f_lo, u64 g_lo) noexcept +{ + i64 u = 1, v = 0, q = 0, r = 1; + for (int i = 0; i < BATCH; ++i) { + if (g_lo & 1) { + if (delta > 0) { + u64 nf = g_lo, ng = (g_lo - f_lo) >> 1; + i64 nu = q << 1, nv = r << 1, nq = q - u, nr = r - v; + f_lo = nf; + g_lo = ng; + u = nu; + v = nv; + q = nq; + r = nr; + delta = 1 - delta; + } else { + g_lo = (g_lo + f_lo) >> 1; + q = q + u; + r = r + v; + u <<= 1; + v <<= 1; + delta = delta + 1; + } + } else { + g_lo >>= 1; + u <<= 1; + v <<= 1; + delta = delta + 1; + } + } + return { u, v, q, r }; +} + +inline void Native5x64::apply_divstep_matrix(const DivstepMatrix& m, + Native5x64& f, + Native5x64& g, + Native5x64& d, + Native5x64& e, + const Native5x64& p, + u64 p_inv_mod_2k) noexcept +{ + constexpr u64 MASK_BATCH = (1ULL << BATCH) - 1; + + u64 nf[6], ng[6]; + NativeMatrix::signed_linear_combination(m.u, f, m.v, g, nf); + NativeMatrix::signed_linear_combination(m.q, f, m.r, g, ng); + f = NativeMatrix::arithmetic_shift_by_batch(nf); + g = NativeMatrix::arithmetic_shift_by_batch(ng); + + // k = -t · p_inv_mod_2k mod 2^BATCH makes t + k·p divisible by 2^BATCH. + auto apply_corrected_row = [&](i64 a, const Native5x64& da, i64 b, const Native5x64& eb, Native5x64& out) { + u64 t[6]; + NativeMatrix::signed_linear_combination(a, da, b, eb, t); + u64 k = ((0ULL - t[0]) * p_inv_mod_2k) & MASK_BATCH; + u64 kp[6] = {}; + u64 carry = 0; + for (int i = 0; i < 5; ++i) { + __uint128_t prod = (__uint128_t)k * (u64)p.l[i] + carry; + kp[i] = (u64)prod; + carry = (u64)(prod >> 64); + } + kp[5] = carry; + u64 c = 0; + for (int i = 0; i < 6; ++i) { + __uint128_t s = (__uint128_t)t[i] + kp[i] + c; + t[i] = (u64)s; + c = (u64)(s >> 64); + } + out = NativeMatrix::arithmetic_shift_by_batch(t); + }; + Native5x64 nd, ne; + apply_corrected_row(m.u, d, m.v, e, nd); + apply_corrected_row(m.q, d, m.r, e, ne); + d = nd; + e = ne; +} + +} // namespace bb::bernstein_yang + +#include "./bernstein_yang_inverse_wasm.hpp" + +namespace bb::bernstein_yang { + +#if defined(__wasm__) +using State = Wasm9x29; +#else +using State = Native5x64; +#endif + +/** + * @brief Variable-time safegcd inverse (Bernstein-Yang TCHES 2019, Pornin 2020 §4). + * + * Iterates (f, g) starting at (p, a); each outer iter batches BATCH divsteps + * into a 2×2 matrix M and applies M to (f, g) / (d, e). When g reaches 0, + * gcd(p, a) = ±f and a⁻¹ = ±d mod p. Returns 0 for a == 0. + * + * @param p_inv_mod_2k p⁻¹ mod 2^BATCH (used by apply_divstep_matrix's 2-adic correction). + * @pre p odd prime, p < 2^255, 0 ≤ a < p. + */ +template +inline uint256_t invert_vartime(const uint256_t& a, const uint256_t& p, u64 p_inv_mod_2k) noexcept +{ + if (a == uint256_t(0)) { + return uint256_t(0); + } + S P(p), f = P, g(a), d, e = S::one(); + // δ is Pornin's auxiliary used by the divstep rule to decide swap-vs-add cases. + i64 delta = 1; + for (int i = 0; i < S::NUM_ITERATIONS; ++i) { + DivstepMatrix m = S::compute_divstep_matrix(delta, f.low_64(), g.low_64()); + S::apply_divstep_matrix(m, f, g, d, e, P, p_inv_mod_2k); + if (g.is_zero()) { + break; + } + if ((i + 1) % S::REDUCE_INTERVAL == 0) { + d.reduce_to_canonical(P); + e.reduce_to_canonical(P); + } + } + d.reduce_to_canonical(P); + if (f.is_negative()) { + d.neg(); + d.reduce_to_canonical(P); + } + return d.to_uint256(); +} + +inline constexpr u64 p_inv_mod_2k_from_montgomery_r_inv(u64 r_inv) noexcept +{ + return State::p_inv_mod_2k_from_montgomery_r_inv(r_inv); +} + +// True iff `invert_vartime` is usable for field params T: the active +// kernel must be compilable on this toolchain (Native5x64 needs __int128, the +// WASM kernel is unconditional) and T's modulus must fit BY's < 2^255 +// precondition. Used to gate the dispatch in `field::invert()`. +template +inline constexpr bool supported_v = +#if defined(__SIZEOF_INT128__) || defined(__wasm__) + T::modulus_3 < (1ULL << 63); +#else + false; +#endif + +} // namespace bb::bernstein_yang diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.md b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.md new file mode 100644 index 000000000000..c03ca5c5bd0e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.md @@ -0,0 +1,392 @@ +# Bernstein–Yang modular inverse: the algorithm + +A description of the modular inverse algorithm implemented in `bernstein_yang_inverse.hpp`. + +Throughout, $p$ is an **odd prime**, $0 < a < p$, and we want +$$a^{-1} \bmod p.$$ + +All quantities are integers; reductions modulo $p$ are made explicit when used. + +--- + +## 1. Setup + +We track a $2 \times 2$ integer matrix + +$$ +\Phi \;=\; \begin{pmatrix} f & d \\ g & e \end{pmatrix} +$$ + +initialised at + +$$ +\Phi_0 \;=\; \begin{pmatrix} p & 0 \\ a & 1 \end{pmatrix}, \qquad \det \Phi_0 \;=\; p. +$$ + +### The kernel invariant + +The whole algorithm preserves a single congruence: + +$$ +\boxed{\quad \Phi \begin{pmatrix} 1 \\ -a \end{pmatrix} \;\equiv\; \begin{pmatrix} 0 \\ 0 \end{pmatrix} \pmod p. \quad} +$$ + +Equivalently, the column vector $(1, -a)^T \in \mathbb{F}_p^2$ is in the kernel +of $\Phi \bmod p$. Unpacking entry by entry, this is just two Bezout congruences: + +$$ +f \;\equiv\; d \cdot a \pmod p, \qquad g \;\equiv\; e \cdot a \pmod p. +$$ + +The initial state satisfies them ($p \equiv 0 \cdot a$, $a \equiv 1 \cdot a$). + +### The reduction goal + +We reduce $\Phi$ to upper triangular form: + +$$ +\Phi_N \;=\; \begin{pmatrix} \pm 1 & a^{-1} \bmod p \\ 0 & \star \end{pmatrix}. +$$ + +When $g = 0$, the kernel invariant gives $e a \equiv 0 \pmod p$, +hence (since $\gcd(a, p) = 1$) $p \mid e$, putting the bottom-right at a +multiple of $p$. Independently, $f$ at termination equals $\pm \gcd(p, a) = \pm 1$, +and the invariant collapses to $d a \equiv \pm 1 \pmod p$, giving +$a^{-1} \equiv \pm d \pmod p$. The sign is read off the top-left entry. + +So **the BY algorithm is a reduction of $\Phi_0$ to upper triangular form, with +the inverse appearing as the top-right entry.** + +--- + +## 2. The generators $L_a, L_b, L_c$ + +The algorithm proceeds by repeated left multiplication: $\Phi \to L_n \Phi$, +choosing $L_n$ from a fixed set of three matrices: + +$$ +L_a \;=\; \begin{pmatrix} 1 & 0 \\ 0 & \tfrac{1}{2} \end{pmatrix}, \qquad +L_b \;=\; \begin{pmatrix} 1 & 0 \\ \tfrac{1}{2} & \tfrac{1}{2} \end{pmatrix}, \qquad +L_c \;=\; \begin{pmatrix} 0 & 1 \\ -\tfrac{1}{2} & \tfrac{1}{2} \end{pmatrix}. +$$ + +Each has $\det L_n = \tfrac{1}{2}$, so $L_n \in \mathrm{GL}_2(\mathbb{Z}[\tfrac{1}{2}])$ +but not in $\mathrm{SL}_2$. They act on the rows of $\Phi$: equivalently, on +$(f, g)$ and on $(d, e)$ in lockstep. + +### Divstep + +A small auxiliary integer $\delta$ is carried alongside $\Phi$, initialised at +$\delta_0 = 1$. At every step, the parity of $g$ together with the sign of +$\delta$ dictates which generator to apply: + +| Condition | Generator | $\delta$ update | +| --- | --- | --- | +| $g$ even | $L_a$ | $\delta \leftarrow \delta + 1$ | +| $g$ odd, $\delta \le 0$ | $L_b$ | $\delta \leftarrow \delta + 1$ | +| $g$ odd, $\delta > 0$ | $L_c$ | $\delta \leftarrow 1 - \delta$ | + +The convention $f$ odd is maintained throughout: $p$ is odd, the $L_n$ preserve +$f \bmod 2$, so $f$ stays odd until termination. + +One application of this rule is one **divstep**. Each divstep multiplies $\det \Phi$ +by $\tfrac{1}{2}$ (so after $N$ divsteps $\det \Phi_N = p / 2^N$) and shrinks +the magnitude of the lower-left entry $g$ on average. + +### Why the case split makes sense + +Unpacking $L_a, L_b, L_c$ as row operations on $(f, g)$: + +- $L_a$: $g \leftarrow g/2$. Valid only when $g$ is even, otherwise the result is non-integer. +- $L_b$: $g \leftarrow (g + f)/2$. Used when $g$ is odd but $|g| \le |f|$ in spirit (tracked by $\delta \le 0$): adding $f$ first makes the sum even. +- $L_c$: $(f, g) \leftarrow (g, (g - f)/2)$. Swap-and-subtract; used when $g$ is odd and $|g| > |f|$ in spirit ($\delta > 0$). + +The "in spirit" caveats are because BY tracks $|f|$ vs. $|g|$ comparisons via the +integer $\delta$ rather than by an actual size comparison — $\delta$ effectively +measures the running deficit "extra divisions of $g$ over extra divisions of $f$." + +### Right-column $p$-shift + +Left multiplication by $L_n$ alone would leave $\Phi$ with non-integer entries +in the right column (because $L_n$ has $\tfrac{1}{2}$ entries acting on +$(d, e)$). To keep the state integer-valued we add a multiple of $p$ to the +right column before halving — a *2-adic correction* that vanishes modulo $p$ +and hence doesn't disturb the kernel invariant. The mechanics live in §6. + +So one full divstep is: +$$ +\Phi \;\longmapsto\; L_n \,\Phi \;+\; p \cdot \big(\text{adjustment in right column}\big), \qquad L_n \in \{L_a, L_b, L_c\}. +$$ + +The left column ($f, g$) updates via clean left multiplication; the right +column ($d, e$) updates via left multiplication plus a $p$-shift. + +--- + +## 3. Convergence + +The Bernstein--Yang/Pornin convergence proof guarantees $g = 0$ within 735 divsteps for 254-bit inputs; native runs $12 \cdot 62 = 744$ divsteps and wasm runs $13 \cdot 58 = 754$, so both cover the bound. + +--- + +## 4. Batching: products of $L_n$ as a $2 \times 2$ matrix + +A single divstep touches only the lowest bit of $g$ (to read parity) and is a +linear combination of $(f, g)$. So the next $\mathrm{BATCH}$ divsteps depend +only on the low $\mathrm{BATCH}$ bits of $(f, g)$ — the high bits do not +influence the choice between $L_a, L_b, L_c$ within those steps. + +Let $\mathrm{BATCH} = 62$ (the implementation choice on native; $58$ on wasm). +Run $\mathrm{BATCH}$ divsteps purely on the low $64$ bits of $(f, g)$, +accumulating the result as a single $2 \times 2$ rational matrix + +$$ +M \;=\; L_{n_{\mathrm{BATCH}-1}} \cdots L_{n_1} L_{n_0} \;=\; \begin{pmatrix} u & v \\ q & r \end{pmatrix} \cdot 2^{-\mathrm{BATCH}}. +$$ + +After clearing the implicit denominator, the *integer* part $\begin{pmatrix} u & v \\ q & r \end{pmatrix} = 2^{\mathrm{BATCH}} M$ has all four entries bounded by $|u|, |v|, |q|, |r| \le 2^{\mathrm{BATCH}}$ (each individual $L_n$ at most doubles one entry of the running product). With $\mathrm{BATCH} = 62$, the four entries fit in `int64_t`. + +--- + +## 5. Applying $M$ to the left column $(f, g)$ + +The new $(f', g')^T = M \cdot (f, g)^T$ is computed as + +1. The two integer linear combinations + $$t_f = u \cdot f + v \cdot g, \qquad t_g = q \cdot f + r \cdot g$$ + in full precision. With $|u|, \ldots, |r| \le 2^{62}$ and $|f|, |g|$ + fitting in $256$ bits (see §7), each product fits in $318$ bits and the + sum in $319$ bits. +2. Arithmetic-right-shift by $\mathrm{BATCH}$ bits: + $$f' \;=\; t_f \gg \mathrm{BATCH}, \qquad g' \;=\; t_g \gg \mathrm{BATCH}.$$ + +The shift is exact: the low $\mathrm{BATCH}$ bits of $t_f$ and $t_g$ are zero +by construction. Each divstep makes one bit of $g$ cancel, and after +$\mathrm{BATCH}$ divsteps the bottom $\mathrm{BATCH}$ bits of the linear +combinations are guaranteed zero — this is the "exact integer division" +property of the divstep cascade. + +In the implementation this lives in `NativeMatrix::signed_linear_combination` (the +products) and `NativeMatrix::arithmetic_shift_by_batch` (the right shift). + +--- + +## 6. Applying $M$ to the right column $(d, e)$: the 2-adic correction + +Applying $M$ to $(d, e)$ presents the same divisibility question, but now the +state lives modulo $p$. The integer linear combination $t = u \cdot d + v \cdot e$ +is **not** generally divisible by $2^{\mathrm{BATCH}}$. We need an integer +correction $k$ such that $t + k \cdot p$ is divisible by $2^{\mathrm{BATCH}}$, +then take the quotient. + +This is a 2-adic problem: + +$$ +t + k\cdot p \;\equiv\; 0 \pmod{2^{\mathrm{BATCH}}} +\;\Longleftrightarrow\; +k \;\equiv\; -\, t \cdot p^{-1} \pmod{2^{\mathrm{BATCH}}}. +$$ + +$p$ is odd, so $p^{-1} \bmod 2^{\mathrm{BATCH}}$ exists. The implementation +precomputes it once: $p^{-1} \bmod 2^{\mathrm{BATCH}}$ is the low +$\mathrm{BATCH}$ bits of $-r_{\mathrm{inv}}$, where $r_{\mathrm{inv}}$ is +barretenberg's Montgomery constant $-p^{-1} \bmod 2^{64}$. + +The correction step: + +$$ +\begin{aligned} +t &\;=\; u \cdot d + v \cdot e, \\ +k &\;\equiv\; -\, t \cdot p^{-1} \pmod{2^{\mathrm{BATCH}}}, \\ +d' &\;=\; (t + k \cdot p) \gg \mathrm{BATCH}. +\end{aligned} +$$ + +After the shift, $d'$ is an integer (because $t + k \cdot p$ is divisible by +$2^{\mathrm{BATCH}}$). The added $k \cdot p$ contributes only a multiple of $p$ +to the right column, so the kernel invariant $\Phi \binom{1}{-a} \equiv 0 \pmod p$ +is preserved. + +The same construction applied with $(q, r)$ and the second row of $M$ gives +the new $e'$. This is `apply_corrected_row` in the implementation. + +--- + +## 7. State bounds: why 5 limbs + +`Native5x64` stores each state value in five signed 64-bit limbs. Four limbs +would be enough for canonical field elements, but the BY state is not always +canonical while a batched matrix is being applied. + +For the left column, $f$ and $g$ are roughly 256-bit values between matrix +applications. During §5, however, the products $u f$, $v g$, $q f$, and $r g$ +can be as large as $2^{62} \cdot 2^{256}$, and their sums need about 319 bits. +Those sums are held in the temporary six-limb arrays inside +`NativeMatrix::signed_linear_combination`; after the exact right shift by +`BATCH`, $f$ and $g$ return to the normal state size. + +For the right column, $d$ and $e$ need extra resting headroom too. The 2-adic +correction adds $k \cdot p$ before the shift, and repeated matrix applications +can move 00,p)1 The implementation therefore reduces them +to canonical form every `REDUCE_INTERVAL = 4` iterations rather than after every +matrix application. + +Between reductions, $|d|$ and $|e|$ are bounded by roughly $32p$. Five signed +64-bit limbs provide about 319 bits of magnitude, enough room for that growth. +`Native5x64::reduce_to_canonical(p)` then repeatedly adds or subtracts $p$, +with a loop bound of 36 to cover the same worst-case headroom. + +--- + +## 8. Final answer extraction + +After the iteration loop: + +- $g = 0$. +- $f = \pm \gcd(p, a) = \pm 1$. +- Kernel invariant: $d \cdot a \equiv f \pmod{p}$, so $d \equiv \pm a^{-1} \pmod p$. + +Reduce $d$ to canonical form $[0, p)$. Then + +$$ +a^{-1} \bmod p \;=\; +\begin{cases} +d & \text{if } f > 0, \\ +{-d} \bmod p & \text{if } f < 0. +\end{cases} +$$ + +In code, this is the +`if (f.is_negative()) { d.neg(); d.reduce_to_canonical(P); }` at the end of +`invert_vartime`. + +--- + +## 9. Math-to-code map + +The implementation keeps the same mathematical state but hides the limb details +behind `Native5x64` and `Wasm9x29`. + +| Math description | Code | +| --- | --- | +| $\Phi = \begin{pmatrix} f & d \\ g & e \end{pmatrix}$ | `S P(p), f = P, g(a), d, e = S::one()` in `invert_vartime` | +| Auxiliary divstep counter $\delta$ | local `i64 delta` | +| Product of one batch of divsteps | `S::compute_divstep_matrix(delta, f.low_64(), g.low_64())` | +| $M = \begin{pmatrix} u & v \\ q & r \end{pmatrix} 2^{-B}$ | `DivstepMatrix { u, v, q, r }`; the denominator is the implicit `2^BATCH` | +| $M(f,g)/2^B$ | `apply_divstep_matrix`, using `NativeMatrix::signed_linear_combination` and `arithmetic_shift_by_batch` on native | +| $k \equiv -t p^{-1} \pmod {2^B}$ | `apply_corrected_row` on native; streamed as `k_d`, `k_e` on wasm | +| $p^{-1} \bmod 2^B$ from Montgomery metadata | `p_inv_mod_2k_from_montgomery_r_inv` | +| Periodic reduction of $d,e$ modulo $p$ | `reduce_to_canonical(P)` every `REDUCE_INTERVAL` iterations | +| Final sign correction $a^{-1} = \pm d$ | final `if (f.is_negative()) { d.neg(); ... }` | +| Platform-specific limb representation | `using State = Native5x64` or `Wasm9x29` | + +--- + +## 10. Example + +This example uses the same batched mechanics as the implementation, but with a toy $B = 3$ instead of native $B = 62$. + +Let + +$$ +p = 17, \qquad a = 3, \qquad +\Phi_0 = \begin{pmatrix} f & d \\ g & e \end{pmatrix} + = \begin{pmatrix} 17 & 0 \\ 3 & 1 \end{pmatrix}, \qquad +\delta_0 = 1. +$$ + +Since $17 \equiv 1 \pmod 8$, we have $p^{-1} \equiv 1 \pmod 8$. For each row +of the right column, the correction is + +$$ +k \equiv -t \cdot p^{-1} \pmod 8, +\qquad +x^\prime = (t + k p) / 8. +$$ + +### Batch 0 + +The first three divsteps are $L_c, L_b, L_a$. Their product is + +$$ +M_0 = \begin{pmatrix} 0 & 8 \\ -1 & 3 \end{pmatrix} \cdot 2^{-3}. +$$ + +Apply it to the left column: + +$$ +f^\prime = \frac{0 \cdot 17 + 8 \cdot 3}{8} = 3, +\qquad +g^\prime = \frac{-1 \cdot 17 + 3 \cdot 3}{8} = -1. +$$ + +Apply it to the right column. For $d^\prime$, $t = 0 \cdot 0 + 8 \cdot 1 = 8$, +so $k = 0$ and $d^\prime = 1$. For $e^\prime$, $t = -1 \cdot 0 + 3 \cdot 1 = 3$, +so $k \equiv -3 \equiv 5 \pmod 8$ and + +$$ +e^\prime = \frac{3 + 5 \cdot 17}{8} = 11. +$$ + +After batch 0, + +$$ +(f,g,d,e;\delta) = (3,-1,1,11;2). +$$ + +### Batch 1 + +The next three divsteps are $L_c, L_a, L_b$, giving + +$$ +M_1 = \begin{pmatrix} 0 & 8 \\ -1 & 5 \end{pmatrix} \cdot 2^{-3}. +$$ + +For the left column, + +$$ +f^\prime = \frac{0 \cdot 3 + 8 \cdot (-1)}{8} = -1, +\qquad +g^\prime = \frac{-1 \cdot 3 + 5 \cdot (-1)}{8} = -1. +$$ + +For the right column, the first row gives $t = 88$ and $k = 0$, hence +$d^\prime = 11$. The second row gives $t = -1 \cdot 1 + 5 \cdot 11 = 54$, +so $k \equiv -54 \equiv 2 \pmod 8$ and + +$$ +e^\prime = \frac{54 + 2 \cdot 17}{8} = 11. +$$ + +After batch 1, + +$$ +(f,g,d,e;\delta) = (-1,-1,11,11;1). +$$ + +### Batch 2 + +The next batch starts with the terminating divstep $L_c$; the remaining two +low-bit divsteps keep $g = 0$. The accumulated matrix is + +$$ +M_2 = \begin{pmatrix} 0 & 8 \\ -1 & 1 \end{pmatrix} \cdot 2^{-3}. +$$ + +Applying it gives + +$$ +f^\prime = \frac{0 \cdot (-1) + 8 \cdot (-1)}{8} = -1, +\qquad +g^\prime = \frac{-1 \cdot (-1) + 1 \cdot (-1)}{8} = 0, +$$ + +and for the right column, $d^\prime = 11$ and $e^\prime = 0$. + +Now $g=0$. Since $f=-1$, the inverse is $-d \bmod p$: + +$$ +a^{-1} \equiv -11 \equiv 6 \pmod {17}, +\qquad +3 \cdot 6 \equiv 1 \pmod {17}. +$$ diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.test.cpp new file mode 100644 index 000000000000..35f65e5c56fe --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.test.cpp @@ -0,0 +1,150 @@ +#include "barretenberg/ecc/fields/bernstein_yang_inverse.hpp" +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp" +#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp" +#include "barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" +#include + +namespace { + +using bb::numeric::uint256_t; +using Native = bb::bernstein_yang::Native5x64; +using Wasm = bb::bernstein_yang::Wasm9x29; + +template uint256_t to_raw(const F& a) +{ + F nonmont = a.from_montgomery_form_reduced(); + return { nonmont.data[0], nonmont.data[1], nonmont.data[2], nonmont.data[3] }; +} + +template F from_raw(const uint256_t& a) +{ + F r{ a.data[0], a.data[1], a.data[2], a.data[3] }; + r.self_to_montgomery_form(); + return r; +} + +template uint256_t by_invert(const F& a) +{ + constexpr uint256_t p = F::modulus; + constexpr uint64_t p_inv_mod_2k = S::p_inv_mod_2k_from_montgomery_r_inv(F::Params::r_inv); + return bb::bernstein_yang::invert_vartime(to_raw(a), p, p_inv_mod_2k); +} + +// Random a, BY result roundtripped through Montgomery must invert a. +template void check_inverse_matches_modexp(size_t n) +{ + for (size_t i = 0; i < n; ++i) { + F a = F::random_element(); + if (a == F::zero()) { + continue; + } + F got = from_raw(by_invert(a)); + EXPECT_EQ(got * a, F::one()) << "iteration " << i; + } +} + +// Same input through both kernels must produce identical canonical output. +template void check_native_matches_wasm(size_t n) +{ + for (size_t i = 0; i < n; ++i) { + F a = F::random_element(); + if (a == F::zero()) { + continue; + } + EXPECT_EQ(by_invert(a), by_invert(a)) << "iteration " << i; + } +} + +template void check_edge_cases() +{ + // invert(1) == 1 + EXPECT_EQ(from_raw(by_invert(F::one())), F::one()); + + // invert(-1) == -1 + F neg_one = -F::one(); + EXPECT_EQ(from_raw(by_invert(neg_one)), neg_one); + + // a * invert(a) == 1 for small / boundary / sparse inputs + F two = F::one() + F::one(); + F neg_two = -two; + F top_limb_only{ 0, 0, 0, 1 }; // raw value 2^192, well below modulus for 254-bit fields + top_limb_only.self_to_montgomery_form(); + for (const F& a : { two, neg_two, top_limb_only }) { + F inv = from_raw(by_invert(a)); + EXPECT_EQ(inv * a, F::one()); + } + + // Involution: invert(invert(a)) == a, on random samples. + for (int i = 0; i < 64; ++i) { + F a = F::random_element(); + if (a == F::zero()) { + continue; + } + F inv = from_raw(by_invert(a)); + F inv_inv = from_raw(by_invert(inv)); + EXPECT_EQ(inv_inv, a); + } +} + +} // namespace + +TEST(Wasm9x29, MatchesModexp_BN254_Fr) +{ + check_inverse_matches_modexp(500); +} +TEST(Wasm9x29, MatchesModexp_BN254_Fq) +{ + check_inverse_matches_modexp(500); +} + +TEST(Native5x64, MatchesModexp_BN254_Fr) +{ + check_inverse_matches_modexp(500); +} +TEST(Native5x64, MatchesModexp_BN254_Fq) +{ + check_inverse_matches_modexp(500); +} + +TEST(Wasm9x29, EdgeCases_BN254_Fr) +{ + check_edge_cases(); +} +TEST(Wasm9x29, EdgeCases_BN254_Fq) +{ + check_edge_cases(); +} +TEST(Native5x64, EdgeCases_BN254_Fr) +{ + check_edge_cases(); +} +TEST(Native5x64, EdgeCases_BN254_Fq) +{ + check_edge_cases(); +} + +TEST(BernsteinYang, NativeMatchesWasm_BN254_Fr) +{ + check_native_matches_wasm(500); +} +TEST(BernsteinYang, NativeMatchesWasm_BN254_Fq) +{ + check_native_matches_wasm(500); +} + +// 256-bit moduli must keep working through field::invert() via the Fermat +// fallback (the BY dispatch is gated by `modulus_3 < 2^63`, which excludes +// secp256k1/r1). Pin that behavior so a future change to the gate gets caught. +TEST(BernsteinYang, FermatFallback_Secp256k1_Fr) +{ + auto a = bb::secp256k1::fr::random_element(); + EXPECT_EQ(a * a.invert(), bb::secp256k1::fr::one()); +} +TEST(BernsteinYang, FermatFallback_Secp256r1_Fr) +{ + auto a = bb::secp256r1::fr::random_element(); + EXPECT_EQ(a * a.invert(), bb::secp256r1::fr::one()); +} diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp new file mode 100644 index 000000000000..4d728e3de73b --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp @@ -0,0 +1,280 @@ +// 9 × 29-bit-limb state. Included from bernstein_yang_inverse.hpp; uses the +// u64 / i64 / DivstepMatrix names declared there. +// +// Why a different limb size from Native5x64: on wasm32 there is no native +// 64×64→128 multiply, so i64 × u64 → __int128 lowers to a compiler-rt +// __multi3 dispatch. Pack the 254-bit state into 9 limbs of 29 bits each +// instead: every limb-level product is then i29 × i29 = i58, fitting in a +// single WASM i64.mul. Choosing the per-iter BATCH as exactly 2 × LIMB_BITS +// makes the "/ 2^BATCH" at the end of apply_divstep_matrix equivalent to dropping +// the bottom two 29-bit limbs (no sub-limb shift on the intermediate). + +#pragma once + +#include "barretenberg/numeric/uint256/uint256.hpp" +#include + +namespace bb::bernstein_yang { + +class Wasm9x29 { + public: + // Divsteps per matrix application; smaller than Native5x64::BATCH so + // the resulting "/ 2^BATCH" is limb-aligned (= drop the bottom two + // 29-bit limbs) and no sub-limb shift is needed on the intermediate. + static constexpr int BATCH = 58; + + // ⌈735 / 58⌉ = 13. Same convergence-bound logic as Native5x64; one + // iter more because BATCH is smaller. + static constexpr int NUM_ITERATIONS = 13; + + // |d|, |e| can grow by ~2× + p per matrix application; after 4 iters + // they reach ~31p ≈ 2^259, which still fits in the 9 × 29-bit signed + // state (capacity ~2^260). Reducing once every 4 iters instead of + // every iter saves ~3× reduce_to_canonical calls per inversion. + static constexpr int REDUCE_INTERVAL = 4; + + // Worst-case iteration cap inside reduce_to_canonical. After + // REDUCE_INTERVAL iters between reductions, |d|, |e| ≤ (2^(REDUCE_INTERVAL+1) - 1)·p, + // so reducing requires that many subtractions plus one break iter. + static constexpr int REDUCE_TO_CANONICAL_MAX_ITERS = 36; + static_assert((1U << (REDUCE_INTERVAL + 1)) <= REDUCE_TO_CANONICAL_MAX_ITERS, + "REDUCE_INTERVAL too large for reduce_to_canonical iteration bound"); + + Wasm9x29() noexcept + : l{} + {} + explicit Wasm9x29(const uint256_t& x) noexcept + { + const u64* d = x.data; + l[0] = (i64)(d[0] & LIMB_MASK); + l[1] = (i64)((d[0] >> 29) & LIMB_MASK); + l[2] = (i64)(((d[0] >> 58) & 0x3FULL) | ((d[1] & 0x7FFFFFULL) << 6)); + l[3] = (i64)((d[1] >> 23) & LIMB_MASK); + l[4] = (i64)(((d[1] >> 52) & 0xFFFULL) | ((d[2] & 0x1FFFFULL) << 12)); + l[5] = (i64)((d[2] >> 17) & LIMB_MASK); + l[6] = (i64)(((d[2] >> 46) & 0x3FFFFULL) | ((d[3] & 0x7FFULL) << 18)); + l[7] = (i64)((d[3] >> 11) & LIMB_MASK); + l[8] = (i64)((d[3] >> 40) & 0xFFFFFFULL); + } + static Wasm9x29 one() noexcept + { + Wasm9x29 r; + r.l[0] = 1; + return r; + } + + uint256_t to_uint256() const noexcept + { + return { (u64)l[0] | ((u64)l[1] << 29) | ((u64)l[2] << 58), + ((u64)l[2] >> 6) | ((u64)l[3] << 23) | ((u64)l[4] << 52), + ((u64)l[4] >> 12) | ((u64)l[5] << 17) | ((u64)l[6] << 46), + ((u64)l[6] >> 18) | ((u64)l[7] << 11) | ((u64)l[8] << 40) }; + } + u64 low_64() const noexcept { return (u64)l[0] | ((u64)l[1] << 29) | (((u64)l[2] & 0x3F) << 58); } + bool is_zero() const noexcept + { + i64 a = 0; + for (int i = 0; i < N; ++i) { + a |= l[i]; + } + return a == 0; + } + bool is_negative() const noexcept { return l[N - 1] < 0; } + void neg() noexcept + { + for (int i = 0; i < N; ++i) { + l[i] = -l[i]; + } + normalise(); + } + void reduce_to_canonical(const Wasm9x29& p) noexcept; + + // See Native5x64 for the batched divstep matrix, matrix application, + // and p_inv_mod_2k_from_montgomery_r_inv contracts; the bodies differ only + // in limb representation. + static DivstepMatrix compute_divstep_matrix(i64& delta, u64 f_lo, u64 g_lo) noexcept; + static void apply_divstep_matrix(const DivstepMatrix& m, + Wasm9x29& f, + Wasm9x29& g, + Wasm9x29& d, + Wasm9x29& e, + const Wasm9x29& p, + u64 p_inv_mod_2k) noexcept; + static constexpr u64 p_inv_mod_2k_from_montgomery_r_inv(u64 r_inv) noexcept + { + // r_inv = -p^{-1} mod 2^64, so 0 - r_inv = p^{-1} mod 2^64. + return (0ULL - r_inv) & ((1ULL << BATCH) - 1); + } + + private: + static constexpr int N = 9; + static constexpr int LIMB_BITS = 29; + static constexpr u64 LIMB_MASK = (1ULL << LIMB_BITS) - 1; + i64 l[N]; // top limb carries sign; lower limbs in [0, 2^29) post-normalise + + void normalise() noexcept + { + i64 c = 0; + for (int i = 0; i < N - 1; ++i) { + i64 v = l[i] + c; + l[i] = v & (i64)LIMB_MASK; + c = v >> LIMB_BITS; + } + l[N - 1] += c; + } + void add_inplace(const Wasm9x29& b) noexcept + { + for (int i = 0; i < N; ++i) { + l[i] += b.l[i]; + } + normalise(); + } + void sub_inplace(const Wasm9x29& b) noexcept + { + for (int i = 0; i < N; ++i) { + l[i] -= b.l[i]; + } + normalise(); + } +}; + +// Iter cap chosen by the REDUCE_TO_CANONICAL_MAX_ITERS / REDUCE_INTERVAL +// static_assert above; see those constants for the magnitude argument. +inline void Wasm9x29::reduce_to_canonical(const Wasm9x29& p) noexcept +{ + normalise(); + for (int it = 0; it < REDUCE_TO_CANONICAL_MAX_ITERS; ++it) { + if (is_negative()) { + add_inplace(p); + continue; + } + int cmp = 0; + for (int i = N - 1; i >= 0; --i) { + if (l[i] != p.l[i]) { + cmp = l[i] > p.l[i] ? 1 : -1; + break; + } + } + if (cmp < 0) { + break; + } + sub_inplace(p); + } +} + +inline DivstepMatrix Wasm9x29::compute_divstep_matrix(i64& delta, u64 f_lo, u64 g_lo) noexcept +{ + i64 u = 1, v = 0, q = 0, r = 1; + for (int i = 0; i < BATCH; ++i) { + if (g_lo & 1) { + if (delta > 0) { + u64 nf = g_lo, ng = (g_lo - f_lo) >> 1; + i64 nu = q << 1, nv = r << 1, nq = q - u, nr = r - v; + f_lo = nf; + g_lo = ng; + u = nu; + v = nv; + q = nq; + r = nr; + delta = 1 - delta; + } else { + g_lo = (g_lo + f_lo) >> 1; + q = q + u; + r = r + v; + u <<= 1; + v <<= 1; + delta = delta + 1; + } + } else { + g_lo >>= 1; + u <<= 1; + v <<= 1; + delta = delta + 1; + } + } + return { u, v, q, r }; +} + +// Streamed schoolbook: for each limb position i compute +// nf_i = u_lo·f_i + v_lo·g_i + u_hi·f_{i-1} + v_hi·g_{i-1} + carry_in +// (similarly ng, nd, ne), then carry_out = nf_i >> LIMB_BITS, masked low +// 29 bits land at output position i - 2 (= exact >> BATCH). The de row +// derives k_d, k_e from the low two limbs up front and folds k·p into the +// per-limb formula from position 2 onward. No 11-limb intermediate is +// materialised — the JIT keeps the four running carries in registers. +inline void Wasm9x29::apply_divstep_matrix(const DivstepMatrix& m, + Wasm9x29& f, + Wasm9x29& g, + Wasm9x29& d, + Wasm9x29& e, + const Wasm9x29& p, + u64 p_inv_mod_2k) noexcept +{ + constexpr u64 MASK_BATCH = (1ULL << BATCH) - 1; + const i64 u_lo = m.u & (i64)LIMB_MASK, u_hi = m.u >> LIMB_BITS; + const i64 v_lo = m.v & (i64)LIMB_MASK, v_hi = m.v >> LIMB_BITS; + const i64 q_lo = m.q & (i64)LIMB_MASK, q_hi = m.q >> LIMB_BITS; + const i64 r_lo = m.r & (i64)LIMB_MASK, r_hi = m.r >> LIMB_BITS; + + { + i64 cf = 0, cg = 0, fp = 0, gp = 0; + for (int i = 0; i < N; ++i) { + const i64 fi = f.l[i], gi = g.l[i]; + const i64 nf = u_lo * fi + v_lo * gi + u_hi * fp + v_hi * gp + cf; + const i64 ng = q_lo * fi + r_lo * gi + q_hi * fp + r_hi * gp + cg; + cf = nf >> LIMB_BITS; + cg = ng >> LIMB_BITS; + if (i >= 2) { + f.l[i - 2] = nf & (i64)LIMB_MASK; + g.l[i - 2] = ng & (i64)LIMB_MASK; + } + fp = fi; + gp = gi; + } + const i64 nf9 = u_hi * fp + v_hi * gp + cf; + const i64 ng9 = q_hi * fp + r_hi * gp + cg; + f.l[N - 2] = nf9 & (i64)LIMB_MASK; + g.l[N - 2] = ng9 & (i64)LIMB_MASK; + f.l[N - 1] = nf9 >> LIMB_BITS; + g.l[N - 1] = ng9 >> LIMB_BITS; + } + + // k_d, k_e (mod 2^BATCH) clear the low BATCH bits of nd, ne; fold k·p + // into the streaming pass from position 2 onward. + { + const i64 d0 = d.l[0], e0 = e.l[0], d1 = d.l[1], e1 = e.l[1]; + const i64 nd0 = u_lo * d0 + v_lo * e0; + const i64 ne0 = q_lo * d0 + r_lo * e0; + const i64 nd1 = u_lo * d1 + v_lo * e1 + u_hi * d0 + v_hi * e0; + const i64 ne1 = q_lo * d1 + r_lo * e1 + q_hi * d0 + r_hi * e0; + const u64 t_d = ((u64)nd0 & LIMB_MASK) | (((u64)(nd1 + (nd0 >> LIMB_BITS)) & LIMB_MASK) << LIMB_BITS); + const u64 t_e = ((u64)ne0 & LIMB_MASK) | (((u64)(ne1 + (ne0 >> LIMB_BITS)) & LIMB_MASK) << LIMB_BITS); + const u64 k_d = ((0ULL - t_d) * p_inv_mod_2k) & MASK_BATCH; + const u64 k_e = ((0ULL - t_e) * p_inv_mod_2k) & MASK_BATCH; + const i64 kd_lo = (i64)(k_d & LIMB_MASK), kd_hi = (i64)(k_d >> LIMB_BITS); + const i64 ke_lo = (i64)(k_e & LIMB_MASK), ke_hi = (i64)(k_e >> LIMB_BITS); + i64 cd = (nd1 + kd_lo * p.l[1] + kd_hi * p.l[0] + ((nd0 + kd_lo * p.l[0]) >> LIMB_BITS)) >> LIMB_BITS; + i64 ce = (ne1 + ke_lo * p.l[1] + ke_hi * p.l[0] + ((ne0 + ke_lo * p.l[0]) >> LIMB_BITS)) >> LIMB_BITS; + + i64 dp = d1, ep = e1; + for (int i = 2; i < N; ++i) { + const i64 di = d.l[i], ei = e.l[i]; + const i64 nd = u_lo * di + v_lo * ei + u_hi * dp + v_hi * ep + kd_lo * p.l[i] + kd_hi * p.l[i - 1] + cd; + const i64 ne = q_lo * di + r_lo * ei + q_hi * dp + r_hi * ep + ke_lo * p.l[i] + ke_hi * p.l[i - 1] + ce; + cd = nd >> LIMB_BITS; + ce = ne >> LIMB_BITS; + d.l[i - 2] = nd & (i64)LIMB_MASK; + e.l[i - 2] = ne & (i64)LIMB_MASK; + dp = di; + ep = ei; + } + const i64 nd9 = u_hi * dp + v_hi * ep + kd_hi * p.l[N - 1] + cd; + const i64 ne9 = q_hi * dp + r_hi * ep + ke_hi * p.l[N - 1] + ce; + d.l[N - 2] = nd9 & (i64)LIMB_MASK; + e.l[N - 2] = ne9 & (i64)LIMB_MASK; + d.l[N - 1] = nd9 >> LIMB_BITS; + e.l[N - 1] = ne9 >> LIMB_BITS; + } +} + +} // namespace bb::bernstein_yang diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp index fdbb7508dfa8..6362ac70e04c 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp @@ -340,6 +340,7 @@ template struct alignas(32) field { static constexpr uint256_t modulus_minus_two = uint256_t(Params::modulus_0 - 2ULL, Params::modulus_1, Params::modulus_2, Params::modulus_3); constexpr field invert() const noexcept; + constexpr field invert_const_time() const noexcept; template // has size() and operator[]. requires requires(C& c) { diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp index f97695d9be19..c9283b3847c6 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp @@ -15,6 +15,8 @@ #include #include +#include "./bernstein_yang_inverse.hpp" +#include "./bernstein_yang_inverse_wasm.hpp" #include "./field_declarations.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" @@ -384,6 +386,29 @@ template constexpr field field::pow(const uint64_t exponent) con } template constexpr field field::invert() const noexcept +{ + if (*this == zero()) { + bb::assert_failure("Trying to invert zero in the field"); + } + // BY uses __int128 and is not constexpr-evaluable; compile-time inversions keep Fermat. + if (std::is_constant_evaluated()) { + return pow(modulus_minus_two); + } + if constexpr (bernstein_yang::supported_v) { + constexpr uint256_t p_uint = modulus; + constexpr uint64_t p_inv_mod_2k = bernstein_yang::p_inv_mod_2k_from_montgomery_r_inv(T::r_inv); + field non_mont = from_montgomery_form_reduced(); + uint256_t a{ non_mont.data[0], non_mont.data[1], non_mont.data[2], non_mont.data[3] }; + uint256_t inv = bernstein_yang::invert_vartime(a, p_uint, p_inv_mod_2k); + field result{ inv.data[0], inv.data[1], inv.data[2], inv.data[3] }; + result.self_to_montgomery_form(); + return result; + } else { + return pow(modulus_minus_two); + } +} + +template constexpr field field::invert_const_time() const noexcept { if (*this == zero()) { bb::assert_failure("Trying to invert zero in the field"); diff --git a/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp index 03c24a5acb91..7c6fbb8d1c5b 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp @@ -113,6 +113,8 @@ template class alignas(32) element { // constexpr Fr operator/(const element& other) noexcept {} constexpr element normalize() const noexcept; + constexpr element normalize_const_time() const noexcept; + constexpr affine_element to_affine_const_time() const noexcept; static element infinity(); BB_INLINE constexpr element set_infinity() const noexcept; BB_INLINE constexpr void self_set_infinity() noexcept; diff --git a/barretenberg/cpp/src/barretenberg/ecc/groups/element_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/element_impl.hpp index bf3687445ad6..7c7f299f5fda 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/element_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/groups/element_impl.hpp @@ -63,6 +63,10 @@ constexpr element& element::operator=(element&& other) noe return *this; } +// Warning: variable-time — calls `z.invert()` (Bernstein-Yang safegcd). Do not +// use on points derived from secret material (signing nonces, private keys, DH +// shared secrets). For those, call `to_affine_const_time()` explicitly; the +// implicit conversion does NOT pick up the const-time path. template constexpr element::operator affine_element() const noexcept { if (is_point_at_infinity()) { @@ -79,6 +83,23 @@ template constexpr element::operator af return result; } +template +constexpr affine_element element::to_affine_const_time() const noexcept +{ + if (is_point_at_infinity()) { + affine_element result; + result.x = Fq(0); + result.y = Fq(0); + result.self_set_infinity(); + return result; + } + Fq z_inv = z.invert_const_time(); + Fq zz_inv = z_inv.sqr(); + Fq zzz_inv = zz_inv * z_inv; + affine_element result(x * zz_inv, y * zzz_inv); + return result; +} + template constexpr void element::self_dbl() noexcept { if constexpr (Fq::modulus.data[3] >= MODULUS_TOP_LIMB_LARGE_THRESHOLD) { @@ -461,12 +482,20 @@ element element::mul_const_time(const Fr& scalar, numeric: return R0; } +// Warning: variable-time via the implicit affine conversion above. For +// secret-input points use `normalize_const_time()`. template constexpr element element::normalize() const noexcept { const affine_element converted = *this; return element(converted); } +template +constexpr element element::normalize_const_time() const noexcept +{ + return element(to_affine_const_time()); +} + template element element::infinity() { element e{}; diff --git a/barretenberg/cpp/src/barretenberg/nodejs_module/util/async_op.hpp b/barretenberg/cpp/src/barretenberg/nodejs_module/util/async_op.hpp index ad62bc2bf4ae..e91306c7a62c 100644 --- a/barretenberg/cpp/src/barretenberg/nodejs_module/util/async_op.hpp +++ b/barretenberg/cpp/src/barretenberg/nodejs_module/util/async_op.hpp @@ -1,11 +1,16 @@ #pragma once #include "barretenberg/serialize/msgpack_impl.hpp" +#include #include #include #include #include +#ifndef _WIN32 +#include +#endif + namespace bb::nodejs { using async_fn = std::function; @@ -109,10 +114,17 @@ class ThreadedAsyncOperation : public std::enable_shared_from_this_fn(self->_result); self->_success = true; @@ -138,7 +150,43 @@ class ThreadedAsyncOperation : public std::enable_shared_from_this_completion_tsfn.Release(); }); - }).detach(); + }); + } + + // Launch `work` on a detached OS thread with an explicitly large stack (see WORKER_STACK_SIZE). + // std::thread cannot set a stack size, so use pthreads where available and fall back to a + // default-stack std::thread only if pthread creation is unavailable or fails. + static void launch_detached_with_large_stack(std::function work) + { +#ifndef _WIN32 + pthread_attr_t attr; + if (pthread_attr_init(&attr) == 0) { + pthread_attr_setstacksize(&attr, WORKER_STACK_SIZE); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + auto* heap_work = new std::function(std::move(work)); + pthread_t tid; + int rc = pthread_create( + &tid, + &attr, + [](void* arg) -> void* { + std::unique_ptr> fn(static_cast*>(arg)); + (*fn)(); + return nullptr; + }, + heap_work); + pthread_attr_destroy(&attr); + + if (rc == 0) { + return; + } + + // pthread_create failed; reclaim the work and fall back to a default std::thread. + std::unique_ptr> reclaimed(heap_work); + work = std::move(*reclaimed); + } +#endif + std::thread(std::move(work)).detach(); } async_fn _fn; diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/avm_io.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/avm_io.hpp index b503c573f12c..4378671f2521 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/avm_io.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/avm_io.hpp @@ -113,18 +113,16 @@ struct PublicInputs { //////////////////////////////////////////////////////////////////////////// // Hints (contracts) //////////////////////////////////////////////////////////////////////////// +// Only ivpk_m is sent as a point; the others are field-element hashes. struct PublicKeysHint { - AffinePoint master_nullifier_public_key; - AffinePoint master_incoming_viewing_public_key; - AffinePoint master_outgoing_viewing_public_key; - AffinePoint master_tagging_public_key; + FF npk_m_hash; + AffinePoint ivpk_m; + FF ovpk_m_hash; + FF tpk_m_hash; bool operator==(const PublicKeysHint& other) const = default; - MSGPACK_CAMEL_CASE_FIELDS(master_nullifier_public_key, - master_incoming_viewing_public_key, - master_outgoing_viewing_public_key, - master_tagging_public_key); + MSGPACK_CAMEL_CASE_FIELDS(npk_m_hash, ivpk_m, ovpk_m_hash, tpk_m_hash); }; struct ContractInstanceHint { @@ -135,6 +133,7 @@ struct ContractInstanceHint { ContractClassId current_contract_class_id; ContractClassId original_contract_class_id; FF initialization_hash; + FF immutables_hash; PublicKeysHint public_keys; bool operator==(const ContractInstanceHint& other) const = default; @@ -146,6 +145,7 @@ struct ContractInstanceHint { current_contract_class_id, original_contract_class_id, initialization_hash, + immutables_hash, public_keys); }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp index 4f8ec3dc8a11..f7e7ef9ed09c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp @@ -77,23 +77,29 @@ enum class ContractInstanceMember : uint8_t { DEPLOYER = 0, CLASS_ID = 1, INIT_HASH = 2, - MAX = INIT_HASH, + IMMUTABLES_HASH = 3, + MAX = IMMUTABLES_HASH, }; //////////////////////////////////////////////////////////////////////////// // Keys, Instances, Classes //////////////////////////////////////////////////////////////////////////// +// Only `incoming_viewing_key` is exposed as a point (since address derivation +// needs the curve point in-circuit); the other three keys are exposed as their hashes. struct PublicKeys { - AffinePoint nullifier_key; + FF nullifier_key_hash; AffinePoint incoming_viewing_key; - AffinePoint outgoing_viewing_key; - AffinePoint tagging_key; + FF outgoing_viewing_key_hash; + FF tagging_key_hash; std::vector to_fields() const { - return { nullifier_key.x, nullifier_key.y, incoming_viewing_key.x, incoming_viewing_key.y, - outgoing_viewing_key.x, outgoing_viewing_key.y, tagging_key.x, tagging_key.y }; + return { nullifier_key_hash, + incoming_viewing_key.x, + incoming_viewing_key.y, + outgoing_viewing_key_hash, + tagging_key_hash }; } bool operator==(const PublicKeys& other) const = default; @@ -102,14 +108,14 @@ struct PublicKeys { // TODO(fcarreiro): solve with macro void msgpack(auto pack_fn) { - pack_fn("masterNullifierPublicKey", - nullifier_key, - "masterIncomingViewingPublicKey", + pack_fn("npkMHash", + nullifier_key_hash, + "ivpkM", incoming_viewing_key, - "masterOutgoingViewingPublicKey", - outgoing_viewing_key, - "masterTaggingPublicKey", - tagging_key); + "ovpkMHash", + outgoing_viewing_key_hash, + "tpkMHash", + tagging_key_hash); } }; @@ -119,7 +125,8 @@ struct ContractInstance { ContractClassId current_contract_class_id = 0; ContractClassId original_contract_class_id = 0; FF initialization_hash = 0; - PublicKeys public_keys; + FF immutables_hash = 0; + PublicKeys public_keys{}; bool operator==(const ContractInstance& other) const = default; @@ -136,6 +143,8 @@ struct ContractInstance { original_contract_class_id, "initializationHash", initialization_hash, + "immutablesHash", + immutables_hash, "publicKeys", public_keys); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp index 112997b74b0d..3e6c7b6bb243 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp @@ -99,7 +99,7 @@ const std::unordered_map>& { WireOpCode::POSEIDON2PERM, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { WireOpCode::SHA256COMPRESSION, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { WireOpCode::KECCAKF1600, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { WireOpCode::ECADD, { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { WireOpCode::ECADD, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // Conversions { WireOpCode::TORADIXBE, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, }; @@ -420,7 +420,7 @@ const std::unordered_map& get_wire_instruction_ .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::KECCAKF1600) } }, { WireOpCode::ECADD, { .exec_opcode = ExecutionOpCode::ECADD, - .size_in_bytes = 17, + .size_in_bytes = 13, .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::ECADD) } }, // Conversions { WireOpCode::TORADIXBE, @@ -737,14 +737,12 @@ const std::unordered_map& get_exec_instruc { .num_addresses = 2, .gas_cost = { .opcode_gas = AVM_KECCAKF1600_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } }, { ExecutionOpCode::ECADD, - { .num_addresses = 7, + { .num_addresses = 5, .gas_cost = { .opcode_gas = AVM_ECADD_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 }, .register_info = RegisterInfo().add_inputs({ /*p_x=*/ValueTag::FF, /*p_y=*/ValueTag::FF, - /*p_inf*/ ValueTag::U1, /*q_x*/ ValueTag::FF, - /*q_y*/ ValueTag::FF, - /*q_inf*/ ValueTag::U1 }) } }, + /*q_y*/ ValueTag::FF }) } }, { ExecutionOpCode::TORADIXBE, { .num_addresses = 5, .gas_cost = { .opcode_gas = AVM_TORADIXBE_BASE_L2_GAS, diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.hpp index bbf2e6dbd9fb..1f0b271724fd 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.hpp @@ -6,16 +6,15 @@ namespace bb::avm2 { /** - * AVM bytecode expects the representation of points to be triplets, the two coordinates and an is_infinity boolean. - * Furthermore, its representation of infinity is inherited from noir's and is expected to be 0,0,true. - * BB, however, uses only the two coordinates to represent points. Infinity in barretenberg is represented as (P+1)/2,0. - * This class is a wrapper of the BB representation, needed to operate with points, that allows to extract the standard - * representation that AVM bytecode expects. - * NOTE: When constructing infinity from BB's two element representation, is_infinity() will be true but the coordinates - * will remain (P+1)/2,0. - * NOTE: When constructing infinity via BaseFields, input coordinates are maintained and can be any values, so may - * mismatch the underlying AffinePoint. Always check is_infinity() before ECC operations on coordinates. See test - * InfinityPreservesRawCoordinates for an example. + * The AVM's representation of infinity is inherited from noir's and is expected to be 0,0. + * BB, however, uses only the two coordinates to represent points. Infinity in barretenberg is represented as + * (P+1)/2,0,true. This class is a wrapper of the BB representation, needed to operate with points, that allows us to + * extract the standard representation that AVM bytecode expects. + * + * NOTE: When constructing infinity from BB's two element representation, we keep the original AffinePoint so operations + * can use it in the background, but set extractable coordinates to be our represention of (0,0). + * NOTE: When constructing infinity via BaseFields (equiv. inputting (0, 0), the underlying AffinePoint is set to BB's + * representation so operations can use it in the background. */ template class StandardAffinePoint { public: @@ -26,12 +25,12 @@ template class StandardAffinePoint { constexpr StandardAffinePoint(AffinePoint val) noexcept : point(val) - , x_coord(val.x) - , y_coord(val.y) + , x_coord(val.is_point_at_infinity() ? zero : val.x) + , y_coord(val.is_point_at_infinity() ? zero : val.y) {} - constexpr StandardAffinePoint(BaseField x, BaseField y, bool is_infinity) noexcept - : point(is_infinity ? AffinePoint::infinity() : AffinePoint(x, y)) + constexpr StandardAffinePoint(BaseField x, BaseField y) noexcept + : point((x.is_zero() && y.is_zero()) ? AffinePoint::infinity() : AffinePoint(x, y)) , x_coord(x) , y_coord(y) {} @@ -74,15 +73,15 @@ template class StandardAffinePoint { [[nodiscard]] constexpr bool on_curve() const noexcept { return point.on_curve(); } - // Always returns the raw coordinates, when an operation results in infinity these will be (0,0). - // If a point at infinity is constructed with non-zero coordinates, we likely want to preserve those. + // Always returns Noir standard coordinates. For the point at infinity this is always (0, 0). If that point was + // constructed via AffinePoint with a different representation, those non-zero coordinates are preserved in .point. constexpr const BaseField& x() const noexcept { return x_coord; } constexpr const BaseField& y() const noexcept { return y_coord; } static const StandardAffinePoint& infinity() { - static auto infinity = StandardAffinePoint(zero, zero, true); + static auto infinity = StandardAffinePoint(zero, zero); return infinity; } @@ -94,7 +93,7 @@ template class StandardAffinePoint { private: // The affine point for operations, this will always match the raw coordinates unless the point is infinity. - // In that case, the point will be set to barretenberg's infinity representation - which is not (0,0). + // In that case, the point will be set to AffinePoint's infinity representation - which may not be (0,0). AffinePoint point; // These are the raw x and y coordinates, that are set when constructing the point. When an operation results // in infinity, these will be set to (0,0) to match noir's expected representation. diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.test.cpp index 6a9386842417..b8e79e2a1f50 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.test.cpp @@ -10,18 +10,17 @@ using EmbeddedCurvePoint = StandardAffinePoint; using Fr = grumpkin::fr; using Fq = grumpkin::fq; -TEST(StandardAffinePointTest, InfinityPreservesRawCoordinates) +TEST(StandardAffinePointTest, ConstructingInfinityNormalized) { - // When constructing an infinity point with non-zero coordinates, - // x() and y() should return the raw coordinates - Fq raw_x = 1; - Fq raw_y = 2; - - EmbeddedCurvePoint point(raw_x, raw_y, /*is_infinity=*/true); - - EXPECT_TRUE(point.is_infinity()); - EXPECT_EQ(point.x(), raw_x); - EXPECT_EQ(point.y(), raw_y); + // Constructing a point with (0,0) coordinates should result in infinity + EmbeddedCurvePoint inf(0, 0); + EXPECT_TRUE(inf.is_infinity()); + // Constructing a point with BB's inf should result in infinity with (0,0) coordinates + EmbeddedCurvePoint inf_bb(grumpkin::g1::affine_element::infinity()); + EXPECT_TRUE(inf_bb.is_infinity()); + EXPECT_TRUE(inf_bb.x().is_zero()); + EXPECT_TRUE(inf_bb.y().is_zero()); + EXPECT_EQ(inf, inf_bb); } TEST(StandardAffinePointTest, NormalPointCoordinates) @@ -72,7 +71,7 @@ TEST(StandardAffinePointTest, ScalarMultiplicationResultingInInfinityNormalized) TEST(StandardAffinePointTest, StaticInfinityHasZeroCoordinates) { - // The static infinity() method should return (0,0,true) + // The static infinity() method should return (0,0) auto& inf = EmbeddedCurvePoint::infinity(); EXPECT_TRUE(inf.is_infinity()); @@ -80,18 +79,14 @@ TEST(StandardAffinePointTest, StaticInfinityHasZeroCoordinates) EXPECT_TRUE(inf.y().is_zero()); } -TEST(StandardAffinePointTest, NegatingInfinityPreservesRawCoordinates) +TEST(StandardAffinePointTest, NegatingInfinity) { - // Negating an infinity point should preserve its raw coordinates - Fq raw_x = 1; - Fq raw_y = 2; - EmbeddedCurvePoint inf(raw_x, raw_y, /*is_infinity=*/true); - - auto neg_inf = -inf; + // Negating an infinity point should return (0,0) + auto neg_inf = -EmbeddedCurvePoint::infinity(); EXPECT_TRUE(neg_inf.is_infinity()); - EXPECT_EQ(neg_inf.x(), raw_x); - EXPECT_EQ(neg_inf.y(), raw_y); + EXPECT_TRUE(neg_inf.x().is_zero()); + EXPECT_TRUE(neg_inf.y().is_zero()); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp index c060244f6965..a3d2d285a8b3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp @@ -17,7 +17,7 @@ class AvmHardCodedVKAndHash { using FF = bb::curve::BN254::ScalarField; // Precomputed VK hash (hash of all commitments below). - static FF vk_hash() { return FF(uint256_t("0x23a03c6f87c465dbecc386b091e8123a8936597b5b0749f276d042a8964bd390")); } + static FF vk_hash() { return FF(uint256_t("0x07c6aee864d89db19813358d6b6ea4e41643f8e60ce88ab8974314313a0470e1")); } static constexpr std::array get_all() { @@ -71,9 +71,9 @@ class AvmHardCodedVKAndHash { uint256_t( "0x090dda25e7d64ab5cabe09fd80fbb731af2a98de7a608157dc10394b4fc022a4")), // precomputed_exec_opcode_dynamic_l2_gas Commitment( - uint256_t("0x26086b5fb31a24f236f0441d5b922b94ca141e861b9cc640184681c518cd68d3"), + uint256_t("0x1fbccee2ff656d845414c1a520adde56aa3625e29b6fff377044986493023e6d"), uint256_t( - "0x0bab134bb4e25ff33584c1094847e762ce6573054bae27715d0e4eb2b7278d80")), // precomputed_exec_opcode_opcode_gas + "0x05c88802d3174f1c7b3c9aa1abf4754ebdaf6409d1aaf1dfa3f551da1c10fa93")), // precomputed_exec_opcode_opcode_gas Commitment( uint256_t("0x296def9415d1c96b4d8ab91df5f59ad8522a726f98461b1ab5c4d4c5b22471a4"), uint256_t( @@ -83,18 +83,15 @@ class AvmHardCodedVKAndHash { uint256_t( "0x06ea9cd6f2a50e2156f80beebc721d11d24821fd4b723932da48d8750300fbaa")), // precomputed_expected_tag_reg_1_ Commitment( - uint256_t("0x1cb1c6d46ddf9f7bd7a87a5e7dca5ef92c8a44669ab0cbc557a0fcb8331d0d8d"), + uint256_t("0x034e06277dc6d6e4f2ddea6d71635693db1a2869d33b918f0f70efa0530ecaa6"), uint256_t( - "0x281a3e4b96e4f595db502ba69acda314bc335957ae605af17423b0ff3d0528c3")), // precomputed_expected_tag_reg_2_ + "0x2d3e564f6e8885163d356daec0387132097e73dbf8e04475675b715151ce3cb9")), // precomputed_expected_tag_reg_2_ Commitment( uint256_t("0x1a3c36c4933c956751e6ca5631077a9418cd0ba4ec29e965508eaf8bc1a7ffd4"), uint256_t( "0x1203bdd1aab5bfc5f3ed6abbefc30ab303770b847d022c1c9c0f8de202a76560")), // precomputed_expected_tag_reg_3_ Commitment::infinity(), // precomputed_expected_tag_reg_4_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_expected_tag_reg_5_ + Commitment::infinity(), // precomputed_expected_tag_reg_5_ Commitment( uint256_t("0x0000000000000000000000000000000000000000000000000000000000000001"), uint256_t( @@ -103,9 +100,9 @@ class AvmHardCodedVKAndHash { uint256_t("0x14567e2c3e84fc1e3e69d81f6ce5808ca9a0451964a7bbabbd9e369db7556253"), uint256_t("0x0378926f150c30c760965df469ae6ed609c59feecf899f2b95aff519bbf3fb3c")), // precomputed_idx Commitment( - uint256_t("0x1e497723c3f95466c480f1ac1addb1e0dc68bb123cae27ee70d00e6d6fcc6896"), + uint256_t("0x2bef1e5de8c449d3cfa4cf9ab94e8b846755023b02e94dbbba1ffb3c73da0d1d"), uint256_t( - "0x24c9a31064fb5f18c18ac3ea4be1a10809765a43b06bcea177fbb171dd547ced")), // precomputed_instr_size + "0x06905ac3e0ae01f14b1bc598f9ba30af7eced70893019ca78b0e55668c38f3e0")), // precomputed_instr_size Commitment( uint256_t("0x11b710f896157a9557278a1f776cd6c7e1e7e256a572bd080797daaf1d6307d1"), uint256_t( @@ -134,6 +131,10 @@ class AvmHardCodedVKAndHash { uint256_t("0x0000000000000000000000000000000000000000000000000000000000000001"), uint256_t( "0x0000000000000000000000000000000000000000000000000000000000000002")), // precomputed_is_deployer + Commitment( + uint256_t("0x210bedcbb97a2e72905c082dd087be36c29c67e85b47de07b639e28a7dd78c76"), + uint256_t( + "0x18d1e431b83aa3ab2f6904bbbc452fee3472c01c0ceaf6d2fe6e37c4ff79e265")), // precomputed_is_immutables_hash Commitment( uint256_t("0x020ad6e43ccd48a6a39e43897cc85187bd364919be8a3b82d4809715cfe489db"), uint256_t( @@ -171,9 +172,9 @@ class AvmHardCodedVKAndHash { uint256_t( "0x23268ad7678b97fba97cc3e75da6cff9a3659c3b8a49046cce4062820e5c1116")), // precomputed_is_tree_padding Commitment( - uint256_t("0x210cdba7d0dae8d84cdd77a912060188657a0628905c0531fa63138ec3cbc9ea"), + uint256_t("0x00c43726f75b6fda0de22ce0e0dfab6bcc7a05ff95a96b289424c5f733670d96"), uint256_t( - "0x264f0d3eab260e5a20bdc5324e1ddcb3a0c0d811bb4a23b983417fd8c280486a")), // precomputed_is_valid_member_enum + "0x2f9b6e0b4e2c01968de5c32482aa7d1d0a09d7178ec93bad7858f96e64f0b48d")), // precomputed_is_valid_member_enum Commitment( uint256_t("0x057e5478fbad129bb84bfb618f6e7a747812510b4f6f70bd84d4688f760ecb62"), uint256_t( @@ -280,14 +281,8 @@ class AvmHardCodedVKAndHash { uint256_t("0x1530ccb47d1198320c163380a82ca8cbaf87b2d40ede856d21c60535e2251262"), uint256_t( "0x29dd7ccea05e6d47a7373ea950a7988caed0d20880612e046af575217a21652a")), // precomputed_sel_mem_op_reg_3_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_mem_op_reg_4_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_mem_op_reg_5_ + Commitment::infinity(), // precomputed_sel_mem_op_reg_4_ + Commitment::infinity(), // precomputed_sel_mem_op_reg_5_ Commitment( uint256_t("0x089cdab4e8e8381977b093cb267a1b7c8c60f4466c39a99af1247e37fe56ebfe"), uint256_t( @@ -296,10 +291,7 @@ class AvmHardCodedVKAndHash { uint256_t("0x0bf1970c2e92fee577ba15d063fa78fdd17752cafd19261ff0f176a1d3348769"), uint256_t( "0x21f1906edf2fe01e804774aa539abe8411cfda1731be99853f90253ed2652868")), // precomputed_sel_op_dc_0 - Commitment( - uint256_t("0x2ad6f77a7f7c14780d95de8bd1f5b2146fe71fb1b7e6d55016734664f10d653b"), - uint256_t( - "0x131ac1fc680fbc2584b74e5aece1f0d50afe030adf4289613e54935339829496")), // precomputed_sel_op_dc_1 + Commitment::infinity(), // precomputed_sel_op_dc_1 Commitment( uint256_t("0x225d208d9012b15a17b7dac26e737c0d2f9c8bf80de627bd13e1a9c042ede642"), uint256_t( @@ -380,14 +372,8 @@ class AvmHardCodedVKAndHash { uint256_t("0x1530ccb47d1198320c163380a82ca8cbaf87b2d40ede856d21c60535e2251262"), uint256_t( "0x29dd7ccea05e6d47a7373ea950a7988caed0d20880612e046af575217a21652a")), // precomputed_sel_op_is_address_4_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_op_is_address_5_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_op_is_address_6_ + Commitment::infinity(), // precomputed_sel_op_is_address_5_ + Commitment::infinity(), // precomputed_sel_op_is_address_6_ Commitment( uint256_t("0x1525ae740393f8dec3a1ea8f39f456861afece20561b5870db4291410d2f3429"), uint256_t( @@ -424,14 +410,8 @@ class AvmHardCodedVKAndHash { uint256_t("0x1530ccb47d1198320c163380a82ca8cbaf87b2d40ede856d21c60535e2251262"), uint256_t( "0x29dd7ccea05e6d47a7373ea950a7988caed0d20880612e046af575217a21652a")), // precomputed_sel_tag_check_reg_3_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_tag_check_reg_4_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_tag_check_reg_5_ + Commitment::infinity(), // precomputed_sel_tag_check_reg_4_ + Commitment::infinity(), // precomputed_sel_tag_check_reg_5_ Commitment( uint256_t("0x2b770f46bb0db9c1447e6010b3ca12f1dc2b2a237ff6d2390d9ddf5a056d09ad"), uint256_t( diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp index 8720e12efd4e..252c8793a4a2 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp @@ -72,14 +72,17 @@ TEST(AddressDerivationConstrainingTest, Basic) auto instance = testing::random_contract_instance(); - FF salted_initialization_hash = poseidon2::hash( - { DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer }); + FF salted_initialization_hash = poseidon2::hash({ DOM_SEP__SALTED_INITIALIZATION_HASH, + instance.salt, + instance.initialization_hash, + instance.deployer, + instance.immutables_hash }); FF partial_address = poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash }); FF public_keys_hash = hash_public_keys(instance.public_keys); - FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }); + FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }); EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one(); EmbeddedCurvePoint preaddress_public_key = g1 * Fq(preaddress); @@ -215,6 +218,62 @@ TEST(AddressDerivationConstrainingTest, NegativeWithInteractions) "Failed.*PREADDRESS_SCALAR_MUL. Could not find tuple in destination."); } +TEST(AddressDerivationConstrainingTest, NegativeMutateImmutablesHash) +{ + EventEmitter ecadd_event_emitter; + EventEmitter scalar_mul_event_emitter; + NoopEventEmitter ecc_add_memory_event_emitter; + EventEmitter hash_event_emitter; + NoopEventEmitter perm_event_emitter; + NoopEventEmitter perm_mem_event_emitter; + EventEmitter address_derivation_event_emitter; + + StrictMock mock_exec_id_manager; + EXPECT_CALL(mock_exec_id_manager, get_execution_id).WillRepeatedly(Return(0)); + StrictMock mock_gt; + Poseidon2 poseidon2_simulator( + mock_exec_id_manager, mock_gt, hash_event_emitter, perm_event_emitter, perm_mem_event_emitter); + + PureToRadix to_radix_simulator; + Ecc ecc_simulator(mock_exec_id_manager, + mock_gt, + to_radix_simulator, + ecadd_event_emitter, + scalar_mul_event_emitter, + ecc_add_memory_event_emitter); + + AddressDerivation address_derivation(poseidon2_simulator, ecc_simulator, address_derivation_event_emitter); + + TestTraceContainer trace({ + { { C::precomputed_first_row, 1 } }, + }); + + AddressDerivationTraceBuilder builder; + Poseidon2TraceBuilder poseidon2_builder; + EccTraceBuilder ecc_builder; + + ContractInstance instance = testing::random_contract_instance(); + AztecAddress address = compute_contract_address(instance); + address_derivation.assert_derivation(address, instance); + + builder.process(address_derivation_event_emitter.dump_events(), trace); + poseidon2_builder.process_hash(hash_event_emitter.dump_events(), trace); + ecc_builder.process_add(ecadd_event_emitter.dump_events(), trace); + ecc_builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace); + + check_all_interactions(trace); + check_relation(trace); + + // Mutate immutables_hash (the second input of the second poseidon2 round). The salted-init-hash + // round-2 lookup into poseidon2 should now fail because (deployer, mutated_immutables_hash, 0, + // salted_init_hash) no longer exists in the poseidon2 trace. + trace.set(C::address_derivation_immutables_hash, 0, instance.immutables_hash + 1); + EXPECT_THROW_WITH_MESSAGE( + (check_interaction(trace)), + "Failed.*SALTED_INITIALIZATION_HASH_POSEIDON2_1. Could not find tuple in destination."); +} + TEST(AddressDerivationConstrainingTest, NegativeIVKNotOnCurve) { TestTraceContainer trace; @@ -232,7 +291,7 @@ TEST(AddressDerivationConstrainingTest, NegativeIVKNotOnCurve) poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash }); FF public_keys_hash = hash_public_keys(instance.public_keys); - FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }); + FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }); EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one(); EmbeddedCurvePoint preaddress_public_key = g1 * Fq(preaddress); diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp index 793b2edc1488..10251ffaccc7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp @@ -45,12 +45,13 @@ ContractInstance create_test_contract_instance(uint32_t salt_value = 123) .current_contract_class_id = FF(0xdeadbeefULL), .original_contract_class_id = FF(0xcafebabeULL), .initialization_hash = FF(0x11111111ULL), + .immutables_hash = FF(0x22222222ULL), .public_keys = PublicKeys{ - .nullifier_key = { FF(0x100), FF(0x101) }, + .nullifier_key_hash = FF(0x100), .incoming_viewing_key = { FF(0x200), FF(0x201) }, - .outgoing_viewing_key = { FF(0x300), FF(0x301) }, - .tagging_key = { FF(0x400), FF(0x401) }, + .outgoing_viewing_key_hash = FF(0x300), + .tagging_key_hash = FF(0x400), }, }; } @@ -72,14 +73,12 @@ TEST(ContractInstanceRetrievalConstrainingTest, CompleteValidTrace) const auto current_class_id = FF(0xdeadbeefULL); const auto original_class_id = FF(0xcafebabeULL); const auto init_hash = FF(0x11111111ULL); - const auto nullifier_key_x = FF(0x100); - const auto nullifier_key_y = FF(0x101); + const auto immutables_hash = FF(0x22222222ULL); + const auto nullifier_key_hash = FF(0x100); const auto incoming_viewing_key_x = FF(0x200); const auto incoming_viewing_key_y = FF(0x201); - const auto outgoing_viewing_key_x = FF(0x300); - const auto outgoing_viewing_key_y = FF(0x301); - const auto tagging_key_x = FF(0x400); - const auto tagging_key_y = FF(0x401); + const auto outgoing_viewing_key_hash = FF(0x300); + const auto tagging_key_hash = FF(0x400); // Test complete valid trace with all constraints TestTraceContainer trace({ @@ -92,19 +91,17 @@ TEST(ContractInstanceRetrievalConstrainingTest, CompleteValidTrace) { C::contract_instance_retrieval_current_class_id, current_class_id }, { C::contract_instance_retrieval_original_class_id, original_class_id }, { C::contract_instance_retrieval_init_hash, init_hash }, + { C::contract_instance_retrieval_immutables_hash, immutables_hash }, { C::contract_instance_retrieval_public_data_tree_root, public_data_tree_root }, { C::contract_instance_retrieval_nullifier_tree_root, nullifier_tree_root }, { C::contract_instance_retrieval_nullifier_tree_height, NULLIFIER_TREE_HEIGHT }, { C::contract_instance_retrieval_nullifier_merkle_separator, DOM_SEP__NULLIFIER_MERKLE }, { C::contract_instance_retrieval_siloing_separator, DOM_SEP__SILOED_NULLIFIER }, - { C::contract_instance_retrieval_nullifier_key_x, nullifier_key_x }, - { C::contract_instance_retrieval_nullifier_key_y, nullifier_key_y }, + { C::contract_instance_retrieval_nullifier_key_hash, nullifier_key_hash }, { C::contract_instance_retrieval_incoming_viewing_key_x, incoming_viewing_key_x }, { C::contract_instance_retrieval_incoming_viewing_key_y, incoming_viewing_key_y }, - { C::contract_instance_retrieval_outgoing_viewing_key_x, outgoing_viewing_key_x }, - { C::contract_instance_retrieval_outgoing_viewing_key_y, outgoing_viewing_key_y }, - { C::contract_instance_retrieval_tagging_key_x, tagging_key_x }, - { C::contract_instance_retrieval_tagging_key_y, tagging_key_y }, + { C::contract_instance_retrieval_outgoing_viewing_key_hash, outgoing_viewing_key_hash }, + { C::contract_instance_retrieval_tagging_key_hash, tagging_key_hash }, { C::contract_instance_retrieval_deployer_protocol_contract_address, CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS }, // Protocol Contract conditionals @@ -147,23 +144,20 @@ TEST(ContractInstanceRetrievalConstrainingTest, MultipleInstancesTrace) { C::contract_instance_retrieval_current_class_id, contract_instance.current_contract_class_id }, { C::contract_instance_retrieval_original_class_id, contract_instance.original_contract_class_id }, { C::contract_instance_retrieval_init_hash, contract_instance.initialization_hash }, + { C::contract_instance_retrieval_immutables_hash, contract_instance.immutables_hash }, { C::contract_instance_retrieval_public_data_tree_root, FF(base_public_data_tree_root + i) }, { C::contract_instance_retrieval_nullifier_tree_root, FF(base_nullifier_tree_root + i) }, { C::contract_instance_retrieval_nullifier_tree_height, NULLIFIER_TREE_HEIGHT }, { C::contract_instance_retrieval_nullifier_merkle_separator, DOM_SEP__NULLIFIER_MERKLE }, { C::contract_instance_retrieval_siloing_separator, DOM_SEP__SILOED_NULLIFIER }, - { C::contract_instance_retrieval_nullifier_key_x, contract_instance.public_keys.nullifier_key.x }, - { C::contract_instance_retrieval_nullifier_key_y, contract_instance.public_keys.nullifier_key.y }, + { C::contract_instance_retrieval_nullifier_key_hash, contract_instance.public_keys.nullifier_key_hash }, { C::contract_instance_retrieval_incoming_viewing_key_x, contract_instance.public_keys.incoming_viewing_key.x }, { C::contract_instance_retrieval_incoming_viewing_key_y, contract_instance.public_keys.incoming_viewing_key.y }, - { C::contract_instance_retrieval_outgoing_viewing_key_x, - contract_instance.public_keys.outgoing_viewing_key.x }, - { C::contract_instance_retrieval_outgoing_viewing_key_y, - contract_instance.public_keys.outgoing_viewing_key.y }, - { C::contract_instance_retrieval_tagging_key_x, contract_instance.public_keys.tagging_key.x }, - { C::contract_instance_retrieval_tagging_key_y, contract_instance.public_keys.tagging_key.y }, + { C::contract_instance_retrieval_outgoing_viewing_key_hash, + contract_instance.public_keys.outgoing_viewing_key_hash }, + { C::contract_instance_retrieval_tagging_key_hash, contract_instance.public_keys.tagging_key_hash }, { C::contract_instance_retrieval_deployer_protocol_contract_address, CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS }, // Protocol Contract conditionals @@ -199,6 +193,7 @@ TEST(ContractInstanceRetrievalConstrainingTest, NonExistentInstanceTrace) { C::contract_instance_retrieval_current_class_id, 0 }, { C::contract_instance_retrieval_original_class_id, 0 }, { C::contract_instance_retrieval_init_hash, 0 }, + { C::contract_instance_retrieval_immutables_hash, 0 }, { C::contract_instance_retrieval_public_data_tree_root, public_data_tree_root }, { C::contract_instance_retrieval_nullifier_tree_root, nullifier_tree_root }, { C::contract_instance_retrieval_nullifier_tree_height, NULLIFIER_TREE_HEIGHT }, @@ -242,6 +237,12 @@ TEST(ContractInstanceRetrievalConstrainingTest, NonExistentInstanceTrace) "INSTANCE_MEMBER_INIT_HASH_IS_ZERO_IF_DNE"); // reset trace.set(C::contract_instance_retrieval_init_hash, 1, 0); + // mutate immutables_hash + trace.set(C::contract_instance_retrieval_immutables_hash, 1, 1); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace), + "INSTANCE_MEMBER_IMMUTABLES_HASH_IS_ZERO_IF_DNE"); + // reset + trace.set(C::contract_instance_retrieval_immutables_hash, 1, 0); } TEST(ContractInstanceRetrievalConstrainingTest, MaximumFieldValuesTrace) @@ -260,19 +261,17 @@ TEST(ContractInstanceRetrievalConstrainingTest, MaximumFieldValuesTrace) { C::contract_instance_retrieval_current_class_id, max_field }, { C::contract_instance_retrieval_original_class_id, max_field }, { C::contract_instance_retrieval_init_hash, max_field }, + { C::contract_instance_retrieval_immutables_hash, max_field }, { C::contract_instance_retrieval_public_data_tree_root, max_field }, { C::contract_instance_retrieval_nullifier_tree_root, max_field }, { C::contract_instance_retrieval_nullifier_tree_height, NULLIFIER_TREE_HEIGHT }, { C::contract_instance_retrieval_nullifier_merkle_separator, DOM_SEP__NULLIFIER_MERKLE }, { C::contract_instance_retrieval_siloing_separator, DOM_SEP__SILOED_NULLIFIER }, - { C::contract_instance_retrieval_nullifier_key_x, max_field }, - { C::contract_instance_retrieval_nullifier_key_y, max_field }, + { C::contract_instance_retrieval_nullifier_key_hash, max_field }, { C::contract_instance_retrieval_incoming_viewing_key_x, max_field }, { C::contract_instance_retrieval_incoming_viewing_key_y, max_field }, - { C::contract_instance_retrieval_outgoing_viewing_key_x, max_field }, - { C::contract_instance_retrieval_outgoing_viewing_key_y, max_field }, - { C::contract_instance_retrieval_tagging_key_x, max_field }, - { C::contract_instance_retrieval_tagging_key_y, max_field }, + { C::contract_instance_retrieval_outgoing_viewing_key_hash, max_field }, + { C::contract_instance_retrieval_tagging_key_hash, max_field }, { C::contract_instance_retrieval_deployer_protocol_contract_address, CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS }, // Protocol Contract conditionals @@ -460,14 +459,13 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenValidInstance { C::address_derivation_deployer_addr, contract_instance_data.deployer }, { C::address_derivation_class_id, contract_instance_data.original_contract_class_id }, { C::address_derivation_init_hash, contract_instance_data.initialization_hash }, - { C::address_derivation_nullifier_key_x, contract_instance_data.public_keys.nullifier_key.x }, - { C::address_derivation_nullifier_key_y, contract_instance_data.public_keys.nullifier_key.y }, + { C::address_derivation_immutables_hash, contract_instance_data.immutables_hash }, + { C::address_derivation_nullifier_key_hash, contract_instance_data.public_keys.nullifier_key_hash }, { C::address_derivation_incoming_viewing_key_x, contract_instance_data.public_keys.incoming_viewing_key.x }, { C::address_derivation_incoming_viewing_key_y, contract_instance_data.public_keys.incoming_viewing_key.y }, - { C::address_derivation_outgoing_viewing_key_x, contract_instance_data.public_keys.outgoing_viewing_key.x }, - { C::address_derivation_outgoing_viewing_key_y, contract_instance_data.public_keys.outgoing_viewing_key.y }, - { C::address_derivation_tagging_key_x, contract_instance_data.public_keys.tagging_key.x }, - { C::address_derivation_tagging_key_y, contract_instance_data.public_keys.tagging_key.y }, + { C::address_derivation_outgoing_viewing_key_hash, + contract_instance_data.public_keys.outgoing_viewing_key_hash }, + { C::address_derivation_tagging_key_hash, contract_instance_data.public_keys.tagging_key_hash }, // For update check lookup { C::update_check_sel, 1 }, { C::update_check_address, contract_address }, @@ -535,18 +533,16 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenNonExistentIn // For address derivation lookup { C::address_derivation_sel, 0 }, // Not selected since nullifier doesn't exist { C::address_derivation_address, contract_address }, - { C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_nullifier_key_x, 0 }, - { C::address_derivation_nullifier_key_y, 0 }, + { C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_immutables_hash, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_nullifier_key_hash, 0 }, { C::address_derivation_incoming_viewing_key_x, 0 }, { C::address_derivation_incoming_viewing_key_y, 0 }, - { C::address_derivation_outgoing_viewing_key_x, 0 }, - { C::address_derivation_outgoing_viewing_key_y, 0 }, - { C::address_derivation_tagging_key_x, 0 }, - { C::address_derivation_tagging_key_y, 0 }, + { C::address_derivation_outgoing_viewing_key_hash, 0 }, + { C::address_derivation_tagging_key_hash, 0 }, // For update check lookup (only populated when nullifier exists) { C::update_check_sel, 0 }, // Not selected since nullifier doesn't exist { C::update_check_address, contract_address }, @@ -616,18 +612,16 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenAddressZero) // For address derivation lookup { C::address_derivation_sel, 0 }, // Not selected since nullifier doesn't exist { C::address_derivation_address, contract_address }, - { C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_nullifier_key_x, 0 }, - { C::address_derivation_nullifier_key_y, 0 }, + { C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_immutables_hash, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_nullifier_key_hash, 0 }, { C::address_derivation_incoming_viewing_key_x, 0 }, { C::address_derivation_incoming_viewing_key_y, 0 }, - { C::address_derivation_outgoing_viewing_key_x, 0 }, - { C::address_derivation_outgoing_viewing_key_y, 0 }, - { C::address_derivation_tagging_key_x, 0 }, - { C::address_derivation_tagging_key_y, 0 }, + { C::address_derivation_outgoing_viewing_key_hash, 0 }, + { C::address_derivation_tagging_key_hash, 0 }, // For update check lookup (only populated when nullifier exists) { C::update_check_sel, 0 }, // Not selected since nullifier doesn't exist { C::update_check_address, contract_address }, @@ -710,18 +704,15 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenMultipleInsta { C::address_derivation_deployer_addr, contract_instance_data.deployer }, { C::address_derivation_class_id, contract_instance_data.original_contract_class_id }, { C::address_derivation_init_hash, contract_instance_data.initialization_hash }, - { C::address_derivation_nullifier_key_x, contract_instance_data.public_keys.nullifier_key.x }, - { C::address_derivation_nullifier_key_y, contract_instance_data.public_keys.nullifier_key.y }, + { C::address_derivation_immutables_hash, contract_instance_data.immutables_hash }, + { C::address_derivation_nullifier_key_hash, contract_instance_data.public_keys.nullifier_key_hash }, { C::address_derivation_incoming_viewing_key_x, contract_instance_data.public_keys.incoming_viewing_key.x }, { C::address_derivation_incoming_viewing_key_y, contract_instance_data.public_keys.incoming_viewing_key.y }, - { C::address_derivation_outgoing_viewing_key_x, - contract_instance_data.public_keys.outgoing_viewing_key.x }, - { C::address_derivation_outgoing_viewing_key_y, - contract_instance_data.public_keys.outgoing_viewing_key.y }, - { C::address_derivation_tagging_key_x, contract_instance_data.public_keys.tagging_key.x }, - { C::address_derivation_tagging_key_y, contract_instance_data.public_keys.tagging_key.y }, + { C::address_derivation_outgoing_viewing_key_hash, + contract_instance_data.public_keys.outgoing_viewing_key_hash }, + { C::address_derivation_tagging_key_hash, contract_instance_data.public_keys.tagging_key_hash }, // For update check lookup (only when nullifier exists) { C::update_check_sel, 1 }, { C::update_check_address, FF(base_address + i) }, diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp index 50bb15ba3321..cfe37e518bda 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -63,11 +64,11 @@ using simulation::ToRadixMemoryEvent; // Known good points for P and Q FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); -EmbeddedCurvePoint p(p_x, p_y, false); +EmbeddedCurvePoint p(p_x, p_y); FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); -EmbeddedCurvePoint q(q_x, q_y, false); +EmbeddedCurvePoint q(q_x, q_y); TEST(EccAddConstrainingTest, EccEmptyRow) { @@ -79,7 +80,7 @@ TEST(EccAddConstrainingTest, EccAdd) // R = P + Q; FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); auto trace = TestTraceContainer({ { { C::ecc_add_op, 1 }, @@ -102,7 +103,6 @@ TEST(EccAddConstrainingTest, EccAdd) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -123,7 +123,7 @@ TEST(EccAddConstrainingTest, EccDouble) // R = P + P; FF r_x("0x088b996194bb5e6e8e5e49733bb671c3e660cf77254f743f366cc8e33534ee3b"); FF r_y("0x2807ffa01c0f522d0be1e1acfb6914ac8eabf1acf420c0629d37beee992e9a0e"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); auto trace = TestTraceContainer({ { { C::ecc_add_op, 0 }, @@ -146,7 +146,6 @@ TEST(EccAddConstrainingTest, EccDouble) { C::ecc_q_y, p.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -173,13 +172,13 @@ TEST(EccAddConstrainingTest, EccAddSameYDifferentX) // Point P - known valid point on Grumpkin FF local_p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF local_p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint local_p(local_p_x, local_p_y, false); + EmbeddedCurvePoint local_p(local_p_x, local_p_y); // Point Q - p_x * omega (cube root of unity), same y-coordinate! // omega = 0x0000000000000000b3c4d79d41a917585bfc41088d8daaa78b17ea66b99c90dd FF local_q_x("0x14dd39aa19e1c8b29e0c530a28106a7d64d2213486baba3c86dce51bdddf75bb"); FF local_q_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint local_q(local_q_x, local_q_y, false); + EmbeddedCurvePoint local_q(local_q_x, local_q_y); // Verify preconditions: same y, different x ASSERT_NE(local_p.x(), local_q.x()); @@ -188,7 +187,7 @@ TEST(EccAddConstrainingTest, EccAddSameYDifferentX) // Expected result R = P + Q (lambda = 0 since y's are equal) FF local_r_x("0x16bdb7ada0799a3088b9dd3faade12c3f79dbfe9cb1234783a1a7add546398dc"); FF local_r_y("0x2d08e098faf58cb97223d13f2a1b87dd6614173f3cefe87ca6a74e3034c244a1"); - EmbeddedCurvePoint local_r(local_r_x, local_r_y, false); + EmbeddedCurvePoint local_r(local_r_x, local_r_y); // Use simulation to generate events EventEmitter ecc_add_event_emitter; @@ -221,8 +220,8 @@ TEST(EccAddConstrainingTest, EccAddSameYDifferentX) TEST(EccAddConstrainingTest, EccAddResultingInInfinity) { // R = P + (-P) = O; , where O is the point at infinity - EmbeddedCurvePoint q(p.x(), -p.y(), false); - EmbeddedCurvePoint r(0, 0, true); + EmbeddedCurvePoint q(p.x(), -p.y()); + EmbeddedCurvePoint r(0, 0); auto trace = TestTraceContainer({ { { C::ecc_add_op, 0 }, @@ -245,7 +244,6 @@ TEST(EccAddConstrainingTest, EccAddResultingInInfinity) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -261,11 +259,11 @@ TEST(EccAddConstrainingTest, EccAddResultingInInfinity) TEST(EccAddConstrainingTest, EccAddingToInfinity) { - EmbeddedCurvePoint p(0, 0, true); + EmbeddedCurvePoint p(0, 0); // R = O + Q = Q; , where O is the point at infinity - EmbeddedCurvePoint r(q.x(), q.y(), false); + EmbeddedCurvePoint r(q.x(), q.y()); auto trace = TestTraceContainer({ { { C::ecc_add_op, 1 }, @@ -288,7 +286,6 @@ TEST(EccAddConstrainingTest, EccAddingToInfinity) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -304,10 +301,10 @@ TEST(EccAddConstrainingTest, EccAddingToInfinity) TEST(EccAddConstrainingTest, EccAddingInfinity) { - EmbeddedCurvePoint q(0, 0, true); + EmbeddedCurvePoint q(0, 0); // R = P + O = P; , where O is the point at infinity - EmbeddedCurvePoint r(p.x(), p.y(), false); + EmbeddedCurvePoint r(p.x(), p.y()); auto trace = TestTraceContainer({ { { C::ecc_add_op, 1 }, @@ -330,7 +327,6 @@ TEST(EccAddConstrainingTest, EccAddingInfinity) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -347,10 +343,10 @@ TEST(EccAddConstrainingTest, EccAddingInfinity) TEST(EccAddConstrainingTest, EccDoublingInf) { - EmbeddedCurvePoint p(0, 0, true); + EmbeddedCurvePoint p(0, 0); // r = O + O = O; , where O is the point at infinity - EmbeddedCurvePoint r(0, 0, true); + EmbeddedCurvePoint r(0, 0); auto trace = TestTraceContainer({ { { C::ecc_add_op, 0 }, @@ -373,7 +369,6 @@ TEST(EccAddConstrainingTest, EccDoublingInf) { C::ecc_q_y, p.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -414,7 +409,6 @@ TEST(EccAddConstrainingTest, EccTwoOps) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r1.is_infinity()) }, { C::ecc_r_x, r1.x() }, { C::ecc_r_y, r1.y() }, @@ -447,7 +441,6 @@ TEST(EccAddConstrainingTest, EccTwoOps) { C::ecc_q_y, r1.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r2.is_infinity()) }, { C::ecc_r_x, r2.x() }, { C::ecc_r_y, r2.y() }, @@ -469,7 +462,7 @@ TEST(EccAddConstrainingTest, EccNegativeBadAdd) FF r_x("0x20f096ae3de9aea007e0b94a0274b2443d6682d1901f6909f284ec967bc169be"); FF r_y("0x27948713833bb314e828f2b6f45f408da6564a3ac03b9e430a9c6634bb849ef2"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); auto trace = TestTraceContainer({ { { C::ecc_add_op, 1 }, @@ -492,7 +485,6 @@ TEST(EccAddConstrainingTest, EccNegativeBadAdd) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -513,7 +505,7 @@ TEST(EccAddConstrainingTest, EccNegativeBadDouble) FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); auto trace = TestTraceContainer({ { { C::ecc_add_op, 0 }, @@ -536,7 +528,6 @@ TEST(EccAddConstrainingTest, EccNegativeBadDouble) { C::ecc_q_y, p.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -771,40 +762,6 @@ TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinity) EventEmitter scalar_mul_event_emitter; NoopEventEmitter ecc_add_memory_event_emitter; - StrictMock execution_id_manager; - StrictMock gt; - PureToRadix to_radix_simulator = PureToRadix(); - EccSimulator ecc_simulator(execution_id_manager, - gt, - to_radix_simulator, - ecc_add_event_emitter, - scalar_mul_event_emitter, - ecc_add_memory_event_emitter); - - EmbeddedCurvePoint result = ecc_simulator.scalar_mul(EmbeddedCurvePoint::infinity(), FF(10)); - ASSERT_TRUE(result.is_infinity()); - - TestTraceContainer trace({ - { { C::precomputed_first_row, 1 } }, - }); - - builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace); - builder.process_add(ecc_add_event_emitter.dump_events(), trace); - - check_interaction(trace); - - check_relation(trace); - check_relation(trace); -} - -TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinityRep) -{ - EccTraceBuilder builder; - - EventEmitter ecc_add_event_emitter; - EventEmitter scalar_mul_event_emitter; - NoopEventEmitter ecc_add_memory_event_emitter; - StrictMock execution_id_manager; StrictMock gt; PureToRadix to_radix_simulator = PureToRadix(); @@ -816,14 +773,13 @@ TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinityRep) ecc_add_memory_event_emitter); EmbeddedCurvePoint inf = EmbeddedCurvePoint::infinity(); - // EmbeddedCurvePoint preserves raw coordinates (see StandardAffinePointTest) + EmbeddedCurvePoint inf_bb = EmbeddedCurvePoint(avm2::AffinePoint::infinity()); - EmbeddedCurvePoint inf_alt = EmbeddedCurvePoint(1, 2, true); EmbeddedCurvePoint result = ecc_simulator.scalar_mul(inf_bb, FF(10)); ASSERT_TRUE(result.is_infinity()); - result = ecc_simulator.scalar_mul(inf_alt, FF(10)); - ASSERT_TRUE(result.is_infinity()); + EXPECT_EQ(result.x(), inf.x()); + EXPECT_EQ(result.y(), inf.y()); TestTraceContainer trace({ { { C::precomputed_first_row, 1 } }, @@ -1178,16 +1134,14 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInteractions) // Execution { C::execution_sel, 1 }, { C::execution_sel_exec_dispatch_ecc_add, 1 }, - { C::execution_rop_6_, dst_address }, + { C::execution_rop_4_, dst_address }, { C::execution_register_0_, p.x() }, { C::execution_register_1_, p.y() }, - { C::execution_register_2_, p.is_infinity() ? 1 : 0 }, - { C::execution_register_3_, q.x() }, - { C::execution_register_4_, q.y() }, - { C::execution_register_5_, q.is_infinity() ? 1 : 0 }, + { C::execution_register_2_, q.x() }, + { C::execution_register_3_, q.y() }, // GT - dst out of range check { C::gt_sel, 1 }, - { C::gt_input_a, dst_address + 2 }, // highest write address is dst_address + 2 + { C::gt_input_a, dst_address + 1 }, // highest write address is dst_address + 1 { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, { C::gt_res, 0 }, // Memory Writes @@ -1205,14 +1159,6 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInteractions) { C::memory_rw, 1 }, // write { C::memory_tag, static_cast(MemoryTag::FF) }, }, - { - // Memory Writes - { C::memory_address, dst_address + 2 }, - { C::memory_value, result.is_infinity() }, - { C::memory_sel, 1 }, - { C::memory_rw, 1 }, // write - { C::memory_tag, static_cast(MemoryTag::U1) }, - }, }); ecc_simulator.add(memory, p, q, dst_address); @@ -1237,7 +1183,7 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInvalidDstRange) StrictMock execution_id_manager; EXPECT_CALL(execution_id_manager, get_execution_id) - .WillRepeatedly(Return(0)); // Use a fixed execution IDfor the test + .WillRepeatedly(Return(0)); // Use a fixed execution ID for the test PureGreaterThan gt; PureToRadix to_radix_simulator = PureToRadix(); @@ -1248,7 +1194,7 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInvalidDstRange) scalar_mul_event_emitter, ecc_add_memory_event_emitter); - uint32_t dst_address = AVM_HIGHEST_MEM_ADDRESS - 1; // Invalid address, will result in out of range error + uint32_t dst_address = AVM_HIGHEST_MEM_ADDRESS; // Invalid address, will result in out of range error // Set the execution and gt traces TestTraceContainer trace = TestTraceContainer({ // Row 0 @@ -1256,17 +1202,15 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInvalidDstRange) // Execution { C::execution_sel, 1 }, { C::execution_sel_exec_dispatch_ecc_add, 1 }, - { C::execution_rop_6_, dst_address }, + { C::execution_rop_4_, dst_address }, { C::execution_register_0_, p.x() }, { C::execution_register_1_, p.y() }, - { C::execution_register_2_, p.is_infinity() ? 1 : 0 }, - { C::execution_register_3_, q.x() }, - { C::execution_register_4_, q.y() }, - { C::execution_register_5_, q.is_infinity() ? 1 : 0 }, + { C::execution_register_2_, q.x() }, + { C::execution_register_3_, q.y() }, { C::execution_sel_opcode_error, 1 }, // GT - dst out of range check { C::gt_sel, 1 }, - { C::gt_input_a, static_cast(dst_address) + 2 }, + { C::gt_input_a, static_cast(dst_address) + 1 }, { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, { C::gt_res, 1 }, }, @@ -1306,7 +1250,7 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryPointError) // Point P is not on the curve FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); uint32_t dst_address = 0x1000; @@ -1318,17 +1262,15 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryPointError) // Execution { C::execution_sel, 1 }, { C::execution_sel_exec_dispatch_ecc_add, 1 }, - { C::execution_rop_6_, dst_address }, + { C::execution_rop_4_, dst_address }, { C::execution_register_0_, p.x() }, { C::execution_register_1_, p.y() }, - { C::execution_register_2_, p.is_infinity() ? 1 : 0 }, - { C::execution_register_3_, q.x() }, - { C::execution_register_4_, q.y() }, - { C::execution_register_5_, q.is_infinity() ? 1 : 0 }, + { C::execution_register_2_, q.x() }, + { C::execution_register_3_, q.y() }, { C::execution_sel_opcode_error, 1 }, // Indicate an error in the operation // GT - dst out of range check { C::gt_sel, 1 }, - { C::gt_input_a, dst_address + 2 }, // highest write address is dst_address + 2 + { C::gt_input_a, dst_address + 1 }, // highest write address is dst_address + 1 { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, { C::gt_res, 0 }, }, @@ -1368,42 +1310,23 @@ TEST(EccAddMemoryConstrainingTest, InfinityRepresentations) // Point P is infinity EmbeddedCurvePoint inf = EmbeddedCurvePoint::infinity(); - // EmbeddedCurvePoint preserves raw coordinates (see StandardAffinePointTest) + // EmbeddedCurvePoint always sets extractable coordinates as (0,0) and the underlying point as + // AffinePoint::infinity() for input infinity points. EmbeddedCurvePoint inf_bb = EmbeddedCurvePoint(avm2::AffinePoint::infinity()); - EmbeddedCurvePoint inf_alt = EmbeddedCurvePoint(1, 2, true); + EXPECT_EQ(inf_bb, inf); TestTraceContainer trace; - // Internal add() expects normalized points: - EXPECT_THROW_WITH_MESSAGE(ecc_simulator.add(inf, inf_alt), "normalized"); - - // Coordinates are normalized in tracegen, so even though inf_bb and inf_alt have different coordinates, the circuit - // correctly assigns double_op = true when doubling inf: - ecc_simulator.add(memory, inf, inf_alt, dst_address); - // As above for the noir (0, 0) and bb (x, 0) inf reps: - ecc_simulator.add(memory, inf, inf_bb, dst_address + 3); + // The circuit correctly assigns double_op = true when doubling inf: + ecc_simulator.add(memory, inf, inf_bb, dst_address); builder.process_add(ecc_add_event_emitter.dump_events(), trace); check_relation(trace); EXPECT_EQ(trace.get(C::ecc_double_op, 0), 1); + ecc_simulator.add(memory, inf, inf_bb, dst_address); + // Set memory reads: trace.set(0, - { { // Execution - { C::execution_sel, 1 }, - { C::execution_sel_exec_dispatch_ecc_add, 1 }, - { C::execution_rop_6_, dst_address }, - { C::execution_register_0_, inf.x() }, - { C::execution_register_1_, inf.y() }, - { C::execution_register_2_, inf.is_infinity() ? 1 : 0 }, - { C::execution_register_3_, inf_alt.x() }, - { C::execution_register_4_, inf_alt.y() }, - { C::execution_register_5_, inf_alt.is_infinity() ? 1 : 0 }, - // GT - dst out of range check - { C::gt_sel, 1 }, - { C::gt_input_a, dst_address + 2 }, // highest write address is dst_address + 2 - { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, - { C::gt_res, 0 } } }); - trace.set(1, { { // Execution { C::execution_sel, 1 }, { C::execution_sel_exec_dispatch_ecc_add, 1 }, @@ -1416,22 +1339,21 @@ TEST(EccAddMemoryConstrainingTest, InfinityRepresentations) { C::execution_register_5_, inf_bb.is_infinity() ? 1 : 0 }, // GT - dst out of range check { C::gt_sel, 1 }, - { C::gt_input_a, dst_address + 5 }, + { C::gt_input_a, dst_address + 2 }, { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, { C::gt_res, 0 } } }); builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace); - // The original coordinates are stored in memory for the read... - EXPECT_EQ(trace.get(C::ecc_add_mem_q_x, 1), inf_bb.x()); - EXPECT_EQ(trace.get(C::ecc_add_mem_q_y, 1), inf_bb.y()); - // ...but normalised coordinates are sent to the ecc subtrace: - EXPECT_EQ(trace.get(C::ecc_add_mem_q_x_n, 1), 0); - EXPECT_EQ(trace.get(C::ecc_add_mem_q_y_n, 1), 0); - check_relation(trace); - check_relation(trace); - check_all_interactions(trace); - check_interaction(trace); + // The derived is_inf column must be true if the coordinates are (0, 0): + trace.set(C::ecc_add_mem_p_is_inf, 0, 0); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, mem_aware_ecc::SR_P_CURVE_EQN), "P_CURVE_EQN"); + + // If is_inf is set, the coordinates must be (0, 0): + trace.set(C::ecc_add_mem_q_x, 0, 1); + trace.set(C::ecc_add_mem_q_y, 0, 2); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, mem_aware_ecc::SR_Q_INF_X_CHECK), "Q_INF_X_CHECK"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, mem_aware_ecc::SR_Q_INF_Y_CHECK), "Q_INF_Y_CHECK"); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp index 30337347c8de..3ac442fe3116 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp @@ -141,6 +141,7 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint) const FF deployer_addr = 0x1234; const FF class_id = 0x5678; const FF init_hash = 0x9ABC; + const FF immutables_hash = 0xCAFE; const FF wrong_value = 0x1111; // Test selected member subrelation @@ -152,9 +153,11 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint) { C::get_contract_instance_is_deployer, 1 }, { C::get_contract_instance_is_class_id, 0 }, { C::get_contract_instance_is_init_hash, 0 }, + { C::get_contract_instance_is_immutables_hash, 0 }, { C::get_contract_instance_retrieved_deployer_addr, deployer_addr }, { C::get_contract_instance_retrieved_class_id, class_id }, - { C::get_contract_instance_retrieved_init_hash, init_hash } }, + { C::get_contract_instance_retrieved_init_hash, init_hash }, + { C::get_contract_instance_retrieved_immutables_hash, immutables_hash } }, }); check_relation(trace, get_contract_instance::SR_SELECTED_MEMBER); @@ -171,6 +174,12 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint) trace.set(C::get_contract_instance_is_init_hash, 1, 1); check_relation(trace, get_contract_instance::SR_SELECTED_MEMBER); + // Test IMMUTABLES_HASH selection + trace.set(C::get_contract_instance_selected_member, 1, immutables_hash); + trace.set(C::get_contract_instance_is_init_hash, 1, 0); + trace.set(C::get_contract_instance_is_immutables_hash, 1, 1); + check_relation(trace, get_contract_instance::SR_SELECTED_MEMBER); + // Negative test: wrong selected member trace.set(C::get_contract_instance_selected_member, 1, wrong_value); // Wrong value EXPECT_THROW_WITH_MESSAGE(check_relation(trace, get_contract_instance::SR_SELECTED_MEMBER), diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp index 3ab83cac013e..16b5e1b14b22 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp @@ -96,9 +96,7 @@ TEST(InstrFetchingConstrainingTest, EcaddWithTraceGen) Operand::from(0x127a), Operand::from(0x127b), Operand::from(0x127c), - Operand::from(0x127d), - Operand::from(0x127e), - Operand::from(0x127f) }, + Operand::from(0x127d), }, }; std::vector bytecode = ecadd_instruction.serialize(); diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp index 3d1bfac00e40..55bf30c6aac7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp @@ -7,9 +7,9 @@ namespace bb::avm2 { // clang-format off -#define AVM2_PRECOMPUTED_ENTITIES_E(e) e precomputed_addressing_gas, e precomputed_bitwise_input_a, e precomputed_bitwise_input_b, e precomputed_bitwise_output_and, e precomputed_bitwise_output_or, e precomputed_bitwise_output_xor, e precomputed_dyn_gas_id, e precomputed_envvar_pi_row_idx, e precomputed_exec_opcode, e precomputed_exec_opcode_base_da_gas, e precomputed_exec_opcode_dynamic_da_gas, e precomputed_exec_opcode_dynamic_l2_gas, e precomputed_exec_opcode_opcode_gas, e precomputed_expected_tag_reg_0_, e precomputed_expected_tag_reg_1_, e precomputed_expected_tag_reg_2_, e precomputed_expected_tag_reg_3_, e precomputed_expected_tag_reg_4_, e precomputed_expected_tag_reg_5_, e precomputed_first_row, e precomputed_idx, e precomputed_instr_size, e precomputed_invalid_envvar_enum, e precomputed_is_address, e precomputed_is_class_id, e precomputed_is_cleanup, e precomputed_is_collect_fee, e precomputed_is_dagasleft, e precomputed_is_deployer, e precomputed_is_init_hash, e precomputed_is_isstaticcall, e precomputed_is_l2gasleft, e precomputed_is_public_call_request, e precomputed_is_revertible, e precomputed_is_sender, e precomputed_is_teardown, e precomputed_is_transactionfee, e precomputed_is_tree_padding, e precomputed_is_valid_member_enum, e precomputed_keccak_round_constant, e precomputed_next_phase_on_revert, e precomputed_opcode_out_of_range, e precomputed_out_tag, e precomputed_p_decomposition_limb, e precomputed_p_decomposition_limb_index, e precomputed_p_decomposition_radix, e precomputed_power_of_2, e precomputed_read_pi_length_offset, e precomputed_read_pi_start_offset, e precomputed_rw_reg_0_, e precomputed_rw_reg_1_, e precomputed_rw_reg_2_, e precomputed_rw_reg_3_, e precomputed_rw_reg_4_, e precomputed_rw_reg_5_, e precomputed_sel_addressing_gas, e precomputed_sel_append_l2_l1_msg, e precomputed_sel_append_note_hash, e precomputed_sel_append_nullifier, e precomputed_sel_envvar_pi_lookup_col0, e precomputed_sel_envvar_pi_lookup_col1, e precomputed_sel_exec_spec, e precomputed_sel_has_tag, e precomputed_sel_keccak, e precomputed_sel_mem_op_reg_0_, e precomputed_sel_mem_op_reg_1_, e precomputed_sel_mem_op_reg_2_, e precomputed_sel_mem_op_reg_3_, e precomputed_sel_mem_op_reg_4_, e precomputed_sel_mem_op_reg_5_, e precomputed_sel_mem_tag_out_of_range, e precomputed_sel_op_dc_0, e precomputed_sel_op_dc_1, e precomputed_sel_op_dc_10, e precomputed_sel_op_dc_11, e precomputed_sel_op_dc_12, e precomputed_sel_op_dc_13, e precomputed_sel_op_dc_14, e precomputed_sel_op_dc_15, e precomputed_sel_op_dc_16, e precomputed_sel_op_dc_2, e precomputed_sel_op_dc_3, e precomputed_sel_op_dc_4, e precomputed_sel_op_dc_5, e precomputed_sel_op_dc_6, e precomputed_sel_op_dc_7, e precomputed_sel_op_dc_8, e precomputed_sel_op_dc_9, e precomputed_sel_op_is_address_0_, e precomputed_sel_op_is_address_1_, e precomputed_sel_op_is_address_2_, e precomputed_sel_op_is_address_3_, e precomputed_sel_op_is_address_4_, e precomputed_sel_op_is_address_5_, e precomputed_sel_op_is_address_6_, e precomputed_sel_p_decomposition, e precomputed_sel_phase, e precomputed_sel_range_16, e precomputed_sel_range_8, e precomputed_sel_sha256_compression, e precomputed_sel_tag_check_reg_0_, e precomputed_sel_tag_check_reg_1_, e precomputed_sel_tag_check_reg_2_, e precomputed_sel_tag_check_reg_3_, e precomputed_sel_tag_check_reg_4_, e precomputed_sel_tag_check_reg_5_, e precomputed_sel_tag_is_op2, e precomputed_sel_tag_parameters, e precomputed_sel_to_radix_p_limb_counts, e precomputed_sha256_compression_round_constant, e precomputed_subtrace_id, e precomputed_subtrace_operation_id, e precomputed_tag_byte_length, e precomputed_tag_max_bits, e precomputed_tag_max_value, e precomputed_to_radix_num_limbs_for_p, e precomputed_to_radix_safe_limbs, e precomputed_zero, e public_inputs_sel -#define AVM2_WIRE_ENTITIES_E(e) e public_inputs_cols_0_, e public_inputs_cols_1_, e public_inputs_cols_2_, e public_inputs_cols_3_, e address_derivation_address, e address_derivation_address_y, e address_derivation_class_id, e address_derivation_const_four, e address_derivation_const_thirteen, e address_derivation_const_three, e address_derivation_const_two, e address_derivation_deployer_addr, e address_derivation_g1_x, e address_derivation_g1_y, e address_derivation_incoming_viewing_key_x, e address_derivation_incoming_viewing_key_y, e address_derivation_init_hash, e address_derivation_nullifier_key_x, e address_derivation_nullifier_key_y, e address_derivation_outgoing_viewing_key_x, e address_derivation_outgoing_viewing_key_y, e address_derivation_partial_address, e address_derivation_partial_address_domain_separator, e address_derivation_preaddress, e address_derivation_preaddress_domain_separator, e address_derivation_preaddress_public_key_x, e address_derivation_preaddress_public_key_y, e address_derivation_public_keys_hash, e address_derivation_public_keys_hash_domain_separator, e address_derivation_salt, e address_derivation_salted_init_hash, e address_derivation_salted_init_hash_domain_separator, e address_derivation_sel, e address_derivation_tagging_key_x, e address_derivation_tagging_key_y, e alu_a_hi, e alu_a_hi_bits, e alu_a_lo, e alu_a_lo_bits, e alu_ab_diff_inv, e alu_ab_tags_diff_inv, e alu_b_hi, e alu_b_inv, e alu_b_lo, e alu_c_hi, e alu_cf, e alu_constant_64, e alu_gt_input_a, e alu_gt_input_b, e alu_gt_result_c, e alu_helper1, e alu_ia, e alu_ia_tag, e alu_ib, e alu_ib_tag, e alu_ic, e alu_ic_tag, e alu_max_bits, e alu_max_value, e alu_mid, e alu_mid_bits, e alu_op_id, e alu_sel, e alu_sel_ab_tag_mismatch, e alu_sel_decompose_a, e alu_sel_div_0_err, e alu_sel_div_no_err, e alu_sel_err, e alu_sel_ff_gt, e alu_sel_int_gt, e alu_sel_is_ff, e alu_sel_is_u128, e alu_sel_mul_div_u128, e alu_sel_mul_no_err_non_ff, e alu_sel_op_add, e alu_sel_op_div, e alu_sel_op_eq, e alu_sel_op_fdiv, e alu_sel_op_lt, e alu_sel_op_lte, e alu_sel_op_mul, e alu_sel_op_not, e alu_sel_op_shl, e alu_sel_op_shr, e alu_sel_op_sub, e alu_sel_op_truncate, e alu_sel_shift_ops_no_overflow, e alu_sel_tag_err, e alu_sel_trunc_gte_128, e alu_sel_trunc_lt_128, e alu_sel_trunc_non_trivial, e alu_sel_trunc_trivial, e alu_shift_lo_bits, e alu_tag_ff_diff_inv, e alu_tag_u128_diff_inv, e alu_two_pow_shift_lo_bits, e bc_decomposition_bytes_pc_plus_36, e bc_decomposition_bytes_rem_inv, e bc_decomposition_bytes_rem_min_one_inv, e bc_decomposition_bytes_to_read, e bc_decomposition_last_of_contract, e bc_decomposition_next_packed_pc_min_pc_inv, e bc_decomposition_packed_field, e bc_decomposition_sel_packed, e bc_decomposition_sel_packed_read_0_, e bc_decomposition_sel_packed_read_1_, e bc_decomposition_sel_packed_read_2_, e bc_decomposition_sel_windows_eq_remaining, e bc_decomposition_windows_min_remaining_inv, e bc_hashing_end, e bc_hashing_input_len, e bc_hashing_packed_fields_0, e bc_hashing_packed_fields_1, e bc_hashing_packed_fields_2, e bc_hashing_pc_index, e bc_hashing_pc_index_2, e bc_hashing_sel_not_padding_1, e bc_hashing_sel_not_padding_2, e bc_hashing_size_in_bytes, e bc_retrieval_address, e bc_retrieval_artifact_hash, e bc_retrieval_bytecode_id, e bc_retrieval_current_class_id, e bc_retrieval_error, e bc_retrieval_instance_exists, e bc_retrieval_is_new_class, e bc_retrieval_next_retrieved_bytecodes_tree_root, e bc_retrieval_next_retrieved_bytecodes_tree_size, e bc_retrieval_no_remaining_bytecodes, e bc_retrieval_nullifier_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_size, e bc_retrieval_private_functions_root, e bc_retrieval_public_data_tree_root, e bc_retrieval_remaining_bytecodes_inv, e bc_retrieval_retrieved_bytecodes_merkle_separator, e bc_retrieval_retrieved_bytecodes_tree_height, e bc_retrieval_sel, e bc_retrieval_should_retrieve, e bitwise_ctr_min_one_inv, e bitwise_end, e bitwise_err, e bitwise_ia_byte, e bitwise_ib_byte, e bitwise_ic_byte, e bitwise_output_and, e bitwise_output_or, e bitwise_output_xor, e bitwise_sel_and, e bitwise_sel_compute, e bitwise_sel_get_ctr, e bitwise_sel_or, e bitwise_sel_tag_ff_err, e bitwise_sel_tag_mismatch_err, e bitwise_sel_xor, e bitwise_start_keccak, e bitwise_start_sha256, e bitwise_tag_a, e bitwise_tag_a_inv, e bitwise_tag_ab_diff_inv, e bitwise_tag_b, e bitwise_tag_c, e calldata_end, e calldata_hashing_end, e calldata_hashing_index_1_, e calldata_hashing_index_2_, e calldata_hashing_input_0_, e calldata_hashing_input_1_, e calldata_hashing_input_2_, e calldata_hashing_input_len, e calldata_hashing_sel_end_not_empty, e calldata_hashing_sel_not_padding_1, e calldata_hashing_sel_not_padding_2, e calldata_hashing_sel_not_start, e calldata_value, e class_id_derivation_artifact_hash, e class_id_derivation_class_id, e class_id_derivation_const_four, e class_id_derivation_gen_index_contract_class_id, e class_id_derivation_private_functions_root, e class_id_derivation_public_bytecode_commitment, e class_id_derivation_sel, e context_stack_bytecode_id, e context_stack_context_id, e context_stack_contract_address, e context_stack_entered_context_id, e context_stack_internal_call_id, e context_stack_internal_call_return_id, e context_stack_is_static, e context_stack_msg_sender, e context_stack_next_internal_call_id, e context_stack_next_pc, e context_stack_note_hash_tree_root, e context_stack_note_hash_tree_size, e context_stack_nullifier_tree_root, e context_stack_nullifier_tree_size, e context_stack_num_l2_to_l1_messages, e context_stack_num_note_hashes_emitted, e context_stack_num_nullifiers_emitted, e context_stack_num_public_log_fields, e context_stack_parent_calldata_addr, e context_stack_parent_calldata_size, e context_stack_parent_da_gas_limit, e context_stack_parent_da_gas_used, e context_stack_parent_id, e context_stack_parent_l2_gas_limit, e context_stack_parent_l2_gas_used, e context_stack_public_data_tree_root, e context_stack_public_data_tree_size, e context_stack_sel, e context_stack_written_public_data_slots_tree_root, e context_stack_written_public_data_slots_tree_size, e contract_instance_retrieval_address, e contract_instance_retrieval_address_sub_one, e contract_instance_retrieval_current_class_id, e contract_instance_retrieval_deployer_addr, e contract_instance_retrieval_deployer_protocol_contract_address, e contract_instance_retrieval_derived_address, e contract_instance_retrieval_derived_address_pi_index, e contract_instance_retrieval_exists, e contract_instance_retrieval_incoming_viewing_key_x, e contract_instance_retrieval_incoming_viewing_key_y, e contract_instance_retrieval_init_hash, e contract_instance_retrieval_is_protocol_contract, e contract_instance_retrieval_max_protocol_contracts, e contract_instance_retrieval_nullifier_key_x, e contract_instance_retrieval_nullifier_key_y, e contract_instance_retrieval_nullifier_merkle_separator, e contract_instance_retrieval_nullifier_tree_height, e contract_instance_retrieval_nullifier_tree_root, e contract_instance_retrieval_original_class_id, e contract_instance_retrieval_outgoing_viewing_key_x, e contract_instance_retrieval_outgoing_viewing_key_y, e contract_instance_retrieval_protocol_contract_derived_address_inv, e contract_instance_retrieval_public_data_tree_root, e contract_instance_retrieval_salt, e contract_instance_retrieval_sel, e contract_instance_retrieval_should_check_for_update, e contract_instance_retrieval_should_check_nullifier, e contract_instance_retrieval_siloing_separator, e contract_instance_retrieval_tagging_key_x, e contract_instance_retrieval_tagging_key_y, e data_copy_cd_copy_col_read, e data_copy_clamped_read_index_upper_bound, e data_copy_dst_out_of_range_err, e data_copy_end, e data_copy_is_top_level, e data_copy_mem_size, e data_copy_offset, e data_copy_offset_plus_size, e data_copy_offset_plus_size_is_gt, e data_copy_parent_id_inv, e data_copy_read_addr_plus_one, e data_copy_read_addr_upper_bound, e data_copy_reads_left_inv, e data_copy_sel_cd_copy_start, e data_copy_sel_has_reads, e data_copy_sel_mem_read, e data_copy_sel_mem_write, e data_copy_sel_rd_copy_start, e data_copy_sel_write_count_is_zero, e data_copy_src_addr, e data_copy_src_data_size, e data_copy_src_reads_exceed_mem, e data_copy_start_no_err, e data_copy_tag, e data_copy_value, e data_copy_write_addr_upper_bound, e data_copy_write_count_minus_one_inv, e data_copy_write_count_zero_inv, e ecc_add_mem_dst_addr_0_, e ecc_add_mem_dst_addr_1_, e ecc_add_mem_dst_addr_2_, e ecc_add_mem_err, e ecc_add_mem_execution_clk, e ecc_add_mem_max_mem_addr, e ecc_add_mem_p_is_inf, e ecc_add_mem_p_is_on_curve_eqn, e ecc_add_mem_p_is_on_curve_eqn_inv, e ecc_add_mem_p_x, e ecc_add_mem_p_x_n, e ecc_add_mem_p_y, e ecc_add_mem_p_y_n, e ecc_add_mem_q_is_inf, e ecc_add_mem_q_is_on_curve_eqn, e ecc_add_mem_q_is_on_curve_eqn_inv, e ecc_add_mem_q_x, e ecc_add_mem_q_x_n, e ecc_add_mem_q_y, e ecc_add_mem_q_y_n, e ecc_add_mem_res_is_inf, e ecc_add_mem_res_x, e ecc_add_mem_res_y, e ecc_add_mem_sel, e ecc_add_mem_sel_dst_out_of_range_err, e ecc_add_mem_sel_p_not_on_curve_err, e ecc_add_mem_sel_q_not_on_curve_err, e ecc_add_mem_sel_should_exec, e ecc_add_mem_space_id, e ecc_add_op, e ecc_double_op, e ecc_inv_2_p_y, e ecc_inv_x_diff, e ecc_inv_y_diff, e ecc_lambda, e ecc_p_is_inf, e ecc_p_x, e ecc_p_y, e ecc_q_is_inf, e ecc_q_x, e ecc_q_y, e ecc_r_is_inf, e ecc_r_x, e ecc_r_y, e ecc_result_infinity, e ecc_sel, e ecc_use_computed_result, e ecc_x_match, e ecc_y_match, e emit_public_log_discard, e emit_public_log_end, e emit_public_log_end_log_address_upper_bound, e emit_public_log_error, e emit_public_log_error_too_many_log_fields, e emit_public_log_expected_next_log_fields, e emit_public_log_is_static, e emit_public_log_log_size, e emit_public_log_max_mem_size, e emit_public_log_max_public_logs_payload_length, e emit_public_log_next_num_public_log_fields, e emit_public_log_prev_num_public_log_fields, e emit_public_log_public_inputs_value, e emit_public_log_remaining_rows_inv, e emit_public_log_sel_read_memory, e emit_public_log_tag, e emit_public_log_tag_inv, e emit_public_log_value, e execution_addressing_error_collection_inv, e execution_addressing_gas, e execution_addressing_mode, e execution_base_address_tag, e execution_base_address_tag_diff_inv, e execution_base_address_val, e execution_base_da_gas, e execution_batched_tags_diff_inv, e execution_batched_tags_diff_inv_reg, e execution_da_gas_left, e execution_da_gas_used, e execution_dying_context_diff_inv, e execution_dying_context_id_inv, e execution_dyn_gas_id, e execution_dynamic_da_gas, e execution_dynamic_da_gas_factor, e execution_dynamic_l2_gas, e execution_dynamic_l2_gas_factor, e execution_enqueued_call_end, e execution_envvar_pi_row_idx, e execution_exec_opcode, e execution_expected_tag_reg_0_, e execution_expected_tag_reg_1_, e execution_expected_tag_reg_2_, e execution_expected_tag_reg_3_, e execution_expected_tag_reg_4_, e execution_expected_tag_reg_5_, e execution_has_parent_ctx, e execution_highest_address, e execution_instr_size, e execution_internal_call_return_id_inv, e execution_is_address, e execution_is_da_gas_left_gt_allocated, e execution_is_dagasleft, e execution_is_dying_context, e execution_is_isstaticcall, e execution_is_l2_gas_left_gt_allocated, e execution_is_l2gasleft, e execution_is_parent_id_inv, e execution_is_sender, e execution_is_transactionfee, e execution_l1_to_l2_msg_leaf_in_range, e execution_l1_to_l2_msg_tree_leaf_count, e execution_l2_gas_left, e execution_l2_gas_used, e execution_max_data_writes_reached, e execution_max_eth_address_value, e execution_mem_tag_reg_0_, e execution_mem_tag_reg_1_, e execution_mem_tag_reg_2_, e execution_mem_tag_reg_3_, e execution_mem_tag_reg_4_, e execution_mem_tag_reg_5_, e execution_nested_failure, e execution_nested_return, e execution_next_pc, e execution_note_hash_leaf_in_range, e execution_note_hash_tree_leaf_count, e execution_note_hash_tree_root, e execution_note_hash_tree_size, e execution_nullifier_merkle_separator, e execution_nullifier_pi_offset, e execution_nullifier_siloing_separator, e execution_nullifier_tree_height, e execution_nullifier_tree_root, e execution_nullifier_tree_size, e execution_num_l2_to_l1_messages, e execution_num_note_hashes_emitted, e execution_num_nullifiers_emitted, e execution_num_p_limbs, e execution_num_public_log_fields, e execution_num_relative_operands_inv, e execution_op_0_, e execution_op_1_, e execution_op_2_, e execution_op_3_, e execution_op_4_, e execution_op_5_, e execution_op_6_, e execution_op_after_relative_0_, e execution_op_after_relative_1_, e execution_op_after_relative_2_, e execution_op_after_relative_3_, e execution_op_after_relative_4_, e execution_op_after_relative_5_, e execution_op_after_relative_6_, e execution_opcode_gas, e execution_out_of_gas_da, e execution_out_of_gas_l2, e execution_public_data_tree_root, e execution_public_data_tree_size, e execution_public_inputs_index, e execution_register_0_, e execution_register_1_, e execution_register_2_, e execution_register_3_, e execution_register_4_, e execution_register_5_, e execution_remaining_data_writes_inv, e execution_remaining_l2_to_l1_msgs_inv, e execution_remaining_note_hashes_inv, e execution_remaining_nullifiers_inv, e execution_retrieved_bytecodes_tree_root, e execution_retrieved_bytecodes_tree_size, e execution_rop_0_, e execution_rop_1_, e execution_rop_2_, e execution_rop_3_, e execution_rop_4_, e execution_rop_5_, e execution_rop_6_, e execution_rop_tag_0_, e execution_rop_tag_1_, e execution_rop_tag_2_, e execution_rop_tag_3_, e execution_rop_tag_4_, e execution_rop_tag_5_, e execution_rop_tag_6_, e execution_rw_reg_0_, e execution_rw_reg_1_, e execution_rw_reg_2_, e execution_rw_reg_3_, e execution_rw_reg_4_, e execution_rw_reg_5_, e execution_sel_addressing_error, e execution_sel_apply_indirection_0_, e execution_sel_apply_indirection_1_, e execution_sel_apply_indirection_2_, e execution_sel_apply_indirection_3_, e execution_sel_apply_indirection_4_, e execution_sel_apply_indirection_5_, e execution_sel_apply_indirection_6_, e execution_sel_base_address_failure, e execution_sel_bytecode_retrieval_failure, e execution_sel_bytecode_retrieval_success, e execution_sel_check_gas, e execution_sel_do_base_check, e execution_sel_enter_call, e execution_sel_envvar_pi_lookup_col0, e execution_sel_envvar_pi_lookup_col1, e execution_sel_error, e execution_sel_exec_dispatch_alu, e execution_sel_exec_dispatch_bitwise, e execution_sel_exec_dispatch_calldata_copy, e execution_sel_exec_dispatch_cast, e execution_sel_exec_dispatch_ecc_add, e execution_sel_exec_dispatch_emit_public_log, e execution_sel_exec_dispatch_execution, e execution_sel_exec_dispatch_get_contract_instance, e execution_sel_exec_dispatch_keccakf1600, e execution_sel_exec_dispatch_poseidon2_perm, e execution_sel_exec_dispatch_returndata_copy, e execution_sel_exec_dispatch_set, e execution_sel_exec_dispatch_sha256_compression, e execution_sel_exec_dispatch_to_radix, e execution_sel_execute_call, e execution_sel_execute_debug_log, e execution_sel_execute_emit_notehash, e execution_sel_execute_emit_nullifier, e execution_sel_execute_get_env_var, e execution_sel_execute_internal_call, e execution_sel_execute_internal_return, e execution_sel_execute_jump, e execution_sel_execute_jumpi, e execution_sel_execute_l1_to_l2_message_exists, e execution_sel_execute_mov, e execution_sel_execute_notehash_exists, e execution_sel_execute_nullifier_exists, e execution_sel_execute_opcode, e execution_sel_execute_return, e execution_sel_execute_returndata_size, e execution_sel_execute_revert, e execution_sel_execute_send_l2_to_l1_msg, e execution_sel_execute_sload, e execution_sel_execute_sstore, e execution_sel_execute_static_call, e execution_sel_execute_success_copy, e execution_sel_exit_call, e execution_sel_failure, e execution_sel_gas_bitwise, e execution_sel_gas_calldata_copy, e execution_sel_gas_emit_public_log, e execution_sel_gas_returndata_copy, e execution_sel_gas_sstore, e execution_sel_gas_to_radix, e execution_sel_instruction_fetching_failure, e execution_sel_instruction_fetching_success, e execution_sel_l2_to_l1_msg_limit_error, e execution_sel_lookup_num_p_limbs, e execution_sel_mem_op_reg_0_, e execution_sel_mem_op_reg_1_, e execution_sel_mem_op_reg_2_, e execution_sel_mem_op_reg_3_, e execution_sel_mem_op_reg_4_, e execution_sel_mem_op_reg_5_, e execution_sel_op_do_overflow_check_0_, e execution_sel_op_do_overflow_check_1_, e execution_sel_op_do_overflow_check_2_, e execution_sel_op_do_overflow_check_3_, e execution_sel_op_do_overflow_check_4_, e execution_sel_op_do_overflow_check_5_, e execution_sel_op_do_overflow_check_6_, e execution_sel_op_is_address_0_, e execution_sel_op_is_address_1_, e execution_sel_op_is_address_2_, e execution_sel_op_is_address_3_, e execution_sel_op_is_address_4_, e execution_sel_op_is_address_5_, e execution_sel_op_is_address_6_, e execution_sel_op_is_indirect_wire_0_, e execution_sel_op_is_indirect_wire_1_, e execution_sel_op_is_indirect_wire_2_, e execution_sel_op_is_indirect_wire_3_, e execution_sel_op_is_indirect_wire_4_, e execution_sel_op_is_indirect_wire_5_, e execution_sel_op_is_indirect_wire_6_, e execution_sel_op_is_indirect_wire_7_, e execution_sel_op_is_relative_wire_0_, e execution_sel_op_is_relative_wire_1_, e execution_sel_op_is_relative_wire_2_, e execution_sel_op_is_relative_wire_3_, e execution_sel_op_is_relative_wire_4_, e execution_sel_op_is_relative_wire_5_, e execution_sel_op_is_relative_wire_6_, e execution_sel_op_is_relative_wire_7_, e execution_sel_op_reg_effective_0_, e execution_sel_op_reg_effective_1_, e execution_sel_op_reg_effective_2_, e execution_sel_op_reg_effective_3_, e execution_sel_op_reg_effective_4_, e execution_sel_op_reg_effective_5_, e execution_sel_opcode_error, e execution_sel_out_of_gas, e execution_sel_radix_gt_256, e execution_sel_reached_max_note_hashes, e execution_sel_reached_max_nullifiers, e execution_sel_read_registers, e execution_sel_read_unwind_call_stack, e execution_sel_register_read_error, e execution_sel_relative_overflow_0_, e execution_sel_relative_overflow_1_, e execution_sel_relative_overflow_2_, e execution_sel_relative_overflow_3_, e execution_sel_relative_overflow_4_, e execution_sel_relative_overflow_5_, e execution_sel_relative_overflow_6_, e execution_sel_some_final_check_failed, e execution_sel_tag_check_reg_0_, e execution_sel_tag_check_reg_1_, e execution_sel_tag_check_reg_2_, e execution_sel_tag_check_reg_3_, e execution_sel_tag_check_reg_4_, e execution_sel_tag_check_reg_5_, e execution_sel_too_large_recipient_error, e execution_sel_use_num_limbs, e execution_sel_write_l2_to_l1_msg, e execution_sel_write_note_hash, e execution_sel_write_nullifier, e execution_sel_write_public_data, e execution_sel_write_registers, e execution_subtrace_id, e execution_subtrace_operation_id, e execution_total_gas_da, e execution_total_gas_l2, e execution_two_five_six, e execution_value_from_pi, e execution_written_public_data_slots_tree_root, e execution_written_public_data_slots_tree_size, e execution_written_slots_merkle_separator, e execution_written_slots_tree_height, e execution_written_slots_tree_siloing_separator, e ff_gt_a, e ff_gt_b, e ff_gt_borrow, e ff_gt_constant_128, e ff_gt_end, e ff_gt_p_a_borrow, e ff_gt_p_b_borrow, e ff_gt_res_hi, e ff_gt_res_lo, e ff_gt_result, e get_contract_instance_clk, e get_contract_instance_contract_address, e get_contract_instance_dst_offset, e get_contract_instance_dst_offset_diff_max_inv, e get_contract_instance_exists_tag, e get_contract_instance_instance_exists, e get_contract_instance_is_class_id, e get_contract_instance_is_deployer, e get_contract_instance_is_init_hash, e get_contract_instance_is_valid_member_enum, e get_contract_instance_is_valid_writes_in_bounds, e get_contract_instance_member_enum, e get_contract_instance_member_tag, e get_contract_instance_member_write_offset, e get_contract_instance_nullifier_tree_root, e get_contract_instance_public_data_tree_root, e get_contract_instance_retrieved_class_id, e get_contract_instance_retrieved_deployer_addr, e get_contract_instance_retrieved_init_hash, e get_contract_instance_sel, e get_contract_instance_sel_error, e get_contract_instance_selected_member, e get_contract_instance_space_id, e gt_abs_diff, e gt_input_a, e gt_input_b, e gt_num_bits, e gt_res, e gt_sel, e gt_sel_addressing, e gt_sel_alu, e gt_sel_gas, e gt_sel_others, e gt_sel_sha256, e indexed_tree_check_address, e indexed_tree_check_const_three, e indexed_tree_check_discard, e indexed_tree_check_exists, e indexed_tree_check_intermediate_root, e indexed_tree_check_low_leaf_hash, e indexed_tree_check_low_leaf_index, e indexed_tree_check_low_leaf_next_index, e indexed_tree_check_low_leaf_next_value, e indexed_tree_check_low_leaf_value, e indexed_tree_check_merkle_hash_separator, e indexed_tree_check_new_leaf_hash, e indexed_tree_check_next_value_inv, e indexed_tree_check_next_value_is_nonzero, e indexed_tree_check_not_exists, e indexed_tree_check_public_inputs_index, e indexed_tree_check_root, e indexed_tree_check_sel, e indexed_tree_check_sel_insert, e indexed_tree_check_sel_silo, e indexed_tree_check_sel_write_to_public_inputs, e indexed_tree_check_siloed_value, e indexed_tree_check_siloing_separator, e indexed_tree_check_tree_height, e indexed_tree_check_tree_size_after_write, e indexed_tree_check_tree_size_before_write, e indexed_tree_check_updated_low_leaf_hash, e indexed_tree_check_updated_low_leaf_next_index, e indexed_tree_check_updated_low_leaf_next_value, e indexed_tree_check_value, e indexed_tree_check_value_low_leaf_value_diff_inv, e indexed_tree_check_write, e indexed_tree_check_write_root, e instr_fetching_addressing_mode, e instr_fetching_bd0, e instr_fetching_bd1, e instr_fetching_bd10, e instr_fetching_bd11, e instr_fetching_bd12, e instr_fetching_bd13, e instr_fetching_bd14, e instr_fetching_bd15, e instr_fetching_bd16, e instr_fetching_bd17, e instr_fetching_bd18, e instr_fetching_bd19, e instr_fetching_bd2, e instr_fetching_bd20, e instr_fetching_bd21, e instr_fetching_bd22, e instr_fetching_bd23, e instr_fetching_bd24, e instr_fetching_bd25, e instr_fetching_bd26, e instr_fetching_bd27, e instr_fetching_bd28, e instr_fetching_bd29, e instr_fetching_bd3, e instr_fetching_bd30, e instr_fetching_bd31, e instr_fetching_bd32, e instr_fetching_bd33, e instr_fetching_bd34, e instr_fetching_bd35, e instr_fetching_bd36, e instr_fetching_bd4, e instr_fetching_bd5, e instr_fetching_bd6, e instr_fetching_bd7, e instr_fetching_bd8, e instr_fetching_bd9, e instr_fetching_bytecode_id, e instr_fetching_bytecode_size, e instr_fetching_bytes_to_read, e instr_fetching_exec_opcode, e instr_fetching_instr_abs_diff, e instr_fetching_instr_out_of_range, e instr_fetching_instr_size, e instr_fetching_op1, e instr_fetching_op2, e instr_fetching_op3, e instr_fetching_op4, e instr_fetching_op5, e instr_fetching_op6, e instr_fetching_op7, e instr_fetching_opcode_out_of_range, e instr_fetching_pc, e instr_fetching_pc_abs_diff, e instr_fetching_pc_out_of_range, e instr_fetching_pc_size_in_bits, e instr_fetching_sel, e instr_fetching_sel_has_tag, e instr_fetching_sel_op_dc_0, e instr_fetching_sel_op_dc_1, e instr_fetching_sel_op_dc_10, e instr_fetching_sel_op_dc_11, e instr_fetching_sel_op_dc_12, e instr_fetching_sel_op_dc_13, e instr_fetching_sel_op_dc_14, e instr_fetching_sel_op_dc_15, e instr_fetching_sel_op_dc_16, e instr_fetching_sel_op_dc_2, e instr_fetching_sel_op_dc_3, e instr_fetching_sel_op_dc_4, e instr_fetching_sel_op_dc_5, e instr_fetching_sel_op_dc_6, e instr_fetching_sel_op_dc_7, e instr_fetching_sel_op_dc_8, e instr_fetching_sel_op_dc_9, e instr_fetching_sel_parsing_err, e instr_fetching_sel_pc_in_range, e instr_fetching_sel_tag_is_op2, e instr_fetching_tag_out_of_range, e instr_fetching_tag_value, e internal_call_stack_call_id, e internal_call_stack_context_id, e internal_call_stack_entered_call_id, e internal_call_stack_return_call_id, e internal_call_stack_return_pc, e internal_call_stack_sel, e keccak_memory_ctr_end, e keccak_memory_end, e keccak_memory_single_tag_error, e keccak_memory_state_size_min_ctr_inv, e keccak_memory_tag, e keccak_memory_tag_min_u64_inv, e keccak_memory_val_24_, e keccakf1600_bitwise_and_op_id, e keccakf1600_bitwise_xor_op_id, e keccakf1600_dst_out_of_range_error, e keccakf1600_end, e keccakf1600_error, e keccakf1600_highest_slice_address, e keccakf1600_rot_64_min_len_01, e keccakf1600_rot_64_min_len_03, e keccakf1600_rot_64_min_len_11, e keccakf1600_rot_64_min_len_13, e keccakf1600_rot_64_min_len_20, e keccakf1600_rot_64_min_len_22, e keccakf1600_rot_64_min_len_24, e keccakf1600_rot_64_min_len_31, e keccakf1600_rot_64_min_len_34, e keccakf1600_rot_64_min_len_42, e keccakf1600_rot_len_02, e keccakf1600_rot_len_04, e keccakf1600_rot_len_10, e keccakf1600_rot_len_12, e keccakf1600_rot_len_14, e keccakf1600_rot_len_21, e keccakf1600_rot_len_23, e keccakf1600_rot_len_30, e keccakf1600_rot_len_32, e keccakf1600_rot_len_33, e keccakf1600_rot_len_40, e keccakf1600_rot_len_41, e keccakf1600_rot_len_43, e keccakf1600_rot_len_44, e keccakf1600_round_cst, e keccakf1600_sel_slice_read, e keccakf1600_sel_slice_write, e keccakf1600_src_addr, e keccakf1600_src_out_of_range_error, e keccakf1600_state_chi_00, e keccakf1600_state_chi_01, e keccakf1600_state_chi_02, e keccakf1600_state_chi_03, e keccakf1600_state_chi_04, e keccakf1600_state_chi_10, e keccakf1600_state_chi_11, e keccakf1600_state_chi_12, e keccakf1600_state_chi_13, e keccakf1600_state_chi_14, e keccakf1600_state_chi_20, e keccakf1600_state_chi_21, e keccakf1600_state_chi_22, e keccakf1600_state_chi_23, e keccakf1600_state_chi_24, e keccakf1600_state_chi_30, e keccakf1600_state_chi_31, e keccakf1600_state_chi_32, e keccakf1600_state_chi_33, e keccakf1600_state_chi_34, e keccakf1600_state_chi_40, e keccakf1600_state_chi_41, e keccakf1600_state_chi_42, e keccakf1600_state_chi_43, e keccakf1600_state_chi_44, e keccakf1600_state_iota_00, e keccakf1600_state_pi_and_00, e keccakf1600_state_pi_and_01, e keccakf1600_state_pi_and_02, e keccakf1600_state_pi_and_03, e keccakf1600_state_pi_and_04, e keccakf1600_state_pi_and_10, e keccakf1600_state_pi_and_11, e keccakf1600_state_pi_and_12, e keccakf1600_state_pi_and_13, e keccakf1600_state_pi_and_14, e keccakf1600_state_pi_and_20, e keccakf1600_state_pi_and_21, e keccakf1600_state_pi_and_22, e keccakf1600_state_pi_and_23, e keccakf1600_state_pi_and_24, e keccakf1600_state_pi_and_30, e keccakf1600_state_pi_and_31, e keccakf1600_state_pi_and_32, e keccakf1600_state_pi_and_33, e keccakf1600_state_pi_and_34, e keccakf1600_state_pi_and_40, e keccakf1600_state_pi_and_41, e keccakf1600_state_pi_and_42, e keccakf1600_state_pi_and_43, e keccakf1600_state_pi_and_44, e keccakf1600_state_pi_not_00, e keccakf1600_state_pi_not_01, e keccakf1600_state_pi_not_02, e keccakf1600_state_pi_not_03, e keccakf1600_state_pi_not_04, e keccakf1600_state_pi_not_10, e keccakf1600_state_pi_not_11, e keccakf1600_state_pi_not_12, e keccakf1600_state_pi_not_13, e keccakf1600_state_pi_not_14, e keccakf1600_state_pi_not_20, e keccakf1600_state_pi_not_21, e keccakf1600_state_pi_not_22, e keccakf1600_state_pi_not_23, e keccakf1600_state_pi_not_24, e keccakf1600_state_pi_not_30, e keccakf1600_state_pi_not_31, e keccakf1600_state_pi_not_32, e keccakf1600_state_pi_not_33, e keccakf1600_state_pi_not_34, e keccakf1600_state_pi_not_40, e keccakf1600_state_pi_not_41, e keccakf1600_state_pi_not_42, e keccakf1600_state_pi_not_43, e keccakf1600_state_pi_not_44, e keccakf1600_state_rho_01, e keccakf1600_state_rho_02, e keccakf1600_state_rho_03, e keccakf1600_state_rho_04, e keccakf1600_state_rho_10, e keccakf1600_state_rho_11, e keccakf1600_state_rho_12, e keccakf1600_state_rho_13, e keccakf1600_state_rho_14, e keccakf1600_state_rho_20, e keccakf1600_state_rho_21, e keccakf1600_state_rho_22, e keccakf1600_state_rho_23, e keccakf1600_state_rho_24, e keccakf1600_state_rho_30, e keccakf1600_state_rho_31, e keccakf1600_state_rho_32, e keccakf1600_state_rho_33, e keccakf1600_state_rho_34, e keccakf1600_state_rho_40, e keccakf1600_state_rho_41, e keccakf1600_state_rho_42, e keccakf1600_state_rho_43, e keccakf1600_state_rho_44, e keccakf1600_state_theta_00, e keccakf1600_state_theta_01, e keccakf1600_state_theta_02, e keccakf1600_state_theta_03, e keccakf1600_state_theta_04, e keccakf1600_state_theta_10, e keccakf1600_state_theta_11, e keccakf1600_state_theta_12, e keccakf1600_state_theta_13, e keccakf1600_state_theta_14, e keccakf1600_state_theta_20, e keccakf1600_state_theta_21, e keccakf1600_state_theta_22, e keccakf1600_state_theta_23, e keccakf1600_state_theta_24, e keccakf1600_state_theta_30, e keccakf1600_state_theta_31, e keccakf1600_state_theta_32, e keccakf1600_state_theta_33, e keccakf1600_state_theta_34, e keccakf1600_state_theta_40, e keccakf1600_state_theta_41, e keccakf1600_state_theta_42, e keccakf1600_state_theta_43, e keccakf1600_state_theta_44, e keccakf1600_state_theta_hi_02, e keccakf1600_state_theta_hi_04, e keccakf1600_state_theta_hi_10, e keccakf1600_state_theta_hi_12, e keccakf1600_state_theta_hi_14, e keccakf1600_state_theta_hi_21, e keccakf1600_state_theta_hi_23, e keccakf1600_state_theta_hi_30, e keccakf1600_state_theta_hi_32, e keccakf1600_state_theta_hi_33, e keccakf1600_state_theta_hi_40, e keccakf1600_state_theta_hi_41, e keccakf1600_state_theta_hi_43, e keccakf1600_state_theta_hi_44, e keccakf1600_state_theta_low_01, e keccakf1600_state_theta_low_03, e keccakf1600_state_theta_low_11, e keccakf1600_state_theta_low_13, e keccakf1600_state_theta_low_20, e keccakf1600_state_theta_low_22, e keccakf1600_state_theta_low_24, e keccakf1600_state_theta_low_31, e keccakf1600_state_theta_low_34, e keccakf1600_state_theta_low_42, e keccakf1600_tag_error, e keccakf1600_tag_u64, e keccakf1600_theta_combined_xor_0, e keccakf1600_theta_combined_xor_1, e keccakf1600_theta_combined_xor_2, e keccakf1600_theta_combined_xor_3, e keccakf1600_theta_combined_xor_4, e keccakf1600_theta_xor_01, e keccakf1600_theta_xor_02, e keccakf1600_theta_xor_03, e keccakf1600_theta_xor_11, e keccakf1600_theta_xor_12, e keccakf1600_theta_xor_13, e keccakf1600_theta_xor_21, e keccakf1600_theta_xor_22, e keccakf1600_theta_xor_23, e keccakf1600_theta_xor_31, e keccakf1600_theta_xor_32, e keccakf1600_theta_xor_33, e keccakf1600_theta_xor_41, e keccakf1600_theta_xor_42, e keccakf1600_theta_xor_43, e keccakf1600_theta_xor_row_0, e keccakf1600_theta_xor_row_1, e keccakf1600_theta_xor_row_2, e keccakf1600_theta_xor_row_3, e keccakf1600_theta_xor_row_4, e keccakf1600_theta_xor_row_msb_0, e keccakf1600_theta_xor_row_msb_1, e keccakf1600_theta_xor_row_msb_2, e keccakf1600_theta_xor_row_msb_3, e keccakf1600_theta_xor_row_msb_4, e keccakf1600_theta_xor_row_rotl1_0, e keccakf1600_theta_xor_row_rotl1_1, e keccakf1600_theta_xor_row_rotl1_2, e keccakf1600_theta_xor_row_rotl1_3, e keccakf1600_theta_xor_row_rotl1_4, e l1_to_l2_message_tree_check_exists, e l1_to_l2_message_tree_check_l1_to_l2_message_tree_height, e l1_to_l2_message_tree_check_leaf_index, e l1_to_l2_message_tree_check_leaf_value, e l1_to_l2_message_tree_check_leaf_value_msg_hash_diff_inv, e l1_to_l2_message_tree_check_merkle_hash_separator, e l1_to_l2_message_tree_check_msg_hash, e l1_to_l2_message_tree_check_root, e l1_to_l2_message_tree_check_sel, e memory_diff, e memory_glob_addr_diff_inv, e memory_last_access, e memory_limb_0_, e memory_limb_1_, e memory_limb_2_, e memory_max_bits, e memory_sel_addressing_base, e memory_sel_addressing_indirect_0_, e memory_sel_addressing_indirect_1_, e memory_sel_addressing_indirect_2_, e memory_sel_addressing_indirect_3_, e memory_sel_addressing_indirect_4_, e memory_sel_addressing_indirect_5_, e memory_sel_addressing_indirect_6_, e memory_sel_data_copy_read, e memory_sel_data_copy_write, e memory_sel_ecc_write_0_, e memory_sel_ecc_write_1_, e memory_sel_ecc_write_2_, e memory_sel_get_contract_instance_exists_write, e memory_sel_get_contract_instance_member_write, e memory_sel_keccak, e memory_sel_poseidon2_read_0_, e memory_sel_poseidon2_read_1_, e memory_sel_poseidon2_read_2_, e memory_sel_poseidon2_read_3_, e memory_sel_poseidon2_write_0_, e memory_sel_poseidon2_write_1_, e memory_sel_poseidon2_write_2_, e memory_sel_poseidon2_write_3_, e memory_sel_public_log_read, e memory_sel_register_op_0_, e memory_sel_register_op_1_, e memory_sel_register_op_2_, e memory_sel_register_op_3_, e memory_sel_register_op_4_, e memory_sel_register_op_5_, e memory_sel_rng_chk, e memory_sel_rng_write, e memory_sel_sha256_op_0_, e memory_sel_sha256_op_1_, e memory_sel_sha256_op_2_, e memory_sel_sha256_op_3_, e memory_sel_sha256_op_4_, e memory_sel_sha256_op_5_, e memory_sel_sha256_op_6_, e memory_sel_sha256_op_7_, e memory_sel_sha256_read, e memory_sel_tag_is_ff, e memory_sel_to_radix_write, e memory_tag_ff_diff_inv, e merkle_check_const_three, e merkle_check_end, e merkle_check_index_is_even, e merkle_check_path_len_min_one_inv, e merkle_check_read_left_node, e merkle_check_read_output_hash, e merkle_check_read_right_node, e merkle_check_sibling, e merkle_check_write_left_node, e merkle_check_write_output_hash, e merkle_check_write_right_node, e note_hash_tree_check_address, e note_hash_tree_check_const_three, e note_hash_tree_check_discard, e note_hash_tree_check_exists, e note_hash_tree_check_first_nullifier, e note_hash_tree_check_first_nullifier_pi_index, e note_hash_tree_check_leaf_index, e note_hash_tree_check_merkle_hash_separator, e note_hash_tree_check_next_leaf_value, e note_hash_tree_check_next_root, e note_hash_tree_check_nonce, e note_hash_tree_check_nonce_separator, e note_hash_tree_check_note_hash, e note_hash_tree_check_note_hash_index, e note_hash_tree_check_note_hash_tree_height, e note_hash_tree_check_prev_leaf_value, e note_hash_tree_check_prev_leaf_value_unique_note_hash_diff_inv, e note_hash_tree_check_prev_root, e note_hash_tree_check_public_inputs_index, e note_hash_tree_check_sel, e note_hash_tree_check_sel_silo, e note_hash_tree_check_sel_unique, e note_hash_tree_check_sel_write_to_public_inputs, e note_hash_tree_check_siloed_note_hash, e note_hash_tree_check_siloing_separator, e note_hash_tree_check_unique_note_hash, e note_hash_tree_check_unique_note_hash_separator, e note_hash_tree_check_write, e poseidon2_hash_b_0, e poseidon2_hash_b_1, e poseidon2_hash_b_2, e poseidon2_hash_b_3, e poseidon2_hash_end, e poseidon2_hash_input_len, e poseidon2_hash_num_perm_rounds_rem_min_one_inv, e poseidon2_hash_padding, e poseidon2_perm_B_10_0, e poseidon2_perm_B_10_1, e poseidon2_perm_B_10_2, e poseidon2_perm_B_10_3, e poseidon2_perm_B_11_0, e poseidon2_perm_B_11_1, e poseidon2_perm_B_11_2, e poseidon2_perm_B_11_3, e poseidon2_perm_B_12_0, e poseidon2_perm_B_12_1, e poseidon2_perm_B_12_2, e poseidon2_perm_B_12_3, e poseidon2_perm_B_13_0, e poseidon2_perm_B_13_1, e poseidon2_perm_B_13_2, e poseidon2_perm_B_13_3, e poseidon2_perm_B_14_0, e poseidon2_perm_B_14_1, e poseidon2_perm_B_14_2, e poseidon2_perm_B_14_3, e poseidon2_perm_B_15_0, e poseidon2_perm_B_15_1, e poseidon2_perm_B_15_2, e poseidon2_perm_B_15_3, e poseidon2_perm_B_16_0, e poseidon2_perm_B_16_1, e poseidon2_perm_B_16_2, e poseidon2_perm_B_16_3, e poseidon2_perm_B_17_0, e poseidon2_perm_B_17_1, e poseidon2_perm_B_17_2, e poseidon2_perm_B_17_3, e poseidon2_perm_B_18_0, e poseidon2_perm_B_18_1, e poseidon2_perm_B_18_2, e poseidon2_perm_B_18_3, e poseidon2_perm_B_19_0, e poseidon2_perm_B_19_1, e poseidon2_perm_B_19_2, e poseidon2_perm_B_19_3, e poseidon2_perm_B_20_0, e poseidon2_perm_B_20_1, e poseidon2_perm_B_20_2, e poseidon2_perm_B_20_3, e poseidon2_perm_B_21_0, e poseidon2_perm_B_21_1, e poseidon2_perm_B_21_2, e poseidon2_perm_B_21_3, e poseidon2_perm_B_22_0, e poseidon2_perm_B_22_1, e poseidon2_perm_B_22_2, e poseidon2_perm_B_22_3, e poseidon2_perm_B_23_0, e poseidon2_perm_B_23_1, e poseidon2_perm_B_23_2, e poseidon2_perm_B_23_3, e poseidon2_perm_B_24_0, e poseidon2_perm_B_24_1, e poseidon2_perm_B_24_2, e poseidon2_perm_B_24_3, e poseidon2_perm_B_25_0, e poseidon2_perm_B_25_1, e poseidon2_perm_B_25_2, e poseidon2_perm_B_25_3, e poseidon2_perm_B_26_0, e poseidon2_perm_B_26_1, e poseidon2_perm_B_26_2, e poseidon2_perm_B_26_3, e poseidon2_perm_B_27_0, e poseidon2_perm_B_27_1, e poseidon2_perm_B_27_2, e poseidon2_perm_B_27_3, e poseidon2_perm_B_28_0, e poseidon2_perm_B_28_1, e poseidon2_perm_B_28_2, e poseidon2_perm_B_28_3, e poseidon2_perm_B_29_0, e poseidon2_perm_B_29_1, e poseidon2_perm_B_29_2, e poseidon2_perm_B_29_3, e poseidon2_perm_B_30_0, e poseidon2_perm_B_30_1, e poseidon2_perm_B_30_2, e poseidon2_perm_B_30_3, e poseidon2_perm_B_31_0, e poseidon2_perm_B_31_1, e poseidon2_perm_B_31_2, e poseidon2_perm_B_31_3, e poseidon2_perm_B_32_0, e poseidon2_perm_B_32_1, e poseidon2_perm_B_32_2, e poseidon2_perm_B_32_3, e poseidon2_perm_B_33_0, e poseidon2_perm_B_33_1, e poseidon2_perm_B_33_2, e poseidon2_perm_B_33_3, e poseidon2_perm_B_34_0, e poseidon2_perm_B_34_1, e poseidon2_perm_B_34_2, e poseidon2_perm_B_34_3, e poseidon2_perm_B_35_0, e poseidon2_perm_B_35_1, e poseidon2_perm_B_35_2, e poseidon2_perm_B_35_3, e poseidon2_perm_B_36_0, e poseidon2_perm_B_36_1, e poseidon2_perm_B_36_2, e poseidon2_perm_B_36_3, e poseidon2_perm_B_37_0, e poseidon2_perm_B_37_1, e poseidon2_perm_B_37_2, e poseidon2_perm_B_37_3, e poseidon2_perm_B_38_0, e poseidon2_perm_B_38_1, e poseidon2_perm_B_38_2, e poseidon2_perm_B_38_3, e poseidon2_perm_B_39_0, e poseidon2_perm_B_39_1, e poseidon2_perm_B_39_2, e poseidon2_perm_B_39_3, e poseidon2_perm_B_40_0, e poseidon2_perm_B_40_1, e poseidon2_perm_B_40_2, e poseidon2_perm_B_40_3, e poseidon2_perm_B_41_0, e poseidon2_perm_B_41_1, e poseidon2_perm_B_41_2, e poseidon2_perm_B_41_3, e poseidon2_perm_B_42_0, e poseidon2_perm_B_42_1, e poseidon2_perm_B_42_2, e poseidon2_perm_B_42_3, e poseidon2_perm_B_43_0, e poseidon2_perm_B_43_1, e poseidon2_perm_B_43_2, e poseidon2_perm_B_43_3, e poseidon2_perm_B_44_0, e poseidon2_perm_B_44_1, e poseidon2_perm_B_44_2, e poseidon2_perm_B_44_3, e poseidon2_perm_B_45_0, e poseidon2_perm_B_45_1, e poseidon2_perm_B_45_2, e poseidon2_perm_B_45_3, e poseidon2_perm_B_46_0, e poseidon2_perm_B_46_1, e poseidon2_perm_B_46_2, e poseidon2_perm_B_46_3, e poseidon2_perm_B_47_0, e poseidon2_perm_B_47_1, e poseidon2_perm_B_47_2, e poseidon2_perm_B_47_3, e poseidon2_perm_B_48_0, e poseidon2_perm_B_48_1, e poseidon2_perm_B_48_2, e poseidon2_perm_B_48_3, e poseidon2_perm_B_49_0, e poseidon2_perm_B_49_1, e poseidon2_perm_B_49_2, e poseidon2_perm_B_49_3, e poseidon2_perm_B_4_0, e poseidon2_perm_B_4_1, e poseidon2_perm_B_4_2, e poseidon2_perm_B_4_3, e poseidon2_perm_B_50_0, e poseidon2_perm_B_50_1, e poseidon2_perm_B_50_2, e poseidon2_perm_B_50_3, e poseidon2_perm_B_51_0, e poseidon2_perm_B_51_1, e poseidon2_perm_B_51_2, e poseidon2_perm_B_51_3, e poseidon2_perm_B_52_0, e poseidon2_perm_B_52_1, e poseidon2_perm_B_52_2, e poseidon2_perm_B_52_3, e poseidon2_perm_B_53_0, e poseidon2_perm_B_53_1, e poseidon2_perm_B_53_2, e poseidon2_perm_B_53_3, e poseidon2_perm_B_54_0, e poseidon2_perm_B_54_1, e poseidon2_perm_B_54_2, e poseidon2_perm_B_54_3, e poseidon2_perm_B_55_0, e poseidon2_perm_B_55_1, e poseidon2_perm_B_55_2, e poseidon2_perm_B_55_3, e poseidon2_perm_B_56_0, e poseidon2_perm_B_56_1, e poseidon2_perm_B_56_2, e poseidon2_perm_B_56_3, e poseidon2_perm_B_57_0, e poseidon2_perm_B_57_1, e poseidon2_perm_B_57_2, e poseidon2_perm_B_57_3, e poseidon2_perm_B_58_0, e poseidon2_perm_B_58_1, e poseidon2_perm_B_58_2, e poseidon2_perm_B_58_3, e poseidon2_perm_B_59_0, e poseidon2_perm_B_59_1, e poseidon2_perm_B_59_2, e poseidon2_perm_B_59_3, e poseidon2_perm_B_5_0, e poseidon2_perm_B_5_1, e poseidon2_perm_B_5_2, e poseidon2_perm_B_5_3, e poseidon2_perm_B_6_0, e poseidon2_perm_B_6_1, e poseidon2_perm_B_6_2, e poseidon2_perm_B_6_3, e poseidon2_perm_B_7_0, e poseidon2_perm_B_7_1, e poseidon2_perm_B_7_2, e poseidon2_perm_B_7_3, e poseidon2_perm_B_8_0, e poseidon2_perm_B_8_1, e poseidon2_perm_B_8_2, e poseidon2_perm_B_8_3, e poseidon2_perm_B_9_0, e poseidon2_perm_B_9_1, e poseidon2_perm_B_9_2, e poseidon2_perm_B_9_3, e poseidon2_perm_EXT_LAYER_4, e poseidon2_perm_EXT_LAYER_5, e poseidon2_perm_EXT_LAYER_6, e poseidon2_perm_EXT_LAYER_7, e poseidon2_perm_T_0_4, e poseidon2_perm_T_0_5, e poseidon2_perm_T_0_6, e poseidon2_perm_T_0_7, e poseidon2_perm_T_1_4, e poseidon2_perm_T_1_5, e poseidon2_perm_T_1_6, e poseidon2_perm_T_1_7, e poseidon2_perm_T_2_4, e poseidon2_perm_T_2_5, e poseidon2_perm_T_2_6, e poseidon2_perm_T_2_7, e poseidon2_perm_T_3_4, e poseidon2_perm_T_3_5, e poseidon2_perm_T_3_6, e poseidon2_perm_T_3_7, e poseidon2_perm_T_60_4, e poseidon2_perm_T_60_5, e poseidon2_perm_T_60_6, e poseidon2_perm_T_60_7, e poseidon2_perm_T_61_4, e poseidon2_perm_T_61_5, e poseidon2_perm_T_61_6, e poseidon2_perm_T_61_7, e poseidon2_perm_T_62_4, e poseidon2_perm_T_62_5, e poseidon2_perm_T_62_6, e poseidon2_perm_T_62_7, e poseidon2_perm_T_63_4, e poseidon2_perm_T_63_5, e poseidon2_perm_T_63_6, e poseidon2_perm_T_63_7, e poseidon2_perm_a_0, e poseidon2_perm_a_1, e poseidon2_perm_a_2, e poseidon2_perm_a_3, e poseidon2_perm_b_0, e poseidon2_perm_b_1, e poseidon2_perm_b_2, e poseidon2_perm_b_3, e poseidon2_perm_mem_batch_tag_inv, e poseidon2_perm_mem_err, e poseidon2_perm_mem_execution_clk, e poseidon2_perm_mem_input_0_, e poseidon2_perm_mem_input_1_, e poseidon2_perm_mem_input_2_, e poseidon2_perm_mem_input_3_, e poseidon2_perm_mem_input_tag_0_, e poseidon2_perm_mem_input_tag_1_, e poseidon2_perm_mem_input_tag_2_, e poseidon2_perm_mem_input_tag_3_, e poseidon2_perm_mem_max_mem_addr, e poseidon2_perm_mem_output_0_, e poseidon2_perm_mem_output_1_, e poseidon2_perm_mem_output_2_, e poseidon2_perm_mem_output_3_, e poseidon2_perm_mem_read_address_0_, e poseidon2_perm_mem_read_address_1_, e poseidon2_perm_mem_read_address_2_, e poseidon2_perm_mem_read_address_3_, e poseidon2_perm_mem_sel, e poseidon2_perm_mem_sel_dst_out_of_range_err, e poseidon2_perm_mem_sel_invalid_tag_err, e poseidon2_perm_mem_sel_should_exec, e poseidon2_perm_mem_sel_should_read_mem, e poseidon2_perm_mem_sel_src_out_of_range_err, e poseidon2_perm_mem_space_id, e poseidon2_perm_mem_write_address_0_, e poseidon2_perm_mem_write_address_1_, e poseidon2_perm_mem_write_address_2_, e poseidon2_perm_mem_write_address_3_, e poseidon2_perm_sel, e public_data_check_address, e public_data_check_clk_diff_hi, e public_data_check_clk_diff_lo, e public_data_check_const_four, e public_data_check_const_three, e public_data_check_discard, e public_data_check_end, e public_data_check_final_value, e public_data_check_intermediate_root, e public_data_check_leaf_not_exists, e public_data_check_leaf_slot, e public_data_check_leaf_slot_low_leaf_slot_diff_inv, e public_data_check_length_pi_idx, e public_data_check_low_leaf_hash, e public_data_check_low_leaf_index, e public_data_check_low_leaf_next_index, e public_data_check_low_leaf_next_slot, e public_data_check_low_leaf_slot, e public_data_check_low_leaf_value, e public_data_check_merkle_hash_separator, e public_data_check_new_leaf_hash, e public_data_check_next_slot_inv, e public_data_check_next_slot_is_nonzero, e public_data_check_non_discarded_write, e public_data_check_non_protocol_write, e public_data_check_not_end, e public_data_check_protocol_write, e public_data_check_public_data_writes_length, e public_data_check_root, e public_data_check_sel_write_to_public_inputs, e public_data_check_should_insert, e public_data_check_siloing_separator, e public_data_check_slot, e public_data_check_tree_height, e public_data_check_tree_size_after_write, e public_data_check_tree_size_before_write, e public_data_check_updated_low_leaf_hash, e public_data_check_updated_low_leaf_next_index, e public_data_check_updated_low_leaf_next_slot, e public_data_check_updated_low_leaf_value, e public_data_check_value, e public_data_check_write, e public_data_check_write_root, e public_data_squash_check_clock, e public_data_squash_clk_diff_hi, e public_data_squash_clk_diff_lo, e public_data_squash_leaf_slot_increase, e public_data_squash_value, e range_check_dyn_diff, e range_check_dyn_rng_chk_bits, e range_check_dyn_rng_chk_pow_2, e range_check_is_lte_u112, e range_check_is_lte_u128, e range_check_is_lte_u16, e range_check_is_lte_u32, e range_check_is_lte_u48, e range_check_is_lte_u64, e range_check_is_lte_u80, e range_check_is_lte_u96, e range_check_rng_chk_bits, e range_check_sel, e range_check_sel_alu, e range_check_sel_gt, e range_check_sel_keccak, e range_check_sel_memory, e range_check_sel_r0_16_bit_rng_lookup, e range_check_sel_r1_16_bit_rng_lookup, e range_check_sel_r2_16_bit_rng_lookup, e range_check_sel_r3_16_bit_rng_lookup, e range_check_sel_r4_16_bit_rng_lookup, e range_check_sel_r5_16_bit_rng_lookup, e range_check_sel_r6_16_bit_rng_lookup, e range_check_u16_r0, e range_check_u16_r1, e range_check_u16_r2, e range_check_u16_r3, e range_check_u16_r4, e range_check_u16_r5, e range_check_u16_r6, e range_check_u16_r7, e range_check_value, e scalar_mul_bit, e scalar_mul_const_two, e scalar_mul_end, e scalar_mul_sel_not_end, e scalar_mul_should_add, e sha256_a_and_b, e sha256_a_and_b_xor_a_and_c, e sha256_a_and_c, e sha256_a_rotr_13, e sha256_a_rotr_2, e sha256_a_rotr_22, e sha256_a_rotr_2_xor_a_rotr_13, e sha256_and_op_id, e sha256_b_and_c, e sha256_batch_tag_inv, e sha256_ch, e sha256_computed_w_lhs, e sha256_computed_w_rhs, e sha256_e_and_f, e sha256_e_rotr_11, e sha256_e_rotr_25, e sha256_e_rotr_6, e sha256_e_rotr_6_xor_e_rotr_11, e sha256_end, e sha256_err, e sha256_input, e sha256_input_rounds_rem_inv, e sha256_input_tag, e sha256_input_tag_diff_inv, e sha256_last, e sha256_lhs_w_10, e sha256_lhs_w_3, e sha256_maj, e sha256_max_input_addr, e sha256_max_mem_addr, e sha256_max_output_addr, e sha256_max_state_addr, e sha256_mem_out_of_range_err, e sha256_memory_address_0_, e sha256_memory_address_1_, e sha256_memory_address_2_, e sha256_memory_address_3_, e sha256_memory_address_4_, e sha256_memory_address_5_, e sha256_memory_address_6_, e sha256_memory_address_7_, e sha256_memory_register_0_, e sha256_memory_register_1_, e sha256_memory_register_2_, e sha256_memory_register_3_, e sha256_memory_register_4_, e sha256_memory_register_5_, e sha256_memory_register_6_, e sha256_memory_register_7_, e sha256_memory_tag_0_, e sha256_memory_tag_1_, e sha256_memory_tag_2_, e sha256_memory_tag_3_, e sha256_memory_tag_4_, e sha256_memory_tag_5_, e sha256_memory_tag_6_, e sha256_memory_tag_7_, e sha256_next_a_lhs, e sha256_next_a_rhs, e sha256_next_e_lhs, e sha256_next_e_rhs, e sha256_not_e, e sha256_not_e_and_g, e sha256_output_a_lhs, e sha256_output_a_rhs, e sha256_output_b_lhs, e sha256_output_b_rhs, e sha256_output_c_lhs, e sha256_output_c_rhs, e sha256_output_d_lhs, e sha256_output_d_rhs, e sha256_output_e_lhs, e sha256_output_e_rhs, e sha256_output_f_lhs, e sha256_output_f_rhs, e sha256_output_g_lhs, e sha256_output_g_rhs, e sha256_output_h_lhs, e sha256_output_h_rhs, e sha256_perform_round, e sha256_rhs_a_13, e sha256_rhs_a_2, e sha256_rhs_a_22, e sha256_rhs_e_11, e sha256_rhs_e_25, e sha256_rhs_e_6, e sha256_rhs_w_10, e sha256_rhs_w_17, e sha256_rhs_w_18, e sha256_rhs_w_19, e sha256_rhs_w_3, e sha256_rhs_w_7, e sha256_round_constant, e sha256_round_count, e sha256_rounds_remaining_inv, e sha256_rw, e sha256_s_0, e sha256_s_1, e sha256_sel_compute_w, e sha256_sel_input_out_of_range_err, e sha256_sel_invalid_input_row_tag_err, e sha256_sel_invalid_state_tag_err, e sha256_sel_is_input_round, e sha256_sel_mem_state_or_output, e sha256_sel_output_out_of_range_err, e sha256_sel_read_input_from_memory, e sha256_sel_state_out_of_range_err, e sha256_state_addr, e sha256_two_pow_10, e sha256_two_pow_11, e sha256_two_pow_13, e sha256_two_pow_17, e sha256_two_pow_18, e sha256_two_pow_19, e sha256_two_pow_2, e sha256_two_pow_22, e sha256_two_pow_25, e sha256_two_pow_3, e sha256_two_pow_32, e sha256_two_pow_6, e sha256_two_pow_7, e sha256_u32_tag, e sha256_w, e sha256_w_15_rotr_18, e sha256_w_15_rotr_7, e sha256_w_15_rotr_7_xor_w_15_rotr_18, e sha256_w_2_rotr_17, e sha256_w_2_rotr_17_xor_w_2_rotr_19, e sha256_w_2_rotr_19, e sha256_w_s_0, e sha256_w_s_1, e sha256_xor_op_id, e to_radix_end, e to_radix_found, e to_radix_is_unsafe_limb, e to_radix_limb_p_diff, e to_radix_limb_radix_diff, e to_radix_mem_err, e to_radix_mem_input_validation_error, e to_radix_mem_last, e to_radix_mem_limb_index_to_lookup, e to_radix_mem_limb_value, e to_radix_mem_max_mem_size, e to_radix_mem_num_limbs_inv, e to_radix_mem_num_limbs_minus_one_inv, e to_radix_mem_output_tag, e to_radix_mem_radix_min_two_inv, e to_radix_mem_sel_dst_out_of_range_err, e to_radix_mem_sel_invalid_bitwise_radix, e to_radix_mem_sel_num_limbs_is_zero, e to_radix_mem_sel_radix_eq_2, e to_radix_mem_sel_radix_gt_256_err, e to_radix_mem_sel_radix_lt_2_err, e to_radix_mem_sel_value_is_zero, e to_radix_mem_two, e to_radix_mem_two_five_six, e to_radix_mem_value_found, e to_radix_mem_value_inv, e to_radix_mem_write_addr_upper_bound, e to_radix_p_limb, e to_radix_rem_inverse, e to_radix_safety_diff_inverse, e tx_array_length_l2_to_l1_messages_pi_offset, e tx_array_length_note_hashes_pi_offset, e tx_array_length_nullifiers_pi_offset, e tx_calldata_hash, e tx_calldata_size, e tx_const_three, e tx_contract_addr, e tx_dom_sep_public_storage_map_slot, e tx_effective_fee_per_da_gas, e tx_effective_fee_per_l2_gas, e tx_end_phase, e tx_fee_juice_balance_slot, e tx_fee_juice_balances_slot_constant, e tx_fee_juice_contract_address, e tx_fee_payer, e tx_fee_payer_balance, e tx_fee_payer_new_balance, e tx_fee_payer_pi_offset, e tx_fields_length_public_logs_pi_offset, e tx_gas_limit_pi_offset, e tx_gas_used_pi_offset, e tx_is_cleanup, e tx_is_collect_fee, e tx_is_padded, e tx_is_public_call_request, e tx_is_static, e tx_is_tree_insert_phase, e tx_is_tree_padding, e tx_l1_l2_pi_offset, e tx_l2_l1_msg_content, e tx_l2_l1_msg_contract_address, e tx_l2_l1_msg_recipient, e tx_leaf_value, e tx_msg_sender, e tx_next_da_gas_used, e tx_next_da_gas_used_sent_to_enqueued_call, e tx_next_l2_gas_used, e tx_next_l2_gas_used_sent_to_enqueued_call, e tx_next_note_hash_tree_root, e tx_next_note_hash_tree_size, e tx_next_nullifier_tree_root, e tx_next_nullifier_tree_size, e tx_next_num_l2_to_l1_messages, e tx_next_num_note_hashes_emitted, e tx_next_num_nullifiers_emitted, e tx_next_num_public_log_fields, e tx_next_phase_on_revert, e tx_next_public_data_tree_root, e tx_next_public_data_tree_size, e tx_next_retrieved_bytecodes_tree_root, e tx_next_retrieved_bytecodes_tree_size, e tx_next_written_public_data_slots_tree_root, e tx_next_written_public_data_slots_tree_size, e tx_note_hash_pi_offset, e tx_nullifier_limit_error, e tx_nullifier_merkle_separator, e tx_nullifier_pi_offset, e tx_nullifier_tree_height, e tx_prev_da_gas_used_sent_to_enqueued_call, e tx_prev_l2_gas_used_sent_to_enqueued_call, e tx_public_data_pi_offset, e tx_read_pi_length_offset, e tx_read_pi_start_offset, e tx_remaining_phase_inv, e tx_remaining_phase_minus_one_inv, e tx_remaining_side_effects_inv, e tx_reverted_pi_offset, e tx_sel_append_l2_l1_msg, e tx_sel_append_note_hash, e tx_sel_append_nullifier, e tx_sel_l2_l1_msg_append, e tx_sel_note_hash_append, e tx_sel_nullifier_append, e tx_sel_process_call_request, e tx_sel_read_phase_length, e tx_sel_read_trees_and_gas_used, e tx_sel_try_l2_l1_msg_append, e tx_sel_try_note_hash_append, e tx_sel_try_nullifier_append, e tx_setup_phase_value, e tx_should_read_gas_limit, e tx_uint32_max, e tx_write_nullifier_pi_offset, e tx_write_pi_offset, e update_check_address, e update_check_const_three, e update_check_contract_instance_registry_address, e update_check_current_class_id, e update_check_delayed_public_mutable_hash_slot, e update_check_delayed_public_mutable_slot, e update_check_dom_sep_public_storage_map_slot, e update_check_hash_not_zero, e update_check_original_class_id, e update_check_public_data_tree_root, e update_check_sel, e update_check_timestamp, e update_check_timestamp_is_lt_timestamp_of_change, e update_check_timestamp_of_change, e update_check_timestamp_of_change_bit_size, e update_check_timestamp_pi_offset, e update_check_update_hash, e update_check_update_hash_inv, e update_check_update_hi_metadata, e update_check_update_hi_metadata_bit_size, e update_check_update_post_class_id_is_zero, e update_check_update_post_class_inv, e update_check_update_pre_class_id_is_zero, e update_check_update_pre_class_inv, e update_check_update_preimage_metadata, e update_check_update_preimage_post_class_id, e update_check_update_preimage_pre_class_id, e update_check_updated_class_ids_slot, e lookup_range_check_dyn_rng_chk_pow_2_counts, e lookup_range_check_dyn_diff_is_u16_counts, e lookup_range_check_r0_is_u16_counts, e lookup_range_check_r1_is_u16_counts, e lookup_range_check_r2_is_u16_counts, e lookup_range_check_r3_is_u16_counts, e lookup_range_check_r4_is_u16_counts, e lookup_range_check_r5_is_u16_counts, e lookup_range_check_r6_is_u16_counts, e lookup_range_check_r7_is_u16_counts, e lookup_ff_gt_a_lo_range_counts, e lookup_ff_gt_a_hi_range_counts, e lookup_gt_gt_range_counts, e lookup_alu_tag_max_bits_value_counts, e lookup_alu_range_check_decomposition_a_lo_counts, e lookup_alu_range_check_decomposition_a_hi_counts, e lookup_alu_range_check_decomposition_b_lo_counts, e lookup_alu_range_check_decomposition_b_hi_counts, e lookup_alu_range_check_mul_c_hi_counts, e lookup_alu_range_check_div_remainder_counts, e lookup_alu_ff_gt_counts, e lookup_alu_int_gt_counts, e lookup_alu_shifts_two_pow_counts, e lookup_alu_large_trunc_canonical_dec_counts, e lookup_alu_range_check_trunc_mid_counts, e lookup_bitwise_integral_tag_length_counts, e lookup_bitwise_byte_operations_counts, e lookup_memory_range_check_limb_0_counts, e lookup_memory_range_check_limb_1_counts, e lookup_memory_range_check_limb_2_counts, e lookup_memory_tag_max_bits_counts, e lookup_memory_range_check_write_tagged_value_counts, e lookup_data_copy_offset_plus_size_is_gt_data_size_counts, e lookup_data_copy_check_src_addr_in_range_counts, e lookup_data_copy_check_dst_addr_in_range_counts, e lookup_data_copy_sel_has_reads_counts, e lookup_data_copy_col_read_counts, e lookup_ecc_mem_check_dst_addr_in_range_counts, e lookup_ecc_mem_input_output_ecc_add_counts, e lookup_keccakf1600_theta_xor_01_counts, e lookup_keccakf1600_theta_xor_02_counts, e lookup_keccakf1600_theta_xor_03_counts, e lookup_keccakf1600_theta_xor_row_0_counts, e lookup_keccakf1600_theta_xor_11_counts, e lookup_keccakf1600_theta_xor_12_counts, e lookup_keccakf1600_theta_xor_13_counts, e lookup_keccakf1600_theta_xor_row_1_counts, e lookup_keccakf1600_theta_xor_21_counts, e lookup_keccakf1600_theta_xor_22_counts, e lookup_keccakf1600_theta_xor_23_counts, e lookup_keccakf1600_theta_xor_row_2_counts, e lookup_keccakf1600_theta_xor_31_counts, e lookup_keccakf1600_theta_xor_32_counts, e lookup_keccakf1600_theta_xor_33_counts, e lookup_keccakf1600_theta_xor_row_3_counts, e lookup_keccakf1600_theta_xor_41_counts, e lookup_keccakf1600_theta_xor_42_counts, e lookup_keccakf1600_theta_xor_43_counts, e lookup_keccakf1600_theta_xor_row_4_counts, e lookup_keccakf1600_theta_combined_xor_0_counts, e lookup_keccakf1600_theta_combined_xor_1_counts, e lookup_keccakf1600_theta_combined_xor_2_counts, e lookup_keccakf1600_theta_combined_xor_3_counts, e lookup_keccakf1600_theta_combined_xor_4_counts, e lookup_keccakf1600_state_theta_00_counts, e lookup_keccakf1600_state_theta_01_counts, e lookup_keccakf1600_state_theta_02_counts, e lookup_keccakf1600_state_theta_03_counts, e lookup_keccakf1600_state_theta_04_counts, e lookup_keccakf1600_state_theta_10_counts, e lookup_keccakf1600_state_theta_11_counts, e lookup_keccakf1600_state_theta_12_counts, e lookup_keccakf1600_state_theta_13_counts, e lookup_keccakf1600_state_theta_14_counts, e lookup_keccakf1600_state_theta_20_counts, e lookup_keccakf1600_state_theta_21_counts, e lookup_keccakf1600_state_theta_22_counts, e lookup_keccakf1600_state_theta_23_counts, e lookup_keccakf1600_state_theta_24_counts, e lookup_keccakf1600_state_theta_30_counts, e lookup_keccakf1600_state_theta_31_counts, e lookup_keccakf1600_state_theta_32_counts, e lookup_keccakf1600_state_theta_33_counts, e lookup_keccakf1600_state_theta_34_counts, e lookup_keccakf1600_state_theta_40_counts, e lookup_keccakf1600_state_theta_41_counts, e lookup_keccakf1600_state_theta_42_counts, e lookup_keccakf1600_state_theta_43_counts, e lookup_keccakf1600_state_theta_44_counts, e lookup_keccakf1600_theta_limb_02_range_counts, e lookup_keccakf1600_theta_limb_04_range_counts, e lookup_keccakf1600_theta_limb_10_range_counts, e lookup_keccakf1600_theta_limb_12_range_counts, e lookup_keccakf1600_theta_limb_14_range_counts, e lookup_keccakf1600_theta_limb_21_range_counts, e lookup_keccakf1600_theta_limb_23_range_counts, e lookup_keccakf1600_theta_limb_30_range_counts, e lookup_keccakf1600_theta_limb_32_range_counts, e lookup_keccakf1600_theta_limb_33_range_counts, e lookup_keccakf1600_theta_limb_40_range_counts, e lookup_keccakf1600_theta_limb_41_range_counts, e lookup_keccakf1600_theta_limb_43_range_counts, e lookup_keccakf1600_theta_limb_44_range_counts, e lookup_keccakf1600_theta_limb_01_range_counts, e lookup_keccakf1600_theta_limb_03_range_counts, e lookup_keccakf1600_theta_limb_11_range_counts, e lookup_keccakf1600_theta_limb_13_range_counts, e lookup_keccakf1600_theta_limb_20_range_counts, e lookup_keccakf1600_theta_limb_22_range_counts, e lookup_keccakf1600_theta_limb_24_range_counts, e lookup_keccakf1600_theta_limb_31_range_counts, e lookup_keccakf1600_theta_limb_34_range_counts, e lookup_keccakf1600_theta_limb_42_range_counts, e lookup_keccakf1600_state_pi_and_00_counts, e lookup_keccakf1600_state_pi_and_01_counts, e lookup_keccakf1600_state_pi_and_02_counts, e lookup_keccakf1600_state_pi_and_03_counts, e lookup_keccakf1600_state_pi_and_04_counts, e lookup_keccakf1600_state_pi_and_10_counts, e lookup_keccakf1600_state_pi_and_11_counts, e lookup_keccakf1600_state_pi_and_12_counts, e lookup_keccakf1600_state_pi_and_13_counts, e lookup_keccakf1600_state_pi_and_14_counts, e lookup_keccakf1600_state_pi_and_20_counts, e lookup_keccakf1600_state_pi_and_21_counts, e lookup_keccakf1600_state_pi_and_22_counts, e lookup_keccakf1600_state_pi_and_23_counts, e lookup_keccakf1600_state_pi_and_24_counts, e lookup_keccakf1600_state_pi_and_30_counts, e lookup_keccakf1600_state_pi_and_31_counts, e lookup_keccakf1600_state_pi_and_32_counts, e lookup_keccakf1600_state_pi_and_33_counts, e lookup_keccakf1600_state_pi_and_34_counts, e lookup_keccakf1600_state_pi_and_40_counts, e lookup_keccakf1600_state_pi_and_41_counts, e lookup_keccakf1600_state_pi_and_42_counts, e lookup_keccakf1600_state_pi_and_43_counts, e lookup_keccakf1600_state_pi_and_44_counts, e lookup_keccakf1600_state_chi_00_counts, e lookup_keccakf1600_state_chi_01_counts, e lookup_keccakf1600_state_chi_02_counts, e lookup_keccakf1600_state_chi_03_counts, e lookup_keccakf1600_state_chi_04_counts, e lookup_keccakf1600_state_chi_10_counts, e lookup_keccakf1600_state_chi_11_counts, e lookup_keccakf1600_state_chi_12_counts, e lookup_keccakf1600_state_chi_13_counts, e lookup_keccakf1600_state_chi_14_counts, e lookup_keccakf1600_state_chi_20_counts, e lookup_keccakf1600_state_chi_21_counts, e lookup_keccakf1600_state_chi_22_counts, e lookup_keccakf1600_state_chi_23_counts, e lookup_keccakf1600_state_chi_24_counts, e lookup_keccakf1600_state_chi_30_counts, e lookup_keccakf1600_state_chi_31_counts, e lookup_keccakf1600_state_chi_32_counts, e lookup_keccakf1600_state_chi_33_counts, e lookup_keccakf1600_state_chi_34_counts, e lookup_keccakf1600_state_chi_40_counts, e lookup_keccakf1600_state_chi_41_counts, e lookup_keccakf1600_state_chi_42_counts, e lookup_keccakf1600_state_chi_43_counts, e lookup_keccakf1600_state_chi_44_counts, e lookup_keccakf1600_round_cst_counts, e lookup_keccakf1600_state_iota_00_counts, e lookup_keccakf1600_src_out_of_range_toggle_counts, e lookup_keccakf1600_dst_out_of_range_toggle_counts, e lookup_poseidon2_mem_check_src_addr_in_range_counts, e lookup_poseidon2_mem_check_dst_addr_in_range_counts, e lookup_poseidon2_mem_input_output_poseidon2_perm_counts, e lookup_to_radix_limb_range_counts, e lookup_to_radix_limb_less_than_radix_range_counts, e lookup_to_radix_fetch_safe_limbs_counts, e lookup_to_radix_fetch_p_limb_counts, e lookup_to_radix_limb_p_diff_range_counts, e lookup_scalar_mul_to_radix_counts, e lookup_scalar_mul_double_counts, e lookup_scalar_mul_add_counts, e lookup_sha256_range_comp_w_lhs_counts, e lookup_sha256_range_comp_w_rhs_counts, e lookup_sha256_range_rhs_w_7_counts, e lookup_sha256_range_rhs_w_18_counts, e lookup_sha256_range_rhs_w_3_counts, e lookup_sha256_w_s_0_xor_0_counts, e lookup_sha256_w_s_0_xor_1_counts, e lookup_sha256_range_rhs_w_17_counts, e lookup_sha256_range_rhs_w_19_counts, e lookup_sha256_range_rhs_w_10_counts, e lookup_sha256_w_s_1_xor_0_counts, e lookup_sha256_w_s_1_xor_1_counts, e lookup_sha256_range_rhs_e_6_counts, e lookup_sha256_range_rhs_e_11_counts, e lookup_sha256_range_rhs_e_25_counts, e lookup_sha256_s_1_xor_0_counts, e lookup_sha256_s_1_xor_1_counts, e lookup_sha256_ch_and_0_counts, e lookup_sha256_ch_and_1_counts, e lookup_sha256_ch_xor_counts, e lookup_sha256_round_constant_counts, e lookup_sha256_range_rhs_a_2_counts, e lookup_sha256_range_rhs_a_13_counts, e lookup_sha256_range_rhs_a_22_counts, e lookup_sha256_s_0_xor_0_counts, e lookup_sha256_s_0_xor_1_counts, e lookup_sha256_maj_and_0_counts, e lookup_sha256_maj_and_1_counts, e lookup_sha256_maj_and_2_counts, e lookup_sha256_maj_xor_0_counts, e lookup_sha256_maj_xor_1_counts, e lookup_sha256_range_comp_next_a_lhs_counts, e lookup_sha256_range_comp_next_a_rhs_counts, e lookup_sha256_range_comp_next_e_lhs_counts, e lookup_sha256_range_comp_next_e_rhs_counts, e lookup_sha256_range_comp_a_rhs_counts, e lookup_sha256_range_comp_b_rhs_counts, e lookup_sha256_range_comp_c_rhs_counts, e lookup_sha256_range_comp_d_rhs_counts, e lookup_sha256_range_comp_e_rhs_counts, e lookup_sha256_range_comp_f_rhs_counts, e lookup_sha256_range_comp_g_rhs_counts, e lookup_sha256_range_comp_h_rhs_counts, e lookup_sha256_mem_check_state_addr_in_range_counts, e lookup_sha256_mem_check_input_addr_in_range_counts, e lookup_sha256_mem_check_output_addr_in_range_counts, e lookup_to_radix_mem_check_dst_addr_in_range_counts, e lookup_to_radix_mem_check_radix_lt_2_counts, e lookup_to_radix_mem_check_radix_gt_256_counts, e lookup_to_radix_mem_input_output_to_radix_counts, e lookup_poseidon2_hash_poseidon2_perm_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_counts, e lookup_address_derivation_partial_address_poseidon2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_0_counts, e lookup_address_derivation_public_keys_hash_poseidon2_1_counts, e lookup_address_derivation_public_keys_hash_poseidon2_2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_3_counts, e lookup_address_derivation_public_keys_hash_poseidon2_4_counts, e lookup_address_derivation_preaddress_poseidon2_counts, e lookup_address_derivation_preaddress_scalar_mul_counts, e lookup_address_derivation_address_ecadd_counts, e lookup_bc_decomposition_bytes_are_bytes_counts, e lookup_bc_hashing_poseidon2_hash_counts, e lookup_merkle_check_merkle_poseidon2_read_counts, e lookup_merkle_check_merkle_poseidon2_write_counts, e lookup_indexed_tree_check_silo_poseidon2_counts, e lookup_indexed_tree_check_low_leaf_value_validation_counts, e lookup_indexed_tree_check_low_leaf_next_value_validation_counts, e lookup_indexed_tree_check_low_leaf_poseidon2_counts, e lookup_indexed_tree_check_updated_low_leaf_poseidon2_counts, e lookup_indexed_tree_check_low_leaf_merkle_check_counts, e lookup_indexed_tree_check_new_leaf_poseidon2_counts, e lookup_indexed_tree_check_new_leaf_merkle_check_counts, e lookup_indexed_tree_check_write_value_to_public_inputs_counts, e lookup_public_data_squash_leaf_slot_increase_ff_gt_counts, e lookup_public_data_squash_clk_diff_range_lo_counts, e lookup_public_data_squash_clk_diff_range_hi_counts, e lookup_public_data_check_clk_diff_range_lo_counts, e lookup_public_data_check_clk_diff_range_hi_counts, e lookup_public_data_check_silo_poseidon2_counts, e lookup_public_data_check_low_leaf_slot_validation_counts, e lookup_public_data_check_low_leaf_next_slot_validation_counts, e lookup_public_data_check_low_leaf_poseidon2_0_counts, e lookup_public_data_check_low_leaf_poseidon2_1_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_0_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_1_counts, e lookup_public_data_check_low_leaf_merkle_check_counts, e lookup_public_data_check_new_leaf_poseidon2_0_counts, e lookup_public_data_check_new_leaf_poseidon2_1_counts, e lookup_public_data_check_new_leaf_merkle_check_counts, e lookup_public_data_check_write_public_data_to_public_inputs_counts, e lookup_public_data_check_write_writes_length_to_public_inputs_counts, e lookup_update_check_timestamp_from_public_inputs_counts, e lookup_update_check_delayed_public_mutable_slot_poseidon2_counts, e lookup_update_check_update_hash_public_data_read_counts, e lookup_update_check_update_hash_poseidon2_counts, e lookup_update_check_update_hi_metadata_range_counts, e lookup_update_check_update_lo_metadata_range_counts, e lookup_update_check_timestamp_is_lt_timestamp_of_change_counts, e lookup_contract_instance_retrieval_check_protocol_address_range_counts, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_counts, e lookup_contract_instance_retrieval_deployment_nullifier_read_counts, e lookup_contract_instance_retrieval_address_derivation_counts, e lookup_contract_instance_retrieval_update_check_counts, e lookup_class_id_derivation_class_id_poseidon2_0_counts, e lookup_class_id_derivation_class_id_poseidon2_1_counts, e lookup_bc_retrieval_contract_instance_retrieval_counts, e lookup_bc_retrieval_class_id_derivation_counts, e lookup_bc_retrieval_is_new_class_check_counts, e lookup_bc_retrieval_retrieved_bytecodes_insertion_counts, e lookup_instr_fetching_pc_abs_diff_positive_counts, e lookup_instr_fetching_instr_abs_diff_positive_counts, e lookup_instr_fetching_tag_value_validation_counts, e lookup_instr_fetching_bytecode_size_from_bc_dec_counts, e lookup_instr_fetching_bytes_from_bc_dec_counts, e lookup_instr_fetching_wire_instruction_info_counts, e lookup_emit_public_log_check_memory_out_of_bounds_counts, e lookup_emit_public_log_check_log_fields_count_counts, e lookup_emit_public_log_write_data_to_public_inputs_counts, e lookup_get_contract_instance_precomputed_info_counts, e lookup_get_contract_instance_contract_instance_retrieval_counts, e lookup_l1_to_l2_message_tree_check_merkle_check_counts, e lookup_internal_call_unwind_call_stack_counts, e lookup_context_ctx_stack_rollback_counts, e lookup_context_ctx_stack_return_counts, e lookup_addressing_relative_overflow_result_0_counts, e lookup_addressing_relative_overflow_result_1_counts, e lookup_addressing_relative_overflow_result_2_counts, e lookup_addressing_relative_overflow_result_3_counts, e lookup_addressing_relative_overflow_result_4_counts, e lookup_addressing_relative_overflow_result_5_counts, e lookup_addressing_relative_overflow_result_6_counts, e lookup_gas_addressing_gas_read_counts, e lookup_gas_is_out_of_gas_l2_counts, e lookup_gas_is_out_of_gas_da_counts, e lookup_note_hash_tree_check_silo_poseidon2_counts, e lookup_note_hash_tree_check_read_first_nullifier_counts, e lookup_note_hash_tree_check_nonce_computation_poseidon2_counts, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_counts, e lookup_note_hash_tree_check_merkle_check_counts, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_counts, e lookup_emit_notehash_notehash_tree_write_counts, e lookup_emit_nullifier_write_nullifier_counts, e lookup_external_call_is_l2_gas_left_gt_allocated_counts, e lookup_external_call_is_da_gas_left_gt_allocated_counts, e lookup_get_env_var_precomputed_info_counts, e lookup_get_env_var_read_from_public_inputs_col0_counts, e lookup_get_env_var_read_from_public_inputs_col1_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_counts, e lookup_notehash_exists_note_hash_leaf_index_in_range_counts, e lookup_notehash_exists_note_hash_read_counts, e lookup_nullifier_exists_nullifier_exists_check_counts, e lookup_send_l2_to_l1_msg_recipient_check_counts, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_counts, e lookup_sload_storage_read_counts, e lookup_sstore_record_written_storage_slot_counts, e lookup_execution_bytecode_retrieval_result_counts, e lookup_execution_instruction_fetching_result_counts, e lookup_execution_instruction_fetching_body_counts, e lookup_execution_exec_spec_read_counts, e lookup_execution_dyn_l2_factor_bitwise_counts, e lookup_execution_check_radix_gt_256_counts, e lookup_execution_get_p_limbs_counts, e lookup_execution_get_max_limbs_counts, e lookup_execution_check_written_storage_slot_counts, e lookup_execution_dispatch_to_alu_counts, e lookup_execution_dispatch_to_bitwise_counts, e lookup_execution_dispatch_to_cast_counts, e lookup_execution_dispatch_to_set_counts, e lookup_calldata_hashing_get_calldata_field_0_counts, e lookup_calldata_hashing_get_calldata_field_1_counts, e lookup_calldata_hashing_get_calldata_field_2_counts, e lookup_calldata_hashing_poseidon2_hash_counts, e lookup_tx_context_public_inputs_note_hash_tree_counts, e lookup_tx_context_public_inputs_nullifier_tree_counts, e lookup_tx_context_public_inputs_public_data_tree_counts, e lookup_tx_context_public_inputs_l1_l2_tree_counts, e lookup_tx_context_public_inputs_gas_used_counts, e lookup_tx_context_public_inputs_read_gas_limit_counts, e lookup_tx_context_public_inputs_read_reverted_counts, e lookup_tx_context_restore_state_on_revert_counts, e lookup_tx_context_public_inputs_write_note_hash_count_counts, e lookup_tx_context_public_inputs_write_nullifier_count_counts, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_counts, e lookup_tx_context_public_inputs_write_public_log_count_counts, e lookup_tx_read_phase_spec_counts, e lookup_tx_read_phase_length_counts, e lookup_tx_read_public_call_request_phase_counts, e lookup_tx_read_tree_insert_value_counts, e lookup_tx_note_hash_append_counts, e lookup_tx_nullifier_append_counts, e lookup_tx_read_l2_l1_msg_counts, e lookup_tx_write_l2_l1_msg_counts, e lookup_tx_read_effective_fee_public_inputs_counts, e lookup_tx_read_fee_payer_public_inputs_counts, e lookup_tx_balance_slot_poseidon2_counts, e lookup_tx_balance_read_counts, e lookup_tx_balance_validation_counts, e lookup_tx_write_fee_public_inputs_counts, e bc_decomposition_bytes, e bc_decomposition_bytes_pc_plus_1, e bc_decomposition_bytes_pc_plus_10, e bc_decomposition_bytes_pc_plus_11, e bc_decomposition_bytes_pc_plus_12, e bc_decomposition_bytes_pc_plus_13, e bc_decomposition_bytes_pc_plus_14, e bc_decomposition_bytes_pc_plus_15, e bc_decomposition_bytes_pc_plus_16, e bc_decomposition_bytes_pc_plus_17, e bc_decomposition_bytes_pc_plus_18, e bc_decomposition_bytes_pc_plus_19, e bc_decomposition_bytes_pc_plus_2, e bc_decomposition_bytes_pc_plus_20, e bc_decomposition_bytes_pc_plus_21, e bc_decomposition_bytes_pc_plus_22, e bc_decomposition_bytes_pc_plus_23, e bc_decomposition_bytes_pc_plus_24, e bc_decomposition_bytes_pc_plus_25, e bc_decomposition_bytes_pc_plus_26, e bc_decomposition_bytes_pc_plus_27, e bc_decomposition_bytes_pc_plus_28, e bc_decomposition_bytes_pc_plus_29, e bc_decomposition_bytes_pc_plus_3, e bc_decomposition_bytes_pc_plus_30, e bc_decomposition_bytes_pc_plus_31, e bc_decomposition_bytes_pc_plus_32, e bc_decomposition_bytes_pc_plus_33, e bc_decomposition_bytes_pc_plus_34, e bc_decomposition_bytes_pc_plus_35, e bc_decomposition_bytes_pc_plus_4, e bc_decomposition_bytes_pc_plus_5, e bc_decomposition_bytes_pc_plus_6, e bc_decomposition_bytes_pc_plus_7, e bc_decomposition_bytes_pc_plus_8, e bc_decomposition_bytes_pc_plus_9, e bc_decomposition_bytes_remaining, e bc_decomposition_id, e bc_decomposition_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_windows_gt_remaining, e bc_decomposition_start, e bc_hashing_bytecode_id, e bc_hashing_padding, e bc_hashing_pc_index_1, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_sel_not_start, e bc_hashing_start, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e bitwise_sel, e bitwise_start, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_src_context_id, e data_copy_start, e emit_public_log_contract_address, e emit_public_log_correct_tag, e emit_public_log_error_out_of_bounds, e emit_public_log_error_tag_mismatch, e emit_public_log_execution_clk, e emit_public_log_is_write_contract_address, e emit_public_log_is_write_memory_value, e emit_public_log_log_address, e emit_public_log_public_inputs_index, e emit_public_log_remaining_rows, e emit_public_log_seen_wrong_tag, e emit_public_log_sel, e emit_public_log_sel_write_to_public_inputs, e emit_public_log_space_id, e emit_public_log_start, e execution_bytecode_id, e execution_clk, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_public_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_sel, e keccak_memory_space_id, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_start, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_address, e memory_clk, e memory_rw, e memory_sel, e memory_space_id, e memory_tag, e memory_value, e merkle_check_index, e merkle_check_merkle_hash_separator, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_start, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, e poseidon2_hash_a_0, e poseidon2_hash_a_1, e poseidon2_hash_a_2, e poseidon2_hash_a_3, e poseidon2_hash_input_0, e poseidon2_hash_input_1, e poseidon2_hash_input_2, e poseidon2_hash_num_perm_rounds_rem, e poseidon2_hash_output, e poseidon2_hash_sel, e poseidon2_hash_start, e public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, e scalar_mul_bit_idx, e scalar_mul_point_inf, e scalar_mul_point_x, e scalar_mul_point_y, e scalar_mul_res_inf, e scalar_mul_res_x, e scalar_mul_res_y, e scalar_mul_scalar, e scalar_mul_sel, e scalar_mul_start, e scalar_mul_temp_inf, e scalar_mul_temp_x, e scalar_mul_temp_y, e sha256_a, e sha256_b, e sha256_c, e sha256_d, e sha256_e, e sha256_execution_clk, e sha256_f, e sha256_g, e sha256_h, e sha256_helper_w0, e sha256_helper_w1, e sha256_helper_w10, e sha256_helper_w11, e sha256_helper_w12, e sha256_helper_w13, e sha256_helper_w14, e sha256_helper_w15, e sha256_helper_w2, e sha256_helper_w3, e sha256_helper_w4, e sha256_helper_w5, e sha256_helper_w6, e sha256_helper_w7, e sha256_helper_w8, e sha256_helper_w9, e sha256_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_power, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_public_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted -#define AVM2_DERIVED_WITNESS_ENTITIES_E(e) e perm_data_copy_mem_write_inv, e perm_data_copy_mem_read_inv, e perm_ecc_mem_write_mem_0_inv, e perm_ecc_mem_write_mem_1_inv, e perm_ecc_mem_write_mem_2_inv, e perm_keccak_memory_slice_to_mem_inv, e perm_keccakf1600_read_to_slice_inv, e perm_keccakf1600_write_to_slice_inv, e perm_poseidon2_mem_pos_read_mem_0_inv, e perm_poseidon2_mem_pos_read_mem_1_inv, e perm_poseidon2_mem_pos_read_mem_2_inv, e perm_poseidon2_mem_pos_read_mem_3_inv, e perm_poseidon2_mem_pos_write_mem_0_inv, e perm_poseidon2_mem_pos_write_mem_1_inv, e perm_poseidon2_mem_pos_write_mem_2_inv, e perm_poseidon2_mem_pos_write_mem_3_inv, e perm_sha256_mem_mem_op_0_inv, e perm_sha256_mem_mem_op_1_inv, e perm_sha256_mem_mem_op_2_inv, e perm_sha256_mem_mem_op_3_inv, e perm_sha256_mem_mem_op_4_inv, e perm_sha256_mem_mem_op_5_inv, e perm_sha256_mem_mem_op_6_inv, e perm_sha256_mem_mem_op_7_inv, e perm_sha256_mem_mem_input_read_inv, e perm_to_radix_mem_write_mem_inv, e perm_bc_hashing_bytecode_length_bytes_inv, e perm_bc_hashing_get_packed_field_0_inv, e perm_bc_hashing_get_packed_field_1_inv, e perm_bc_hashing_get_packed_field_2_inv, e perm_public_data_check_squashing_inv, e perm_emit_public_log_read_mem_inv, e perm_get_contract_instance_mem_write_contract_instance_exists_inv, e perm_get_contract_instance_mem_write_contract_instance_member_inv, e perm_internal_call_push_call_stack_inv, e perm_context_ctx_stack_call_inv, e perm_addressing_base_address_from_memory_inv, e perm_addressing_indirect_from_memory_0_inv, e perm_addressing_indirect_from_memory_1_inv, e perm_addressing_indirect_from_memory_2_inv, e perm_addressing_indirect_from_memory_3_inv, e perm_addressing_indirect_from_memory_4_inv, e perm_addressing_indirect_from_memory_5_inv, e perm_addressing_indirect_from_memory_6_inv, e perm_registers_mem_op_0_inv, e perm_registers_mem_op_1_inv, e perm_registers_mem_op_2_inv, e perm_registers_mem_op_3_inv, e perm_registers_mem_op_4_inv, e perm_registers_mem_op_5_inv, e perm_sstore_storage_write_inv, e perm_execution_dispatch_to_cd_copy_inv, e perm_execution_dispatch_to_rd_copy_inv, e perm_execution_dispatch_to_get_contract_instance_inv, e perm_execution_dispatch_to_emit_public_log_inv, e perm_execution_dispatch_to_poseidon2_perm_inv, e perm_execution_dispatch_to_sha256_compression_inv, e perm_execution_dispatch_to_keccakf1600_inv, e perm_execution_dispatch_to_ecc_add_inv, e perm_execution_dispatch_to_to_radix_inv, e perm_calldata_hashing_check_final_size_inv, e perm_tx_read_calldata_hash_inv, e perm_tx_dispatch_exec_start_inv, e perm_tx_dispatch_exec_end_inv, e perm_tx_balance_update_inv, e lookup_range_check_dyn_rng_chk_pow_2_inv, e lookup_range_check_dyn_diff_is_u16_inv, e lookup_range_check_r0_is_u16_inv, e lookup_range_check_r1_is_u16_inv, e lookup_range_check_r2_is_u16_inv, e lookup_range_check_r3_is_u16_inv, e lookup_range_check_r4_is_u16_inv, e lookup_range_check_r5_is_u16_inv, e lookup_range_check_r6_is_u16_inv, e lookup_range_check_r7_is_u16_inv, e lookup_ff_gt_a_lo_range_inv, e lookup_ff_gt_a_hi_range_inv, e lookup_gt_gt_range_inv, e lookup_alu_tag_max_bits_value_inv, e lookup_alu_range_check_decomposition_a_lo_inv, e lookup_alu_range_check_decomposition_a_hi_inv, e lookup_alu_range_check_decomposition_b_lo_inv, e lookup_alu_range_check_decomposition_b_hi_inv, e lookup_alu_range_check_mul_c_hi_inv, e lookup_alu_range_check_div_remainder_inv, e lookup_alu_ff_gt_inv, e lookup_alu_int_gt_inv, e lookup_alu_shifts_two_pow_inv, e lookup_alu_large_trunc_canonical_dec_inv, e lookup_alu_range_check_trunc_mid_inv, e lookup_bitwise_integral_tag_length_inv, e lookup_bitwise_byte_operations_inv, e lookup_memory_range_check_limb_0_inv, e lookup_memory_range_check_limb_1_inv, e lookup_memory_range_check_limb_2_inv, e lookup_memory_tag_max_bits_inv, e lookup_memory_range_check_write_tagged_value_inv, e lookup_data_copy_offset_plus_size_is_gt_data_size_inv, e lookup_data_copy_check_src_addr_in_range_inv, e lookup_data_copy_check_dst_addr_in_range_inv, e lookup_data_copy_sel_has_reads_inv, e lookup_data_copy_col_read_inv, e lookup_ecc_mem_check_dst_addr_in_range_inv, e lookup_ecc_mem_input_output_ecc_add_inv, e lookup_keccakf1600_theta_xor_01_inv, e lookup_keccakf1600_theta_xor_02_inv, e lookup_keccakf1600_theta_xor_03_inv, e lookup_keccakf1600_theta_xor_row_0_inv, e lookup_keccakf1600_theta_xor_11_inv, e lookup_keccakf1600_theta_xor_12_inv, e lookup_keccakf1600_theta_xor_13_inv, e lookup_keccakf1600_theta_xor_row_1_inv, e lookup_keccakf1600_theta_xor_21_inv, e lookup_keccakf1600_theta_xor_22_inv, e lookup_keccakf1600_theta_xor_23_inv, e lookup_keccakf1600_theta_xor_row_2_inv, e lookup_keccakf1600_theta_xor_31_inv, e lookup_keccakf1600_theta_xor_32_inv, e lookup_keccakf1600_theta_xor_33_inv, e lookup_keccakf1600_theta_xor_row_3_inv, e lookup_keccakf1600_theta_xor_41_inv, e lookup_keccakf1600_theta_xor_42_inv, e lookup_keccakf1600_theta_xor_43_inv, e lookup_keccakf1600_theta_xor_row_4_inv, e lookup_keccakf1600_theta_combined_xor_0_inv, e lookup_keccakf1600_theta_combined_xor_1_inv, e lookup_keccakf1600_theta_combined_xor_2_inv, e lookup_keccakf1600_theta_combined_xor_3_inv, e lookup_keccakf1600_theta_combined_xor_4_inv, e lookup_keccakf1600_state_theta_00_inv, e lookup_keccakf1600_state_theta_01_inv, e lookup_keccakf1600_state_theta_02_inv, e lookup_keccakf1600_state_theta_03_inv, e lookup_keccakf1600_state_theta_04_inv, e lookup_keccakf1600_state_theta_10_inv, e lookup_keccakf1600_state_theta_11_inv, e lookup_keccakf1600_state_theta_12_inv, e lookup_keccakf1600_state_theta_13_inv, e lookup_keccakf1600_state_theta_14_inv, e lookup_keccakf1600_state_theta_20_inv, e lookup_keccakf1600_state_theta_21_inv, e lookup_keccakf1600_state_theta_22_inv, e lookup_keccakf1600_state_theta_23_inv, e lookup_keccakf1600_state_theta_24_inv, e lookup_keccakf1600_state_theta_30_inv, e lookup_keccakf1600_state_theta_31_inv, e lookup_keccakf1600_state_theta_32_inv, e lookup_keccakf1600_state_theta_33_inv, e lookup_keccakf1600_state_theta_34_inv, e lookup_keccakf1600_state_theta_40_inv, e lookup_keccakf1600_state_theta_41_inv, e lookup_keccakf1600_state_theta_42_inv, e lookup_keccakf1600_state_theta_43_inv, e lookup_keccakf1600_state_theta_44_inv, e lookup_keccakf1600_theta_limb_02_range_inv, e lookup_keccakf1600_theta_limb_04_range_inv, e lookup_keccakf1600_theta_limb_10_range_inv, e lookup_keccakf1600_theta_limb_12_range_inv, e lookup_keccakf1600_theta_limb_14_range_inv, e lookup_keccakf1600_theta_limb_21_range_inv, e lookup_keccakf1600_theta_limb_23_range_inv, e lookup_keccakf1600_theta_limb_30_range_inv, e lookup_keccakf1600_theta_limb_32_range_inv, e lookup_keccakf1600_theta_limb_33_range_inv, e lookup_keccakf1600_theta_limb_40_range_inv, e lookup_keccakf1600_theta_limb_41_range_inv, e lookup_keccakf1600_theta_limb_43_range_inv, e lookup_keccakf1600_theta_limb_44_range_inv, e lookup_keccakf1600_theta_limb_01_range_inv, e lookup_keccakf1600_theta_limb_03_range_inv, e lookup_keccakf1600_theta_limb_11_range_inv, e lookup_keccakf1600_theta_limb_13_range_inv, e lookup_keccakf1600_theta_limb_20_range_inv, e lookup_keccakf1600_theta_limb_22_range_inv, e lookup_keccakf1600_theta_limb_24_range_inv, e lookup_keccakf1600_theta_limb_31_range_inv, e lookup_keccakf1600_theta_limb_34_range_inv, e lookup_keccakf1600_theta_limb_42_range_inv, e lookup_keccakf1600_state_pi_and_00_inv, e lookup_keccakf1600_state_pi_and_01_inv, e lookup_keccakf1600_state_pi_and_02_inv, e lookup_keccakf1600_state_pi_and_03_inv, e lookup_keccakf1600_state_pi_and_04_inv, e lookup_keccakf1600_state_pi_and_10_inv, e lookup_keccakf1600_state_pi_and_11_inv, e lookup_keccakf1600_state_pi_and_12_inv, e lookup_keccakf1600_state_pi_and_13_inv, e lookup_keccakf1600_state_pi_and_14_inv, e lookup_keccakf1600_state_pi_and_20_inv, e lookup_keccakf1600_state_pi_and_21_inv, e lookup_keccakf1600_state_pi_and_22_inv, e lookup_keccakf1600_state_pi_and_23_inv, e lookup_keccakf1600_state_pi_and_24_inv, e lookup_keccakf1600_state_pi_and_30_inv, e lookup_keccakf1600_state_pi_and_31_inv, e lookup_keccakf1600_state_pi_and_32_inv, e lookup_keccakf1600_state_pi_and_33_inv, e lookup_keccakf1600_state_pi_and_34_inv, e lookup_keccakf1600_state_pi_and_40_inv, e lookup_keccakf1600_state_pi_and_41_inv, e lookup_keccakf1600_state_pi_and_42_inv, e lookup_keccakf1600_state_pi_and_43_inv, e lookup_keccakf1600_state_pi_and_44_inv, e lookup_keccakf1600_state_chi_00_inv, e lookup_keccakf1600_state_chi_01_inv, e lookup_keccakf1600_state_chi_02_inv, e lookup_keccakf1600_state_chi_03_inv, e lookup_keccakf1600_state_chi_04_inv, e lookup_keccakf1600_state_chi_10_inv, e lookup_keccakf1600_state_chi_11_inv, e lookup_keccakf1600_state_chi_12_inv, e lookup_keccakf1600_state_chi_13_inv, e lookup_keccakf1600_state_chi_14_inv, e lookup_keccakf1600_state_chi_20_inv, e lookup_keccakf1600_state_chi_21_inv, e lookup_keccakf1600_state_chi_22_inv, e lookup_keccakf1600_state_chi_23_inv, e lookup_keccakf1600_state_chi_24_inv, e lookup_keccakf1600_state_chi_30_inv, e lookup_keccakf1600_state_chi_31_inv, e lookup_keccakf1600_state_chi_32_inv, e lookup_keccakf1600_state_chi_33_inv, e lookup_keccakf1600_state_chi_34_inv, e lookup_keccakf1600_state_chi_40_inv, e lookup_keccakf1600_state_chi_41_inv, e lookup_keccakf1600_state_chi_42_inv, e lookup_keccakf1600_state_chi_43_inv, e lookup_keccakf1600_state_chi_44_inv, e lookup_keccakf1600_round_cst_inv, e lookup_keccakf1600_state_iota_00_inv, e lookup_keccakf1600_src_out_of_range_toggle_inv, e lookup_keccakf1600_dst_out_of_range_toggle_inv, e lookup_poseidon2_mem_check_src_addr_in_range_inv, e lookup_poseidon2_mem_check_dst_addr_in_range_inv, e lookup_poseidon2_mem_input_output_poseidon2_perm_inv, e lookup_to_radix_limb_range_inv, e lookup_to_radix_limb_less_than_radix_range_inv, e lookup_to_radix_fetch_safe_limbs_inv, e lookup_to_radix_fetch_p_limb_inv, e lookup_to_radix_limb_p_diff_range_inv, e lookup_scalar_mul_to_radix_inv, e lookup_scalar_mul_double_inv, e lookup_scalar_mul_add_inv, e lookup_sha256_range_comp_w_lhs_inv, e lookup_sha256_range_comp_w_rhs_inv, e lookup_sha256_range_rhs_w_7_inv, e lookup_sha256_range_rhs_w_18_inv, e lookup_sha256_range_rhs_w_3_inv, e lookup_sha256_w_s_0_xor_0_inv, e lookup_sha256_w_s_0_xor_1_inv, e lookup_sha256_range_rhs_w_17_inv, e lookup_sha256_range_rhs_w_19_inv, e lookup_sha256_range_rhs_w_10_inv, e lookup_sha256_w_s_1_xor_0_inv, e lookup_sha256_w_s_1_xor_1_inv, e lookup_sha256_range_rhs_e_6_inv, e lookup_sha256_range_rhs_e_11_inv, e lookup_sha256_range_rhs_e_25_inv, e lookup_sha256_s_1_xor_0_inv, e lookup_sha256_s_1_xor_1_inv, e lookup_sha256_ch_and_0_inv, e lookup_sha256_ch_and_1_inv, e lookup_sha256_ch_xor_inv, e lookup_sha256_round_constant_inv, e lookup_sha256_range_rhs_a_2_inv, e lookup_sha256_range_rhs_a_13_inv, e lookup_sha256_range_rhs_a_22_inv, e lookup_sha256_s_0_xor_0_inv, e lookup_sha256_s_0_xor_1_inv, e lookup_sha256_maj_and_0_inv, e lookup_sha256_maj_and_1_inv, e lookup_sha256_maj_and_2_inv, e lookup_sha256_maj_xor_0_inv, e lookup_sha256_maj_xor_1_inv, e lookup_sha256_range_comp_next_a_lhs_inv, e lookup_sha256_range_comp_next_a_rhs_inv, e lookup_sha256_range_comp_next_e_lhs_inv, e lookup_sha256_range_comp_next_e_rhs_inv, e lookup_sha256_range_comp_a_rhs_inv, e lookup_sha256_range_comp_b_rhs_inv, e lookup_sha256_range_comp_c_rhs_inv, e lookup_sha256_range_comp_d_rhs_inv, e lookup_sha256_range_comp_e_rhs_inv, e lookup_sha256_range_comp_f_rhs_inv, e lookup_sha256_range_comp_g_rhs_inv, e lookup_sha256_range_comp_h_rhs_inv, e lookup_sha256_mem_check_state_addr_in_range_inv, e lookup_sha256_mem_check_input_addr_in_range_inv, e lookup_sha256_mem_check_output_addr_in_range_inv, e lookup_to_radix_mem_check_dst_addr_in_range_inv, e lookup_to_radix_mem_check_radix_lt_2_inv, e lookup_to_radix_mem_check_radix_gt_256_inv, e lookup_to_radix_mem_input_output_to_radix_inv, e lookup_poseidon2_hash_poseidon2_perm_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv, e lookup_address_derivation_partial_address_poseidon2_inv, e lookup_address_derivation_public_keys_hash_poseidon2_0_inv, e lookup_address_derivation_public_keys_hash_poseidon2_1_inv, e lookup_address_derivation_public_keys_hash_poseidon2_2_inv, e lookup_address_derivation_public_keys_hash_poseidon2_3_inv, e lookup_address_derivation_public_keys_hash_poseidon2_4_inv, e lookup_address_derivation_preaddress_poseidon2_inv, e lookup_address_derivation_preaddress_scalar_mul_inv, e lookup_address_derivation_address_ecadd_inv, e lookup_bc_decomposition_bytes_are_bytes_inv, e lookup_bc_hashing_poseidon2_hash_inv, e lookup_merkle_check_merkle_poseidon2_read_inv, e lookup_merkle_check_merkle_poseidon2_write_inv, e lookup_indexed_tree_check_silo_poseidon2_inv, e lookup_indexed_tree_check_low_leaf_value_validation_inv, e lookup_indexed_tree_check_low_leaf_next_value_validation_inv, e lookup_indexed_tree_check_low_leaf_poseidon2_inv, e lookup_indexed_tree_check_updated_low_leaf_poseidon2_inv, e lookup_indexed_tree_check_low_leaf_merkle_check_inv, e lookup_indexed_tree_check_new_leaf_poseidon2_inv, e lookup_indexed_tree_check_new_leaf_merkle_check_inv, e lookup_indexed_tree_check_write_value_to_public_inputs_inv, e lookup_public_data_squash_leaf_slot_increase_ff_gt_inv, e lookup_public_data_squash_clk_diff_range_lo_inv, e lookup_public_data_squash_clk_diff_range_hi_inv, e lookup_public_data_check_clk_diff_range_lo_inv, e lookup_public_data_check_clk_diff_range_hi_inv, e lookup_public_data_check_silo_poseidon2_inv, e lookup_public_data_check_low_leaf_slot_validation_inv, e lookup_public_data_check_low_leaf_next_slot_validation_inv, e lookup_public_data_check_low_leaf_poseidon2_0_inv, e lookup_public_data_check_low_leaf_poseidon2_1_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_0_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_1_inv, e lookup_public_data_check_low_leaf_merkle_check_inv, e lookup_public_data_check_new_leaf_poseidon2_0_inv, e lookup_public_data_check_new_leaf_poseidon2_1_inv, e lookup_public_data_check_new_leaf_merkle_check_inv, e lookup_public_data_check_write_public_data_to_public_inputs_inv, e lookup_public_data_check_write_writes_length_to_public_inputs_inv, e lookup_update_check_timestamp_from_public_inputs_inv, e lookup_update_check_delayed_public_mutable_slot_poseidon2_inv, e lookup_update_check_update_hash_public_data_read_inv, e lookup_update_check_update_hash_poseidon2_inv, e lookup_update_check_update_hi_metadata_range_inv, e lookup_update_check_update_lo_metadata_range_inv, e lookup_update_check_timestamp_is_lt_timestamp_of_change_inv, e lookup_contract_instance_retrieval_check_protocol_address_range_inv, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_inv, e lookup_contract_instance_retrieval_deployment_nullifier_read_inv, e lookup_contract_instance_retrieval_address_derivation_inv, e lookup_contract_instance_retrieval_update_check_inv, e lookup_class_id_derivation_class_id_poseidon2_0_inv, e lookup_class_id_derivation_class_id_poseidon2_1_inv, e lookup_bc_retrieval_contract_instance_retrieval_inv, e lookup_bc_retrieval_class_id_derivation_inv, e lookup_bc_retrieval_is_new_class_check_inv, e lookup_bc_retrieval_retrieved_bytecodes_insertion_inv, e lookup_instr_fetching_pc_abs_diff_positive_inv, e lookup_instr_fetching_instr_abs_diff_positive_inv, e lookup_instr_fetching_tag_value_validation_inv, e lookup_instr_fetching_bytecode_size_from_bc_dec_inv, e lookup_instr_fetching_bytes_from_bc_dec_inv, e lookup_instr_fetching_wire_instruction_info_inv, e lookup_emit_public_log_check_memory_out_of_bounds_inv, e lookup_emit_public_log_check_log_fields_count_inv, e lookup_emit_public_log_write_data_to_public_inputs_inv, e lookup_get_contract_instance_precomputed_info_inv, e lookup_get_contract_instance_contract_instance_retrieval_inv, e lookup_l1_to_l2_message_tree_check_merkle_check_inv, e lookup_internal_call_unwind_call_stack_inv, e lookup_context_ctx_stack_rollback_inv, e lookup_context_ctx_stack_return_inv, e lookup_addressing_relative_overflow_result_0_inv, e lookup_addressing_relative_overflow_result_1_inv, e lookup_addressing_relative_overflow_result_2_inv, e lookup_addressing_relative_overflow_result_3_inv, e lookup_addressing_relative_overflow_result_4_inv, e lookup_addressing_relative_overflow_result_5_inv, e lookup_addressing_relative_overflow_result_6_inv, e lookup_gas_addressing_gas_read_inv, e lookup_gas_is_out_of_gas_l2_inv, e lookup_gas_is_out_of_gas_da_inv, e lookup_note_hash_tree_check_silo_poseidon2_inv, e lookup_note_hash_tree_check_read_first_nullifier_inv, e lookup_note_hash_tree_check_nonce_computation_poseidon2_inv, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_inv, e lookup_note_hash_tree_check_merkle_check_inv, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_inv, e lookup_emit_notehash_notehash_tree_write_inv, e lookup_emit_nullifier_write_nullifier_inv, e lookup_external_call_is_l2_gas_left_gt_allocated_inv, e lookup_external_call_is_da_gas_left_gt_allocated_inv, e lookup_get_env_var_precomputed_info_inv, e lookup_get_env_var_read_from_public_inputs_col0_inv, e lookup_get_env_var_read_from_public_inputs_col1_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_inv, e lookup_notehash_exists_note_hash_leaf_index_in_range_inv, e lookup_notehash_exists_note_hash_read_inv, e lookup_nullifier_exists_nullifier_exists_check_inv, e lookup_send_l2_to_l1_msg_recipient_check_inv, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_inv, e lookup_sload_storage_read_inv, e lookup_sstore_record_written_storage_slot_inv, e lookup_execution_bytecode_retrieval_result_inv, e lookup_execution_instruction_fetching_result_inv, e lookup_execution_instruction_fetching_body_inv, e lookup_execution_exec_spec_read_inv, e lookup_execution_dyn_l2_factor_bitwise_inv, e lookup_execution_check_radix_gt_256_inv, e lookup_execution_get_p_limbs_inv, e lookup_execution_get_max_limbs_inv, e lookup_execution_check_written_storage_slot_inv, e lookup_execution_dispatch_to_alu_inv, e lookup_execution_dispatch_to_bitwise_inv, e lookup_execution_dispatch_to_cast_inv, e lookup_execution_dispatch_to_set_inv, e lookup_calldata_hashing_get_calldata_field_0_inv, e lookup_calldata_hashing_get_calldata_field_1_inv, e lookup_calldata_hashing_get_calldata_field_2_inv, e lookup_calldata_hashing_poseidon2_hash_inv, e lookup_tx_context_public_inputs_note_hash_tree_inv, e lookup_tx_context_public_inputs_nullifier_tree_inv, e lookup_tx_context_public_inputs_public_data_tree_inv, e lookup_tx_context_public_inputs_l1_l2_tree_inv, e lookup_tx_context_public_inputs_gas_used_inv, e lookup_tx_context_public_inputs_read_gas_limit_inv, e lookup_tx_context_public_inputs_read_reverted_inv, e lookup_tx_context_restore_state_on_revert_inv, e lookup_tx_context_public_inputs_write_note_hash_count_inv, e lookup_tx_context_public_inputs_write_nullifier_count_inv, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_inv, e lookup_tx_context_public_inputs_write_public_log_count_inv, e lookup_tx_read_phase_spec_inv, e lookup_tx_read_phase_length_inv, e lookup_tx_read_public_call_request_phase_inv, e lookup_tx_read_tree_insert_value_inv, e lookup_tx_note_hash_append_inv, e lookup_tx_nullifier_append_inv, e lookup_tx_read_l2_l1_msg_inv, e lookup_tx_write_l2_l1_msg_inv, e lookup_tx_read_effective_fee_public_inputs_inv, e lookup_tx_read_fee_payer_public_inputs_inv, e lookup_tx_balance_slot_poseidon2_inv, e lookup_tx_balance_read_inv, e lookup_tx_balance_validation_inv, e lookup_tx_write_fee_public_inputs_inv +#define AVM2_PRECOMPUTED_ENTITIES_E(e) e precomputed_addressing_gas, e precomputed_bitwise_input_a, e precomputed_bitwise_input_b, e precomputed_bitwise_output_and, e precomputed_bitwise_output_or, e precomputed_bitwise_output_xor, e precomputed_dyn_gas_id, e precomputed_envvar_pi_row_idx, e precomputed_exec_opcode, e precomputed_exec_opcode_base_da_gas, e precomputed_exec_opcode_dynamic_da_gas, e precomputed_exec_opcode_dynamic_l2_gas, e precomputed_exec_opcode_opcode_gas, e precomputed_expected_tag_reg_0_, e precomputed_expected_tag_reg_1_, e precomputed_expected_tag_reg_2_, e precomputed_expected_tag_reg_3_, e precomputed_expected_tag_reg_4_, e precomputed_expected_tag_reg_5_, e precomputed_first_row, e precomputed_idx, e precomputed_instr_size, e precomputed_invalid_envvar_enum, e precomputed_is_address, e precomputed_is_class_id, e precomputed_is_cleanup, e precomputed_is_collect_fee, e precomputed_is_dagasleft, e precomputed_is_deployer, e precomputed_is_immutables_hash, e precomputed_is_init_hash, e precomputed_is_isstaticcall, e precomputed_is_l2gasleft, e precomputed_is_public_call_request, e precomputed_is_revertible, e precomputed_is_sender, e precomputed_is_teardown, e precomputed_is_transactionfee, e precomputed_is_tree_padding, e precomputed_is_valid_member_enum, e precomputed_keccak_round_constant, e precomputed_next_phase_on_revert, e precomputed_opcode_out_of_range, e precomputed_out_tag, e precomputed_p_decomposition_limb, e precomputed_p_decomposition_limb_index, e precomputed_p_decomposition_radix, e precomputed_power_of_2, e precomputed_read_pi_length_offset, e precomputed_read_pi_start_offset, e precomputed_rw_reg_0_, e precomputed_rw_reg_1_, e precomputed_rw_reg_2_, e precomputed_rw_reg_3_, e precomputed_rw_reg_4_, e precomputed_rw_reg_5_, e precomputed_sel_addressing_gas, e precomputed_sel_append_l2_l1_msg, e precomputed_sel_append_note_hash, e precomputed_sel_append_nullifier, e precomputed_sel_envvar_pi_lookup_col0, e precomputed_sel_envvar_pi_lookup_col1, e precomputed_sel_exec_spec, e precomputed_sel_has_tag, e precomputed_sel_keccak, e precomputed_sel_mem_op_reg_0_, e precomputed_sel_mem_op_reg_1_, e precomputed_sel_mem_op_reg_2_, e precomputed_sel_mem_op_reg_3_, e precomputed_sel_mem_op_reg_4_, e precomputed_sel_mem_op_reg_5_, e precomputed_sel_mem_tag_out_of_range, e precomputed_sel_op_dc_0, e precomputed_sel_op_dc_1, e precomputed_sel_op_dc_10, e precomputed_sel_op_dc_11, e precomputed_sel_op_dc_12, e precomputed_sel_op_dc_13, e precomputed_sel_op_dc_14, e precomputed_sel_op_dc_15, e precomputed_sel_op_dc_16, e precomputed_sel_op_dc_2, e precomputed_sel_op_dc_3, e precomputed_sel_op_dc_4, e precomputed_sel_op_dc_5, e precomputed_sel_op_dc_6, e precomputed_sel_op_dc_7, e precomputed_sel_op_dc_8, e precomputed_sel_op_dc_9, e precomputed_sel_op_is_address_0_, e precomputed_sel_op_is_address_1_, e precomputed_sel_op_is_address_2_, e precomputed_sel_op_is_address_3_, e precomputed_sel_op_is_address_4_, e precomputed_sel_op_is_address_5_, e precomputed_sel_op_is_address_6_, e precomputed_sel_p_decomposition, e precomputed_sel_phase, e precomputed_sel_range_16, e precomputed_sel_range_8, e precomputed_sel_sha256_compression, e precomputed_sel_tag_check_reg_0_, e precomputed_sel_tag_check_reg_1_, e precomputed_sel_tag_check_reg_2_, e precomputed_sel_tag_check_reg_3_, e precomputed_sel_tag_check_reg_4_, e precomputed_sel_tag_check_reg_5_, e precomputed_sel_tag_is_op2, e precomputed_sel_tag_parameters, e precomputed_sel_to_radix_p_limb_counts, e precomputed_sha256_compression_round_constant, e precomputed_subtrace_id, e precomputed_subtrace_operation_id, e precomputed_tag_byte_length, e precomputed_tag_max_bits, e precomputed_tag_max_value, e precomputed_to_radix_num_limbs_for_p, e precomputed_to_radix_safe_limbs, e precomputed_zero, e public_inputs_sel +#define AVM2_WIRE_ENTITIES_E(e) e public_inputs_cols_0_, e public_inputs_cols_1_, e public_inputs_cols_2_, e public_inputs_cols_3_, e address_derivation_address, e address_derivation_address_y, e address_derivation_class_id, e address_derivation_const_five, e address_derivation_const_three, e address_derivation_deployer_addr, e address_derivation_g1_x, e address_derivation_g1_y, e address_derivation_immutables_hash, e address_derivation_incoming_viewing_key_hash, e address_derivation_incoming_viewing_key_x, e address_derivation_incoming_viewing_key_y, e address_derivation_init_hash, e address_derivation_nullifier_key_hash, e address_derivation_outgoing_viewing_key_hash, e address_derivation_partial_address, e address_derivation_partial_address_domain_separator, e address_derivation_preaddress, e address_derivation_preaddress_domain_separator, e address_derivation_preaddress_public_key_x, e address_derivation_preaddress_public_key_y, e address_derivation_public_keys_hash, e address_derivation_public_keys_hash_domain_separator, e address_derivation_salt, e address_derivation_salted_init_hash, e address_derivation_salted_init_hash_domain_separator, e address_derivation_sel, e address_derivation_single_public_key_hash_domain_separator, e address_derivation_tagging_key_hash, e alu_a_hi, e alu_a_hi_bits, e alu_a_lo, e alu_a_lo_bits, e alu_ab_diff_inv, e alu_ab_tags_diff_inv, e alu_b_hi, e alu_b_inv, e alu_b_lo, e alu_c_hi, e alu_cf, e alu_constant_64, e alu_gt_input_a, e alu_gt_input_b, e alu_gt_result_c, e alu_helper1, e alu_ia, e alu_ia_tag, e alu_ib, e alu_ib_tag, e alu_ic, e alu_ic_tag, e alu_max_bits, e alu_max_value, e alu_mid, e alu_mid_bits, e alu_op_id, e alu_sel, e alu_sel_ab_tag_mismatch, e alu_sel_decompose_a, e alu_sel_div_0_err, e alu_sel_div_no_err, e alu_sel_err, e alu_sel_ff_gt, e alu_sel_int_gt, e alu_sel_is_ff, e alu_sel_is_u128, e alu_sel_mul_div_u128, e alu_sel_mul_no_err_non_ff, e alu_sel_op_add, e alu_sel_op_div, e alu_sel_op_eq, e alu_sel_op_fdiv, e alu_sel_op_lt, e alu_sel_op_lte, e alu_sel_op_mul, e alu_sel_op_not, e alu_sel_op_shl, e alu_sel_op_shr, e alu_sel_op_sub, e alu_sel_op_truncate, e alu_sel_shift_ops_no_overflow, e alu_sel_tag_err, e alu_sel_trunc_gte_128, e alu_sel_trunc_lt_128, e alu_sel_trunc_non_trivial, e alu_sel_trunc_trivial, e alu_shift_lo_bits, e alu_tag_ff_diff_inv, e alu_tag_u128_diff_inv, e alu_two_pow_shift_lo_bits, e bc_decomposition_bytes_pc_plus_36, e bc_decomposition_bytes_rem_inv, e bc_decomposition_bytes_rem_min_one_inv, e bc_decomposition_bytes_to_read, e bc_decomposition_last_of_contract, e bc_decomposition_next_packed_pc_min_pc_inv, e bc_decomposition_packed_field, e bc_decomposition_sel_packed, e bc_decomposition_sel_packed_read_0_, e bc_decomposition_sel_packed_read_1_, e bc_decomposition_sel_packed_read_2_, e bc_decomposition_sel_windows_eq_remaining, e bc_decomposition_windows_min_remaining_inv, e bc_hashing_end, e bc_hashing_input_len, e bc_hashing_packed_fields_0, e bc_hashing_packed_fields_1, e bc_hashing_packed_fields_2, e bc_hashing_pc_index, e bc_hashing_pc_index_2, e bc_hashing_sel_not_padding_1, e bc_hashing_sel_not_padding_2, e bc_hashing_size_in_bytes, e bc_retrieval_address, e bc_retrieval_artifact_hash, e bc_retrieval_bytecode_id, e bc_retrieval_current_class_id, e bc_retrieval_error, e bc_retrieval_instance_exists, e bc_retrieval_is_new_class, e bc_retrieval_next_retrieved_bytecodes_tree_root, e bc_retrieval_next_retrieved_bytecodes_tree_size, e bc_retrieval_no_remaining_bytecodes, e bc_retrieval_nullifier_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_size, e bc_retrieval_private_functions_root, e bc_retrieval_public_data_tree_root, e bc_retrieval_remaining_bytecodes_inv, e bc_retrieval_retrieved_bytecodes_merkle_separator, e bc_retrieval_retrieved_bytecodes_tree_height, e bc_retrieval_sel, e bc_retrieval_should_retrieve, e bitwise_ctr_min_one_inv, e bitwise_end, e bitwise_err, e bitwise_ia_byte, e bitwise_ib_byte, e bitwise_ic_byte, e bitwise_output_and, e bitwise_output_or, e bitwise_output_xor, e bitwise_sel_and, e bitwise_sel_compute, e bitwise_sel_get_ctr, e bitwise_sel_or, e bitwise_sel_tag_ff_err, e bitwise_sel_tag_mismatch_err, e bitwise_sel_xor, e bitwise_start_keccak, e bitwise_start_sha256, e bitwise_tag_a, e bitwise_tag_a_inv, e bitwise_tag_ab_diff_inv, e bitwise_tag_b, e bitwise_tag_c, e calldata_end, e calldata_hashing_end, e calldata_hashing_index_1_, e calldata_hashing_index_2_, e calldata_hashing_input_0_, e calldata_hashing_input_1_, e calldata_hashing_input_2_, e calldata_hashing_input_len, e calldata_hashing_sel_end_not_empty, e calldata_hashing_sel_not_padding_1, e calldata_hashing_sel_not_padding_2, e calldata_hashing_sel_not_start, e calldata_value, e class_id_derivation_artifact_hash, e class_id_derivation_class_id, e class_id_derivation_const_four, e class_id_derivation_gen_index_contract_class_id, e class_id_derivation_private_functions_root, e class_id_derivation_public_bytecode_commitment, e class_id_derivation_sel, e context_stack_bytecode_id, e context_stack_context_id, e context_stack_contract_address, e context_stack_entered_context_id, e context_stack_internal_call_id, e context_stack_internal_call_return_id, e context_stack_is_static, e context_stack_msg_sender, e context_stack_next_internal_call_id, e context_stack_next_pc, e context_stack_note_hash_tree_root, e context_stack_note_hash_tree_size, e context_stack_nullifier_tree_root, e context_stack_nullifier_tree_size, e context_stack_num_l2_to_l1_messages, e context_stack_num_note_hashes_emitted, e context_stack_num_nullifiers_emitted, e context_stack_num_public_log_fields, e context_stack_parent_calldata_addr, e context_stack_parent_calldata_size, e context_stack_parent_da_gas_limit, e context_stack_parent_da_gas_used, e context_stack_parent_id, e context_stack_parent_l2_gas_limit, e context_stack_parent_l2_gas_used, e context_stack_public_data_tree_root, e context_stack_public_data_tree_size, e context_stack_sel, e context_stack_written_public_data_slots_tree_root, e context_stack_written_public_data_slots_tree_size, e contract_instance_retrieval_address, e contract_instance_retrieval_address_sub_one, e contract_instance_retrieval_current_class_id, e contract_instance_retrieval_deployer_addr, e contract_instance_retrieval_deployer_protocol_contract_address, e contract_instance_retrieval_derived_address, e contract_instance_retrieval_derived_address_pi_index, e contract_instance_retrieval_exists, e contract_instance_retrieval_immutables_hash, e contract_instance_retrieval_incoming_viewing_key_x, e contract_instance_retrieval_incoming_viewing_key_y, e contract_instance_retrieval_init_hash, e contract_instance_retrieval_is_protocol_contract, e contract_instance_retrieval_max_protocol_contracts, e contract_instance_retrieval_nullifier_key_hash, e contract_instance_retrieval_nullifier_merkle_separator, e contract_instance_retrieval_nullifier_tree_height, e contract_instance_retrieval_nullifier_tree_root, e contract_instance_retrieval_original_class_id, e contract_instance_retrieval_outgoing_viewing_key_hash, e contract_instance_retrieval_protocol_contract_derived_address_inv, e contract_instance_retrieval_public_data_tree_root, e contract_instance_retrieval_salt, e contract_instance_retrieval_sel, e contract_instance_retrieval_should_check_for_update, e contract_instance_retrieval_should_check_nullifier, e contract_instance_retrieval_siloing_separator, e contract_instance_retrieval_tagging_key_hash, e data_copy_cd_copy_col_read, e data_copy_clamped_read_index_upper_bound, e data_copy_dst_out_of_range_err, e data_copy_end, e data_copy_is_top_level, e data_copy_mem_size, e data_copy_offset, e data_copy_offset_plus_size, e data_copy_offset_plus_size_is_gt, e data_copy_parent_id_inv, e data_copy_read_addr_plus_one, e data_copy_read_addr_upper_bound, e data_copy_reads_left_inv, e data_copy_sel_cd_copy_start, e data_copy_sel_has_reads, e data_copy_sel_mem_read, e data_copy_sel_mem_write, e data_copy_sel_rd_copy_start, e data_copy_sel_write_count_is_zero, e data_copy_src_addr, e data_copy_src_data_size, e data_copy_src_reads_exceed_mem, e data_copy_start_no_err, e data_copy_tag, e data_copy_value, e data_copy_write_addr_upper_bound, e data_copy_write_count_minus_one_inv, e data_copy_write_count_zero_inv, e ecc_add_mem_dst_addr_0_, e ecc_add_mem_dst_addr_1_, e ecc_add_mem_err, e ecc_add_mem_execution_clk, e ecc_add_mem_max_mem_addr, e ecc_add_mem_p_is_inf, e ecc_add_mem_p_is_on_curve_eqn, e ecc_add_mem_p_is_on_curve_eqn_inv, e ecc_add_mem_p_x, e ecc_add_mem_p_y, e ecc_add_mem_q_is_inf, e ecc_add_mem_q_is_on_curve_eqn, e ecc_add_mem_q_is_on_curve_eqn_inv, e ecc_add_mem_q_x, e ecc_add_mem_q_y, e ecc_add_mem_res_x, e ecc_add_mem_res_y, e ecc_add_mem_sel, e ecc_add_mem_sel_dst_out_of_range_err, e ecc_add_mem_sel_p_not_on_curve_err, e ecc_add_mem_sel_q_not_on_curve_err, e ecc_add_mem_sel_should_exec, e ecc_add_mem_space_id, e ecc_add_op, e ecc_double_op, e ecc_inv_2_p_y, e ecc_inv_x_diff, e ecc_inv_y_diff, e ecc_lambda, e ecc_p_is_inf, e ecc_p_x, e ecc_p_y, e ecc_q_is_inf, e ecc_q_x, e ecc_q_y, e ecc_r_x, e ecc_r_y, e ecc_result_infinity, e ecc_sel, e ecc_use_computed_result, e ecc_x_match, e ecc_y_match, e emit_public_log_discard, e emit_public_log_end, e emit_public_log_end_log_address_upper_bound, e emit_public_log_error, e emit_public_log_error_too_many_log_fields, e emit_public_log_expected_next_log_fields, e emit_public_log_is_static, e emit_public_log_log_size, e emit_public_log_max_mem_size, e emit_public_log_max_public_logs_payload_length, e emit_public_log_next_num_public_log_fields, e emit_public_log_prev_num_public_log_fields, e emit_public_log_public_inputs_value, e emit_public_log_remaining_rows_inv, e emit_public_log_sel_read_memory, e emit_public_log_tag, e emit_public_log_tag_inv, e emit_public_log_value, e execution_addressing_error_collection_inv, e execution_addressing_gas, e execution_addressing_mode, e execution_base_address_tag, e execution_base_address_tag_diff_inv, e execution_base_address_val, e execution_base_da_gas, e execution_batched_tags_diff_inv, e execution_batched_tags_diff_inv_reg, e execution_da_gas_left, e execution_da_gas_used, e execution_dying_context_diff_inv, e execution_dying_context_id_inv, e execution_dyn_gas_id, e execution_dynamic_da_gas, e execution_dynamic_da_gas_factor, e execution_dynamic_l2_gas, e execution_dynamic_l2_gas_factor, e execution_enqueued_call_end, e execution_envvar_pi_row_idx, e execution_exec_opcode, e execution_expected_tag_reg_0_, e execution_expected_tag_reg_1_, e execution_expected_tag_reg_2_, e execution_expected_tag_reg_3_, e execution_expected_tag_reg_4_, e execution_expected_tag_reg_5_, e execution_has_parent_ctx, e execution_highest_address, e execution_instr_size, e execution_internal_call_return_id_inv, e execution_is_address, e execution_is_da_gas_left_gt_allocated, e execution_is_dagasleft, e execution_is_dying_context, e execution_is_isstaticcall, e execution_is_l2_gas_left_gt_allocated, e execution_is_l2gasleft, e execution_is_parent_id_inv, e execution_is_sender, e execution_is_transactionfee, e execution_l1_to_l2_msg_leaf_in_range, e execution_l1_to_l2_msg_tree_leaf_count, e execution_l2_gas_left, e execution_l2_gas_used, e execution_max_data_writes_reached, e execution_max_eth_address_value, e execution_mem_tag_reg_0_, e execution_mem_tag_reg_1_, e execution_mem_tag_reg_2_, e execution_mem_tag_reg_3_, e execution_mem_tag_reg_4_, e execution_mem_tag_reg_5_, e execution_nested_failure, e execution_nested_return, e execution_next_pc, e execution_note_hash_leaf_in_range, e execution_note_hash_tree_leaf_count, e execution_note_hash_tree_root, e execution_note_hash_tree_size, e execution_nullifier_merkle_separator, e execution_nullifier_pi_offset, e execution_nullifier_siloing_separator, e execution_nullifier_tree_height, e execution_nullifier_tree_root, e execution_nullifier_tree_size, e execution_num_l2_to_l1_messages, e execution_num_note_hashes_emitted, e execution_num_nullifiers_emitted, e execution_num_p_limbs, e execution_num_public_log_fields, e execution_num_relative_operands_inv, e execution_op_0_, e execution_op_1_, e execution_op_2_, e execution_op_3_, e execution_op_4_, e execution_op_5_, e execution_op_6_, e execution_op_after_relative_0_, e execution_op_after_relative_1_, e execution_op_after_relative_2_, e execution_op_after_relative_3_, e execution_op_after_relative_4_, e execution_op_after_relative_5_, e execution_op_after_relative_6_, e execution_opcode_gas, e execution_out_of_gas_da, e execution_out_of_gas_l2, e execution_public_data_tree_root, e execution_public_data_tree_size, e execution_public_inputs_index, e execution_register_0_, e execution_register_1_, e execution_register_2_, e execution_register_3_, e execution_register_4_, e execution_register_5_, e execution_remaining_data_writes_inv, e execution_remaining_l2_to_l1_msgs_inv, e execution_remaining_note_hashes_inv, e execution_remaining_nullifiers_inv, e execution_retrieved_bytecodes_tree_root, e execution_retrieved_bytecodes_tree_size, e execution_rop_0_, e execution_rop_1_, e execution_rop_2_, e execution_rop_3_, e execution_rop_4_, e execution_rop_5_, e execution_rop_6_, e execution_rop_tag_0_, e execution_rop_tag_1_, e execution_rop_tag_2_, e execution_rop_tag_3_, e execution_rop_tag_4_, e execution_rop_tag_5_, e execution_rop_tag_6_, e execution_rw_reg_0_, e execution_rw_reg_1_, e execution_rw_reg_2_, e execution_rw_reg_3_, e execution_rw_reg_4_, e execution_rw_reg_5_, e execution_sel_addressing_error, e execution_sel_apply_indirection_0_, e execution_sel_apply_indirection_1_, e execution_sel_apply_indirection_2_, e execution_sel_apply_indirection_3_, e execution_sel_apply_indirection_4_, e execution_sel_apply_indirection_5_, e execution_sel_apply_indirection_6_, e execution_sel_base_address_failure, e execution_sel_bytecode_retrieval_failure, e execution_sel_bytecode_retrieval_success, e execution_sel_check_gas, e execution_sel_do_base_check, e execution_sel_enter_call, e execution_sel_envvar_pi_lookup_col0, e execution_sel_envvar_pi_lookup_col1, e execution_sel_error, e execution_sel_exec_dispatch_alu, e execution_sel_exec_dispatch_bitwise, e execution_sel_exec_dispatch_calldata_copy, e execution_sel_exec_dispatch_cast, e execution_sel_exec_dispatch_ecc_add, e execution_sel_exec_dispatch_emit_public_log, e execution_sel_exec_dispatch_execution, e execution_sel_exec_dispatch_get_contract_instance, e execution_sel_exec_dispatch_keccakf1600, e execution_sel_exec_dispatch_poseidon2_perm, e execution_sel_exec_dispatch_returndata_copy, e execution_sel_exec_dispatch_set, e execution_sel_exec_dispatch_sha256_compression, e execution_sel_exec_dispatch_to_radix, e execution_sel_execute_call, e execution_sel_execute_debug_log, e execution_sel_execute_emit_notehash, e execution_sel_execute_emit_nullifier, e execution_sel_execute_get_env_var, e execution_sel_execute_internal_call, e execution_sel_execute_internal_return, e execution_sel_execute_jump, e execution_sel_execute_jumpi, e execution_sel_execute_l1_to_l2_message_exists, e execution_sel_execute_mov, e execution_sel_execute_notehash_exists, e execution_sel_execute_nullifier_exists, e execution_sel_execute_opcode, e execution_sel_execute_return, e execution_sel_execute_returndata_size, e execution_sel_execute_revert, e execution_sel_execute_send_l2_to_l1_msg, e execution_sel_execute_sload, e execution_sel_execute_sstore, e execution_sel_execute_static_call, e execution_sel_execute_success_copy, e execution_sel_exit_call, e execution_sel_failure, e execution_sel_gas_bitwise, e execution_sel_gas_calldata_copy, e execution_sel_gas_emit_public_log, e execution_sel_gas_returndata_copy, e execution_sel_gas_sstore, e execution_sel_gas_to_radix, e execution_sel_instruction_fetching_failure, e execution_sel_instruction_fetching_success, e execution_sel_l2_to_l1_msg_limit_error, e execution_sel_lookup_num_p_limbs, e execution_sel_mem_op_reg_0_, e execution_sel_mem_op_reg_1_, e execution_sel_mem_op_reg_2_, e execution_sel_mem_op_reg_3_, e execution_sel_mem_op_reg_4_, e execution_sel_mem_op_reg_5_, e execution_sel_op_do_overflow_check_0_, e execution_sel_op_do_overflow_check_1_, e execution_sel_op_do_overflow_check_2_, e execution_sel_op_do_overflow_check_3_, e execution_sel_op_do_overflow_check_4_, e execution_sel_op_do_overflow_check_5_, e execution_sel_op_do_overflow_check_6_, e execution_sel_op_is_address_0_, e execution_sel_op_is_address_1_, e execution_sel_op_is_address_2_, e execution_sel_op_is_address_3_, e execution_sel_op_is_address_4_, e execution_sel_op_is_address_5_, e execution_sel_op_is_address_6_, e execution_sel_op_is_indirect_wire_0_, e execution_sel_op_is_indirect_wire_1_, e execution_sel_op_is_indirect_wire_2_, e execution_sel_op_is_indirect_wire_3_, e execution_sel_op_is_indirect_wire_4_, e execution_sel_op_is_indirect_wire_5_, e execution_sel_op_is_indirect_wire_6_, e execution_sel_op_is_indirect_wire_7_, e execution_sel_op_is_relative_wire_0_, e execution_sel_op_is_relative_wire_1_, e execution_sel_op_is_relative_wire_2_, e execution_sel_op_is_relative_wire_3_, e execution_sel_op_is_relative_wire_4_, e execution_sel_op_is_relative_wire_5_, e execution_sel_op_is_relative_wire_6_, e execution_sel_op_is_relative_wire_7_, e execution_sel_op_reg_effective_0_, e execution_sel_op_reg_effective_1_, e execution_sel_op_reg_effective_2_, e execution_sel_op_reg_effective_3_, e execution_sel_op_reg_effective_4_, e execution_sel_op_reg_effective_5_, e execution_sel_opcode_error, e execution_sel_out_of_gas, e execution_sel_radix_gt_256, e execution_sel_reached_max_note_hashes, e execution_sel_reached_max_nullifiers, e execution_sel_read_registers, e execution_sel_read_unwind_call_stack, e execution_sel_register_read_error, e execution_sel_relative_overflow_0_, e execution_sel_relative_overflow_1_, e execution_sel_relative_overflow_2_, e execution_sel_relative_overflow_3_, e execution_sel_relative_overflow_4_, e execution_sel_relative_overflow_5_, e execution_sel_relative_overflow_6_, e execution_sel_some_final_check_failed, e execution_sel_tag_check_reg_0_, e execution_sel_tag_check_reg_1_, e execution_sel_tag_check_reg_2_, e execution_sel_tag_check_reg_3_, e execution_sel_tag_check_reg_4_, e execution_sel_tag_check_reg_5_, e execution_sel_too_large_recipient_error, e execution_sel_use_num_limbs, e execution_sel_write_l2_to_l1_msg, e execution_sel_write_note_hash, e execution_sel_write_nullifier, e execution_sel_write_public_data, e execution_sel_write_registers, e execution_subtrace_id, e execution_subtrace_operation_id, e execution_total_gas_da, e execution_total_gas_l2, e execution_two_five_six, e execution_value_from_pi, e execution_written_public_data_slots_tree_root, e execution_written_public_data_slots_tree_size, e execution_written_slots_merkle_separator, e execution_written_slots_tree_height, e execution_written_slots_tree_siloing_separator, e ff_gt_a, e ff_gt_b, e ff_gt_borrow, e ff_gt_constant_128, e ff_gt_end, e ff_gt_p_a_borrow, e ff_gt_p_b_borrow, e ff_gt_res_hi, e ff_gt_res_lo, e ff_gt_result, e get_contract_instance_clk, e get_contract_instance_contract_address, e get_contract_instance_dst_offset, e get_contract_instance_dst_offset_diff_max_inv, e get_contract_instance_exists_tag, e get_contract_instance_instance_exists, e get_contract_instance_is_class_id, e get_contract_instance_is_deployer, e get_contract_instance_is_immutables_hash, e get_contract_instance_is_init_hash, e get_contract_instance_is_valid_member_enum, e get_contract_instance_is_valid_writes_in_bounds, e get_contract_instance_member_enum, e get_contract_instance_member_tag, e get_contract_instance_member_write_offset, e get_contract_instance_nullifier_tree_root, e get_contract_instance_public_data_tree_root, e get_contract_instance_retrieved_class_id, e get_contract_instance_retrieved_deployer_addr, e get_contract_instance_retrieved_immutables_hash, e get_contract_instance_retrieved_init_hash, e get_contract_instance_sel, e get_contract_instance_sel_error, e get_contract_instance_selected_member, e get_contract_instance_space_id, e gt_abs_diff, e gt_input_a, e gt_input_b, e gt_num_bits, e gt_res, e gt_sel, e gt_sel_addressing, e gt_sel_alu, e gt_sel_gas, e gt_sel_others, e gt_sel_sha256, e indexed_tree_check_address, e indexed_tree_check_const_three, e indexed_tree_check_discard, e indexed_tree_check_exists, e indexed_tree_check_intermediate_root, e indexed_tree_check_low_leaf_hash, e indexed_tree_check_low_leaf_index, e indexed_tree_check_low_leaf_next_index, e indexed_tree_check_low_leaf_next_value, e indexed_tree_check_low_leaf_value, e indexed_tree_check_merkle_hash_separator, e indexed_tree_check_new_leaf_hash, e indexed_tree_check_next_value_inv, e indexed_tree_check_next_value_is_nonzero, e indexed_tree_check_not_exists, e indexed_tree_check_public_inputs_index, e indexed_tree_check_root, e indexed_tree_check_sel, e indexed_tree_check_sel_insert, e indexed_tree_check_sel_silo, e indexed_tree_check_sel_write_to_public_inputs, e indexed_tree_check_siloed_value, e indexed_tree_check_siloing_separator, e indexed_tree_check_tree_height, e indexed_tree_check_tree_size_after_write, e indexed_tree_check_tree_size_before_write, e indexed_tree_check_updated_low_leaf_hash, e indexed_tree_check_updated_low_leaf_next_index, e indexed_tree_check_updated_low_leaf_next_value, e indexed_tree_check_value, e indexed_tree_check_value_low_leaf_value_diff_inv, e indexed_tree_check_write, e indexed_tree_check_write_root, e instr_fetching_addressing_mode, e instr_fetching_bd0, e instr_fetching_bd1, e instr_fetching_bd10, e instr_fetching_bd11, e instr_fetching_bd12, e instr_fetching_bd13, e instr_fetching_bd14, e instr_fetching_bd15, e instr_fetching_bd16, e instr_fetching_bd17, e instr_fetching_bd18, e instr_fetching_bd19, e instr_fetching_bd2, e instr_fetching_bd20, e instr_fetching_bd21, e instr_fetching_bd22, e instr_fetching_bd23, e instr_fetching_bd24, e instr_fetching_bd25, e instr_fetching_bd26, e instr_fetching_bd27, e instr_fetching_bd28, e instr_fetching_bd29, e instr_fetching_bd3, e instr_fetching_bd30, e instr_fetching_bd31, e instr_fetching_bd32, e instr_fetching_bd33, e instr_fetching_bd34, e instr_fetching_bd35, e instr_fetching_bd36, e instr_fetching_bd4, e instr_fetching_bd5, e instr_fetching_bd6, e instr_fetching_bd7, e instr_fetching_bd8, e instr_fetching_bd9, e instr_fetching_bytecode_id, e instr_fetching_bytecode_size, e instr_fetching_bytes_to_read, e instr_fetching_exec_opcode, e instr_fetching_instr_abs_diff, e instr_fetching_instr_out_of_range, e instr_fetching_instr_size, e instr_fetching_op1, e instr_fetching_op2, e instr_fetching_op3, e instr_fetching_op4, e instr_fetching_op5, e instr_fetching_op6, e instr_fetching_op7, e instr_fetching_opcode_out_of_range, e instr_fetching_pc, e instr_fetching_pc_abs_diff, e instr_fetching_pc_out_of_range, e instr_fetching_pc_size_in_bits, e instr_fetching_sel, e instr_fetching_sel_has_tag, e instr_fetching_sel_op_dc_0, e instr_fetching_sel_op_dc_1, e instr_fetching_sel_op_dc_10, e instr_fetching_sel_op_dc_11, e instr_fetching_sel_op_dc_12, e instr_fetching_sel_op_dc_13, e instr_fetching_sel_op_dc_14, e instr_fetching_sel_op_dc_15, e instr_fetching_sel_op_dc_16, e instr_fetching_sel_op_dc_2, e instr_fetching_sel_op_dc_3, e instr_fetching_sel_op_dc_4, e instr_fetching_sel_op_dc_5, e instr_fetching_sel_op_dc_6, e instr_fetching_sel_op_dc_7, e instr_fetching_sel_op_dc_8, e instr_fetching_sel_op_dc_9, e instr_fetching_sel_parsing_err, e instr_fetching_sel_pc_in_range, e instr_fetching_sel_tag_is_op2, e instr_fetching_tag_out_of_range, e instr_fetching_tag_value, e internal_call_stack_call_id, e internal_call_stack_context_id, e internal_call_stack_entered_call_id, e internal_call_stack_return_call_id, e internal_call_stack_return_pc, e internal_call_stack_sel, e keccak_memory_ctr_end, e keccak_memory_end, e keccak_memory_single_tag_error, e keccak_memory_state_size_min_ctr_inv, e keccak_memory_tag, e keccak_memory_tag_min_u64_inv, e keccak_memory_val_24_, e keccakf1600_bitwise_and_op_id, e keccakf1600_bitwise_xor_op_id, e keccakf1600_dst_out_of_range_error, e keccakf1600_end, e keccakf1600_error, e keccakf1600_highest_slice_address, e keccakf1600_rot_64_min_len_01, e keccakf1600_rot_64_min_len_03, e keccakf1600_rot_64_min_len_11, e keccakf1600_rot_64_min_len_13, e keccakf1600_rot_64_min_len_20, e keccakf1600_rot_64_min_len_22, e keccakf1600_rot_64_min_len_24, e keccakf1600_rot_64_min_len_31, e keccakf1600_rot_64_min_len_34, e keccakf1600_rot_64_min_len_42, e keccakf1600_rot_len_02, e keccakf1600_rot_len_04, e keccakf1600_rot_len_10, e keccakf1600_rot_len_12, e keccakf1600_rot_len_14, e keccakf1600_rot_len_21, e keccakf1600_rot_len_23, e keccakf1600_rot_len_30, e keccakf1600_rot_len_32, e keccakf1600_rot_len_33, e keccakf1600_rot_len_40, e keccakf1600_rot_len_41, e keccakf1600_rot_len_43, e keccakf1600_rot_len_44, e keccakf1600_round_cst, e keccakf1600_sel_slice_read, e keccakf1600_sel_slice_write, e keccakf1600_src_addr, e keccakf1600_src_out_of_range_error, e keccakf1600_state_chi_00, e keccakf1600_state_chi_01, e keccakf1600_state_chi_02, e keccakf1600_state_chi_03, e keccakf1600_state_chi_04, e keccakf1600_state_chi_10, e keccakf1600_state_chi_11, e keccakf1600_state_chi_12, e keccakf1600_state_chi_13, e keccakf1600_state_chi_14, e keccakf1600_state_chi_20, e keccakf1600_state_chi_21, e keccakf1600_state_chi_22, e keccakf1600_state_chi_23, e keccakf1600_state_chi_24, e keccakf1600_state_chi_30, e keccakf1600_state_chi_31, e keccakf1600_state_chi_32, e keccakf1600_state_chi_33, e keccakf1600_state_chi_34, e keccakf1600_state_chi_40, e keccakf1600_state_chi_41, e keccakf1600_state_chi_42, e keccakf1600_state_chi_43, e keccakf1600_state_chi_44, e keccakf1600_state_iota_00, e keccakf1600_state_pi_and_00, e keccakf1600_state_pi_and_01, e keccakf1600_state_pi_and_02, e keccakf1600_state_pi_and_03, e keccakf1600_state_pi_and_04, e keccakf1600_state_pi_and_10, e keccakf1600_state_pi_and_11, e keccakf1600_state_pi_and_12, e keccakf1600_state_pi_and_13, e keccakf1600_state_pi_and_14, e keccakf1600_state_pi_and_20, e keccakf1600_state_pi_and_21, e keccakf1600_state_pi_and_22, e keccakf1600_state_pi_and_23, e keccakf1600_state_pi_and_24, e keccakf1600_state_pi_and_30, e keccakf1600_state_pi_and_31, e keccakf1600_state_pi_and_32, e keccakf1600_state_pi_and_33, e keccakf1600_state_pi_and_34, e keccakf1600_state_pi_and_40, e keccakf1600_state_pi_and_41, e keccakf1600_state_pi_and_42, e keccakf1600_state_pi_and_43, e keccakf1600_state_pi_and_44, e keccakf1600_state_pi_not_00, e keccakf1600_state_pi_not_01, e keccakf1600_state_pi_not_02, e keccakf1600_state_pi_not_03, e keccakf1600_state_pi_not_04, e keccakf1600_state_pi_not_10, e keccakf1600_state_pi_not_11, e keccakf1600_state_pi_not_12, e keccakf1600_state_pi_not_13, e keccakf1600_state_pi_not_14, e keccakf1600_state_pi_not_20, e keccakf1600_state_pi_not_21, e keccakf1600_state_pi_not_22, e keccakf1600_state_pi_not_23, e keccakf1600_state_pi_not_24, e keccakf1600_state_pi_not_30, e keccakf1600_state_pi_not_31, e keccakf1600_state_pi_not_32, e keccakf1600_state_pi_not_33, e keccakf1600_state_pi_not_34, e keccakf1600_state_pi_not_40, e keccakf1600_state_pi_not_41, e keccakf1600_state_pi_not_42, e keccakf1600_state_pi_not_43, e keccakf1600_state_pi_not_44, e keccakf1600_state_rho_01, e keccakf1600_state_rho_02, e keccakf1600_state_rho_03, e keccakf1600_state_rho_04, e keccakf1600_state_rho_10, e keccakf1600_state_rho_11, e keccakf1600_state_rho_12, e keccakf1600_state_rho_13, e keccakf1600_state_rho_14, e keccakf1600_state_rho_20, e keccakf1600_state_rho_21, e keccakf1600_state_rho_22, e keccakf1600_state_rho_23, e keccakf1600_state_rho_24, e keccakf1600_state_rho_30, e keccakf1600_state_rho_31, e keccakf1600_state_rho_32, e keccakf1600_state_rho_33, e keccakf1600_state_rho_34, e keccakf1600_state_rho_40, e keccakf1600_state_rho_41, e keccakf1600_state_rho_42, e keccakf1600_state_rho_43, e keccakf1600_state_rho_44, e keccakf1600_state_theta_00, e keccakf1600_state_theta_01, e keccakf1600_state_theta_02, e keccakf1600_state_theta_03, e keccakf1600_state_theta_04, e keccakf1600_state_theta_10, e keccakf1600_state_theta_11, e keccakf1600_state_theta_12, e keccakf1600_state_theta_13, e keccakf1600_state_theta_14, e keccakf1600_state_theta_20, e keccakf1600_state_theta_21, e keccakf1600_state_theta_22, e keccakf1600_state_theta_23, e keccakf1600_state_theta_24, e keccakf1600_state_theta_30, e keccakf1600_state_theta_31, e keccakf1600_state_theta_32, e keccakf1600_state_theta_33, e keccakf1600_state_theta_34, e keccakf1600_state_theta_40, e keccakf1600_state_theta_41, e keccakf1600_state_theta_42, e keccakf1600_state_theta_43, e keccakf1600_state_theta_44, e keccakf1600_state_theta_hi_02, e keccakf1600_state_theta_hi_04, e keccakf1600_state_theta_hi_10, e keccakf1600_state_theta_hi_12, e keccakf1600_state_theta_hi_14, e keccakf1600_state_theta_hi_21, e keccakf1600_state_theta_hi_23, e keccakf1600_state_theta_hi_30, e keccakf1600_state_theta_hi_32, e keccakf1600_state_theta_hi_33, e keccakf1600_state_theta_hi_40, e keccakf1600_state_theta_hi_41, e keccakf1600_state_theta_hi_43, e keccakf1600_state_theta_hi_44, e keccakf1600_state_theta_low_01, e keccakf1600_state_theta_low_03, e keccakf1600_state_theta_low_11, e keccakf1600_state_theta_low_13, e keccakf1600_state_theta_low_20, e keccakf1600_state_theta_low_22, e keccakf1600_state_theta_low_24, e keccakf1600_state_theta_low_31, e keccakf1600_state_theta_low_34, e keccakf1600_state_theta_low_42, e keccakf1600_tag_error, e keccakf1600_tag_u64, e keccakf1600_theta_combined_xor_0, e keccakf1600_theta_combined_xor_1, e keccakf1600_theta_combined_xor_2, e keccakf1600_theta_combined_xor_3, e keccakf1600_theta_combined_xor_4, e keccakf1600_theta_xor_01, e keccakf1600_theta_xor_02, e keccakf1600_theta_xor_03, e keccakf1600_theta_xor_11, e keccakf1600_theta_xor_12, e keccakf1600_theta_xor_13, e keccakf1600_theta_xor_21, e keccakf1600_theta_xor_22, e keccakf1600_theta_xor_23, e keccakf1600_theta_xor_31, e keccakf1600_theta_xor_32, e keccakf1600_theta_xor_33, e keccakf1600_theta_xor_41, e keccakf1600_theta_xor_42, e keccakf1600_theta_xor_43, e keccakf1600_theta_xor_row_0, e keccakf1600_theta_xor_row_1, e keccakf1600_theta_xor_row_2, e keccakf1600_theta_xor_row_3, e keccakf1600_theta_xor_row_4, e keccakf1600_theta_xor_row_msb_0, e keccakf1600_theta_xor_row_msb_1, e keccakf1600_theta_xor_row_msb_2, e keccakf1600_theta_xor_row_msb_3, e keccakf1600_theta_xor_row_msb_4, e keccakf1600_theta_xor_row_rotl1_0, e keccakf1600_theta_xor_row_rotl1_1, e keccakf1600_theta_xor_row_rotl1_2, e keccakf1600_theta_xor_row_rotl1_3, e keccakf1600_theta_xor_row_rotl1_4, e l1_to_l2_message_tree_check_exists, e l1_to_l2_message_tree_check_l1_to_l2_message_tree_height, e l1_to_l2_message_tree_check_leaf_index, e l1_to_l2_message_tree_check_leaf_value, e l1_to_l2_message_tree_check_leaf_value_msg_hash_diff_inv, e l1_to_l2_message_tree_check_merkle_hash_separator, e l1_to_l2_message_tree_check_msg_hash, e l1_to_l2_message_tree_check_root, e l1_to_l2_message_tree_check_sel, e memory_diff, e memory_glob_addr_diff_inv, e memory_last_access, e memory_limb_0_, e memory_limb_1_, e memory_limb_2_, e memory_max_bits, e memory_sel_addressing_base, e memory_sel_addressing_indirect_0_, e memory_sel_addressing_indirect_1_, e memory_sel_addressing_indirect_2_, e memory_sel_addressing_indirect_3_, e memory_sel_addressing_indirect_4_, e memory_sel_addressing_indirect_5_, e memory_sel_addressing_indirect_6_, e memory_sel_data_copy_read, e memory_sel_data_copy_write, e memory_sel_ecc_write_0_, e memory_sel_ecc_write_1_, e memory_sel_get_contract_instance_exists_write, e memory_sel_get_contract_instance_member_write, e memory_sel_keccak, e memory_sel_poseidon2_read_0_, e memory_sel_poseidon2_read_1_, e memory_sel_poseidon2_read_2_, e memory_sel_poseidon2_read_3_, e memory_sel_poseidon2_write_0_, e memory_sel_poseidon2_write_1_, e memory_sel_poseidon2_write_2_, e memory_sel_poseidon2_write_3_, e memory_sel_public_log_read, e memory_sel_register_op_0_, e memory_sel_register_op_1_, e memory_sel_register_op_2_, e memory_sel_register_op_3_, e memory_sel_register_op_4_, e memory_sel_register_op_5_, e memory_sel_rng_chk, e memory_sel_rng_write, e memory_sel_sha256_op_0_, e memory_sel_sha256_op_1_, e memory_sel_sha256_op_2_, e memory_sel_sha256_op_3_, e memory_sel_sha256_op_4_, e memory_sel_sha256_op_5_, e memory_sel_sha256_op_6_, e memory_sel_sha256_op_7_, e memory_sel_sha256_read, e memory_sel_tag_is_ff, e memory_sel_to_radix_write, e memory_tag_ff_diff_inv, e merkle_check_const_three, e merkle_check_end, e merkle_check_index_is_even, e merkle_check_path_len_min_one_inv, e merkle_check_read_left_node, e merkle_check_read_output_hash, e merkle_check_read_right_node, e merkle_check_sibling, e merkle_check_write_left_node, e merkle_check_write_output_hash, e merkle_check_write_right_node, e note_hash_tree_check_address, e note_hash_tree_check_const_three, e note_hash_tree_check_discard, e note_hash_tree_check_exists, e note_hash_tree_check_first_nullifier, e note_hash_tree_check_first_nullifier_pi_index, e note_hash_tree_check_leaf_index, e note_hash_tree_check_merkle_hash_separator, e note_hash_tree_check_next_leaf_value, e note_hash_tree_check_next_root, e note_hash_tree_check_nonce, e note_hash_tree_check_nonce_separator, e note_hash_tree_check_note_hash, e note_hash_tree_check_note_hash_index, e note_hash_tree_check_note_hash_tree_height, e note_hash_tree_check_prev_leaf_value, e note_hash_tree_check_prev_leaf_value_unique_note_hash_diff_inv, e note_hash_tree_check_prev_root, e note_hash_tree_check_public_inputs_index, e note_hash_tree_check_sel, e note_hash_tree_check_sel_silo, e note_hash_tree_check_sel_unique, e note_hash_tree_check_sel_write_to_public_inputs, e note_hash_tree_check_siloed_note_hash, e note_hash_tree_check_siloing_separator, e note_hash_tree_check_unique_note_hash, e note_hash_tree_check_unique_note_hash_separator, e note_hash_tree_check_write, e poseidon2_hash_b_0, e poseidon2_hash_b_1, e poseidon2_hash_b_2, e poseidon2_hash_b_3, e poseidon2_hash_end, e poseidon2_hash_input_len, e poseidon2_hash_num_perm_rounds_rem_min_one_inv, e poseidon2_hash_padding, e poseidon2_perm_B_10_0, e poseidon2_perm_B_10_1, e poseidon2_perm_B_10_2, e poseidon2_perm_B_10_3, e poseidon2_perm_B_11_0, e poseidon2_perm_B_11_1, e poseidon2_perm_B_11_2, e poseidon2_perm_B_11_3, e poseidon2_perm_B_12_0, e poseidon2_perm_B_12_1, e poseidon2_perm_B_12_2, e poseidon2_perm_B_12_3, e poseidon2_perm_B_13_0, e poseidon2_perm_B_13_1, e poseidon2_perm_B_13_2, e poseidon2_perm_B_13_3, e poseidon2_perm_B_14_0, e poseidon2_perm_B_14_1, e poseidon2_perm_B_14_2, e poseidon2_perm_B_14_3, e poseidon2_perm_B_15_0, e poseidon2_perm_B_15_1, e poseidon2_perm_B_15_2, e poseidon2_perm_B_15_3, e poseidon2_perm_B_16_0, e poseidon2_perm_B_16_1, e poseidon2_perm_B_16_2, e poseidon2_perm_B_16_3, e poseidon2_perm_B_17_0, e poseidon2_perm_B_17_1, e poseidon2_perm_B_17_2, e poseidon2_perm_B_17_3, e poseidon2_perm_B_18_0, e poseidon2_perm_B_18_1, e poseidon2_perm_B_18_2, e poseidon2_perm_B_18_3, e poseidon2_perm_B_19_0, e poseidon2_perm_B_19_1, e poseidon2_perm_B_19_2, e poseidon2_perm_B_19_3, e poseidon2_perm_B_20_0, e poseidon2_perm_B_20_1, e poseidon2_perm_B_20_2, e poseidon2_perm_B_20_3, e poseidon2_perm_B_21_0, e poseidon2_perm_B_21_1, e poseidon2_perm_B_21_2, e poseidon2_perm_B_21_3, e poseidon2_perm_B_22_0, e poseidon2_perm_B_22_1, e poseidon2_perm_B_22_2, e poseidon2_perm_B_22_3, e poseidon2_perm_B_23_0, e poseidon2_perm_B_23_1, e poseidon2_perm_B_23_2, e poseidon2_perm_B_23_3, e poseidon2_perm_B_24_0, e poseidon2_perm_B_24_1, e poseidon2_perm_B_24_2, e poseidon2_perm_B_24_3, e poseidon2_perm_B_25_0, e poseidon2_perm_B_25_1, e poseidon2_perm_B_25_2, e poseidon2_perm_B_25_3, e poseidon2_perm_B_26_0, e poseidon2_perm_B_26_1, e poseidon2_perm_B_26_2, e poseidon2_perm_B_26_3, e poseidon2_perm_B_27_0, e poseidon2_perm_B_27_1, e poseidon2_perm_B_27_2, e poseidon2_perm_B_27_3, e poseidon2_perm_B_28_0, e poseidon2_perm_B_28_1, e poseidon2_perm_B_28_2, e poseidon2_perm_B_28_3, e poseidon2_perm_B_29_0, e poseidon2_perm_B_29_1, e poseidon2_perm_B_29_2, e poseidon2_perm_B_29_3, e poseidon2_perm_B_30_0, e poseidon2_perm_B_30_1, e poseidon2_perm_B_30_2, e poseidon2_perm_B_30_3, e poseidon2_perm_B_31_0, e poseidon2_perm_B_31_1, e poseidon2_perm_B_31_2, e poseidon2_perm_B_31_3, e poseidon2_perm_B_32_0, e poseidon2_perm_B_32_1, e poseidon2_perm_B_32_2, e poseidon2_perm_B_32_3, e poseidon2_perm_B_33_0, e poseidon2_perm_B_33_1, e poseidon2_perm_B_33_2, e poseidon2_perm_B_33_3, e poseidon2_perm_B_34_0, e poseidon2_perm_B_34_1, e poseidon2_perm_B_34_2, e poseidon2_perm_B_34_3, e poseidon2_perm_B_35_0, e poseidon2_perm_B_35_1, e poseidon2_perm_B_35_2, e poseidon2_perm_B_35_3, e poseidon2_perm_B_36_0, e poseidon2_perm_B_36_1, e poseidon2_perm_B_36_2, e poseidon2_perm_B_36_3, e poseidon2_perm_B_37_0, e poseidon2_perm_B_37_1, e poseidon2_perm_B_37_2, e poseidon2_perm_B_37_3, e poseidon2_perm_B_38_0, e poseidon2_perm_B_38_1, e poseidon2_perm_B_38_2, e poseidon2_perm_B_38_3, e poseidon2_perm_B_39_0, e poseidon2_perm_B_39_1, e poseidon2_perm_B_39_2, e poseidon2_perm_B_39_3, e poseidon2_perm_B_40_0, e poseidon2_perm_B_40_1, e poseidon2_perm_B_40_2, e poseidon2_perm_B_40_3, e poseidon2_perm_B_41_0, e poseidon2_perm_B_41_1, e poseidon2_perm_B_41_2, e poseidon2_perm_B_41_3, e poseidon2_perm_B_42_0, e poseidon2_perm_B_42_1, e poseidon2_perm_B_42_2, e poseidon2_perm_B_42_3, e poseidon2_perm_B_43_0, e poseidon2_perm_B_43_1, e poseidon2_perm_B_43_2, e poseidon2_perm_B_43_3, e poseidon2_perm_B_44_0, e poseidon2_perm_B_44_1, e poseidon2_perm_B_44_2, e poseidon2_perm_B_44_3, e poseidon2_perm_B_45_0, e poseidon2_perm_B_45_1, e poseidon2_perm_B_45_2, e poseidon2_perm_B_45_3, e poseidon2_perm_B_46_0, e poseidon2_perm_B_46_1, e poseidon2_perm_B_46_2, e poseidon2_perm_B_46_3, e poseidon2_perm_B_47_0, e poseidon2_perm_B_47_1, e poseidon2_perm_B_47_2, e poseidon2_perm_B_47_3, e poseidon2_perm_B_48_0, e poseidon2_perm_B_48_1, e poseidon2_perm_B_48_2, e poseidon2_perm_B_48_3, e poseidon2_perm_B_49_0, e poseidon2_perm_B_49_1, e poseidon2_perm_B_49_2, e poseidon2_perm_B_49_3, e poseidon2_perm_B_4_0, e poseidon2_perm_B_4_1, e poseidon2_perm_B_4_2, e poseidon2_perm_B_4_3, e poseidon2_perm_B_50_0, e poseidon2_perm_B_50_1, e poseidon2_perm_B_50_2, e poseidon2_perm_B_50_3, e poseidon2_perm_B_51_0, e poseidon2_perm_B_51_1, e poseidon2_perm_B_51_2, e poseidon2_perm_B_51_3, e poseidon2_perm_B_52_0, e poseidon2_perm_B_52_1, e poseidon2_perm_B_52_2, e poseidon2_perm_B_52_3, e poseidon2_perm_B_53_0, e poseidon2_perm_B_53_1, e poseidon2_perm_B_53_2, e poseidon2_perm_B_53_3, e poseidon2_perm_B_54_0, e poseidon2_perm_B_54_1, e poseidon2_perm_B_54_2, e poseidon2_perm_B_54_3, e poseidon2_perm_B_55_0, e poseidon2_perm_B_55_1, e poseidon2_perm_B_55_2, e poseidon2_perm_B_55_3, e poseidon2_perm_B_56_0, e poseidon2_perm_B_56_1, e poseidon2_perm_B_56_2, e poseidon2_perm_B_56_3, e poseidon2_perm_B_57_0, e poseidon2_perm_B_57_1, e poseidon2_perm_B_57_2, e poseidon2_perm_B_57_3, e poseidon2_perm_B_58_0, e poseidon2_perm_B_58_1, e poseidon2_perm_B_58_2, e poseidon2_perm_B_58_3, e poseidon2_perm_B_59_0, e poseidon2_perm_B_59_1, e poseidon2_perm_B_59_2, e poseidon2_perm_B_59_3, e poseidon2_perm_B_5_0, e poseidon2_perm_B_5_1, e poseidon2_perm_B_5_2, e poseidon2_perm_B_5_3, e poseidon2_perm_B_6_0, e poseidon2_perm_B_6_1, e poseidon2_perm_B_6_2, e poseidon2_perm_B_6_3, e poseidon2_perm_B_7_0, e poseidon2_perm_B_7_1, e poseidon2_perm_B_7_2, e poseidon2_perm_B_7_3, e poseidon2_perm_B_8_0, e poseidon2_perm_B_8_1, e poseidon2_perm_B_8_2, e poseidon2_perm_B_8_3, e poseidon2_perm_B_9_0, e poseidon2_perm_B_9_1, e poseidon2_perm_B_9_2, e poseidon2_perm_B_9_3, e poseidon2_perm_EXT_LAYER_4, e poseidon2_perm_EXT_LAYER_5, e poseidon2_perm_EXT_LAYER_6, e poseidon2_perm_EXT_LAYER_7, e poseidon2_perm_T_0_4, e poseidon2_perm_T_0_5, e poseidon2_perm_T_0_6, e poseidon2_perm_T_0_7, e poseidon2_perm_T_1_4, e poseidon2_perm_T_1_5, e poseidon2_perm_T_1_6, e poseidon2_perm_T_1_7, e poseidon2_perm_T_2_4, e poseidon2_perm_T_2_5, e poseidon2_perm_T_2_6, e poseidon2_perm_T_2_7, e poseidon2_perm_T_3_4, e poseidon2_perm_T_3_5, e poseidon2_perm_T_3_6, e poseidon2_perm_T_3_7, e poseidon2_perm_T_60_4, e poseidon2_perm_T_60_5, e poseidon2_perm_T_60_6, e poseidon2_perm_T_60_7, e poseidon2_perm_T_61_4, e poseidon2_perm_T_61_5, e poseidon2_perm_T_61_6, e poseidon2_perm_T_61_7, e poseidon2_perm_T_62_4, e poseidon2_perm_T_62_5, e poseidon2_perm_T_62_6, e poseidon2_perm_T_62_7, e poseidon2_perm_T_63_4, e poseidon2_perm_T_63_5, e poseidon2_perm_T_63_6, e poseidon2_perm_T_63_7, e poseidon2_perm_a_0, e poseidon2_perm_a_1, e poseidon2_perm_a_2, e poseidon2_perm_a_3, e poseidon2_perm_b_0, e poseidon2_perm_b_1, e poseidon2_perm_b_2, e poseidon2_perm_b_3, e poseidon2_perm_mem_batch_tag_inv, e poseidon2_perm_mem_err, e poseidon2_perm_mem_execution_clk, e poseidon2_perm_mem_input_0_, e poseidon2_perm_mem_input_1_, e poseidon2_perm_mem_input_2_, e poseidon2_perm_mem_input_3_, e poseidon2_perm_mem_input_tag_0_, e poseidon2_perm_mem_input_tag_1_, e poseidon2_perm_mem_input_tag_2_, e poseidon2_perm_mem_input_tag_3_, e poseidon2_perm_mem_max_mem_addr, e poseidon2_perm_mem_output_0_, e poseidon2_perm_mem_output_1_, e poseidon2_perm_mem_output_2_, e poseidon2_perm_mem_output_3_, e poseidon2_perm_mem_read_address_0_, e poseidon2_perm_mem_read_address_1_, e poseidon2_perm_mem_read_address_2_, e poseidon2_perm_mem_read_address_3_, e poseidon2_perm_mem_sel, e poseidon2_perm_mem_sel_dst_out_of_range_err, e poseidon2_perm_mem_sel_invalid_tag_err, e poseidon2_perm_mem_sel_should_exec, e poseidon2_perm_mem_sel_should_read_mem, e poseidon2_perm_mem_sel_src_out_of_range_err, e poseidon2_perm_mem_space_id, e poseidon2_perm_mem_write_address_0_, e poseidon2_perm_mem_write_address_1_, e poseidon2_perm_mem_write_address_2_, e poseidon2_perm_mem_write_address_3_, e poseidon2_perm_sel, e public_data_check_address, e public_data_check_clk_diff_hi, e public_data_check_clk_diff_lo, e public_data_check_const_four, e public_data_check_const_three, e public_data_check_discard, e public_data_check_end, e public_data_check_final_value, e public_data_check_intermediate_root, e public_data_check_leaf_not_exists, e public_data_check_leaf_slot, e public_data_check_leaf_slot_low_leaf_slot_diff_inv, e public_data_check_length_pi_idx, e public_data_check_low_leaf_hash, e public_data_check_low_leaf_index, e public_data_check_low_leaf_next_index, e public_data_check_low_leaf_next_slot, e public_data_check_low_leaf_slot, e public_data_check_low_leaf_value, e public_data_check_merkle_hash_separator, e public_data_check_new_leaf_hash, e public_data_check_next_slot_inv, e public_data_check_next_slot_is_nonzero, e public_data_check_non_discarded_write, e public_data_check_non_protocol_write, e public_data_check_not_end, e public_data_check_protocol_write, e public_data_check_public_data_writes_length, e public_data_check_root, e public_data_check_sel_write_to_public_inputs, e public_data_check_should_insert, e public_data_check_siloing_separator, e public_data_check_slot, e public_data_check_tree_height, e public_data_check_tree_size_after_write, e public_data_check_tree_size_before_write, e public_data_check_updated_low_leaf_hash, e public_data_check_updated_low_leaf_next_index, e public_data_check_updated_low_leaf_next_slot, e public_data_check_updated_low_leaf_value, e public_data_check_value, e public_data_check_write, e public_data_check_write_root, e public_data_squash_check_clock, e public_data_squash_clk_diff_hi, e public_data_squash_clk_diff_lo, e public_data_squash_leaf_slot_increase, e public_data_squash_value, e range_check_dyn_diff, e range_check_dyn_rng_chk_bits, e range_check_dyn_rng_chk_pow_2, e range_check_is_lte_u112, e range_check_is_lte_u128, e range_check_is_lte_u16, e range_check_is_lte_u32, e range_check_is_lte_u48, e range_check_is_lte_u64, e range_check_is_lte_u80, e range_check_is_lte_u96, e range_check_rng_chk_bits, e range_check_sel, e range_check_sel_alu, e range_check_sel_gt, e range_check_sel_keccak, e range_check_sel_memory, e range_check_sel_r0_16_bit_rng_lookup, e range_check_sel_r1_16_bit_rng_lookup, e range_check_sel_r2_16_bit_rng_lookup, e range_check_sel_r3_16_bit_rng_lookup, e range_check_sel_r4_16_bit_rng_lookup, e range_check_sel_r5_16_bit_rng_lookup, e range_check_sel_r6_16_bit_rng_lookup, e range_check_u16_r0, e range_check_u16_r1, e range_check_u16_r2, e range_check_u16_r3, e range_check_u16_r4, e range_check_u16_r5, e range_check_u16_r6, e range_check_u16_r7, e range_check_value, e scalar_mul_bit, e scalar_mul_const_two, e scalar_mul_end, e scalar_mul_sel_not_end, e scalar_mul_should_add, e sha256_a_and_b, e sha256_a_and_b_xor_a_and_c, e sha256_a_and_c, e sha256_a_rotr_13, e sha256_a_rotr_2, e sha256_a_rotr_22, e sha256_a_rotr_2_xor_a_rotr_13, e sha256_and_op_id, e sha256_b_and_c, e sha256_batch_tag_inv, e sha256_ch, e sha256_computed_w_lhs, e sha256_computed_w_rhs, e sha256_e_and_f, e sha256_e_rotr_11, e sha256_e_rotr_25, e sha256_e_rotr_6, e sha256_e_rotr_6_xor_e_rotr_11, e sha256_end, e sha256_err, e sha256_input, e sha256_input_rounds_rem_inv, e sha256_input_tag, e sha256_input_tag_diff_inv, e sha256_last, e sha256_lhs_w_10, e sha256_lhs_w_3, e sha256_maj, e sha256_max_input_addr, e sha256_max_mem_addr, e sha256_max_output_addr, e sha256_max_state_addr, e sha256_mem_out_of_range_err, e sha256_memory_address_0_, e sha256_memory_address_1_, e sha256_memory_address_2_, e sha256_memory_address_3_, e sha256_memory_address_4_, e sha256_memory_address_5_, e sha256_memory_address_6_, e sha256_memory_address_7_, e sha256_memory_register_0_, e sha256_memory_register_1_, e sha256_memory_register_2_, e sha256_memory_register_3_, e sha256_memory_register_4_, e sha256_memory_register_5_, e sha256_memory_register_6_, e sha256_memory_register_7_, e sha256_memory_tag_0_, e sha256_memory_tag_1_, e sha256_memory_tag_2_, e sha256_memory_tag_3_, e sha256_memory_tag_4_, e sha256_memory_tag_5_, e sha256_memory_tag_6_, e sha256_memory_tag_7_, e sha256_next_a_lhs, e sha256_next_a_rhs, e sha256_next_e_lhs, e sha256_next_e_rhs, e sha256_not_e, e sha256_not_e_and_g, e sha256_output_a_lhs, e sha256_output_a_rhs, e sha256_output_b_lhs, e sha256_output_b_rhs, e sha256_output_c_lhs, e sha256_output_c_rhs, e sha256_output_d_lhs, e sha256_output_d_rhs, e sha256_output_e_lhs, e sha256_output_e_rhs, e sha256_output_f_lhs, e sha256_output_f_rhs, e sha256_output_g_lhs, e sha256_output_g_rhs, e sha256_output_h_lhs, e sha256_output_h_rhs, e sha256_perform_round, e sha256_rhs_a_13, e sha256_rhs_a_2, e sha256_rhs_a_22, e sha256_rhs_e_11, e sha256_rhs_e_25, e sha256_rhs_e_6, e sha256_rhs_w_10, e sha256_rhs_w_17, e sha256_rhs_w_18, e sha256_rhs_w_19, e sha256_rhs_w_3, e sha256_rhs_w_7, e sha256_round_constant, e sha256_round_count, e sha256_rounds_remaining_inv, e sha256_rw, e sha256_s_0, e sha256_s_1, e sha256_sel_compute_w, e sha256_sel_input_out_of_range_err, e sha256_sel_invalid_input_row_tag_err, e sha256_sel_invalid_state_tag_err, e sha256_sel_is_input_round, e sha256_sel_mem_state_or_output, e sha256_sel_output_out_of_range_err, e sha256_sel_read_input_from_memory, e sha256_sel_state_out_of_range_err, e sha256_state_addr, e sha256_two_pow_10, e sha256_two_pow_11, e sha256_two_pow_13, e sha256_two_pow_17, e sha256_two_pow_18, e sha256_two_pow_19, e sha256_two_pow_2, e sha256_two_pow_22, e sha256_two_pow_25, e sha256_two_pow_3, e sha256_two_pow_32, e sha256_two_pow_6, e sha256_two_pow_7, e sha256_u32_tag, e sha256_w, e sha256_w_15_rotr_18, e sha256_w_15_rotr_7, e sha256_w_15_rotr_7_xor_w_15_rotr_18, e sha256_w_2_rotr_17, e sha256_w_2_rotr_17_xor_w_2_rotr_19, e sha256_w_2_rotr_19, e sha256_w_s_0, e sha256_w_s_1, e sha256_xor_op_id, e to_radix_end, e to_radix_found, e to_radix_is_unsafe_limb, e to_radix_limb_p_diff, e to_radix_limb_radix_diff, e to_radix_mem_err, e to_radix_mem_input_validation_error, e to_radix_mem_last, e to_radix_mem_limb_index_to_lookup, e to_radix_mem_limb_value, e to_radix_mem_max_mem_size, e to_radix_mem_num_limbs_inv, e to_radix_mem_num_limbs_minus_one_inv, e to_radix_mem_output_tag, e to_radix_mem_radix_min_two_inv, e to_radix_mem_sel_dst_out_of_range_err, e to_radix_mem_sel_invalid_bitwise_radix, e to_radix_mem_sel_num_limbs_is_zero, e to_radix_mem_sel_radix_eq_2, e to_radix_mem_sel_radix_gt_256_err, e to_radix_mem_sel_radix_lt_2_err, e to_radix_mem_sel_value_is_zero, e to_radix_mem_two, e to_radix_mem_two_five_six, e to_radix_mem_value_found, e to_radix_mem_value_inv, e to_radix_mem_write_addr_upper_bound, e to_radix_p_limb, e to_radix_rem_inverse, e to_radix_safety_diff_inverse, e tx_array_length_l2_to_l1_messages_pi_offset, e tx_array_length_note_hashes_pi_offset, e tx_array_length_nullifiers_pi_offset, e tx_calldata_hash, e tx_calldata_size, e tx_const_three, e tx_contract_addr, e tx_dom_sep_public_storage_map_slot, e tx_effective_fee_per_da_gas, e tx_effective_fee_per_l2_gas, e tx_end_phase, e tx_fee_juice_balance_slot, e tx_fee_juice_balances_slot_constant, e tx_fee_juice_contract_address, e tx_fee_payer, e tx_fee_payer_balance, e tx_fee_payer_new_balance, e tx_fee_payer_pi_offset, e tx_fields_length_public_logs_pi_offset, e tx_gas_limit_pi_offset, e tx_gas_used_pi_offset, e tx_is_cleanup, e tx_is_collect_fee, e tx_is_padded, e tx_is_public_call_request, e tx_is_static, e tx_is_tree_insert_phase, e tx_is_tree_padding, e tx_l1_l2_pi_offset, e tx_l2_l1_msg_content, e tx_l2_l1_msg_contract_address, e tx_l2_l1_msg_recipient, e tx_leaf_value, e tx_msg_sender, e tx_next_da_gas_used, e tx_next_da_gas_used_sent_to_enqueued_call, e tx_next_l2_gas_used, e tx_next_l2_gas_used_sent_to_enqueued_call, e tx_next_note_hash_tree_root, e tx_next_note_hash_tree_size, e tx_next_nullifier_tree_root, e tx_next_nullifier_tree_size, e tx_next_num_l2_to_l1_messages, e tx_next_num_note_hashes_emitted, e tx_next_num_nullifiers_emitted, e tx_next_num_public_log_fields, e tx_next_phase_on_revert, e tx_next_public_data_tree_root, e tx_next_public_data_tree_size, e tx_next_retrieved_bytecodes_tree_root, e tx_next_retrieved_bytecodes_tree_size, e tx_next_written_public_data_slots_tree_root, e tx_next_written_public_data_slots_tree_size, e tx_note_hash_pi_offset, e tx_nullifier_limit_error, e tx_nullifier_merkle_separator, e tx_nullifier_pi_offset, e tx_nullifier_tree_height, e tx_prev_da_gas_used_sent_to_enqueued_call, e tx_prev_l2_gas_used_sent_to_enqueued_call, e tx_public_data_pi_offset, e tx_read_pi_length_offset, e tx_read_pi_start_offset, e tx_remaining_phase_inv, e tx_remaining_phase_minus_one_inv, e tx_remaining_side_effects_inv, e tx_reverted_pi_offset, e tx_sel_append_l2_l1_msg, e tx_sel_append_note_hash, e tx_sel_append_nullifier, e tx_sel_l2_l1_msg_append, e tx_sel_note_hash_append, e tx_sel_nullifier_append, e tx_sel_process_call_request, e tx_sel_read_phase_length, e tx_sel_read_trees_and_gas_used, e tx_sel_try_l2_l1_msg_append, e tx_sel_try_note_hash_append, e tx_sel_try_nullifier_append, e tx_setup_phase_value, e tx_should_read_gas_limit, e tx_uint32_max, e tx_write_nullifier_pi_offset, e tx_write_pi_offset, e update_check_address, e update_check_const_three, e update_check_contract_instance_registry_address, e update_check_current_class_id, e update_check_delayed_public_mutable_hash_slot, e update_check_delayed_public_mutable_slot, e update_check_dom_sep_public_storage_map_slot, e update_check_hash_not_zero, e update_check_original_class_id, e update_check_public_data_tree_root, e update_check_sel, e update_check_timestamp, e update_check_timestamp_is_lt_timestamp_of_change, e update_check_timestamp_of_change, e update_check_timestamp_of_change_bit_size, e update_check_timestamp_pi_offset, e update_check_update_hash, e update_check_update_hash_inv, e update_check_update_hi_metadata, e update_check_update_hi_metadata_bit_size, e update_check_update_post_class_id_is_zero, e update_check_update_post_class_inv, e update_check_update_pre_class_id_is_zero, e update_check_update_pre_class_inv, e update_check_update_preimage_metadata, e update_check_update_preimage_post_class_id, e update_check_update_preimage_pre_class_id, e update_check_updated_class_ids_slot, e lookup_range_check_dyn_rng_chk_pow_2_counts, e lookup_range_check_dyn_diff_is_u16_counts, e lookup_range_check_r0_is_u16_counts, e lookup_range_check_r1_is_u16_counts, e lookup_range_check_r2_is_u16_counts, e lookup_range_check_r3_is_u16_counts, e lookup_range_check_r4_is_u16_counts, e lookup_range_check_r5_is_u16_counts, e lookup_range_check_r6_is_u16_counts, e lookup_range_check_r7_is_u16_counts, e lookup_ff_gt_a_lo_range_counts, e lookup_ff_gt_a_hi_range_counts, e lookup_gt_gt_range_counts, e lookup_alu_tag_max_bits_value_counts, e lookup_alu_range_check_decomposition_a_lo_counts, e lookup_alu_range_check_decomposition_a_hi_counts, e lookup_alu_range_check_decomposition_b_lo_counts, e lookup_alu_range_check_decomposition_b_hi_counts, e lookup_alu_range_check_mul_c_hi_counts, e lookup_alu_range_check_div_remainder_counts, e lookup_alu_ff_gt_counts, e lookup_alu_int_gt_counts, e lookup_alu_shifts_two_pow_counts, e lookup_alu_large_trunc_canonical_dec_counts, e lookup_alu_range_check_trunc_mid_counts, e lookup_bitwise_integral_tag_length_counts, e lookup_bitwise_byte_operations_counts, e lookup_memory_range_check_limb_0_counts, e lookup_memory_range_check_limb_1_counts, e lookup_memory_range_check_limb_2_counts, e lookup_memory_tag_max_bits_counts, e lookup_memory_range_check_write_tagged_value_counts, e lookup_data_copy_offset_plus_size_is_gt_data_size_counts, e lookup_data_copy_check_src_addr_in_range_counts, e lookup_data_copy_check_dst_addr_in_range_counts, e lookup_data_copy_sel_has_reads_counts, e lookup_data_copy_col_read_counts, e lookup_ecc_mem_check_dst_addr_in_range_counts, e lookup_ecc_mem_input_output_ecc_add_counts, e lookup_keccakf1600_theta_xor_01_counts, e lookup_keccakf1600_theta_xor_02_counts, e lookup_keccakf1600_theta_xor_03_counts, e lookup_keccakf1600_theta_xor_row_0_counts, e lookup_keccakf1600_theta_xor_11_counts, e lookup_keccakf1600_theta_xor_12_counts, e lookup_keccakf1600_theta_xor_13_counts, e lookup_keccakf1600_theta_xor_row_1_counts, e lookup_keccakf1600_theta_xor_21_counts, e lookup_keccakf1600_theta_xor_22_counts, e lookup_keccakf1600_theta_xor_23_counts, e lookup_keccakf1600_theta_xor_row_2_counts, e lookup_keccakf1600_theta_xor_31_counts, e lookup_keccakf1600_theta_xor_32_counts, e lookup_keccakf1600_theta_xor_33_counts, e lookup_keccakf1600_theta_xor_row_3_counts, e lookup_keccakf1600_theta_xor_41_counts, e lookup_keccakf1600_theta_xor_42_counts, e lookup_keccakf1600_theta_xor_43_counts, e lookup_keccakf1600_theta_xor_row_4_counts, e lookup_keccakf1600_theta_combined_xor_0_counts, e lookup_keccakf1600_theta_combined_xor_1_counts, e lookup_keccakf1600_theta_combined_xor_2_counts, e lookup_keccakf1600_theta_combined_xor_3_counts, e lookup_keccakf1600_theta_combined_xor_4_counts, e lookup_keccakf1600_state_theta_00_counts, e lookup_keccakf1600_state_theta_01_counts, e lookup_keccakf1600_state_theta_02_counts, e lookup_keccakf1600_state_theta_03_counts, e lookup_keccakf1600_state_theta_04_counts, e lookup_keccakf1600_state_theta_10_counts, e lookup_keccakf1600_state_theta_11_counts, e lookup_keccakf1600_state_theta_12_counts, e lookup_keccakf1600_state_theta_13_counts, e lookup_keccakf1600_state_theta_14_counts, e lookup_keccakf1600_state_theta_20_counts, e lookup_keccakf1600_state_theta_21_counts, e lookup_keccakf1600_state_theta_22_counts, e lookup_keccakf1600_state_theta_23_counts, e lookup_keccakf1600_state_theta_24_counts, e lookup_keccakf1600_state_theta_30_counts, e lookup_keccakf1600_state_theta_31_counts, e lookup_keccakf1600_state_theta_32_counts, e lookup_keccakf1600_state_theta_33_counts, e lookup_keccakf1600_state_theta_34_counts, e lookup_keccakf1600_state_theta_40_counts, e lookup_keccakf1600_state_theta_41_counts, e lookup_keccakf1600_state_theta_42_counts, e lookup_keccakf1600_state_theta_43_counts, e lookup_keccakf1600_state_theta_44_counts, e lookup_keccakf1600_theta_limb_02_range_counts, e lookup_keccakf1600_theta_limb_04_range_counts, e lookup_keccakf1600_theta_limb_10_range_counts, e lookup_keccakf1600_theta_limb_12_range_counts, e lookup_keccakf1600_theta_limb_14_range_counts, e lookup_keccakf1600_theta_limb_21_range_counts, e lookup_keccakf1600_theta_limb_23_range_counts, e lookup_keccakf1600_theta_limb_30_range_counts, e lookup_keccakf1600_theta_limb_32_range_counts, e lookup_keccakf1600_theta_limb_33_range_counts, e lookup_keccakf1600_theta_limb_40_range_counts, e lookup_keccakf1600_theta_limb_41_range_counts, e lookup_keccakf1600_theta_limb_43_range_counts, e lookup_keccakf1600_theta_limb_44_range_counts, e lookup_keccakf1600_theta_limb_01_range_counts, e lookup_keccakf1600_theta_limb_03_range_counts, e lookup_keccakf1600_theta_limb_11_range_counts, e lookup_keccakf1600_theta_limb_13_range_counts, e lookup_keccakf1600_theta_limb_20_range_counts, e lookup_keccakf1600_theta_limb_22_range_counts, e lookup_keccakf1600_theta_limb_24_range_counts, e lookup_keccakf1600_theta_limb_31_range_counts, e lookup_keccakf1600_theta_limb_34_range_counts, e lookup_keccakf1600_theta_limb_42_range_counts, e lookup_keccakf1600_state_pi_and_00_counts, e lookup_keccakf1600_state_pi_and_01_counts, e lookup_keccakf1600_state_pi_and_02_counts, e lookup_keccakf1600_state_pi_and_03_counts, e lookup_keccakf1600_state_pi_and_04_counts, e lookup_keccakf1600_state_pi_and_10_counts, e lookup_keccakf1600_state_pi_and_11_counts, e lookup_keccakf1600_state_pi_and_12_counts, e lookup_keccakf1600_state_pi_and_13_counts, e lookup_keccakf1600_state_pi_and_14_counts, e lookup_keccakf1600_state_pi_and_20_counts, e lookup_keccakf1600_state_pi_and_21_counts, e lookup_keccakf1600_state_pi_and_22_counts, e lookup_keccakf1600_state_pi_and_23_counts, e lookup_keccakf1600_state_pi_and_24_counts, e lookup_keccakf1600_state_pi_and_30_counts, e lookup_keccakf1600_state_pi_and_31_counts, e lookup_keccakf1600_state_pi_and_32_counts, e lookup_keccakf1600_state_pi_and_33_counts, e lookup_keccakf1600_state_pi_and_34_counts, e lookup_keccakf1600_state_pi_and_40_counts, e lookup_keccakf1600_state_pi_and_41_counts, e lookup_keccakf1600_state_pi_and_42_counts, e lookup_keccakf1600_state_pi_and_43_counts, e lookup_keccakf1600_state_pi_and_44_counts, e lookup_keccakf1600_state_chi_00_counts, e lookup_keccakf1600_state_chi_01_counts, e lookup_keccakf1600_state_chi_02_counts, e lookup_keccakf1600_state_chi_03_counts, e lookup_keccakf1600_state_chi_04_counts, e lookup_keccakf1600_state_chi_10_counts, e lookup_keccakf1600_state_chi_11_counts, e lookup_keccakf1600_state_chi_12_counts, e lookup_keccakf1600_state_chi_13_counts, e lookup_keccakf1600_state_chi_14_counts, e lookup_keccakf1600_state_chi_20_counts, e lookup_keccakf1600_state_chi_21_counts, e lookup_keccakf1600_state_chi_22_counts, e lookup_keccakf1600_state_chi_23_counts, e lookup_keccakf1600_state_chi_24_counts, e lookup_keccakf1600_state_chi_30_counts, e lookup_keccakf1600_state_chi_31_counts, e lookup_keccakf1600_state_chi_32_counts, e lookup_keccakf1600_state_chi_33_counts, e lookup_keccakf1600_state_chi_34_counts, e lookup_keccakf1600_state_chi_40_counts, e lookup_keccakf1600_state_chi_41_counts, e lookup_keccakf1600_state_chi_42_counts, e lookup_keccakf1600_state_chi_43_counts, e lookup_keccakf1600_state_chi_44_counts, e lookup_keccakf1600_round_cst_counts, e lookup_keccakf1600_state_iota_00_counts, e lookup_keccakf1600_src_out_of_range_toggle_counts, e lookup_keccakf1600_dst_out_of_range_toggle_counts, e lookup_poseidon2_mem_check_src_addr_in_range_counts, e lookup_poseidon2_mem_check_dst_addr_in_range_counts, e lookup_poseidon2_mem_input_output_poseidon2_perm_counts, e lookup_to_radix_limb_range_counts, e lookup_to_radix_limb_less_than_radix_range_counts, e lookup_to_radix_fetch_safe_limbs_counts, e lookup_to_radix_fetch_p_limb_counts, e lookup_to_radix_limb_p_diff_range_counts, e lookup_scalar_mul_to_radix_counts, e lookup_scalar_mul_double_counts, e lookup_scalar_mul_add_counts, e lookup_sha256_range_comp_w_lhs_counts, e lookup_sha256_range_comp_w_rhs_counts, e lookup_sha256_range_rhs_w_7_counts, e lookup_sha256_range_rhs_w_18_counts, e lookup_sha256_range_rhs_w_3_counts, e lookup_sha256_w_s_0_xor_0_counts, e lookup_sha256_w_s_0_xor_1_counts, e lookup_sha256_range_rhs_w_17_counts, e lookup_sha256_range_rhs_w_19_counts, e lookup_sha256_range_rhs_w_10_counts, e lookup_sha256_w_s_1_xor_0_counts, e lookup_sha256_w_s_1_xor_1_counts, e lookup_sha256_range_rhs_e_6_counts, e lookup_sha256_range_rhs_e_11_counts, e lookup_sha256_range_rhs_e_25_counts, e lookup_sha256_s_1_xor_0_counts, e lookup_sha256_s_1_xor_1_counts, e lookup_sha256_ch_and_0_counts, e lookup_sha256_ch_and_1_counts, e lookup_sha256_ch_xor_counts, e lookup_sha256_round_constant_counts, e lookup_sha256_range_rhs_a_2_counts, e lookup_sha256_range_rhs_a_13_counts, e lookup_sha256_range_rhs_a_22_counts, e lookup_sha256_s_0_xor_0_counts, e lookup_sha256_s_0_xor_1_counts, e lookup_sha256_maj_and_0_counts, e lookup_sha256_maj_and_1_counts, e lookup_sha256_maj_and_2_counts, e lookup_sha256_maj_xor_0_counts, e lookup_sha256_maj_xor_1_counts, e lookup_sha256_range_comp_next_a_lhs_counts, e lookup_sha256_range_comp_next_a_rhs_counts, e lookup_sha256_range_comp_next_e_lhs_counts, e lookup_sha256_range_comp_next_e_rhs_counts, e lookup_sha256_range_comp_a_rhs_counts, e lookup_sha256_range_comp_b_rhs_counts, e lookup_sha256_range_comp_c_rhs_counts, e lookup_sha256_range_comp_d_rhs_counts, e lookup_sha256_range_comp_e_rhs_counts, e lookup_sha256_range_comp_f_rhs_counts, e lookup_sha256_range_comp_g_rhs_counts, e lookup_sha256_range_comp_h_rhs_counts, e lookup_sha256_mem_check_state_addr_in_range_counts, e lookup_sha256_mem_check_input_addr_in_range_counts, e lookup_sha256_mem_check_output_addr_in_range_counts, e lookup_to_radix_mem_check_dst_addr_in_range_counts, e lookup_to_radix_mem_check_radix_lt_2_counts, e lookup_to_radix_mem_check_radix_gt_256_counts, e lookup_to_radix_mem_input_output_to_radix_counts, e lookup_poseidon2_hash_poseidon2_perm_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_counts, e lookup_address_derivation_partial_address_poseidon2_counts, e lookup_address_derivation_ivpk_m_hash_poseidon2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_0_counts, e lookup_address_derivation_public_keys_hash_poseidon2_1_counts, e lookup_address_derivation_preaddress_poseidon2_counts, e lookup_address_derivation_preaddress_scalar_mul_counts, e lookup_address_derivation_address_ecadd_counts, e lookup_bc_decomposition_bytes_are_bytes_counts, e lookup_bc_hashing_poseidon2_hash_counts, e lookup_merkle_check_merkle_poseidon2_read_counts, e lookup_merkle_check_merkle_poseidon2_write_counts, e lookup_indexed_tree_check_silo_poseidon2_counts, e lookup_indexed_tree_check_low_leaf_value_validation_counts, e lookup_indexed_tree_check_low_leaf_next_value_validation_counts, e lookup_indexed_tree_check_low_leaf_poseidon2_counts, e lookup_indexed_tree_check_updated_low_leaf_poseidon2_counts, e lookup_indexed_tree_check_low_leaf_merkle_check_counts, e lookup_indexed_tree_check_new_leaf_poseidon2_counts, e lookup_indexed_tree_check_new_leaf_merkle_check_counts, e lookup_indexed_tree_check_write_value_to_public_inputs_counts, e lookup_public_data_squash_leaf_slot_increase_ff_gt_counts, e lookup_public_data_squash_clk_diff_range_lo_counts, e lookup_public_data_squash_clk_diff_range_hi_counts, e lookup_public_data_check_clk_diff_range_lo_counts, e lookup_public_data_check_clk_diff_range_hi_counts, e lookup_public_data_check_silo_poseidon2_counts, e lookup_public_data_check_low_leaf_slot_validation_counts, e lookup_public_data_check_low_leaf_next_slot_validation_counts, e lookup_public_data_check_low_leaf_poseidon2_0_counts, e lookup_public_data_check_low_leaf_poseidon2_1_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_0_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_1_counts, e lookup_public_data_check_low_leaf_merkle_check_counts, e lookup_public_data_check_new_leaf_poseidon2_0_counts, e lookup_public_data_check_new_leaf_poseidon2_1_counts, e lookup_public_data_check_new_leaf_merkle_check_counts, e lookup_public_data_check_write_public_data_to_public_inputs_counts, e lookup_public_data_check_write_writes_length_to_public_inputs_counts, e lookup_update_check_timestamp_from_public_inputs_counts, e lookup_update_check_delayed_public_mutable_slot_poseidon2_counts, e lookup_update_check_update_hash_public_data_read_counts, e lookup_update_check_update_hash_poseidon2_counts, e lookup_update_check_update_hi_metadata_range_counts, e lookup_update_check_update_lo_metadata_range_counts, e lookup_update_check_timestamp_is_lt_timestamp_of_change_counts, e lookup_contract_instance_retrieval_check_protocol_address_range_counts, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_counts, e lookup_contract_instance_retrieval_deployment_nullifier_read_counts, e lookup_contract_instance_retrieval_address_derivation_counts, e lookup_contract_instance_retrieval_update_check_counts, e lookup_class_id_derivation_class_id_poseidon2_0_counts, e lookup_class_id_derivation_class_id_poseidon2_1_counts, e lookup_bc_retrieval_contract_instance_retrieval_counts, e lookup_bc_retrieval_class_id_derivation_counts, e lookup_bc_retrieval_is_new_class_check_counts, e lookup_bc_retrieval_retrieved_bytecodes_insertion_counts, e lookup_instr_fetching_pc_abs_diff_positive_counts, e lookup_instr_fetching_instr_abs_diff_positive_counts, e lookup_instr_fetching_tag_value_validation_counts, e lookup_instr_fetching_bytecode_size_from_bc_dec_counts, e lookup_instr_fetching_bytes_from_bc_dec_counts, e lookup_instr_fetching_wire_instruction_info_counts, e lookup_emit_public_log_check_memory_out_of_bounds_counts, e lookup_emit_public_log_check_log_fields_count_counts, e lookup_emit_public_log_write_data_to_public_inputs_counts, e lookup_get_contract_instance_precomputed_info_counts, e lookup_get_contract_instance_contract_instance_retrieval_counts, e lookup_l1_to_l2_message_tree_check_merkle_check_counts, e lookup_internal_call_unwind_call_stack_counts, e lookup_context_ctx_stack_rollback_counts, e lookup_context_ctx_stack_return_counts, e lookup_addressing_relative_overflow_result_0_counts, e lookup_addressing_relative_overflow_result_1_counts, e lookup_addressing_relative_overflow_result_2_counts, e lookup_addressing_relative_overflow_result_3_counts, e lookup_addressing_relative_overflow_result_4_counts, e lookup_addressing_relative_overflow_result_5_counts, e lookup_addressing_relative_overflow_result_6_counts, e lookup_gas_addressing_gas_read_counts, e lookup_gas_is_out_of_gas_l2_counts, e lookup_gas_is_out_of_gas_da_counts, e lookup_note_hash_tree_check_silo_poseidon2_counts, e lookup_note_hash_tree_check_read_first_nullifier_counts, e lookup_note_hash_tree_check_nonce_computation_poseidon2_counts, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_counts, e lookup_note_hash_tree_check_merkle_check_counts, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_counts, e lookup_emit_notehash_notehash_tree_write_counts, e lookup_emit_nullifier_write_nullifier_counts, e lookup_external_call_is_l2_gas_left_gt_allocated_counts, e lookup_external_call_is_da_gas_left_gt_allocated_counts, e lookup_get_env_var_precomputed_info_counts, e lookup_get_env_var_read_from_public_inputs_col0_counts, e lookup_get_env_var_read_from_public_inputs_col1_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_counts, e lookup_notehash_exists_note_hash_leaf_index_in_range_counts, e lookup_notehash_exists_note_hash_read_counts, e lookup_nullifier_exists_nullifier_exists_check_counts, e lookup_send_l2_to_l1_msg_recipient_check_counts, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_counts, e lookup_sload_storage_read_counts, e lookup_sstore_record_written_storage_slot_counts, e lookup_execution_bytecode_retrieval_result_counts, e lookup_execution_instruction_fetching_result_counts, e lookup_execution_instruction_fetching_body_counts, e lookup_execution_exec_spec_read_counts, e lookup_execution_dyn_l2_factor_bitwise_counts, e lookup_execution_check_radix_gt_256_counts, e lookup_execution_get_p_limbs_counts, e lookup_execution_get_max_limbs_counts, e lookup_execution_check_written_storage_slot_counts, e lookup_execution_dispatch_to_alu_counts, e lookup_execution_dispatch_to_bitwise_counts, e lookup_execution_dispatch_to_cast_counts, e lookup_execution_dispatch_to_set_counts, e lookup_calldata_hashing_get_calldata_field_0_counts, e lookup_calldata_hashing_get_calldata_field_1_counts, e lookup_calldata_hashing_get_calldata_field_2_counts, e lookup_calldata_hashing_poseidon2_hash_counts, e lookup_tx_context_public_inputs_note_hash_tree_counts, e lookup_tx_context_public_inputs_nullifier_tree_counts, e lookup_tx_context_public_inputs_public_data_tree_counts, e lookup_tx_context_public_inputs_l1_l2_tree_counts, e lookup_tx_context_public_inputs_gas_used_counts, e lookup_tx_context_public_inputs_read_gas_limit_counts, e lookup_tx_context_public_inputs_read_reverted_counts, e lookup_tx_context_restore_state_on_revert_counts, e lookup_tx_context_public_inputs_write_note_hash_count_counts, e lookup_tx_context_public_inputs_write_nullifier_count_counts, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_counts, e lookup_tx_context_public_inputs_write_public_log_count_counts, e lookup_tx_read_phase_spec_counts, e lookup_tx_read_phase_length_counts, e lookup_tx_read_public_call_request_phase_counts, e lookup_tx_read_tree_insert_value_counts, e lookup_tx_note_hash_append_counts, e lookup_tx_nullifier_append_counts, e lookup_tx_read_l2_l1_msg_counts, e lookup_tx_write_l2_l1_msg_counts, e lookup_tx_read_effective_fee_public_inputs_counts, e lookup_tx_read_fee_payer_public_inputs_counts, e lookup_tx_balance_slot_poseidon2_counts, e lookup_tx_balance_read_counts, e lookup_tx_balance_validation_counts, e lookup_tx_write_fee_public_inputs_counts, e bc_decomposition_bytes, e bc_decomposition_bytes_pc_plus_1, e bc_decomposition_bytes_pc_plus_10, e bc_decomposition_bytes_pc_plus_11, e bc_decomposition_bytes_pc_plus_12, e bc_decomposition_bytes_pc_plus_13, e bc_decomposition_bytes_pc_plus_14, e bc_decomposition_bytes_pc_plus_15, e bc_decomposition_bytes_pc_plus_16, e bc_decomposition_bytes_pc_plus_17, e bc_decomposition_bytes_pc_plus_18, e bc_decomposition_bytes_pc_plus_19, e bc_decomposition_bytes_pc_plus_2, e bc_decomposition_bytes_pc_plus_20, e bc_decomposition_bytes_pc_plus_21, e bc_decomposition_bytes_pc_plus_22, e bc_decomposition_bytes_pc_plus_23, e bc_decomposition_bytes_pc_plus_24, e bc_decomposition_bytes_pc_plus_25, e bc_decomposition_bytes_pc_plus_26, e bc_decomposition_bytes_pc_plus_27, e bc_decomposition_bytes_pc_plus_28, e bc_decomposition_bytes_pc_plus_29, e bc_decomposition_bytes_pc_plus_3, e bc_decomposition_bytes_pc_plus_30, e bc_decomposition_bytes_pc_plus_31, e bc_decomposition_bytes_pc_plus_32, e bc_decomposition_bytes_pc_plus_33, e bc_decomposition_bytes_pc_plus_34, e bc_decomposition_bytes_pc_plus_35, e bc_decomposition_bytes_pc_plus_4, e bc_decomposition_bytes_pc_plus_5, e bc_decomposition_bytes_pc_plus_6, e bc_decomposition_bytes_pc_plus_7, e bc_decomposition_bytes_pc_plus_8, e bc_decomposition_bytes_pc_plus_9, e bc_decomposition_bytes_remaining, e bc_decomposition_id, e bc_decomposition_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_windows_gt_remaining, e bc_decomposition_start, e bc_hashing_bytecode_id, e bc_hashing_padding, e bc_hashing_pc_index_1, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_sel_not_start, e bc_hashing_start, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e bitwise_sel, e bitwise_start, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_src_context_id, e data_copy_start, e emit_public_log_contract_address, e emit_public_log_correct_tag, e emit_public_log_error_out_of_bounds, e emit_public_log_error_tag_mismatch, e emit_public_log_execution_clk, e emit_public_log_is_write_contract_address, e emit_public_log_is_write_memory_value, e emit_public_log_log_address, e emit_public_log_public_inputs_index, e emit_public_log_remaining_rows, e emit_public_log_seen_wrong_tag, e emit_public_log_sel, e emit_public_log_sel_write_to_public_inputs, e emit_public_log_space_id, e emit_public_log_start, e execution_bytecode_id, e execution_clk, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_public_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_sel, e keccak_memory_space_id, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_start, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_address, e memory_clk, e memory_rw, e memory_sel, e memory_space_id, e memory_tag, e memory_value, e merkle_check_index, e merkle_check_merkle_hash_separator, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_start, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, e poseidon2_hash_a_0, e poseidon2_hash_a_1, e poseidon2_hash_a_2, e poseidon2_hash_a_3, e poseidon2_hash_input_0, e poseidon2_hash_input_1, e poseidon2_hash_input_2, e poseidon2_hash_num_perm_rounds_rem, e poseidon2_hash_output, e poseidon2_hash_sel, e poseidon2_hash_start, e public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, e scalar_mul_bit_idx, e scalar_mul_point_inf, e scalar_mul_point_x, e scalar_mul_point_y, e scalar_mul_res_inf, e scalar_mul_res_x, e scalar_mul_res_y, e scalar_mul_scalar, e scalar_mul_sel, e scalar_mul_start, e scalar_mul_temp_inf, e scalar_mul_temp_x, e scalar_mul_temp_y, e sha256_a, e sha256_b, e sha256_c, e sha256_d, e sha256_e, e sha256_execution_clk, e sha256_f, e sha256_g, e sha256_h, e sha256_helper_w0, e sha256_helper_w1, e sha256_helper_w10, e sha256_helper_w11, e sha256_helper_w12, e sha256_helper_w13, e sha256_helper_w14, e sha256_helper_w15, e sha256_helper_w2, e sha256_helper_w3, e sha256_helper_w4, e sha256_helper_w5, e sha256_helper_w6, e sha256_helper_w7, e sha256_helper_w8, e sha256_helper_w9, e sha256_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_power, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_public_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted +#define AVM2_DERIVED_WITNESS_ENTITIES_E(e) e perm_data_copy_mem_write_inv, e perm_data_copy_mem_read_inv, e perm_ecc_mem_write_mem_0_inv, e perm_ecc_mem_write_mem_1_inv, e perm_keccak_memory_slice_to_mem_inv, e perm_keccakf1600_read_to_slice_inv, e perm_keccakf1600_write_to_slice_inv, e perm_poseidon2_mem_pos_read_mem_0_inv, e perm_poseidon2_mem_pos_read_mem_1_inv, e perm_poseidon2_mem_pos_read_mem_2_inv, e perm_poseidon2_mem_pos_read_mem_3_inv, e perm_poseidon2_mem_pos_write_mem_0_inv, e perm_poseidon2_mem_pos_write_mem_1_inv, e perm_poseidon2_mem_pos_write_mem_2_inv, e perm_poseidon2_mem_pos_write_mem_3_inv, e perm_sha256_mem_mem_op_0_inv, e perm_sha256_mem_mem_op_1_inv, e perm_sha256_mem_mem_op_2_inv, e perm_sha256_mem_mem_op_3_inv, e perm_sha256_mem_mem_op_4_inv, e perm_sha256_mem_mem_op_5_inv, e perm_sha256_mem_mem_op_6_inv, e perm_sha256_mem_mem_op_7_inv, e perm_sha256_mem_mem_input_read_inv, e perm_to_radix_mem_write_mem_inv, e perm_bc_hashing_bytecode_length_bytes_inv, e perm_bc_hashing_get_packed_field_0_inv, e perm_bc_hashing_get_packed_field_1_inv, e perm_bc_hashing_get_packed_field_2_inv, e perm_public_data_check_squashing_inv, e perm_emit_public_log_read_mem_inv, e perm_get_contract_instance_mem_write_contract_instance_exists_inv, e perm_get_contract_instance_mem_write_contract_instance_member_inv, e perm_internal_call_push_call_stack_inv, e perm_context_ctx_stack_call_inv, e perm_addressing_base_address_from_memory_inv, e perm_addressing_indirect_from_memory_0_inv, e perm_addressing_indirect_from_memory_1_inv, e perm_addressing_indirect_from_memory_2_inv, e perm_addressing_indirect_from_memory_3_inv, e perm_addressing_indirect_from_memory_4_inv, e perm_addressing_indirect_from_memory_5_inv, e perm_addressing_indirect_from_memory_6_inv, e perm_registers_mem_op_0_inv, e perm_registers_mem_op_1_inv, e perm_registers_mem_op_2_inv, e perm_registers_mem_op_3_inv, e perm_registers_mem_op_4_inv, e perm_registers_mem_op_5_inv, e perm_sstore_storage_write_inv, e perm_execution_dispatch_to_cd_copy_inv, e perm_execution_dispatch_to_rd_copy_inv, e perm_execution_dispatch_to_get_contract_instance_inv, e perm_execution_dispatch_to_emit_public_log_inv, e perm_execution_dispatch_to_poseidon2_perm_inv, e perm_execution_dispatch_to_sha256_compression_inv, e perm_execution_dispatch_to_keccakf1600_inv, e perm_execution_dispatch_to_ecc_add_inv, e perm_execution_dispatch_to_to_radix_inv, e perm_calldata_hashing_check_final_size_inv, e perm_tx_read_calldata_hash_inv, e perm_tx_dispatch_exec_start_inv, e perm_tx_dispatch_exec_end_inv, e perm_tx_balance_update_inv, e lookup_range_check_dyn_rng_chk_pow_2_inv, e lookup_range_check_dyn_diff_is_u16_inv, e lookup_range_check_r0_is_u16_inv, e lookup_range_check_r1_is_u16_inv, e lookup_range_check_r2_is_u16_inv, e lookup_range_check_r3_is_u16_inv, e lookup_range_check_r4_is_u16_inv, e lookup_range_check_r5_is_u16_inv, e lookup_range_check_r6_is_u16_inv, e lookup_range_check_r7_is_u16_inv, e lookup_ff_gt_a_lo_range_inv, e lookup_ff_gt_a_hi_range_inv, e lookup_gt_gt_range_inv, e lookup_alu_tag_max_bits_value_inv, e lookup_alu_range_check_decomposition_a_lo_inv, e lookup_alu_range_check_decomposition_a_hi_inv, e lookup_alu_range_check_decomposition_b_lo_inv, e lookup_alu_range_check_decomposition_b_hi_inv, e lookup_alu_range_check_mul_c_hi_inv, e lookup_alu_range_check_div_remainder_inv, e lookup_alu_ff_gt_inv, e lookup_alu_int_gt_inv, e lookup_alu_shifts_two_pow_inv, e lookup_alu_large_trunc_canonical_dec_inv, e lookup_alu_range_check_trunc_mid_inv, e lookup_bitwise_integral_tag_length_inv, e lookup_bitwise_byte_operations_inv, e lookup_memory_range_check_limb_0_inv, e lookup_memory_range_check_limb_1_inv, e lookup_memory_range_check_limb_2_inv, e lookup_memory_tag_max_bits_inv, e lookup_memory_range_check_write_tagged_value_inv, e lookup_data_copy_offset_plus_size_is_gt_data_size_inv, e lookup_data_copy_check_src_addr_in_range_inv, e lookup_data_copy_check_dst_addr_in_range_inv, e lookup_data_copy_sel_has_reads_inv, e lookup_data_copy_col_read_inv, e lookup_ecc_mem_check_dst_addr_in_range_inv, e lookup_ecc_mem_input_output_ecc_add_inv, e lookup_keccakf1600_theta_xor_01_inv, e lookup_keccakf1600_theta_xor_02_inv, e lookup_keccakf1600_theta_xor_03_inv, e lookup_keccakf1600_theta_xor_row_0_inv, e lookup_keccakf1600_theta_xor_11_inv, e lookup_keccakf1600_theta_xor_12_inv, e lookup_keccakf1600_theta_xor_13_inv, e lookup_keccakf1600_theta_xor_row_1_inv, e lookup_keccakf1600_theta_xor_21_inv, e lookup_keccakf1600_theta_xor_22_inv, e lookup_keccakf1600_theta_xor_23_inv, e lookup_keccakf1600_theta_xor_row_2_inv, e lookup_keccakf1600_theta_xor_31_inv, e lookup_keccakf1600_theta_xor_32_inv, e lookup_keccakf1600_theta_xor_33_inv, e lookup_keccakf1600_theta_xor_row_3_inv, e lookup_keccakf1600_theta_xor_41_inv, e lookup_keccakf1600_theta_xor_42_inv, e lookup_keccakf1600_theta_xor_43_inv, e lookup_keccakf1600_theta_xor_row_4_inv, e lookup_keccakf1600_theta_combined_xor_0_inv, e lookup_keccakf1600_theta_combined_xor_1_inv, e lookup_keccakf1600_theta_combined_xor_2_inv, e lookup_keccakf1600_theta_combined_xor_3_inv, e lookup_keccakf1600_theta_combined_xor_4_inv, e lookup_keccakf1600_state_theta_00_inv, e lookup_keccakf1600_state_theta_01_inv, e lookup_keccakf1600_state_theta_02_inv, e lookup_keccakf1600_state_theta_03_inv, e lookup_keccakf1600_state_theta_04_inv, e lookup_keccakf1600_state_theta_10_inv, e lookup_keccakf1600_state_theta_11_inv, e lookup_keccakf1600_state_theta_12_inv, e lookup_keccakf1600_state_theta_13_inv, e lookup_keccakf1600_state_theta_14_inv, e lookup_keccakf1600_state_theta_20_inv, e lookup_keccakf1600_state_theta_21_inv, e lookup_keccakf1600_state_theta_22_inv, e lookup_keccakf1600_state_theta_23_inv, e lookup_keccakf1600_state_theta_24_inv, e lookup_keccakf1600_state_theta_30_inv, e lookup_keccakf1600_state_theta_31_inv, e lookup_keccakf1600_state_theta_32_inv, e lookup_keccakf1600_state_theta_33_inv, e lookup_keccakf1600_state_theta_34_inv, e lookup_keccakf1600_state_theta_40_inv, e lookup_keccakf1600_state_theta_41_inv, e lookup_keccakf1600_state_theta_42_inv, e lookup_keccakf1600_state_theta_43_inv, e lookup_keccakf1600_state_theta_44_inv, e lookup_keccakf1600_theta_limb_02_range_inv, e lookup_keccakf1600_theta_limb_04_range_inv, e lookup_keccakf1600_theta_limb_10_range_inv, e lookup_keccakf1600_theta_limb_12_range_inv, e lookup_keccakf1600_theta_limb_14_range_inv, e lookup_keccakf1600_theta_limb_21_range_inv, e lookup_keccakf1600_theta_limb_23_range_inv, e lookup_keccakf1600_theta_limb_30_range_inv, e lookup_keccakf1600_theta_limb_32_range_inv, e lookup_keccakf1600_theta_limb_33_range_inv, e lookup_keccakf1600_theta_limb_40_range_inv, e lookup_keccakf1600_theta_limb_41_range_inv, e lookup_keccakf1600_theta_limb_43_range_inv, e lookup_keccakf1600_theta_limb_44_range_inv, e lookup_keccakf1600_theta_limb_01_range_inv, e lookup_keccakf1600_theta_limb_03_range_inv, e lookup_keccakf1600_theta_limb_11_range_inv, e lookup_keccakf1600_theta_limb_13_range_inv, e lookup_keccakf1600_theta_limb_20_range_inv, e lookup_keccakf1600_theta_limb_22_range_inv, e lookup_keccakf1600_theta_limb_24_range_inv, e lookup_keccakf1600_theta_limb_31_range_inv, e lookup_keccakf1600_theta_limb_34_range_inv, e lookup_keccakf1600_theta_limb_42_range_inv, e lookup_keccakf1600_state_pi_and_00_inv, e lookup_keccakf1600_state_pi_and_01_inv, e lookup_keccakf1600_state_pi_and_02_inv, e lookup_keccakf1600_state_pi_and_03_inv, e lookup_keccakf1600_state_pi_and_04_inv, e lookup_keccakf1600_state_pi_and_10_inv, e lookup_keccakf1600_state_pi_and_11_inv, e lookup_keccakf1600_state_pi_and_12_inv, e lookup_keccakf1600_state_pi_and_13_inv, e lookup_keccakf1600_state_pi_and_14_inv, e lookup_keccakf1600_state_pi_and_20_inv, e lookup_keccakf1600_state_pi_and_21_inv, e lookup_keccakf1600_state_pi_and_22_inv, e lookup_keccakf1600_state_pi_and_23_inv, e lookup_keccakf1600_state_pi_and_24_inv, e lookup_keccakf1600_state_pi_and_30_inv, e lookup_keccakf1600_state_pi_and_31_inv, e lookup_keccakf1600_state_pi_and_32_inv, e lookup_keccakf1600_state_pi_and_33_inv, e lookup_keccakf1600_state_pi_and_34_inv, e lookup_keccakf1600_state_pi_and_40_inv, e lookup_keccakf1600_state_pi_and_41_inv, e lookup_keccakf1600_state_pi_and_42_inv, e lookup_keccakf1600_state_pi_and_43_inv, e lookup_keccakf1600_state_pi_and_44_inv, e lookup_keccakf1600_state_chi_00_inv, e lookup_keccakf1600_state_chi_01_inv, e lookup_keccakf1600_state_chi_02_inv, e lookup_keccakf1600_state_chi_03_inv, e lookup_keccakf1600_state_chi_04_inv, e lookup_keccakf1600_state_chi_10_inv, e lookup_keccakf1600_state_chi_11_inv, e lookup_keccakf1600_state_chi_12_inv, e lookup_keccakf1600_state_chi_13_inv, e lookup_keccakf1600_state_chi_14_inv, e lookup_keccakf1600_state_chi_20_inv, e lookup_keccakf1600_state_chi_21_inv, e lookup_keccakf1600_state_chi_22_inv, e lookup_keccakf1600_state_chi_23_inv, e lookup_keccakf1600_state_chi_24_inv, e lookup_keccakf1600_state_chi_30_inv, e lookup_keccakf1600_state_chi_31_inv, e lookup_keccakf1600_state_chi_32_inv, e lookup_keccakf1600_state_chi_33_inv, e lookup_keccakf1600_state_chi_34_inv, e lookup_keccakf1600_state_chi_40_inv, e lookup_keccakf1600_state_chi_41_inv, e lookup_keccakf1600_state_chi_42_inv, e lookup_keccakf1600_state_chi_43_inv, e lookup_keccakf1600_state_chi_44_inv, e lookup_keccakf1600_round_cst_inv, e lookup_keccakf1600_state_iota_00_inv, e lookup_keccakf1600_src_out_of_range_toggle_inv, e lookup_keccakf1600_dst_out_of_range_toggle_inv, e lookup_poseidon2_mem_check_src_addr_in_range_inv, e lookup_poseidon2_mem_check_dst_addr_in_range_inv, e lookup_poseidon2_mem_input_output_poseidon2_perm_inv, e lookup_to_radix_limb_range_inv, e lookup_to_radix_limb_less_than_radix_range_inv, e lookup_to_radix_fetch_safe_limbs_inv, e lookup_to_radix_fetch_p_limb_inv, e lookup_to_radix_limb_p_diff_range_inv, e lookup_scalar_mul_to_radix_inv, e lookup_scalar_mul_double_inv, e lookup_scalar_mul_add_inv, e lookup_sha256_range_comp_w_lhs_inv, e lookup_sha256_range_comp_w_rhs_inv, e lookup_sha256_range_rhs_w_7_inv, e lookup_sha256_range_rhs_w_18_inv, e lookup_sha256_range_rhs_w_3_inv, e lookup_sha256_w_s_0_xor_0_inv, e lookup_sha256_w_s_0_xor_1_inv, e lookup_sha256_range_rhs_w_17_inv, e lookup_sha256_range_rhs_w_19_inv, e lookup_sha256_range_rhs_w_10_inv, e lookup_sha256_w_s_1_xor_0_inv, e lookup_sha256_w_s_1_xor_1_inv, e lookup_sha256_range_rhs_e_6_inv, e lookup_sha256_range_rhs_e_11_inv, e lookup_sha256_range_rhs_e_25_inv, e lookup_sha256_s_1_xor_0_inv, e lookup_sha256_s_1_xor_1_inv, e lookup_sha256_ch_and_0_inv, e lookup_sha256_ch_and_1_inv, e lookup_sha256_ch_xor_inv, e lookup_sha256_round_constant_inv, e lookup_sha256_range_rhs_a_2_inv, e lookup_sha256_range_rhs_a_13_inv, e lookup_sha256_range_rhs_a_22_inv, e lookup_sha256_s_0_xor_0_inv, e lookup_sha256_s_0_xor_1_inv, e lookup_sha256_maj_and_0_inv, e lookup_sha256_maj_and_1_inv, e lookup_sha256_maj_and_2_inv, e lookup_sha256_maj_xor_0_inv, e lookup_sha256_maj_xor_1_inv, e lookup_sha256_range_comp_next_a_lhs_inv, e lookup_sha256_range_comp_next_a_rhs_inv, e lookup_sha256_range_comp_next_e_lhs_inv, e lookup_sha256_range_comp_next_e_rhs_inv, e lookup_sha256_range_comp_a_rhs_inv, e lookup_sha256_range_comp_b_rhs_inv, e lookup_sha256_range_comp_c_rhs_inv, e lookup_sha256_range_comp_d_rhs_inv, e lookup_sha256_range_comp_e_rhs_inv, e lookup_sha256_range_comp_f_rhs_inv, e lookup_sha256_range_comp_g_rhs_inv, e lookup_sha256_range_comp_h_rhs_inv, e lookup_sha256_mem_check_state_addr_in_range_inv, e lookup_sha256_mem_check_input_addr_in_range_inv, e lookup_sha256_mem_check_output_addr_in_range_inv, e lookup_to_radix_mem_check_dst_addr_in_range_inv, e lookup_to_radix_mem_check_radix_lt_2_inv, e lookup_to_radix_mem_check_radix_gt_256_inv, e lookup_to_radix_mem_input_output_to_radix_inv, e lookup_poseidon2_hash_poseidon2_perm_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv, e lookup_address_derivation_partial_address_poseidon2_inv, e lookup_address_derivation_ivpk_m_hash_poseidon2_inv, e lookup_address_derivation_public_keys_hash_poseidon2_0_inv, e lookup_address_derivation_public_keys_hash_poseidon2_1_inv, e lookup_address_derivation_preaddress_poseidon2_inv, e lookup_address_derivation_preaddress_scalar_mul_inv, e lookup_address_derivation_address_ecadd_inv, e lookup_bc_decomposition_bytes_are_bytes_inv, e lookup_bc_hashing_poseidon2_hash_inv, e lookup_merkle_check_merkle_poseidon2_read_inv, e lookup_merkle_check_merkle_poseidon2_write_inv, e lookup_indexed_tree_check_silo_poseidon2_inv, e lookup_indexed_tree_check_low_leaf_value_validation_inv, e lookup_indexed_tree_check_low_leaf_next_value_validation_inv, e lookup_indexed_tree_check_low_leaf_poseidon2_inv, e lookup_indexed_tree_check_updated_low_leaf_poseidon2_inv, e lookup_indexed_tree_check_low_leaf_merkle_check_inv, e lookup_indexed_tree_check_new_leaf_poseidon2_inv, e lookup_indexed_tree_check_new_leaf_merkle_check_inv, e lookup_indexed_tree_check_write_value_to_public_inputs_inv, e lookup_public_data_squash_leaf_slot_increase_ff_gt_inv, e lookup_public_data_squash_clk_diff_range_lo_inv, e lookup_public_data_squash_clk_diff_range_hi_inv, e lookup_public_data_check_clk_diff_range_lo_inv, e lookup_public_data_check_clk_diff_range_hi_inv, e lookup_public_data_check_silo_poseidon2_inv, e lookup_public_data_check_low_leaf_slot_validation_inv, e lookup_public_data_check_low_leaf_next_slot_validation_inv, e lookup_public_data_check_low_leaf_poseidon2_0_inv, e lookup_public_data_check_low_leaf_poseidon2_1_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_0_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_1_inv, e lookup_public_data_check_low_leaf_merkle_check_inv, e lookup_public_data_check_new_leaf_poseidon2_0_inv, e lookup_public_data_check_new_leaf_poseidon2_1_inv, e lookup_public_data_check_new_leaf_merkle_check_inv, e lookup_public_data_check_write_public_data_to_public_inputs_inv, e lookup_public_data_check_write_writes_length_to_public_inputs_inv, e lookup_update_check_timestamp_from_public_inputs_inv, e lookup_update_check_delayed_public_mutable_slot_poseidon2_inv, e lookup_update_check_update_hash_public_data_read_inv, e lookup_update_check_update_hash_poseidon2_inv, e lookup_update_check_update_hi_metadata_range_inv, e lookup_update_check_update_lo_metadata_range_inv, e lookup_update_check_timestamp_is_lt_timestamp_of_change_inv, e lookup_contract_instance_retrieval_check_protocol_address_range_inv, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_inv, e lookup_contract_instance_retrieval_deployment_nullifier_read_inv, e lookup_contract_instance_retrieval_address_derivation_inv, e lookup_contract_instance_retrieval_update_check_inv, e lookup_class_id_derivation_class_id_poseidon2_0_inv, e lookup_class_id_derivation_class_id_poseidon2_1_inv, e lookup_bc_retrieval_contract_instance_retrieval_inv, e lookup_bc_retrieval_class_id_derivation_inv, e lookup_bc_retrieval_is_new_class_check_inv, e lookup_bc_retrieval_retrieved_bytecodes_insertion_inv, e lookup_instr_fetching_pc_abs_diff_positive_inv, e lookup_instr_fetching_instr_abs_diff_positive_inv, e lookup_instr_fetching_tag_value_validation_inv, e lookup_instr_fetching_bytecode_size_from_bc_dec_inv, e lookup_instr_fetching_bytes_from_bc_dec_inv, e lookup_instr_fetching_wire_instruction_info_inv, e lookup_emit_public_log_check_memory_out_of_bounds_inv, e lookup_emit_public_log_check_log_fields_count_inv, e lookup_emit_public_log_write_data_to_public_inputs_inv, e lookup_get_contract_instance_precomputed_info_inv, e lookup_get_contract_instance_contract_instance_retrieval_inv, e lookup_l1_to_l2_message_tree_check_merkle_check_inv, e lookup_internal_call_unwind_call_stack_inv, e lookup_context_ctx_stack_rollback_inv, e lookup_context_ctx_stack_return_inv, e lookup_addressing_relative_overflow_result_0_inv, e lookup_addressing_relative_overflow_result_1_inv, e lookup_addressing_relative_overflow_result_2_inv, e lookup_addressing_relative_overflow_result_3_inv, e lookup_addressing_relative_overflow_result_4_inv, e lookup_addressing_relative_overflow_result_5_inv, e lookup_addressing_relative_overflow_result_6_inv, e lookup_gas_addressing_gas_read_inv, e lookup_gas_is_out_of_gas_l2_inv, e lookup_gas_is_out_of_gas_da_inv, e lookup_note_hash_tree_check_silo_poseidon2_inv, e lookup_note_hash_tree_check_read_first_nullifier_inv, e lookup_note_hash_tree_check_nonce_computation_poseidon2_inv, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_inv, e lookup_note_hash_tree_check_merkle_check_inv, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_inv, e lookup_emit_notehash_notehash_tree_write_inv, e lookup_emit_nullifier_write_nullifier_inv, e lookup_external_call_is_l2_gas_left_gt_allocated_inv, e lookup_external_call_is_da_gas_left_gt_allocated_inv, e lookup_get_env_var_precomputed_info_inv, e lookup_get_env_var_read_from_public_inputs_col0_inv, e lookup_get_env_var_read_from_public_inputs_col1_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_inv, e lookup_notehash_exists_note_hash_leaf_index_in_range_inv, e lookup_notehash_exists_note_hash_read_inv, e lookup_nullifier_exists_nullifier_exists_check_inv, e lookup_send_l2_to_l1_msg_recipient_check_inv, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_inv, e lookup_sload_storage_read_inv, e lookup_sstore_record_written_storage_slot_inv, e lookup_execution_bytecode_retrieval_result_inv, e lookup_execution_instruction_fetching_result_inv, e lookup_execution_instruction_fetching_body_inv, e lookup_execution_exec_spec_read_inv, e lookup_execution_dyn_l2_factor_bitwise_inv, e lookup_execution_check_radix_gt_256_inv, e lookup_execution_get_p_limbs_inv, e lookup_execution_get_max_limbs_inv, e lookup_execution_check_written_storage_slot_inv, e lookup_execution_dispatch_to_alu_inv, e lookup_execution_dispatch_to_bitwise_inv, e lookup_execution_dispatch_to_cast_inv, e lookup_execution_dispatch_to_set_inv, e lookup_calldata_hashing_get_calldata_field_0_inv, e lookup_calldata_hashing_get_calldata_field_1_inv, e lookup_calldata_hashing_get_calldata_field_2_inv, e lookup_calldata_hashing_poseidon2_hash_inv, e lookup_tx_context_public_inputs_note_hash_tree_inv, e lookup_tx_context_public_inputs_nullifier_tree_inv, e lookup_tx_context_public_inputs_public_data_tree_inv, e lookup_tx_context_public_inputs_l1_l2_tree_inv, e lookup_tx_context_public_inputs_gas_used_inv, e lookup_tx_context_public_inputs_read_gas_limit_inv, e lookup_tx_context_public_inputs_read_reverted_inv, e lookup_tx_context_restore_state_on_revert_inv, e lookup_tx_context_public_inputs_write_note_hash_count_inv, e lookup_tx_context_public_inputs_write_nullifier_count_inv, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_inv, e lookup_tx_context_public_inputs_write_public_log_count_inv, e lookup_tx_read_phase_spec_inv, e lookup_tx_read_phase_length_inv, e lookup_tx_read_public_call_request_phase_inv, e lookup_tx_read_tree_insert_value_inv, e lookup_tx_note_hash_append_inv, e lookup_tx_nullifier_append_inv, e lookup_tx_read_l2_l1_msg_inv, e lookup_tx_write_l2_l1_msg_inv, e lookup_tx_read_effective_fee_public_inputs_inv, e lookup_tx_read_fee_payer_public_inputs_inv, e lookup_tx_balance_slot_poseidon2_inv, e lookup_tx_balance_read_inv, e lookup_tx_balance_validation_inv, e lookup_tx_write_fee_public_inputs_inv #define AVM2_SHIFTED_ENTITIES_E(e) e bc_decomposition_bytes_shift, e bc_decomposition_bytes_pc_plus_1_shift, e bc_decomposition_bytes_pc_plus_10_shift, e bc_decomposition_bytes_pc_plus_11_shift, e bc_decomposition_bytes_pc_plus_12_shift, e bc_decomposition_bytes_pc_plus_13_shift, e bc_decomposition_bytes_pc_plus_14_shift, e bc_decomposition_bytes_pc_plus_15_shift, e bc_decomposition_bytes_pc_plus_16_shift, e bc_decomposition_bytes_pc_plus_17_shift, e bc_decomposition_bytes_pc_plus_18_shift, e bc_decomposition_bytes_pc_plus_19_shift, e bc_decomposition_bytes_pc_plus_2_shift, e bc_decomposition_bytes_pc_plus_20_shift, e bc_decomposition_bytes_pc_plus_21_shift, e bc_decomposition_bytes_pc_plus_22_shift, e bc_decomposition_bytes_pc_plus_23_shift, e bc_decomposition_bytes_pc_plus_24_shift, e bc_decomposition_bytes_pc_plus_25_shift, e bc_decomposition_bytes_pc_plus_26_shift, e bc_decomposition_bytes_pc_plus_27_shift, e bc_decomposition_bytes_pc_plus_28_shift, e bc_decomposition_bytes_pc_plus_29_shift, e bc_decomposition_bytes_pc_plus_3_shift, e bc_decomposition_bytes_pc_plus_30_shift, e bc_decomposition_bytes_pc_plus_31_shift, e bc_decomposition_bytes_pc_plus_32_shift, e bc_decomposition_bytes_pc_plus_33_shift, e bc_decomposition_bytes_pc_plus_34_shift, e bc_decomposition_bytes_pc_plus_35_shift, e bc_decomposition_bytes_pc_plus_4_shift, e bc_decomposition_bytes_pc_plus_5_shift, e bc_decomposition_bytes_pc_plus_6_shift, e bc_decomposition_bytes_pc_plus_7_shift, e bc_decomposition_bytes_pc_plus_8_shift, e bc_decomposition_bytes_pc_plus_9_shift, e bc_decomposition_bytes_remaining_shift, e bc_decomposition_id_shift, e bc_decomposition_next_packed_pc_shift, e bc_decomposition_pc_shift, e bc_decomposition_sel_shift, e bc_decomposition_sel_windows_gt_remaining_shift, e bc_decomposition_start_shift, e bc_hashing_bytecode_id_shift, e bc_hashing_padding_shift, e bc_hashing_pc_index_1_shift, e bc_hashing_rounds_rem_shift, e bc_hashing_sel_shift, e bc_hashing_sel_not_start_shift, e bc_hashing_start_shift, e bitwise_acc_ia_shift, e bitwise_acc_ib_shift, e bitwise_acc_ic_shift, e bitwise_ctr_shift, e bitwise_op_id_shift, e bitwise_sel_shift, e bitwise_start_shift, e calldata_context_id_shift, e calldata_hashing_calldata_size_shift, e calldata_hashing_context_id_shift, e calldata_hashing_index_0__shift, e calldata_hashing_output_hash_shift, e calldata_hashing_rounds_rem_shift, e calldata_hashing_sel_shift, e calldata_hashing_start_shift, e calldata_index_shift, e calldata_sel_shift, e data_copy_clk_shift, e data_copy_copy_size_shift, e data_copy_dst_addr_shift, e data_copy_dst_context_id_shift, e data_copy_padding_shift, e data_copy_read_addr_shift, e data_copy_reads_left_shift, e data_copy_sel_shift, e data_copy_sel_cd_copy_shift, e data_copy_src_context_id_shift, e data_copy_start_shift, e emit_public_log_contract_address_shift, e emit_public_log_correct_tag_shift, e emit_public_log_error_out_of_bounds_shift, e emit_public_log_error_tag_mismatch_shift, e emit_public_log_execution_clk_shift, e emit_public_log_is_write_contract_address_shift, e emit_public_log_is_write_memory_value_shift, e emit_public_log_log_address_shift, e emit_public_log_public_inputs_index_shift, e emit_public_log_remaining_rows_shift, e emit_public_log_seen_wrong_tag_shift, e emit_public_log_sel_shift, e emit_public_log_sel_write_to_public_inputs_shift, e emit_public_log_space_id_shift, e emit_public_log_start_shift, e execution_bytecode_id_shift, e execution_clk_shift, e execution_context_id_shift, e execution_contract_address_shift, e execution_da_gas_limit_shift, e execution_discard_shift, e execution_dying_context_id_shift, e execution_enqueued_call_start_shift, e execution_internal_call_id_shift, e execution_internal_call_return_id_shift, e execution_is_static_shift, e execution_l1_l2_tree_root_shift, e execution_l2_gas_limit_shift, e execution_last_child_id_shift, e execution_last_child_returndata_addr_shift, e execution_last_child_returndata_size_shift, e execution_last_child_success_shift, e execution_msg_sender_shift, e execution_next_context_id_shift, e execution_next_internal_call_id_shift, e execution_parent_calldata_addr_shift, e execution_parent_calldata_size_shift, e execution_parent_da_gas_limit_shift, e execution_parent_da_gas_used_shift, e execution_parent_id_shift, e execution_parent_l2_gas_limit_shift, e execution_parent_l2_gas_used_shift, e execution_pc_shift, e execution_prev_da_gas_used_shift, e execution_prev_l2_gas_used_shift, e execution_prev_note_hash_tree_root_shift, e execution_prev_note_hash_tree_size_shift, e execution_prev_nullifier_tree_root_shift, e execution_prev_nullifier_tree_size_shift, e execution_prev_num_l2_to_l1_messages_shift, e execution_prev_num_note_hashes_emitted_shift, e execution_prev_num_nullifiers_emitted_shift, e execution_prev_num_public_log_fields_shift, e execution_prev_public_data_tree_root_shift, e execution_prev_public_data_tree_size_shift, e execution_prev_retrieved_bytecodes_tree_root_shift, e execution_prev_retrieved_bytecodes_tree_size_shift, e execution_prev_written_public_data_slots_tree_root_shift, e execution_prev_written_public_data_slots_tree_size_shift, e execution_sel_shift, e execution_sel_first_row_in_context_shift, e execution_transaction_fee_shift, e ff_gt_a_hi_shift, e ff_gt_a_lo_shift, e ff_gt_b_hi_shift, e ff_gt_b_lo_shift, e ff_gt_cmp_rng_ctr_shift, e ff_gt_p_sub_a_hi_shift, e ff_gt_p_sub_a_lo_shift, e ff_gt_p_sub_b_hi_shift, e ff_gt_p_sub_b_lo_shift, e ff_gt_sel_shift, e ff_gt_sel_dec_shift, e ff_gt_sel_gt_shift, e keccak_memory_addr_shift, e keccak_memory_clk_shift, e keccak_memory_ctr_shift, e keccak_memory_rw_shift, e keccak_memory_sel_shift, e keccak_memory_space_id_shift, e keccak_memory_start_read_shift, e keccak_memory_start_write_shift, e keccak_memory_tag_error_shift, e keccak_memory_val_0__shift, e keccak_memory_val_10__shift, e keccak_memory_val_11__shift, e keccak_memory_val_12__shift, e keccak_memory_val_13__shift, e keccak_memory_val_14__shift, e keccak_memory_val_15__shift, e keccak_memory_val_16__shift, e keccak_memory_val_17__shift, e keccak_memory_val_18__shift, e keccak_memory_val_19__shift, e keccak_memory_val_1__shift, e keccak_memory_val_20__shift, e keccak_memory_val_21__shift, e keccak_memory_val_22__shift, e keccak_memory_val_23__shift, e keccak_memory_val_2__shift, e keccak_memory_val_3__shift, e keccak_memory_val_4__shift, e keccak_memory_val_5__shift, e keccak_memory_val_6__shift, e keccak_memory_val_7__shift, e keccak_memory_val_8__shift, e keccak_memory_val_9__shift, e keccakf1600_clk_shift, e keccakf1600_dst_addr_shift, e keccakf1600_round_shift, e keccakf1600_sel_shift, e keccakf1600_sel_no_error_shift, e keccakf1600_space_id_shift, e keccakf1600_start_shift, e keccakf1600_state_in_00_shift, e keccakf1600_state_in_01_shift, e keccakf1600_state_in_02_shift, e keccakf1600_state_in_03_shift, e keccakf1600_state_in_04_shift, e keccakf1600_state_in_10_shift, e keccakf1600_state_in_11_shift, e keccakf1600_state_in_12_shift, e keccakf1600_state_in_13_shift, e keccakf1600_state_in_14_shift, e keccakf1600_state_in_20_shift, e keccakf1600_state_in_21_shift, e keccakf1600_state_in_22_shift, e keccakf1600_state_in_23_shift, e keccakf1600_state_in_24_shift, e keccakf1600_state_in_30_shift, e keccakf1600_state_in_31_shift, e keccakf1600_state_in_32_shift, e keccakf1600_state_in_33_shift, e keccakf1600_state_in_34_shift, e keccakf1600_state_in_40_shift, e keccakf1600_state_in_41_shift, e keccakf1600_state_in_42_shift, e keccakf1600_state_in_43_shift, e keccakf1600_state_in_44_shift, e memory_address_shift, e memory_clk_shift, e memory_rw_shift, e memory_sel_shift, e memory_space_id_shift, e memory_tag_shift, e memory_value_shift, e merkle_check_index_shift, e merkle_check_merkle_hash_separator_shift, e merkle_check_path_len_shift, e merkle_check_read_node_shift, e merkle_check_read_root_shift, e merkle_check_sel_shift, e merkle_check_start_shift, e merkle_check_write_shift, e merkle_check_write_node_shift, e merkle_check_write_root_shift, e poseidon2_hash_a_0_shift, e poseidon2_hash_a_1_shift, e poseidon2_hash_a_2_shift, e poseidon2_hash_a_3_shift, e poseidon2_hash_input_0_shift, e poseidon2_hash_input_1_shift, e poseidon2_hash_input_2_shift, e poseidon2_hash_num_perm_rounds_rem_shift, e poseidon2_hash_output_shift, e poseidon2_hash_sel_shift, e poseidon2_hash_start_shift, e public_data_check_clk_shift, e public_data_check_sel_shift, e public_data_check_write_idx_shift, e public_data_squash_clk_shift, e public_data_squash_final_value_shift, e public_data_squash_leaf_slot_shift, e public_data_squash_sel_shift, e public_data_squash_write_to_public_inputs_shift, e scalar_mul_bit_idx_shift, e scalar_mul_point_inf_shift, e scalar_mul_point_x_shift, e scalar_mul_point_y_shift, e scalar_mul_res_inf_shift, e scalar_mul_res_x_shift, e scalar_mul_res_y_shift, e scalar_mul_scalar_shift, e scalar_mul_sel_shift, e scalar_mul_start_shift, e scalar_mul_temp_inf_shift, e scalar_mul_temp_x_shift, e scalar_mul_temp_y_shift, e sha256_a_shift, e sha256_b_shift, e sha256_c_shift, e sha256_d_shift, e sha256_e_shift, e sha256_execution_clk_shift, e sha256_f_shift, e sha256_g_shift, e sha256_h_shift, e sha256_helper_w0_shift, e sha256_helper_w1_shift, e sha256_helper_w10_shift, e sha256_helper_w11_shift, e sha256_helper_w12_shift, e sha256_helper_w13_shift, e sha256_helper_w14_shift, e sha256_helper_w15_shift, e sha256_helper_w2_shift, e sha256_helper_w3_shift, e sha256_helper_w4_shift, e sha256_helper_w5_shift, e sha256_helper_w6_shift, e sha256_helper_w7_shift, e sha256_helper_w8_shift, e sha256_helper_w9_shift, e sha256_init_a_shift, e sha256_init_b_shift, e sha256_init_c_shift, e sha256_init_d_shift, e sha256_init_e_shift, e sha256_init_f_shift, e sha256_init_g_shift, e sha256_init_h_shift, e sha256_input_addr_shift, e sha256_input_rounds_rem_shift, e sha256_output_addr_shift, e sha256_rounds_remaining_shift, e sha256_sel_shift, e sha256_sel_invalid_input_tag_err_shift, e sha256_space_id_shift, e sha256_start_shift, e to_radix_acc_shift, e to_radix_acc_under_p_shift, e to_radix_limb_shift, e to_radix_limb_eq_p_shift, e to_radix_limb_index_shift, e to_radix_limb_lt_p_shift, e to_radix_mem_dst_addr_shift, e to_radix_mem_execution_clk_shift, e to_radix_mem_is_output_bits_shift, e to_radix_mem_num_limbs_shift, e to_radix_mem_radix_shift, e to_radix_mem_sel_shift, e to_radix_mem_sel_should_decompose_shift, e to_radix_mem_sel_should_write_mem_shift, e to_radix_mem_space_id_shift, e to_radix_mem_start_shift, e to_radix_mem_value_to_decompose_shift, e to_radix_not_padding_limb_shift, e to_radix_power_shift, e to_radix_radix_shift, e to_radix_safe_limbs_shift, e to_radix_sel_shift, e to_radix_start_shift, e to_radix_value_shift, e tx_da_gas_limit_shift, e tx_discard_shift, e tx_fee_shift, e tx_is_revertible_shift, e tx_is_teardown_shift, e tx_l1_l2_tree_root_shift, e tx_l1_l2_tree_size_shift, e tx_l2_gas_limit_shift, e tx_next_context_id_shift, e tx_phase_value_shift, e tx_prev_da_gas_used_shift, e tx_prev_l2_gas_used_shift, e tx_prev_note_hash_tree_root_shift, e tx_prev_note_hash_tree_size_shift, e tx_prev_nullifier_tree_root_shift, e tx_prev_nullifier_tree_size_shift, e tx_prev_num_l2_to_l1_messages_shift, e tx_prev_num_note_hashes_emitted_shift, e tx_prev_num_nullifiers_emitted_shift, e tx_prev_num_public_log_fields_shift, e tx_prev_public_data_tree_root_shift, e tx_prev_public_data_tree_size_shift, e tx_prev_retrieved_bytecodes_tree_root_shift, e tx_prev_retrieved_bytecodes_tree_size_shift, e tx_prev_written_public_data_slots_tree_root_shift, e tx_prev_written_public_data_slots_tree_size_shift, e tx_read_pi_offset_shift, e tx_remaining_phase_counter_shift, e tx_reverted_shift, e tx_sel_shift, e tx_start_phase_shift, e tx_start_tx_shift, e tx_tx_reverted_shift #define AVM2_TO_BE_SHIFTED_E(e) e bc_decomposition_bytes, e bc_decomposition_bytes_pc_plus_1, e bc_decomposition_bytes_pc_plus_10, e bc_decomposition_bytes_pc_plus_11, e bc_decomposition_bytes_pc_plus_12, e bc_decomposition_bytes_pc_plus_13, e bc_decomposition_bytes_pc_plus_14, e bc_decomposition_bytes_pc_plus_15, e bc_decomposition_bytes_pc_plus_16, e bc_decomposition_bytes_pc_plus_17, e bc_decomposition_bytes_pc_plus_18, e bc_decomposition_bytes_pc_plus_19, e bc_decomposition_bytes_pc_plus_2, e bc_decomposition_bytes_pc_plus_20, e bc_decomposition_bytes_pc_plus_21, e bc_decomposition_bytes_pc_plus_22, e bc_decomposition_bytes_pc_plus_23, e bc_decomposition_bytes_pc_plus_24, e bc_decomposition_bytes_pc_plus_25, e bc_decomposition_bytes_pc_plus_26, e bc_decomposition_bytes_pc_plus_27, e bc_decomposition_bytes_pc_plus_28, e bc_decomposition_bytes_pc_plus_29, e bc_decomposition_bytes_pc_plus_3, e bc_decomposition_bytes_pc_plus_30, e bc_decomposition_bytes_pc_plus_31, e bc_decomposition_bytes_pc_plus_32, e bc_decomposition_bytes_pc_plus_33, e bc_decomposition_bytes_pc_plus_34, e bc_decomposition_bytes_pc_plus_35, e bc_decomposition_bytes_pc_plus_4, e bc_decomposition_bytes_pc_plus_5, e bc_decomposition_bytes_pc_plus_6, e bc_decomposition_bytes_pc_plus_7, e bc_decomposition_bytes_pc_plus_8, e bc_decomposition_bytes_pc_plus_9, e bc_decomposition_bytes_remaining, e bc_decomposition_id, e bc_decomposition_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_windows_gt_remaining, e bc_decomposition_start, e bc_hashing_bytecode_id, e bc_hashing_padding, e bc_hashing_pc_index_1, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_sel_not_start, e bc_hashing_start, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e bitwise_sel, e bitwise_start, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_src_context_id, e data_copy_start, e emit_public_log_contract_address, e emit_public_log_correct_tag, e emit_public_log_error_out_of_bounds, e emit_public_log_error_tag_mismatch, e emit_public_log_execution_clk, e emit_public_log_is_write_contract_address, e emit_public_log_is_write_memory_value, e emit_public_log_log_address, e emit_public_log_public_inputs_index, e emit_public_log_remaining_rows, e emit_public_log_seen_wrong_tag, e emit_public_log_sel, e emit_public_log_sel_write_to_public_inputs, e emit_public_log_space_id, e emit_public_log_start, e execution_bytecode_id, e execution_clk, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_public_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_sel, e keccak_memory_space_id, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_start, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_address, e memory_clk, e memory_rw, e memory_sel, e memory_space_id, e memory_tag, e memory_value, e merkle_check_index, e merkle_check_merkle_hash_separator, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_start, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, e poseidon2_hash_a_0, e poseidon2_hash_a_1, e poseidon2_hash_a_2, e poseidon2_hash_a_3, e poseidon2_hash_input_0, e poseidon2_hash_input_1, e poseidon2_hash_input_2, e poseidon2_hash_num_perm_rounds_rem, e poseidon2_hash_output, e poseidon2_hash_sel, e poseidon2_hash_start, e public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, e scalar_mul_bit_idx, e scalar_mul_point_inf, e scalar_mul_point_x, e scalar_mul_point_y, e scalar_mul_res_inf, e scalar_mul_res_x, e scalar_mul_res_y, e scalar_mul_scalar, e scalar_mul_sel, e scalar_mul_start, e scalar_mul_temp_inf, e scalar_mul_temp_x, e scalar_mul_temp_y, e sha256_a, e sha256_b, e sha256_c, e sha256_d, e sha256_e, e sha256_execution_clk, e sha256_f, e sha256_g, e sha256_h, e sha256_helper_w0, e sha256_helper_w1, e sha256_helper_w10, e sha256_helper_w11, e sha256_helper_w12, e sha256_helper_w13, e sha256_helper_w14, e sha256_helper_w15, e sha256_helper_w2, e sha256_helper_w3, e sha256_helper_w4, e sha256_helper_w5, e sha256_helper_w6, e sha256_helper_w7, e sha256_helper_w8, e sha256_helper_w9, e sha256_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_power, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_public_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted #define AVM2_ALL_ENTITIES_E(e) AVM2_PRECOMPUTED_ENTITIES_E(e), AVM2_WIRE_ENTITIES_E(e), AVM2_DERIVED_WITNESS_ENTITIES_E(e), AVM2_SHIFTED_ENTITIES_E(e) @@ -36,16 +36,16 @@ enum class ColumnAndShifts { SENTINEL_DO_NOT_USE, }; -constexpr auto NUM_COLUMNS_WITH_SHIFTS = 3438; -constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 3074; -constexpr auto NUM_PRECOMPUTED_ENTITIES = 119; -constexpr auto NUM_WIRE_ENTITIES = 2511; -constexpr auto NUM_DERIVED_ENTITIES = 444; +constexpr auto NUM_COLUMNS_WITH_SHIFTS = 3424; +constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 3060; +constexpr auto NUM_PRECOMPUTED_ENTITIES = 120; +constexpr auto NUM_WIRE_ENTITIES = 2499; +constexpr auto NUM_DERIVED_ENTITIES = 441; constexpr auto NUM_WITNESS_ENTITIES = NUM_WIRE_ENTITIES + NUM_DERIVED_ENTITIES; constexpr auto NUM_WIRES_TO_BE_SHIFTED = 364; constexpr auto NUM_SHIFTED_ENTITIES = 364; constexpr auto NUM_UNSHIFTED_ENTITIES = NUM_COLUMNS_WITHOUT_SHIFTS; -constexpr auto NUM_ALL_ENTITIES = 3438; +constexpr auto NUM_ALL_ENTITIES = 3424; /* * Layout for all entities is: diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp index 22c2e6bc3473..01e4c415f56e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp @@ -140,11 +140,11 @@ namespace bb::avm2 { struct AvmFlavorVariables { - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 119; - static constexpr size_t NUM_WITNESS_ENTITIES = 2955; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 120; + static constexpr size_t NUM_WITNESS_ENTITIES = 2940; static constexpr size_t NUM_SHIFTED_ENTITIES = 364; - static constexpr size_t NUM_WIRES = 2511; - static constexpr size_t NUM_ALL_ENTITIES = 3438; + static constexpr size_t NUM_WIRES = 2499; + static constexpr size_t NUM_ALL_ENTITIES = 3424; // Need to be templated for recursive verifier template @@ -216,14 +216,12 @@ struct AvmFlavorVariables { using LookupRelations_ = flat_tuple::tuple< // Lookups lookup_address_derivation_address_ecadd_relation, + lookup_address_derivation_ivpk_m_hash_poseidon2_relation, lookup_address_derivation_partial_address_poseidon2_relation, lookup_address_derivation_preaddress_poseidon2_relation, lookup_address_derivation_preaddress_scalar_mul_relation, lookup_address_derivation_public_keys_hash_poseidon2_0_relation, lookup_address_derivation_public_keys_hash_poseidon2_1_relation, - lookup_address_derivation_public_keys_hash_poseidon2_2_relation, - lookup_address_derivation_public_keys_hash_poseidon2_3_relation, - lookup_address_derivation_public_keys_hash_poseidon2_4_relation, lookup_address_derivation_salted_initialization_hash_poseidon2_0_relation, lookup_address_derivation_salted_initialization_hash_poseidon2_1_relation, lookup_addressing_relative_overflow_result_0_relation, @@ -612,7 +610,6 @@ struct AvmFlavorVariables { perm_data_copy_mem_write_relation, perm_ecc_mem_write_mem_0_relation, perm_ecc_mem_write_mem_1_relation, - perm_ecc_mem_write_mem_2_relation, perm_emit_public_log_read_mem_relation, perm_execution_dispatch_to_cd_copy_relation, perm_execution_dispatch_to_ecc_add_relation, diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/address_derivation.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/address_derivation.hpp index 4ebd488f9576..fbaf2e0d85b8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/address_derivation.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/address_derivation.hpp @@ -14,7 +14,7 @@ template class address_derivationImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5 }; template inline static bool skip(const AllEntities& in) { @@ -35,7 +35,7 @@ template class address_derivation : public Relation::accumulate(ContainerOverSubrelations& evals, FF(uint256_t{ 9457493854555940652UL, 3253583849847263892UL, 14921373847124204899UL, 2UL }); const auto constants_DOM_SEP__SALTED_INITIALIZATION_HASH = FF(2763052992UL); const auto constants_DOM_SEP__PUBLIC_KEYS_HASH = FF(777457226); + const auto constants_DOM_SEP__SINGLE_PUBLIC_KEY_HASH = FF(3452068255UL); const auto constants_DOM_SEP__PARTIAL_ADDRESS = FF(2103633018); - const auto constants_DOM_SEP__CONTRACT_ADDRESS_V1 = FF(1788365517); + const auto constants_DOM_SEP__CONTRACT_ADDRESS_V2 = FF(4099338721UL); const auto address_derivation_X3 = in.get(C::address_derivation_incoming_viewing_key_x) * in.get(C::address_derivation_incoming_viewing_key_x) * in.get(C::address_derivation_incoming_viewing_key_x); @@ -37,72 +38,67 @@ void address_derivationImpl::accumulate(ContainerOverSubrelations& evals, { using View = typename std::tuple_element_t<1, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_const_two)) - FF(2)); + (static_cast(in.get(C::address_derivation_const_three)) - FF(3)); std::get<1>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<2, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_const_three)) - FF(3)); + (static_cast(in.get(C::address_derivation_const_five)) - FF(5)); std::get<2>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_const_four)) - FF(4)); + (static_cast(in.get(C::address_derivation_salted_init_hash_domain_separator)) - + CView(constants_DOM_SEP__SALTED_INITIALIZATION_HASH)); std::get<3>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_const_thirteen)) - FF(13)); + (static_cast(in.get(C::address_derivation_partial_address_domain_separator)) - + CView(constants_DOM_SEP__PARTIAL_ADDRESS)); std::get<4>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_salted_init_hash_domain_separator)) - - CView(constants_DOM_SEP__SALTED_INITIALIZATION_HASH)); + (static_cast(in.get(C::address_derivation_single_public_key_hash_domain_separator)) - + CView(constants_DOM_SEP__SINGLE_PUBLIC_KEY_HASH)); std::get<5>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_partial_address_domain_separator)) - - CView(constants_DOM_SEP__PARTIAL_ADDRESS)); + (static_cast(in.get(C::address_derivation_public_keys_hash_domain_separator)) - + CView(constants_DOM_SEP__PUBLIC_KEYS_HASH)); std::get<6>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_public_keys_hash_domain_separator)) - - CView(constants_DOM_SEP__PUBLIC_KEYS_HASH)); + (static_cast(in.get(C::address_derivation_preaddress_domain_separator)) - + CView(constants_DOM_SEP__CONTRACT_ADDRESS_V2)); std::get<7>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_preaddress_domain_separator)) - - CView(constants_DOM_SEP__CONTRACT_ADDRESS_V1)); + (static_cast(in.get(C::address_derivation_g1_x)) - CView(constants_GRUMPKIN_ONE_X)); std::get<8>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_g1_x)) - CView(constants_GRUMPKIN_ONE_X)); - std::get<9>(evals) += (tmp * scaling_factor); - } - { - using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * (static_cast(in.get(C::address_derivation_g1_y)) - CView(constants_GRUMPKIN_ONE_Y)); - std::get<10>(evals) += (tmp * scaling_factor); + std::get<9>(evals) += (tmp * scaling_factor); } { // IVK_ON_CURVE_CHECK - using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * (CView(address_derivation_Y2) - (CView(address_derivation_X3) - FF(17))); - std::get<11>(evals) += (tmp * scaling_factor); + std::get<10>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/contract_instance_retrieval.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/contract_instance_retrieval.hpp index 20d2e8432637..c58b25b8e2d6 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/contract_instance_retrieval.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/contract_instance_retrieval.hpp @@ -14,8 +14,8 @@ template class contract_instance_retrievalImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 2, 3, 3, 5, 3, 3, - 3, 3, 4, 4, 4, 4, 4, 4, 3 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 2, 3, 3, 5, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 4, 3 }; template inline static bool skip(const AllEntities& in) { @@ -47,6 +47,7 @@ template class contract_instance_retrieval : public Relation class contract_instance_retrieval : public Relation::accumulate(ContainerOverSubrelations& static_cast(in.get(C::contract_instance_retrieval_init_hash)); std::get<16>(evals) += (tmp * scaling_factor); } - { + { // INSTANCE_MEMBER_IMMUTABLES_HASH_IS_ZERO_IF_DNE using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::contract_instance_retrieval_sel)) * + (FF(1) - static_cast(in.get(C::contract_instance_retrieval_exists))) * + static_cast(in.get(C::contract_instance_retrieval_immutables_hash)); + std::get<17>(evals) += (tmp * scaling_factor); + } + { + using View = typename std::tuple_element_t<18, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::contract_instance_retrieval_should_check_for_update)) - static_cast(in.get(C::contract_instance_retrieval_should_check_nullifier)) * static_cast(in.get(C::contract_instance_retrieval_exists))); - std::get<17>(evals) += (tmp * scaling_factor); + std::get<18>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc.hpp index 93df40ba85c2..b1d717c5f2ca 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc.hpp @@ -14,8 +14,8 @@ template class eccImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, - 5, 3, 3, 5, 6, 6, 5, 6, 6, 3 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 5, 3, + 5, 3, 3, 5, 6, 6, 5, 6, 6 }; template inline static bool skip(const AllEntities& in) { @@ -37,14 +37,13 @@ template class ecc : public Relation> { // Subrelation indices constants, to be used in tests. static constexpr size_t SR_OP_CHECK = 3; - static constexpr size_t SR_X_MATCH = 8; - static constexpr size_t SR_Y_MATCH = 10; - static constexpr size_t SR_DOUBLE_PRED = 11; - static constexpr size_t SR_COMPUTED_LAMBDA = 14; - static constexpr size_t SR_INFINITY_RESULT = 16; - static constexpr size_t SR_OUTPUT_X_COORD = 17; - static constexpr size_t SR_OUTPUT_Y_COORD = 18; - static constexpr size_t SR_OUTPUT_INF_FLAG = 19; + static constexpr size_t SR_X_MATCH = 7; + static constexpr size_t SR_Y_MATCH = 9; + static constexpr size_t SR_DOUBLE_PRED = 10; + static constexpr size_t SR_COMPUTED_LAMBDA = 13; + static constexpr size_t SR_INFINITY_RESULT = 15; + static constexpr size_t SR_OUTPUT_X_COORD = 16; + static constexpr size_t SR_OUTPUT_Y_COORD = 17; static std::string get_subrelation_label(size_t index) { @@ -65,8 +64,6 @@ template class ecc : public Relation> { return "OUTPUT_X_COORD"; case SR_OUTPUT_Y_COORD: return "OUTPUT_Y_COORD"; - case SR_OUTPUT_INF_FLAG: - return "OUTPUT_INF_FLAG"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_impl.hpp index 5b709819d443..335cdcd557e0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_impl.hpp @@ -62,83 +62,78 @@ void eccImpl::accumulate(ContainerOverSubrelations& evals, } { using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_r_is_inf)) * (FF(1) - static_cast(in.get(C::ecc_r_is_inf))); - std::get<6>(evals) += (tmp * scaling_factor); - } - { - using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_x_match)) * (FF(1) - static_cast(in.get(C::ecc_x_match))); - std::get<7>(evals) += (tmp * scaling_factor); + std::get<6>(evals) += (tmp * scaling_factor); } { // X_MATCH - using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * ((CView(ecc_X_DIFF) * (static_cast(in.get(C::ecc_x_match)) * (FF(1) - static_cast(in.get(C::ecc_inv_x_diff))) + static_cast(in.get(C::ecc_inv_x_diff))) - FF(1)) + static_cast(in.get(C::ecc_x_match))); - std::get<8>(evals) += (tmp * scaling_factor); + std::get<7>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_y_match)) * (FF(1) - static_cast(in.get(C::ecc_y_match))); - std::get<9>(evals) += (tmp * scaling_factor); + std::get<8>(evals) += (tmp * scaling_factor); } { // Y_MATCH - using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * ((CView(ecc_Y_DIFF) * (static_cast(in.get(C::ecc_y_match)) * (FF(1) - static_cast(in.get(C::ecc_inv_y_diff))) + static_cast(in.get(C::ecc_inv_y_diff))) - FF(1)) + static_cast(in.get(C::ecc_y_match))); - std::get<10>(evals) += (tmp * scaling_factor); + std::get<9>(evals) += (tmp * scaling_factor); } { // DOUBLE_PRED - using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_double_op)) - static_cast(in.get(C::ecc_x_match)) * static_cast(in.get(C::ecc_y_match))); - std::get<11>(evals) += (tmp * scaling_factor); + std::get<10>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_double_op)) * (static_cast(in.get(C::ecc_p_is_inf)) - static_cast(in.get(C::ecc_q_is_inf))); - std::get<12>(evals) += (tmp * scaling_factor); + std::get<11>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; auto tmp = (FF(1) - static_cast(in.get(C::ecc_result_infinity))) * static_cast(in.get(C::ecc_double_op)) * (FF(2) * static_cast(in.get(C::ecc_p_y)) * static_cast(in.get(C::ecc_inv_2_p_y)) - FF(1)); - std::get<13>(evals) += (tmp * scaling_factor); + std::get<12>(evals) += (tmp * scaling_factor); } { // COMPUTED_LAMBDA - using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * (static_cast(in.get(C::ecc_lambda)) - (static_cast(in.get(C::ecc_double_op)) * FF(3) * static_cast(in.get(C::ecc_p_x)) * static_cast(in.get(C::ecc_p_x)) * static_cast(in.get(C::ecc_inv_2_p_y)) + static_cast(in.get(C::ecc_add_op)) * CView(ecc_Y_DIFF) * static_cast(in.get(C::ecc_inv_x_diff)))); - std::get<14>(evals) += (tmp * scaling_factor); + std::get<13>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_use_computed_result)) - static_cast(in.get(C::ecc_sel)) * CView(ecc_BOTH_NON_INF) * (FF(1) - CView(ecc_INVERSE_PRED))); - std::get<15>(evals) += (tmp * scaling_factor); + std::get<14>(evals) += (tmp * scaling_factor); } { // INFINITY_RESULT - using View = typename std::tuple_element_t<16, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_result_infinity)) - (CView(ecc_INVERSE_PRED) * CView(ecc_BOTH_NON_INF) + CView(ecc_BOTH_INF))); - std::get<16>(evals) += (tmp * scaling_factor); + std::get<15>(evals) += (tmp * scaling_factor); } { // OUTPUT_X_COORD - using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<16, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * (((static_cast(in.get(C::ecc_r_x)) - CView(ecc_EITHER_INF) * @@ -146,10 +141,10 @@ void eccImpl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::ecc_q_is_inf)) * static_cast(in.get(C::ecc_p_x)))) - static_cast(in.get(C::ecc_result_infinity)) * CView(ecc_INFINITY_X)) - static_cast(in.get(C::ecc_use_computed_result)) * CView(ecc_COMPUTED_R_X)); - std::get<17>(evals) += (tmp * scaling_factor); + std::get<16>(evals) += (tmp * scaling_factor); } { // OUTPUT_Y_COORD - using View = typename std::tuple_element_t<18, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * (((static_cast(in.get(C::ecc_r_y)) - CView(ecc_EITHER_INF) * @@ -157,13 +152,7 @@ void eccImpl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::ecc_q_is_inf)) * static_cast(in.get(C::ecc_p_y)))) - static_cast(in.get(C::ecc_result_infinity)) * CView(ecc_INFINITY_Y)) - static_cast(in.get(C::ecc_use_computed_result)) * CView(ecc_COMPUTED_R_Y)); - std::get<18>(evals) += (tmp * scaling_factor); - } - { // OUTPUT_INF_FLAG - using View = typename std::tuple_element_t<19, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_sel)) * - (static_cast(in.get(C::ecc_r_is_inf)) - static_cast(in.get(C::ecc_result_infinity))); - std::get<19>(evals) += (tmp * scaling_factor); + std::get<17>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem.hpp index 5e7671b889ed..93c24d10d2e7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem.hpp @@ -14,8 +14,9 @@ template class ecc_memImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 6, 5, - 6, 5, 4, 3, 4, 4, 4, 4 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { + 3, 3, 3, 3, 3, 6, 5, 6, 5, 4, 3, 4, 4, 4, 4 + }; template inline static bool skip(const AllEntities& in) { @@ -37,10 +38,14 @@ template class ecc_mem : public Relation> { // Subrelation indices constants, to be used in tests. static constexpr size_t SR_WRITE_INCR_DST_ADDR = 1; - static constexpr size_t SR_P_CURVE_EQN = 6; - static constexpr size_t SR_P_ON_CURVE_CHECK = 7; - static constexpr size_t SR_Q_CURVE_EQN = 8; - static constexpr size_t SR_Q_ON_CURVE_CHECK = 9; + static constexpr size_t SR_P_CURVE_EQN = 5; + static constexpr size_t SR_P_ON_CURVE_CHECK = 6; + static constexpr size_t SR_Q_CURVE_EQN = 7; + static constexpr size_t SR_Q_ON_CURVE_CHECK = 8; + static constexpr size_t SR_P_INF_X_CHECK = 11; + static constexpr size_t SR_P_INF_Y_CHECK = 12; + static constexpr size_t SR_Q_INF_X_CHECK = 13; + static constexpr size_t SR_Q_INF_Y_CHECK = 14; static std::string get_subrelation_label(size_t index) { @@ -55,6 +60,14 @@ template class ecc_mem : public Relation> { return "Q_CURVE_EQN"; case SR_Q_ON_CURVE_CHECK: return "Q_ON_CURVE_CHECK"; + case SR_P_INF_X_CHECK: + return "P_INF_X_CHECK"; + case SR_P_INF_Y_CHECK: + return "P_INF_Y_CHECK"; + case SR_Q_INF_X_CHECK: + return "Q_INF_X_CHECK"; + case SR_Q_INF_Y_CHECK: + return "Q_INF_Y_CHECK"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem_impl.hpp index 7a90c736ffb9..215eb8578019 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem_impl.hpp @@ -38,116 +38,97 @@ void ecc_memImpl::accumulate(ContainerOverSubrelations& evals, } { using View = typename std::tuple_element_t<2, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::ecc_add_mem_dst_addr_2_)) - - static_cast(in.get(C::ecc_add_mem_sel)) * - (static_cast(in.get(C::ecc_add_mem_dst_addr_0_)) + FF(2))); - std::get<2>(evals) += (tmp * scaling_factor); - } - { - using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * (static_cast(in.get(C::ecc_add_mem_max_mem_addr)) - CView(constants_AVM_HIGHEST_MEM_ADDRESS)); - std::get<3>(evals) += (tmp * scaling_factor); + std::get<2>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err)) * (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err))); - std::get<4>(evals) += (tmp * scaling_factor); + std::get<3>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err)) * (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err))); - std::get<5>(evals) += (tmp * scaling_factor); + std::get<4>(evals) += (tmp * scaling_factor); } { // P_CURVE_EQN - using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_add_mem_p_is_on_curve_eqn)) - static_cast(in.get(C::ecc_add_mem_sel)) * (CView(ecc_add_mem_P_Y2) - (CView(ecc_add_mem_P_X3) - FF(17))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_p_is_inf)))); - std::get<6>(evals) += (tmp * scaling_factor); + std::get<5>(evals) += (tmp * scaling_factor); } { // P_ON_CURVE_CHECK - using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * (static_cast(in.get(C::ecc_add_mem_p_is_on_curve_eqn)) * ((FF(1) - static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_p_is_on_curve_eqn_inv))) + static_cast(in.get(C::ecc_add_mem_p_is_on_curve_eqn_inv))) - static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err))); - std::get<7>(evals) += (tmp * scaling_factor); + std::get<6>(evals) += (tmp * scaling_factor); } { // Q_CURVE_EQN - using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_add_mem_q_is_on_curve_eqn)) - static_cast(in.get(C::ecc_add_mem_sel)) * (CView(ecc_add_mem_Q_Y2) - (CView(ecc_add_mem_Q_X3) - FF(17))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_q_is_inf)))); - std::get<8>(evals) += (tmp * scaling_factor); + std::get<7>(evals) += (tmp * scaling_factor); } { // Q_ON_CURVE_CHECK - using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * (static_cast(in.get(C::ecc_add_mem_q_is_on_curve_eqn)) * ((FF(1) - static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_q_is_on_curve_eqn_inv))) + static_cast(in.get(C::ecc_add_mem_q_is_on_curve_eqn_inv))) - static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err))); - std::get<9>(evals) += (tmp * scaling_factor); + std::get<8>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_add_mem_err)) - (FF(1) - (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_dst_out_of_range_err))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err))))); - std::get<10>(evals) += (tmp * scaling_factor); + std::get<9>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_add_mem_sel_should_exec)) - static_cast(in.get(C::ecc_add_mem_sel)) * (FF(1) - static_cast(in.get(C::ecc_add_mem_err)))); + std::get<10>(evals) += (tmp * scaling_factor); + } + { // P_INF_X_CHECK + using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * static_cast(in.get(C::ecc_add_mem_p_is_inf)) * + (static_cast(in.get(C::ecc_add_mem_p_x)) - CView(ecc_INFINITY_X)); std::get<11>(evals) += (tmp * scaling_factor); } - { + { // P_INF_Y_CHECK using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_add_mem_sel_should_exec)) * - ((static_cast(in.get(C::ecc_add_mem_p_x_n)) - - (FF(1) - static_cast(in.get(C::ecc_add_mem_p_is_inf))) * - static_cast(in.get(C::ecc_add_mem_p_x))) - - static_cast(in.get(C::ecc_add_mem_p_is_inf)) * CView(ecc_INFINITY_X)); + auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * static_cast(in.get(C::ecc_add_mem_p_is_inf)) * + (static_cast(in.get(C::ecc_add_mem_p_y)) - CView(ecc_INFINITY_Y)); std::get<12>(evals) += (tmp * scaling_factor); } - { + { // Q_INF_X_CHECK using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_add_mem_sel_should_exec)) * - ((static_cast(in.get(C::ecc_add_mem_p_y_n)) - - (FF(1) - static_cast(in.get(C::ecc_add_mem_p_is_inf))) * - static_cast(in.get(C::ecc_add_mem_p_y))) - - static_cast(in.get(C::ecc_add_mem_p_is_inf)) * CView(ecc_INFINITY_Y)); + auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * static_cast(in.get(C::ecc_add_mem_q_is_inf)) * + (static_cast(in.get(C::ecc_add_mem_q_x)) - CView(ecc_INFINITY_X)); std::get<13>(evals) += (tmp * scaling_factor); } - { + { // Q_INF_Y_CHECK using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_add_mem_sel_should_exec)) * - ((static_cast(in.get(C::ecc_add_mem_q_x_n)) - - (FF(1) - static_cast(in.get(C::ecc_add_mem_q_is_inf))) * - static_cast(in.get(C::ecc_add_mem_q_x))) - - static_cast(in.get(C::ecc_add_mem_q_is_inf)) * CView(ecc_INFINITY_X)); + auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * static_cast(in.get(C::ecc_add_mem_q_is_inf)) * + (static_cast(in.get(C::ecc_add_mem_q_y)) - CView(ecc_INFINITY_Y)); std::get<14>(evals) += (tmp * scaling_factor); } - { - using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_add_mem_sel_should_exec)) * - ((static_cast(in.get(C::ecc_add_mem_q_y_n)) - - (FF(1) - static_cast(in.get(C::ecc_add_mem_q_is_inf))) * - static_cast(in.get(C::ecc_add_mem_q_y))) - - static_cast(in.get(C::ecc_add_mem_q_is_inf)) * CView(ecc_INFINITY_Y)); - std::get<15>(evals) += (tmp * scaling_factor); - } } } // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp index c807d2b34b16..f27fca3e9db1 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp @@ -74,7 +74,9 @@ void get_contract_instanceImpl::accumulate(ContainerOverSubrelations& evals static_cast(in.get(C::get_contract_instance_is_class_id)) * static_cast(in.get(C::get_contract_instance_retrieved_class_id)) + static_cast(in.get(C::get_contract_instance_is_init_hash)) * - static_cast(in.get(C::get_contract_instance_retrieved_init_hash)))); + static_cast(in.get(C::get_contract_instance_retrieved_init_hash)) + + static_cast(in.get(C::get_contract_instance_is_immutables_hash)) * + static_cast(in.get(C::get_contract_instance_retrieved_immutables_hash)))); std::get<6>(evals) += (tmp * scaling_factor); } { // MEMBER_WRITE_OFFSET diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.cpp index 4537e24b46a4..786b2c635dfa 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.cpp @@ -28,11 +28,9 @@ namespace bb::avm2 { INSTANTIATE_LOOKUP(lookup_address_derivation_salted_initialization_hash_poseidon2_0_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_salted_initialization_hash_poseidon2_1_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_partial_address_poseidon2_relation); +INSTANTIATE_LOOKUP(lookup_address_derivation_ivpk_m_hash_poseidon2_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_0_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_1_relation); -INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_2_relation); -INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_3_relation); -INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_4_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_preaddress_poseidon2_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_preaddress_scalar_mul_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_address_ecadd_relation); diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.hpp index dd7af40e2658..38fa5107200e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.hpp @@ -26,7 +26,7 @@ struct lookup_address_derivation_salted_initialization_hash_poseidon2_0_settings ColumnAndShifts::address_derivation_salt, ColumnAndShifts::address_derivation_init_hash, ColumnAndShifts::address_derivation_salted_init_hash, - ColumnAndShifts::address_derivation_const_four + ColumnAndShifts::address_derivation_const_five }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::poseidon2_hash_input_0, @@ -55,7 +55,7 @@ struct lookup_address_derivation_salted_initialization_hash_poseidon2_1_settings static constexpr Column INVERSES = Column::lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv; static constexpr std::array SRC_COLUMNS = { ColumnAndShifts::address_derivation_deployer_addr, - ColumnAndShifts::precomputed_zero, + ColumnAndShifts::address_derivation_immutables_hash, ColumnAndShifts::precomputed_zero, ColumnAndShifts::address_derivation_salted_init_hash }; @@ -105,85 +105,21 @@ template using lookup_address_derivation_partial_address_poseidon2_relation = lookup_relation_base; -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_0 /////////////////// +/////////////////// lookup_address_derivation_ivpk_m_hash_poseidon2 /////////////////// -struct lookup_address_derivation_public_keys_hash_poseidon2_0_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_0"; +struct lookup_address_derivation_ivpk_m_hash_poseidon2_settings_ { + static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_IVPK_M_HASH_POSEIDON2"; static constexpr std::string_view RELATION_NAME = "address_derivation"; static constexpr size_t LOOKUP_TUPLE_SIZE = 5; static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; static constexpr Column DST_SELECTOR = Column::poseidon2_hash_start; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_0_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_0_inv; - static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::address_derivation_public_keys_hash_domain_separator, - ColumnAndShifts::address_derivation_nullifier_key_x, - ColumnAndShifts::address_derivation_nullifier_key_y, - ColumnAndShifts::address_derivation_public_keys_hash, - ColumnAndShifts::address_derivation_const_thirteen - }; - static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::poseidon2_hash_input_0, - ColumnAndShifts::poseidon2_hash_input_1, - ColumnAndShifts::poseidon2_hash_input_2, - ColumnAndShifts::poseidon2_hash_output, - ColumnAndShifts::poseidon2_hash_input_len - }; -}; - -using lookup_address_derivation_public_keys_hash_poseidon2_0_settings = - lookup_settings; -template -using lookup_address_derivation_public_keys_hash_poseidon2_0_relation = - lookup_relation_base; - -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_1 /////////////////// - -struct lookup_address_derivation_public_keys_hash_poseidon2_1_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_1"; - static constexpr std::string_view RELATION_NAME = "address_derivation"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 5; - static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; - static constexpr Column DST_SELECTOR = Column::poseidon2_hash_sel; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_1_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_1_inv; + static constexpr Column COUNTS = Column::lookup_address_derivation_ivpk_m_hash_poseidon2_counts; + static constexpr Column INVERSES = Column::lookup_address_derivation_ivpk_m_hash_poseidon2_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::precomputed_zero, + ColumnAndShifts::address_derivation_single_public_key_hash_domain_separator, ColumnAndShifts::address_derivation_incoming_viewing_key_x, ColumnAndShifts::address_derivation_incoming_viewing_key_y, - ColumnAndShifts::address_derivation_public_keys_hash, - ColumnAndShifts::address_derivation_const_four - }; - static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::poseidon2_hash_input_0, - ColumnAndShifts::poseidon2_hash_input_1, - ColumnAndShifts::poseidon2_hash_input_2, - ColumnAndShifts::poseidon2_hash_output, - ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem - }; -}; - -using lookup_address_derivation_public_keys_hash_poseidon2_1_settings = - lookup_settings; -template -using lookup_address_derivation_public_keys_hash_poseidon2_1_relation = - lookup_relation_base; - -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_2 /////////////////// - -struct lookup_address_derivation_public_keys_hash_poseidon2_2_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_2"; - static constexpr std::string_view RELATION_NAME = "address_derivation"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 5; - static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; - static constexpr Column DST_SELECTOR = Column::poseidon2_hash_sel; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_2_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_2_inv; - static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::precomputed_zero, - ColumnAndShifts::address_derivation_outgoing_viewing_key_x, - ColumnAndShifts::address_derivation_outgoing_viewing_key_y, - ColumnAndShifts::address_derivation_public_keys_hash, + ColumnAndShifts::address_derivation_incoming_viewing_key_hash, ColumnAndShifts::address_derivation_const_three }; static constexpr std::array DST_COLUMNS = { @@ -191,61 +127,61 @@ struct lookup_address_derivation_public_keys_hash_poseidon2_2_settings_ { ColumnAndShifts::poseidon2_hash_input_1, ColumnAndShifts::poseidon2_hash_input_2, ColumnAndShifts::poseidon2_hash_output, - ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem + ColumnAndShifts::poseidon2_hash_input_len }; }; -using lookup_address_derivation_public_keys_hash_poseidon2_2_settings = - lookup_settings; +using lookup_address_derivation_ivpk_m_hash_poseidon2_settings = + lookup_settings; template -using lookup_address_derivation_public_keys_hash_poseidon2_2_relation = - lookup_relation_base; +using lookup_address_derivation_ivpk_m_hash_poseidon2_relation = + lookup_relation_base; -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_3 /////////////////// +/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_0 /////////////////// -struct lookup_address_derivation_public_keys_hash_poseidon2_3_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_3"; +struct lookup_address_derivation_public_keys_hash_poseidon2_0_settings_ { + static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_0"; static constexpr std::string_view RELATION_NAME = "address_derivation"; static constexpr size_t LOOKUP_TUPLE_SIZE = 5; static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; - static constexpr Column DST_SELECTOR = Column::poseidon2_hash_sel; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_3_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_3_inv; + static constexpr Column DST_SELECTOR = Column::poseidon2_hash_start; + static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_0_counts; + static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_0_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::precomputed_zero, - ColumnAndShifts::address_derivation_tagging_key_x, - ColumnAndShifts::address_derivation_tagging_key_y, + ColumnAndShifts::address_derivation_public_keys_hash_domain_separator, + ColumnAndShifts::address_derivation_nullifier_key_hash, + ColumnAndShifts::address_derivation_incoming_viewing_key_hash, ColumnAndShifts::address_derivation_public_keys_hash, - ColumnAndShifts::address_derivation_const_two + ColumnAndShifts::address_derivation_const_five }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::poseidon2_hash_input_0, ColumnAndShifts::poseidon2_hash_input_1, ColumnAndShifts::poseidon2_hash_input_2, ColumnAndShifts::poseidon2_hash_output, - ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem + ColumnAndShifts::poseidon2_hash_input_len }; }; -using lookup_address_derivation_public_keys_hash_poseidon2_3_settings = - lookup_settings; +using lookup_address_derivation_public_keys_hash_poseidon2_0_settings = + lookup_settings; template -using lookup_address_derivation_public_keys_hash_poseidon2_3_relation = - lookup_relation_base; +using lookup_address_derivation_public_keys_hash_poseidon2_0_relation = + lookup_relation_base; -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_4 /////////////////// +/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_1 /////////////////// -struct lookup_address_derivation_public_keys_hash_poseidon2_4_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_4"; +struct lookup_address_derivation_public_keys_hash_poseidon2_1_settings_ { + static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_1"; static constexpr std::string_view RELATION_NAME = "address_derivation"; static constexpr size_t LOOKUP_TUPLE_SIZE = 4; static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; static constexpr Column DST_SELECTOR = Column::poseidon2_hash_end; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_4_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_4_inv; + static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_1_counts; + static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_1_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::precomputed_zero, - ColumnAndShifts::precomputed_zero, + ColumnAndShifts::address_derivation_outgoing_viewing_key_hash, + ColumnAndShifts::address_derivation_tagging_key_hash, ColumnAndShifts::precomputed_zero, ColumnAndShifts::address_derivation_public_keys_hash }; @@ -257,11 +193,11 @@ struct lookup_address_derivation_public_keys_hash_poseidon2_4_settings_ { }; }; -using lookup_address_derivation_public_keys_hash_poseidon2_4_settings = - lookup_settings; +using lookup_address_derivation_public_keys_hash_poseidon2_1_settings = + lookup_settings; template -using lookup_address_derivation_public_keys_hash_poseidon2_4_relation = - lookup_relation_base; +using lookup_address_derivation_public_keys_hash_poseidon2_1_relation = + lookup_relation_base; /////////////////// lookup_address_derivation_preaddress_poseidon2 /////////////////// @@ -332,7 +268,7 @@ using lookup_address_derivation_preaddress_scalar_mul_relation = struct lookup_address_derivation_address_ecadd_settings_ { static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_ADDRESS_ECADD"; static constexpr std::string_view RELATION_NAME = "address_derivation"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 9; + static constexpr size_t LOOKUP_TUPLE_SIZE = 8; static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; static constexpr Column DST_SELECTOR = Column::ecc_sel; static constexpr Column COUNTS = Column::lookup_address_derivation_address_ecadd_counts; @@ -345,13 +281,12 @@ struct lookup_address_derivation_address_ecadd_settings_ { ColumnAndShifts::address_derivation_incoming_viewing_key_y, ColumnAndShifts::precomputed_zero, ColumnAndShifts::address_derivation_address, - ColumnAndShifts::address_derivation_address_y, - ColumnAndShifts::precomputed_zero + ColumnAndShifts::address_derivation_address_y }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::ecc_p_x, ColumnAndShifts::ecc_p_y, ColumnAndShifts::ecc_p_is_inf, ColumnAndShifts::ecc_q_x, ColumnAndShifts::ecc_q_y, ColumnAndShifts::ecc_q_is_inf, - ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_r_is_inf + ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_contract_instance_retrieval.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_contract_instance_retrieval.hpp index a314f368785e..a646a48affed 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_contract_instance_retrieval.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_contract_instance_retrieval.hpp @@ -108,7 +108,7 @@ using lookup_contract_instance_retrieval_deployment_nullifier_read_relation = struct lookup_contract_instance_retrieval_address_derivation_settings_ { static constexpr std::string_view NAME = "LOOKUP_CONTRACT_INSTANCE_RETRIEVAL_ADDRESS_DERIVATION"; static constexpr std::string_view RELATION_NAME = "contract_instance_retrieval"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 13; + static constexpr size_t LOOKUP_TUPLE_SIZE = 11; static constexpr Column SRC_SELECTOR = Column::contract_instance_retrieval_exists; static constexpr Column DST_SELECTOR = Column::address_derivation_sel; static constexpr Column COUNTS = Column::lookup_contract_instance_retrieval_address_derivation_counts; @@ -119,14 +119,12 @@ struct lookup_contract_instance_retrieval_address_derivation_settings_ { ColumnAndShifts::contract_instance_retrieval_deployer_addr, ColumnAndShifts::contract_instance_retrieval_original_class_id, ColumnAndShifts::contract_instance_retrieval_init_hash, - ColumnAndShifts::contract_instance_retrieval_nullifier_key_x, - ColumnAndShifts::contract_instance_retrieval_nullifier_key_y, + ColumnAndShifts::contract_instance_retrieval_immutables_hash, + ColumnAndShifts::contract_instance_retrieval_nullifier_key_hash, ColumnAndShifts::contract_instance_retrieval_incoming_viewing_key_x, ColumnAndShifts::contract_instance_retrieval_incoming_viewing_key_y, - ColumnAndShifts::contract_instance_retrieval_outgoing_viewing_key_x, - ColumnAndShifts::contract_instance_retrieval_outgoing_viewing_key_y, - ColumnAndShifts::contract_instance_retrieval_tagging_key_x, - ColumnAndShifts::contract_instance_retrieval_tagging_key_y + ColumnAndShifts::contract_instance_retrieval_outgoing_viewing_key_hash, + ColumnAndShifts::contract_instance_retrieval_tagging_key_hash }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::address_derivation_address, @@ -134,14 +132,12 @@ struct lookup_contract_instance_retrieval_address_derivation_settings_ { ColumnAndShifts::address_derivation_deployer_addr, ColumnAndShifts::address_derivation_class_id, ColumnAndShifts::address_derivation_init_hash, - ColumnAndShifts::address_derivation_nullifier_key_x, - ColumnAndShifts::address_derivation_nullifier_key_y, + ColumnAndShifts::address_derivation_immutables_hash, + ColumnAndShifts::address_derivation_nullifier_key_hash, ColumnAndShifts::address_derivation_incoming_viewing_key_x, ColumnAndShifts::address_derivation_incoming_viewing_key_y, - ColumnAndShifts::address_derivation_outgoing_viewing_key_x, - ColumnAndShifts::address_derivation_outgoing_viewing_key_y, - ColumnAndShifts::address_derivation_tagging_key_x, - ColumnAndShifts::address_derivation_tagging_key_y + ColumnAndShifts::address_derivation_outgoing_viewing_key_hash, + ColumnAndShifts::address_derivation_tagging_key_hash }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_ecc_mem.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_ecc_mem.hpp index f8ccded46702..f10d3530128e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_ecc_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_ecc_mem.hpp @@ -22,7 +22,7 @@ struct lookup_ecc_mem_check_dst_addr_in_range_settings_ { static constexpr Column COUNTS = Column::lookup_ecc_mem_check_dst_addr_in_range_counts; static constexpr Column INVERSES = Column::lookup_ecc_mem_check_dst_addr_in_range_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::ecc_add_mem_dst_addr_2_, + ColumnAndShifts::ecc_add_mem_dst_addr_1_, ColumnAndShifts::ecc_add_mem_max_mem_addr, ColumnAndShifts::ecc_add_mem_sel_dst_out_of_range_err }; @@ -42,20 +42,20 @@ using lookup_ecc_mem_check_dst_addr_in_range_relation = struct lookup_ecc_mem_input_output_ecc_add_settings_ { static constexpr std::string_view NAME = "LOOKUP_ECC_MEM_INPUT_OUTPUT_ECC_ADD"; static constexpr std::string_view RELATION_NAME = "ecc_mem"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 9; + static constexpr size_t LOOKUP_TUPLE_SIZE = 8; static constexpr Column SRC_SELECTOR = Column::ecc_add_mem_sel_should_exec; static constexpr Column DST_SELECTOR = Column::ecc_sel; static constexpr Column COUNTS = Column::lookup_ecc_mem_input_output_ecc_add_counts; static constexpr Column INVERSES = Column::lookup_ecc_mem_input_output_ecc_add_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::ecc_add_mem_p_x_n, ColumnAndShifts::ecc_add_mem_p_y_n, ColumnAndShifts::ecc_add_mem_p_is_inf, - ColumnAndShifts::ecc_add_mem_q_x_n, ColumnAndShifts::ecc_add_mem_q_y_n, ColumnAndShifts::ecc_add_mem_q_is_inf, - ColumnAndShifts::ecc_add_mem_res_x, ColumnAndShifts::ecc_add_mem_res_y, ColumnAndShifts::ecc_add_mem_res_is_inf + ColumnAndShifts::ecc_add_mem_p_x, ColumnAndShifts::ecc_add_mem_p_y, ColumnAndShifts::ecc_add_mem_p_is_inf, + ColumnAndShifts::ecc_add_mem_q_x, ColumnAndShifts::ecc_add_mem_q_y, ColumnAndShifts::ecc_add_mem_q_is_inf, + ColumnAndShifts::ecc_add_mem_res_x, ColumnAndShifts::ecc_add_mem_res_y }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::ecc_p_x, ColumnAndShifts::ecc_p_y, ColumnAndShifts::ecc_p_is_inf, ColumnAndShifts::ecc_q_x, ColumnAndShifts::ecc_q_y, ColumnAndShifts::ecc_q_is_inf, - ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_r_is_inf + ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp index 44537395dab7..557d30fd5643 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp @@ -16,7 +16,7 @@ namespace bb::avm2 { struct lookup_get_contract_instance_precomputed_info_settings_ { static constexpr std::string_view NAME = "LOOKUP_GET_CONTRACT_INSTANCE_PRECOMPUTED_INFO"; static constexpr std::string_view RELATION_NAME = "get_contract_instance"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 5; + static constexpr size_t LOOKUP_TUPLE_SIZE = 6; static constexpr Column SRC_SELECTOR = Column::get_contract_instance_is_valid_writes_in_bounds; static constexpr Column DST_SELECTOR = Column::precomputed_sel_range_8; static constexpr Column COUNTS = Column::lookup_get_contract_instance_precomputed_info_counts; @@ -26,14 +26,13 @@ struct lookup_get_contract_instance_precomputed_info_settings_ { ColumnAndShifts::get_contract_instance_is_valid_member_enum, ColumnAndShifts::get_contract_instance_is_deployer, ColumnAndShifts::get_contract_instance_is_class_id, - ColumnAndShifts::get_contract_instance_is_init_hash + ColumnAndShifts::get_contract_instance_is_init_hash, + ColumnAndShifts::get_contract_instance_is_immutables_hash }; static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::precomputed_idx, - ColumnAndShifts::precomputed_is_valid_member_enum, - ColumnAndShifts::precomputed_is_deployer, - ColumnAndShifts::precomputed_is_class_id, - ColumnAndShifts::precomputed_is_init_hash + ColumnAndShifts::precomputed_idx, ColumnAndShifts::precomputed_is_valid_member_enum, + ColumnAndShifts::precomputed_is_deployer, ColumnAndShifts::precomputed_is_class_id, + ColumnAndShifts::precomputed_is_init_hash, ColumnAndShifts::precomputed_is_immutables_hash }; }; @@ -48,7 +47,7 @@ using lookup_get_contract_instance_precomputed_info_relation = struct lookup_get_contract_instance_contract_instance_retrieval_settings_ { static constexpr std::string_view NAME = "LOOKUP_GET_CONTRACT_INSTANCE_CONTRACT_INSTANCE_RETRIEVAL"; static constexpr std::string_view RELATION_NAME = "get_contract_instance"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 7; + static constexpr size_t LOOKUP_TUPLE_SIZE = 8; static constexpr Column SRC_SELECTOR = Column::get_contract_instance_is_valid_member_enum; static constexpr Column DST_SELECTOR = Column::contract_instance_retrieval_sel; static constexpr Column COUNTS = Column::lookup_get_contract_instance_contract_instance_retrieval_counts; @@ -60,7 +59,8 @@ struct lookup_get_contract_instance_contract_instance_retrieval_settings_ { ColumnAndShifts::get_contract_instance_instance_exists, ColumnAndShifts::get_contract_instance_retrieved_deployer_addr, ColumnAndShifts::get_contract_instance_retrieved_class_id, - ColumnAndShifts::get_contract_instance_retrieved_init_hash + ColumnAndShifts::get_contract_instance_retrieved_init_hash, + ColumnAndShifts::get_contract_instance_retrieved_immutables_hash }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::contract_instance_retrieval_address, @@ -69,7 +69,8 @@ struct lookup_get_contract_instance_contract_instance_retrieval_settings_ { ColumnAndShifts::contract_instance_retrieval_exists, ColumnAndShifts::contract_instance_retrieval_deployer_addr, ColumnAndShifts::contract_instance_retrieval_current_class_id, - ColumnAndShifts::contract_instance_retrieval_init_hash + ColumnAndShifts::contract_instance_retrieval_init_hash, + ColumnAndShifts::contract_instance_retrieval_immutables_hash }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_scalar_mul.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_scalar_mul.hpp index 55f174a4a09b..b1878c5ca4a0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_scalar_mul.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_scalar_mul.hpp @@ -56,7 +56,7 @@ struct lookup_scalar_mul_double_settings_ { ColumnAndShifts::scalar_mul_sel_not_end }; static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_r_is_inf, + ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_result_infinity, ColumnAndShifts::ecc_p_x, ColumnAndShifts::ecc_p_y, ColumnAndShifts::ecc_p_is_inf, ColumnAndShifts::ecc_double_op }; @@ -84,7 +84,7 @@ struct lookup_scalar_mul_add_settings_ { ColumnAndShifts::scalar_mul_temp_inf }; static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_r_is_inf, + ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_result_infinity, ColumnAndShifts::ecc_p_x, ColumnAndShifts::ecc_p_y, ColumnAndShifts::ecc_p_is_inf, ColumnAndShifts::ecc_q_x, ColumnAndShifts::ecc_q_y, ColumnAndShifts::ecc_q_is_inf }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory.hpp index 1a9fcea17707..774d0abe47ee 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory.hpp @@ -14,10 +14,10 @@ template class memoryImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, - 3, 3, 3, 5, 5, 2, 4, 4, 4, 4, 5, 3 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, + 3, 3, 3, 3, 3, 5, 5, 2, 4, 4, 4, 4, 5, 3 }; template inline static bool skip(const AllEntities& in) { @@ -38,18 +38,18 @@ template class memory : public Relation> { static constexpr const std::string_view NAME = "memory"; // Subrelation indices constants, to be used in tests. - static constexpr size_t SR_ACTIVE_ROW_NEEDS_PERM_SELECTOR = 41; - static constexpr size_t SR_MEM_CONTINUITY = 46; - static constexpr size_t SR_SEL_RNG_CHK = 47; - static constexpr size_t SR_LAST_ACCESS = 48; - static constexpr size_t SR_DIFF = 49; - static constexpr size_t SR_DIFF_DECOMP = 50; - static constexpr size_t SR_MEMORY_INIT_VALUE = 51; - static constexpr size_t SR_MEMORY_INIT_TAG = 52; - static constexpr size_t SR_READ_WRITE_CONSISTENCY_VALUE = 53; - static constexpr size_t SR_READ_WRITE_CONSISTENCY_TAG = 54; - static constexpr size_t SR_TAG_IS_FF = 55; - static constexpr size_t SR_SEL_RNG_WRITE = 56; + static constexpr size_t SR_ACTIVE_ROW_NEEDS_PERM_SELECTOR = 40; + static constexpr size_t SR_MEM_CONTINUITY = 45; + static constexpr size_t SR_SEL_RNG_CHK = 46; + static constexpr size_t SR_LAST_ACCESS = 47; + static constexpr size_t SR_DIFF = 48; + static constexpr size_t SR_DIFF_DECOMP = 49; + static constexpr size_t SR_MEMORY_INIT_VALUE = 50; + static constexpr size_t SR_MEMORY_INIT_TAG = 51; + static constexpr size_t SR_READ_WRITE_CONSISTENCY_VALUE = 52; + static constexpr size_t SR_READ_WRITE_CONSISTENCY_TAG = 53; + static constexpr size_t SR_TAG_IS_FF = 54; + static constexpr size_t SR_SEL_RNG_WRITE = 55; static std::string get_subrelation_label(size_t index) { diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory_impl.hpp index 796a1744fad2..b79718f77609 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory_impl.hpp @@ -261,18 +261,12 @@ void memoryImpl::accumulate(ContainerOverSubrelations& evals, } { using View = typename std::tuple_element_t<39, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::memory_sel_ecc_write_2_)) * - (FF(1) - static_cast(in.get(C::memory_sel_ecc_write_2_))); - std::get<39>(evals) += (tmp * scaling_factor); - } - { - using View = typename std::tuple_element_t<40, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel_to_radix_write)) * (FF(1) - static_cast(in.get(C::memory_sel_to_radix_write))); - std::get<40>(evals) += (tmp * scaling_factor); + std::get<39>(evals) += (tmp * scaling_factor); } { // ACTIVE_ROW_NEEDS_PERM_SELECTOR - using View = typename std::tuple_element_t<41, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<40, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_sel)) - (static_cast(in.get(C::memory_sel_addressing_base)) + @@ -313,118 +307,117 @@ void memoryImpl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::memory_sel_sha256_op_7_)) + static_cast(in.get(C::memory_sel_ecc_write_0_)) + static_cast(in.get(C::memory_sel_ecc_write_1_)) + - static_cast(in.get(C::memory_sel_ecc_write_2_)) + static_cast(in.get(C::memory_sel_to_radix_write)))); - std::get<41>(evals) += (tmp * scaling_factor); + std::get<40>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<42, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<41, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel)) * (FF(1) - static_cast(in.get(C::memory_sel))); - std::get<42>(evals) += (tmp * scaling_factor); + std::get<41>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<43, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<42, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_last_access)) * (FF(1) - static_cast(in.get(C::memory_last_access))); - std::get<43>(evals) += (tmp * scaling_factor); + std::get<42>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<44, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<43, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_rw)) * (FF(1) - static_cast(in.get(C::memory_rw))); - std::get<44>(evals) += (tmp * scaling_factor); + std::get<43>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<45, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<44, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel_tag_is_ff)) * (FF(1) - static_cast(in.get(C::memory_sel_tag_is_ff))); - std::get<45>(evals) += (tmp * scaling_factor); + std::get<44>(evals) += (tmp * scaling_factor); } { // MEM_CONTINUITY - using View = typename std::tuple_element_t<46, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<45, ContainerOverSubrelations>::View; auto tmp = ((FF(1) - static_cast(in.get(C::precomputed_first_row))) - static_cast(in.get(C::memory_sel))) * static_cast(in.get(C::memory_sel_shift)); - std::get<46>(evals) += (tmp * scaling_factor); + std::get<45>(evals) += (tmp * scaling_factor); } { // SEL_RNG_CHK - using View = typename std::tuple_element_t<47, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<46, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_sel_rng_chk)) - static_cast(in.get(C::memory_sel)) * static_cast(in.get(C::memory_sel_shift))); - std::get<47>(evals) += (tmp * scaling_factor); + std::get<46>(evals) += (tmp * scaling_factor); } { // LAST_ACCESS - using View = typename std::tuple_element_t<48, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<47, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel_rng_chk)) * (CView(memory_GLOBAL_ADDR_DIFF) * ((FF(1) - static_cast(in.get(C::memory_last_access))) * (FF(1) - static_cast(in.get(C::memory_glob_addr_diff_inv))) + static_cast(in.get(C::memory_glob_addr_diff_inv))) - static_cast(in.get(C::memory_last_access))); - std::get<48>(evals) += (tmp * scaling_factor); + std::get<47>(evals) += (tmp * scaling_factor); } { // DIFF - using View = typename std::tuple_element_t<49, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<48, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_diff)) - static_cast(in.get(C::memory_sel_rng_chk)) * (static_cast(in.get(C::memory_last_access)) * CView(memory_GLOBAL_ADDR_DIFF) + (FF(1) - static_cast(in.get(C::memory_last_access))) * (CView(memory_TIMESTAMP_DIFF) - static_cast(in.get(C::memory_rw_shift)) * static_cast(in.get(C::memory_rw))))); - std::get<49>(evals) += (tmp * scaling_factor); + std::get<48>(evals) += (tmp * scaling_factor); } { // DIFF_DECOMP - using View = typename std::tuple_element_t<50, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<49, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_diff)) - (static_cast(in.get(C::memory_limb_0_)) + static_cast(in.get(C::memory_limb_1_)) * FF(65536) + static_cast(in.get(C::memory_limb_2_)) * FF(4294967296UL))); - std::get<50>(evals) += (tmp * scaling_factor); + std::get<49>(evals) += (tmp * scaling_factor); } { // MEMORY_INIT_VALUE - using View = typename std::tuple_element_t<51, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<50, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_last_access)) + static_cast(in.get(C::precomputed_first_row))) * (FF(1) - static_cast(in.get(C::memory_rw_shift))) * static_cast(in.get(C::memory_value_shift)); - std::get<51>(evals) += (tmp * scaling_factor); + std::get<50>(evals) += (tmp * scaling_factor); } { // MEMORY_INIT_TAG - using View = typename std::tuple_element_t<52, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<51, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_last_access)) + static_cast(in.get(C::precomputed_first_row))) * (FF(1) - static_cast(in.get(C::memory_rw_shift))) * (static_cast(in.get(C::memory_tag_shift)) - CView(constants_MEM_TAG_FF)); - std::get<52>(evals) += (tmp * scaling_factor); + std::get<51>(evals) += (tmp * scaling_factor); } { // READ_WRITE_CONSISTENCY_VALUE - using View = typename std::tuple_element_t<53, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<52, ContainerOverSubrelations>::View; auto tmp = (FF(1) - static_cast(in.get(C::memory_last_access))) * (FF(1) - static_cast(in.get(C::memory_rw_shift))) * (static_cast(in.get(C::memory_value_shift)) - static_cast(in.get(C::memory_value))); - std::get<53>(evals) += (tmp * scaling_factor); + std::get<52>(evals) += (tmp * scaling_factor); } { // READ_WRITE_CONSISTENCY_TAG - using View = typename std::tuple_element_t<54, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<53, ContainerOverSubrelations>::View; auto tmp = (FF(1) - static_cast(in.get(C::memory_last_access))) * (FF(1) - static_cast(in.get(C::memory_rw_shift))) * (static_cast(in.get(C::memory_tag_shift)) - static_cast(in.get(C::memory_tag))); - std::get<54>(evals) += (tmp * scaling_factor); + std::get<53>(evals) += (tmp * scaling_factor); } { // TAG_IS_FF - using View = typename std::tuple_element_t<55, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<54, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel)) * ((CView(memory_TAG_FF_DIFF) * (static_cast(in.get(C::memory_sel_tag_is_ff)) * (FF(1) - static_cast(in.get(C::memory_tag_ff_diff_inv))) + static_cast(in.get(C::memory_tag_ff_diff_inv))) + static_cast(in.get(C::memory_sel_tag_is_ff))) - FF(1)); - std::get<55>(evals) += (tmp * scaling_factor); + std::get<54>(evals) += (tmp * scaling_factor); } { // SEL_RNG_WRITE - using View = typename std::tuple_element_t<56, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<55, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_sel_rng_write)) - static_cast(in.get(C::memory_rw)) * (FF(1) - static_cast(in.get(C::memory_sel_tag_is_ff)))); - std::get<56>(evals) += (tmp * scaling_factor); + std::get<55>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_ecc_mem.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_ecc_mem.hpp index 57a85acc0089..f4965a2e1901 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_ecc_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_ecc_mem.hpp @@ -59,28 +59,4 @@ using perm_ecc_mem_write_mem_1_settings = permutation_settings using perm_ecc_mem_write_mem_1_relation = permutation_relation_base; -/////////////////// perm_ecc_mem_write_mem_2 /////////////////// - -struct perm_ecc_mem_write_mem_2_settings_ { - static constexpr std::string_view NAME = "PERM_ECC_MEM_WRITE_MEM_2"; - static constexpr std::string_view RELATION_NAME = "ecc_mem"; - static constexpr size_t COLUMNS_PER_SET = 6; - static constexpr Column SRC_SELECTOR = Column::ecc_add_mem_sel_should_exec; - static constexpr Column DST_SELECTOR = Column::memory_sel_ecc_write_2_; - static constexpr Column INVERSES = Column::perm_ecc_mem_write_mem_2_inv; - static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::ecc_add_mem_execution_clk, ColumnAndShifts::ecc_add_mem_space_id, - ColumnAndShifts::ecc_add_mem_dst_addr_2_, ColumnAndShifts::ecc_add_mem_res_is_inf, - ColumnAndShifts::ecc_add_mem_sel_should_exec, ColumnAndShifts::ecc_add_mem_sel_should_exec - }; - static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::memory_clk, ColumnAndShifts::memory_space_id, ColumnAndShifts::memory_address, - ColumnAndShifts::memory_value, ColumnAndShifts::memory_tag, ColumnAndShifts::memory_rw - }; -}; - -using perm_ecc_mem_write_mem_2_settings = permutation_settings; -template -using perm_ecc_mem_write_mem_2_relation = permutation_relation_base; - } // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_execution.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_execution.hpp index a171ea2203bc..0cc2e72ecab0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_execution.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_execution.hpp @@ -256,7 +256,7 @@ using perm_execution_dispatch_to_keccakf1600_relation = struct perm_execution_dispatch_to_ecc_add_settings_ { static constexpr std::string_view NAME = "PERM_EXECUTION_DISPATCH_TO_ECC_ADD"; static constexpr std::string_view RELATION_NAME = "execution"; - static constexpr size_t COLUMNS_PER_SET = 10; + static constexpr size_t COLUMNS_PER_SET = 8; static constexpr Column SRC_SELECTOR = Column::execution_sel_exec_dispatch_ecc_add; static constexpr Column DST_SELECTOR = Column::ecc_add_mem_sel; static constexpr Column INVERSES = Column::perm_execution_dispatch_to_ecc_add_inv; @@ -264,14 +264,12 @@ struct perm_execution_dispatch_to_ecc_add_settings_ { ColumnAndShifts::execution_clk, ColumnAndShifts::execution_context_id, ColumnAndShifts::execution_register_0_, ColumnAndShifts::execution_register_1_, ColumnAndShifts::execution_register_2_, ColumnAndShifts::execution_register_3_, - ColumnAndShifts::execution_register_4_, ColumnAndShifts::execution_register_5_, - ColumnAndShifts::execution_rop_6_, ColumnAndShifts::execution_sel_opcode_error + ColumnAndShifts::execution_rop_4_, ColumnAndShifts::execution_sel_opcode_error }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::ecc_add_mem_execution_clk, ColumnAndShifts::ecc_add_mem_space_id, ColumnAndShifts::ecc_add_mem_p_x, ColumnAndShifts::ecc_add_mem_p_y, - ColumnAndShifts::ecc_add_mem_p_is_inf, ColumnAndShifts::ecc_add_mem_q_x, - ColumnAndShifts::ecc_add_mem_q_y, ColumnAndShifts::ecc_add_mem_q_is_inf, + ColumnAndShifts::ecc_add_mem_q_x, ColumnAndShifts::ecc_add_mem_q_y, ColumnAndShifts::ecc_add_mem_dst_addr_0_, ColumnAndShifts::ecc_add_mem_err }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/address_derivation_event.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/address_derivation_event.hpp index d84d9391653e..1dbc56aff5f9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/address_derivation_event.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/address_derivation_event.hpp @@ -10,6 +10,7 @@ struct AddressDerivationEvent { ContractInstance instance{}; FF salted_initialization_hash = 0; FF partial_address = 0; + FF incoming_viewing_key_hash = 0; FF public_keys_hash = 0; FF preaddress = 0; EmbeddedCurvePoint preaddress_public_key = EmbeddedCurvePoint::infinity(); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/get_contract_instance_event.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/get_contract_instance_event.hpp index a9d7b7195c10..bbc0ecc89a1c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/get_contract_instance_event.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/get_contract_instance_event.hpp @@ -26,12 +26,13 @@ struct GetContractInstanceEvent { FF nullifier_tree_root = 0; FF public_data_tree_root = 0; - // Instance retrieval results including all three members which are all needed for tracegen + // Instance retrieval results including all four members which are all needed for tracegen // despite only needing the selected member in simulation. bool instance_exists = false; FF retrieved_deployer_addr = 0; FF retrieved_class_id = 0; FF retrieved_init_hash = 0; + FF retrieved_immutables_hash = 0; }; } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.cpp index a52fb7c0ef01..db1d13f6ed24 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.cpp @@ -15,19 +15,21 @@ namespace bb::avm2::simulation { * If the address has already been derived, an event has already been emitted and we skip * repeating the computation and emission. Otherwise, we compute the address from the instance * members using the poseidon2, scalar_mul, and ecc traces, which is given as: - * 1. salted_init_hash = Poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr) - * 2. partial_address = Poseidon2(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash) - * 3. public_keys_hash = Poseidon2(DOM_SEP__PUBLIC_KEYS_HASH, [...public_keys.to_fields()]) - * 4. preaddress = Poseidon2(DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address) - * 5. preaddress_public_key = preaddress * G1 (Grumpkin scalar multiplication) - * 6. address = (preaddress_public_key + incoming_viewing_key).x (Grumpkin EC add) + * 1. salted_init_hash = Poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr, + * immutables_hash) + * 2. partial_address = Poseidon2(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash) + * 3. incoming_viewing_key_hash = Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, ivpk.x, ivpk.y) + * 4. public_keys_hash = Poseidon2(DOM_SEP__PUBLIC_KEYS_HASH, + * nullifier_key_hash, incoming_viewing_key_hash, outgoing_viewing_key_hash, + * tagging_key_hash) + * 5. preaddress = Poseidon2(DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address) + * 6. preaddress_public_key = preaddress * G1 (Grumpkin scalar multiplication) + * 7. address = (preaddress_public_key + incoming_viewing_key).x (Grumpkin EC add) * and we add the output to the local cache. * - * @throws Unexpected exception if - * - the calculated address does not match @p address. - * * @param address The expected derived address. - * @param instance The contract instance containing the address preimage. + * @param instance The contract instance containing the address preimage members. + * @throws Unexpected exception if the calculated address does not match @p address. */ void AddressDerivation::assert_derivation(const AztecAddress& address, const ContractInstance& instance) { @@ -44,28 +46,31 @@ void AddressDerivation::assert_derivation(const AztecAddress& address, const Con // First time seeing this address - do the actual derivation. // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[SALTED_INITIALIZATION_HASH_POSEIDON2_i] in // address_derivation.pil. - FF salted_initialization_hash = poseidon2.hash( - { DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer }); + FF salted_initialization_hash = poseidon2.hash({ DOM_SEP__SALTED_INITIALIZATION_HASH, + instance.salt, + instance.initialization_hash, + instance.deployer, + instance.immutables_hash }); + // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PARTIAL_ADDRESS_POSEIDON2] in // address_derivation.pil. FF partial_address = poseidon2.hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash }); - std::vector public_keys_hash_fields = instance.public_keys.to_fields(); - std::vector public_key_hash_vec{ DOM_SEP__PUBLIC_KEYS_HASH }; - for (size_t i = 0; i < public_keys_hash_fields.size(); i += 2) { - // Public key x coordinate. - public_key_hash_vec.push_back(public_keys_hash_fields[i]); - // Public key y coordinate. - public_key_hash_vec.push_back(public_keys_hash_fields[i + 1]); - // TODO(#7529): Public key is_infinity will be removed from address preimage, assuming false. - public_key_hash_vec.push_back(FF::zero()); - } - // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PUBLIC_KEYS_HASH_POSEIDON2_i] in - // address_derivation.pil. - FF public_keys_hash = poseidon2.hash(public_key_hash_vec); + // incoming_viewing_key_hash is the only single-key hash computed in-circuit (see #[IVPK_M_HASH_POSEIDON2]). + FF incoming_viewing_key_hash = poseidon2.hash({ DOM_SEP__SINGLE_PUBLIC_KEY_HASH, + instance.public_keys.incoming_viewing_key.x, + instance.public_keys.incoming_viewing_key.y }); + + // public_keys_hash combines the four single-key hashes (see #[PUBLIC_KEYS_HASH_POSEIDON2_0..1]). + FF public_keys_hash = poseidon2.hash({ DOM_SEP__PUBLIC_KEYS_HASH, + instance.public_keys.nullifier_key_hash, + incoming_viewing_key_hash, + instance.public_keys.outgoing_viewing_key_hash, + instance.public_keys.tagging_key_hash }); + // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PREADDRESS_POSEIDON2] in address_derivation.pil. - FF preaddress = poseidon2.hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }); + FF preaddress = poseidon2.hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }); // Note: the below ecc calls assume points are on the curve. We know preaddress_public_key is (by definition), // but it may be possible that incoming_viewing_key is not. @@ -91,6 +96,7 @@ void AddressDerivation::assert_derivation(const AztecAddress& address, const Con .instance = instance, .salted_initialization_hash = salted_initialization_hash, .partial_address = partial_address, + .incoming_viewing_key_hash = incoming_viewing_key_hash, .public_keys_hash = public_keys_hash, .preaddress = preaddress, .preaddress_public_key = preaddress_public_key, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.test.cpp index 523e7ee6fd5a..aae699067b58 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.test.cpp @@ -40,9 +40,11 @@ TEST(AvmSimulationAddressDerivationTest, Positive) ContractInstance instance = testing::random_contract_instance(); AztecAddress derived_address = compute_contract_address(instance); - std::vector salted_init_hash_inputs = { - DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer - }; + std::vector salted_init_hash_inputs = { DOM_SEP__SALTED_INITIALIZATION_HASH, + instance.salt, + instance.initialization_hash, + instance.deployer, + instance.immutables_hash }; FF salted_init_hash = poseidon2::hash(salted_init_hash_inputs); std::vector partial_address_inputs = { DOM_SEP__PARTIAL_ADDRESS, @@ -52,7 +54,7 @@ TEST(AvmSimulationAddressDerivationTest, Positive) FF public_keys_hash = hash_public_keys(instance.public_keys); - std::vector preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }; + std::vector preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }; FF preaddress = poseidon2::hash(preaddress_inputs); EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one(); @@ -93,9 +95,11 @@ TEST(AvmSimulationAddressDerivationTest, Negative) ContractInstance instance = testing::random_contract_instance(); AztecAddress derived_address = compute_contract_address(instance); - std::vector salted_init_hash_inputs = { - DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer - }; + std::vector salted_init_hash_inputs = { DOM_SEP__SALTED_INITIALIZATION_HASH, + instance.salt, + instance.initialization_hash, + instance.deployer, + instance.immutables_hash }; FF salted_init_hash = poseidon2::hash(salted_init_hash_inputs); std::vector partial_address_inputs = { DOM_SEP__PARTIAL_ADDRESS, @@ -105,7 +109,7 @@ TEST(AvmSimulationAddressDerivationTest, Negative) FF public_keys_hash = hash_public_keys(instance.public_keys); - std::vector preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }; + std::vector preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }; FF preaddress = poseidon2::hash(preaddress_inputs); EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one(); @@ -120,10 +124,10 @@ TEST(AvmSimulationAddressDerivationTest, Negative) EXPECT_THROW(address_derivation.assert_derivation(derived_address + 1, instance), std::runtime_error); // Should fail on mutated instance for unseen address. - instance.public_keys.nullifier_key = AffinePoint::one(); + instance.public_keys.nullifier_key_hash = FF(0xdeadbeef); public_keys_hash = hash_public_keys(instance.public_keys); - preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }; + preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }; preaddress = poseidon2::hash(preaddress_inputs); preaddress_public_key = g1 * Fq(preaddress); address_point = preaddress_public_key + instance.public_keys.incoming_viewing_key; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp index 0f3e66759b28..5d4244697de8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp @@ -18,7 +18,7 @@ class InternalEccException : public std::runtime_error { * @brief Adds Grumpkin curve points P and Q and emits an EccAddEvent. * Corresponds to the non-memory aware subtrace ecc.pil. * - * @throws Unexpected exception if points are not on the curve or not normalized. + * @throws Unexpected exception if points are not on the curve. * Note: This function assumes that the points p and q are on the curve. You should only use this function internally * if you can guarantee this. Otherwise it is called via the opcode ECADD, see the overloaded function Ecc::add (which * performs the curve check). @@ -32,13 +32,6 @@ EmbeddedCurvePoint Ecc::add(const EmbeddedCurvePoint& p, const EmbeddedCurvePoin // Check if points are on the curve. These will throw an unexpected exception if they fail. BB_ASSERT(p.on_curve(), "Point p is not on the curve"); BB_ASSERT(q.on_curve(), "Point q is not on the curve"); - // Check if the points are normalized (infinity points must be (0, 0, true)). - if (p.is_infinity()) { - BB_ASSERT((p.x() == 0) && (p.y() == 0), "Point p is not normalized"); - } - if (q.is_infinity()) { - BB_ASSERT((q.x() == 0) && (q.y() == 0), "Point q is not normalized"); - } EmbeddedCurvePoint result = p + q; add_events.emit({ .p = p, .q = q, .result = result }); @@ -70,14 +63,11 @@ EmbeddedCurvePoint Ecc::scalar_mul(const EmbeddedCurvePoint& point, const FF& sc // Emits ToRadixEvent, see #[TO_RADIX] in scalar_mul.pil. auto bits = to_radix.to_le_bits(scalar, 254).first; - // Normalize input infinity point (infinity points must be (0, 0, true)). - EmbeddedCurvePoint point_input = point.is_infinity() ? EmbeddedCurvePoint::infinity() : point; - // First iteration does conditional assignment instead of addition. Note: in circuit we perform reverse aggregation, // so the corresponding constraints for below are gated by 'end'. // See 'Temp Computation' section in scalar_mul.pil. - EmbeddedCurvePoint temp = point_input; + EmbeddedCurvePoint temp = point; bool bit = bits[0]; // See 'Result Computation' section in scalar_mul.pil. @@ -94,10 +84,8 @@ EmbeddedCurvePoint Ecc::scalar_mul(const EmbeddedCurvePoint& point, const FF& sc } intermediate_states[i] = { result, temp, bit }; } - scalar_mul_events.emit({ .point = point_input, - .scalar = scalar, - .intermediate_states = std::move(intermediate_states), - .result = result }); + scalar_mul_events.emit( + { .point = point, .scalar = scalar, .intermediate_states = std::move(intermediate_states), .result = result }); return result; } @@ -124,11 +112,9 @@ void Ecc::add(MemoryInterface& memory, uint16_t space_id = memory.get_space_id(); try { - // The resulting EmbeddedCurvePoint is a triple of (x, y, is_infinity). - // The x and y coordinates are stored at dst_address and dst_address + 1 respectively, - // and the is_infinity flag is stored at dst_address + 2. - // Therefore, the maximum address that needs to be written to is dst_address + 2. - uint64_t max_write_address = static_cast(dst_address) + 2; + // The resulting EmbeddedCurvePoint is (x, y), stored at dst_address and dst_address + 1 respectively. + // Therefore, the maximum address that needs to be written to is dst_address + 1. + uint64_t max_write_address = static_cast(dst_address) + 1; // Emits GreaterThanEvent, see #[CHECK_DST_ADDR_IN_RANGE] in ecc_mem.pil. if (gt.gt(max_write_address, AVM_HIGHEST_MEM_ADDRESS)) { throw InternalEccException("dst address out of range"); @@ -138,18 +124,12 @@ void Ecc::add(MemoryInterface& memory, throw InternalEccException("One of the points is not on the curve"); } - // Normalize input infinity points. - EmbeddedCurvePoint p_input = p.is_infinity() ? EmbeddedCurvePoint::infinity() : p; - EmbeddedCurvePoint q_input = q.is_infinity() ? EmbeddedCurvePoint::infinity() : q; - // Emits EccAddEvent, see #[INPUT_OUTPUT_ECC_ADD] in ecc_mem.pil. - EmbeddedCurvePoint result = - add(p_input, q_input); // Cannot throw since we have checked on_curve() and normalized. + EmbeddedCurvePoint result = add(p, q); // Cannot throw since we have checked on_curve(). - // Emits MemoryEvents, see #[WRITE_MEM_i] for i = 0, 1, 2, in ecc_mem.pil. + // Emits MemoryEvents, see #[WRITE_MEM_i] for i = 0, 1 in ecc_mem.pil. memory.set(dst_address, MemoryValue::from(result.x())); memory.set(dst_address + 1, MemoryValue::from(result.y())); - memory.set(dst_address + 2, MemoryValue::from(result.is_infinity() ? 1 : 0)); add_memory_events.emit({ .execution_clk = execution_clk, .space_id = space_id, @@ -158,9 +138,11 @@ void Ecc::add(MemoryInterface& memory, .result = result, .dst_address = dst_address }); } catch (const InternalEccException& e) { - // Note this point is not on the curve, but corresponds - // to default values the circuit will assign. - EmbeddedCurvePoint res = EmbeddedCurvePoint(0, 0, false); + // Note this point is technically infinity, but we are treating it as 'empty' to corresponds + // to default values the circuit will assign. Since we have caught an InternalEccException, + // we have an error which the circuit should recognise and assign sel_should_exec == 0, so res will not be + // treated as inf. + EmbeddedCurvePoint res = EmbeddedCurvePoint(0, 0); add_memory_events.emit({ .execution_clk = execution_clk, .space_id = space_id, .p = p, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp index c47cdef79b2e..6667c3573883 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp @@ -37,11 +37,11 @@ TEST(AvmSimulationEccTest, Add) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); EmbeddedCurvePoint result = ecc.add(p, q); @@ -74,7 +74,7 @@ TEST(AvmSimulationEccTest, ScalarMul) FF scalar("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); uint256_t scalar_num = scalar; - std::vector bits(254, false); + std::vector bits(254); for (size_t i = 0; i < 254; ++i) { bits[i] = scalar_num.get_bit(i); } @@ -83,7 +83,7 @@ TEST(AvmSimulationEccTest, ScalarMul) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); EmbeddedCurvePoint result = ecc.scalar_mul(p, scalar); @@ -128,7 +128,7 @@ TEST(AvmSimulationEccDeathTest, ScalarMulNotOnCurve) // Point P is not on the curve FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); FF scalar("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); @@ -148,29 +148,27 @@ TEST(AvmSimulationEccTest, AddWithMemory) MemoryStore memory; EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); - EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + EXPECT_CALL(gt, gt(0x1000 + 1, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); Ecc ecc( execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint expected_result(r_x, r_y, false); + EmbeddedCurvePoint expected_result(r_x, r_y); uint32_t dst_address = 0x1000; ecc.add(memory, p, q, dst_address); - EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(), - memory.get(dst_address + 1).as_ff(), - static_cast(memory.get(dst_address + 2).as_ff()) }; + EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(), memory.get(dst_address + 1).as_ff() }; EXPECT_EQ(result, expected_result); } @@ -186,7 +184,7 @@ TEST(AvmSimulationEccTest, AddNotOnCurve) MemoryStore memory; EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); - EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + EXPECT_CALL(gt, gt(0x1000 + 1, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); Ecc ecc( execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); @@ -194,12 +192,12 @@ TEST(AvmSimulationEccTest, AddNotOnCurve) // Point P is not on the curve FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); // Point Q is on the curve FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); uint32_t dst_address = 0x1000; EXPECT_THROW(ecc.add(memory, p, q, dst_address), EccException); @@ -217,7 +215,7 @@ TEST(AvmSimulationEccTest, InfinityOnCurve) MemoryStore memory; EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); - EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + EXPECT_CALL(gt, gt(0x1000 + 1, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); Ecc ecc( execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); @@ -228,14 +226,12 @@ TEST(AvmSimulationEccTest, InfinityOnCurve) // Point Q is on the curve FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); uint32_t dst_address = 0x1000; ecc.add(memory, p, q, dst_address); - EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(), - memory.get(dst_address + 1).as_ff(), - static_cast(memory.get(dst_address + 2).as_ff()) }; + EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(), memory.get(dst_address + 1).as_ff() }; // INF + Q = Q EXPECT_EQ(result, q); } @@ -252,7 +248,7 @@ TEST(AvmSimulationEccTest, AddsUpToInfinity) MemoryStore memory; EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); - EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + EXPECT_CALL(gt, gt(0x1000 + 1, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); Ecc ecc( execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); @@ -260,7 +256,7 @@ TEST(AvmSimulationEccTest, AddsUpToInfinity) // Both points on the curve, q = -p FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); EmbeddedCurvePoint q = -p; @@ -270,8 +266,6 @@ TEST(AvmSimulationEccTest, AddsUpToInfinity) // Zero as coordinates EXPECT_EQ(memory.get(dst_address).as_ff(), FF(0)); EXPECT_EQ(memory.get(dst_address + 1).as_ff(), FF(0)); - // Infinity - EXPECT_EQ(memory.get(dst_address + 2).as_ff(), 1); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp index 8677802581c5..d7198445dee9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp @@ -1469,19 +1469,15 @@ void Execution::poseidon2_permutation(ContextInterface& context, MemoryAddress s * @param context The context. * @param p_x_addr The resolved address of the x coordinate of the first point. * @param p_y_addr The resolved address of the y coordinate of the first point. - * @param p_inf_addr The resolved address of the infinity flag of the first point. * @param q_x_addr The resolved address of the x coordinate of the second point. * @param q_y_addr The resolved address of the y coordinate of the second point. - * @param q_inf_addr The resolved address of the infinity flag of the second point. * @param dst_addr The resolved address of the destination memory address. * * @throws RegisterValidationException if the tags of the input values do not match the expected tags: * - tag of the memory value at p_x_addr is not FF. * - tag of the memory value at p_y_addr is not FF. - * - tag of the memory value at p_inf_addr is not U1. * - tag of the memory value at q_x_addr is not FF. * - tag of the memory value at q_y_addr is not FF. - * - tag of the memory value at q_inf_addr is not U1. * @throws OutOfGasException if the gas limit is exceeded. * @throws OpcodeExecutionException if the elliptic curve addition operation fails: * - memory write out of bounds. @@ -1490,10 +1486,8 @@ void Execution::poseidon2_permutation(ContextInterface& context, MemoryAddress s void Execution::ecc_add(ContextInterface& context, MemoryAddress p_x_addr, MemoryAddress p_y_addr, - MemoryAddress p_inf_addr, MemoryAddress q_x_addr, MemoryAddress q_y_addr, - MemoryAddress q_inf_addr, MemoryAddress dst_addr) { BB_BENCH_NAME("Execution::ecc_add"); @@ -1503,19 +1497,17 @@ void Execution::ecc_add(ContextInterface& context, // Read the points from memory. const auto& p_x = memory.get(p_x_addr); const auto& p_y = memory.get(p_y_addr); - const auto& p_inf = memory.get(p_inf_addr); const auto& q_x = memory.get(q_x_addr); const auto& q_y = memory.get(q_y_addr); - const auto& q_inf = memory.get(q_inf_addr); - set_and_validate_inputs(opcode, { p_x, p_y, p_inf, q_x, q_y, q_inf }); + set_and_validate_inputs(opcode, { p_x, p_y, q_x, q_y }); get_gas_tracker().consume_gas(); // Once inputs are tag checked the conversion to EmbeddedCurvePoint is safe, on curve checks are done in the add // method. - EmbeddedCurvePoint p = EmbeddedCurvePoint(p_x.as_ff(), p_y.as_ff(), p_inf == MemoryValue::from(1)); - EmbeddedCurvePoint q = EmbeddedCurvePoint(q_x.as_ff(), q_y.as_ff(), q_inf == MemoryValue::from(1)); + EmbeddedCurvePoint p = EmbeddedCurvePoint(p_x.as_ff(), p_y.as_ff()); + EmbeddedCurvePoint q = EmbeddedCurvePoint(q_x.as_ff(), q_y.as_ff()); try { embedded_curve.add(memory, p, q, dst_addr); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp index 2c40a5d412f3..af2ade7692ad 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp @@ -173,10 +173,8 @@ class Execution : public ExecutionInterface { void ecc_add(ContextInterface& context, MemoryAddress p_x_addr, MemoryAddress p_y_addr, - MemoryAddress p_inf_addr, MemoryAddress q_x_addr, MemoryAddress q_y_addr, - MemoryAddress q_inf_addr, MemoryAddress dst_addr); void to_radix_be(ContextInterface& context, MemoryAddress value_addr, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp index 8824c8fe91a0..234e8b4e409b 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp @@ -1034,29 +1034,24 @@ TEST_F(ExecutionSimulationTest, EccAdd) { MemoryAddress p_x_addr = 10; MemoryAddress p_y_addr = 15; - MemoryAddress p_is_inf_addr = 25; MemoryAddress q_x_addr = 20; MemoryAddress q_y_addr = 30; - MemoryAddress q_is_inf_addr = 35; MemoryAddress dst_addr = 40; MemoryValue p_x = MemoryValue::from(FF("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a")); MemoryValue p_y = MemoryValue::from(FF("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60")); - EmbeddedCurvePoint p(p_x.as_ff(), p_y, false); + EmbeddedCurvePoint p(p_x.as_ff(), p_y); MemoryValue q_x = MemoryValue::from(FF("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7")); MemoryValue q_y = MemoryValue::from(FF("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3")); - EmbeddedCurvePoint q(q_x.as_ff(), q_y.as_ff(), false); + EmbeddedCurvePoint q(q_x.as_ff(), q_y.as_ff()); // Mock the context and memory interactions - MemoryValue zero = MemoryValue::from(0); EXPECT_CALL(context, get_memory()).WillRepeatedly(ReturnRef(memory)); EXPECT_CALL(Const(memory), get(p_x_addr)).WillOnce(ReturnRef(p_x)); EXPECT_CALL(memory, get(p_y_addr)).WillOnce(ReturnRef(p_y)); - EXPECT_CALL(memory, get(p_is_inf_addr)).WillOnce(ReturnRef(zero)); // p is not infinity EXPECT_CALL(memory, get(q_x_addr)).WillOnce(ReturnRef(q_x)); EXPECT_CALL(memory, get(q_y_addr)).WillOnce(ReturnRef(q_y)); - EXPECT_CALL(memory, get(q_is_inf_addr)).WillOnce(ReturnRef(zero)); // q is not infinity EXPECT_CALL(gas_tracker, consume_gas); @@ -1064,7 +1059,7 @@ TEST_F(ExecutionSimulationTest, EccAdd) EXPECT_CALL(ecc, add(_, _, _, dst_addr)); // Execute the ECC add operation - execution.ecc_add(context, p_x_addr, p_y_addr, p_is_inf_addr, q_x_addr, q_y_addr, q_is_inf_addr, dst_addr); + execution.ecc_add(context, p_x_addr, p_y_addr, q_x_addr, q_y_addr, dst_addr); } TEST_F(ExecutionSimulationTest, ToRadixBE) diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/get_contract_instance.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/get_contract_instance.cpp index 91b2818a724c..c79ed4ae21b7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/get_contract_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/get_contract_instance.cpp @@ -39,7 +39,8 @@ GetContractInstance::GetContractInstance(ExecutionIdManagerInterface& execution_ * @param memory The memory interface for the current context. * @param contract_address The address of the contract to look up. * @param dst_offset The memory offset at which to write the exists flag. - * @param member_enum The enum selecting which instance member to retrieve (deployer/class_id/init_hash). + * @param member_enum The enum selecting which instance member to retrieve + * (deployer/class_id/init_hash/immutables_hash). * @throws GetContractInstanceException If dst_offset+1 is out of bounds (checked first). * @throws GetContractInstanceException If member_enum is invalid (checked after bounds check). */ @@ -90,17 +91,20 @@ void GetContractInstance::get_contract_instance(MemoryInterface& memory, instance_exists ? select_instance_member(maybe_instance.value(), member_enum) : FF(0); write_results(memory, dst_offset, instance_exists, selected_member_value); - event_emitter.emit({ .execution_clk = execution_clk, - .contract_address = contract_address, - .dst_offset = dst_offset, - .member_enum = member_enum, - .space_id = space_id, - .nullifier_tree_root = nullifier_tree_root, - .public_data_tree_root = public_data_tree_root, - .instance_exists = instance_exists, - .retrieved_deployer_addr = instance_exists ? maybe_instance->deployer : FF(0), - .retrieved_class_id = instance_exists ? maybe_instance->current_contract_class_id : FF(0), - .retrieved_init_hash = instance_exists ? maybe_instance->initialization_hash : FF(0) }); + event_emitter.emit({ + .execution_clk = execution_clk, + .contract_address = contract_address, + .dst_offset = dst_offset, + .member_enum = member_enum, + .space_id = space_id, + .nullifier_tree_root = nullifier_tree_root, + .public_data_tree_root = public_data_tree_root, + .instance_exists = instance_exists, + .retrieved_deployer_addr = instance_exists ? maybe_instance->deployer : FF(0), + .retrieved_class_id = instance_exists ? maybe_instance->current_contract_class_id : FF(0), + .retrieved_init_hash = instance_exists ? maybe_instance->initialization_hash : FF(0), + .retrieved_immutables_hash = instance_exists ? maybe_instance->immutables_hash : FF(0), + }); } /** @@ -139,6 +143,8 @@ FF GetContractInstance::select_instance_member(const ContractInstance& instance, return instance.current_contract_class_id; case ContractInstanceMember::INIT_HASH: return instance.initialization_hash; + case ContractInstanceMember::IMMUTABLES_HASH: + return instance.immutables_hash; default: throw std::runtime_error("This error should have been handled earlier! Invalid member enum: " + std::to_string(member_enum)); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp index 77db48bc7606..dc6df18c382d 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp @@ -74,18 +74,17 @@ FF compute_contract_class_id(const FF& artifact_hash, const FF& private_fn_root, return poseidon2::hash({ DOM_SEP__CONTRACT_CLASS_ID, artifact_hash, private_fn_root, public_bytecode_commitment }); } +// public_keys_hash combines the four hashes (with the ivpk_m one computed in-circuit +// from its (x, y) coordinates) under DOM_SEP__PUBLIC_KEYS_HASH. FF hash_public_keys(const PublicKeys& public_keys) { - std::vector public_keys_hash_fields = public_keys.to_fields(); - - std::vector public_key_hash_vec{ DOM_SEP__PUBLIC_KEYS_HASH }; - for (size_t i = 0; i < public_keys_hash_fields.size(); i += 2) { - public_key_hash_vec.push_back(public_keys_hash_fields[i]); - public_key_hash_vec.push_back(public_keys_hash_fields[i + 1]); - // TODO(#7529): is_infinity will be removed from address preimage, assuming false. - public_key_hash_vec.push_back(FF::zero()); - } - return poseidon2::hash({ public_key_hash_vec }); + FF incoming_viewing_key_hash = poseidon2::hash( + { DOM_SEP__SINGLE_PUBLIC_KEY_HASH, public_keys.incoming_viewing_key.x, public_keys.incoming_viewing_key.y }); + return poseidon2::hash({ DOM_SEP__PUBLIC_KEYS_HASH, + public_keys.nullifier_key_hash, + incoming_viewing_key_hash, + public_keys.outgoing_viewing_key_hash, + public_keys.tagging_key_hash }); } // Computes a contract instance's derived address. Follows method of AddressDerivation::assert_derivation() (noir's @@ -95,12 +94,13 @@ FF compute_contract_address(const ContractInstance& contract_instance) FF salted_initialization_hash = poseidon2::hash({ DOM_SEP__SALTED_INITIALIZATION_HASH, contract_instance.salt, contract_instance.initialization_hash, - contract_instance.deployer }); + contract_instance.deployer, + contract_instance.immutables_hash }); FF partial_address = poseidon2::hash( { DOM_SEP__PARTIAL_ADDRESS, contract_instance.original_contract_class_id, salted_initialization_hash }); FF public_keys_hash = hash_public_keys(contract_instance.public_keys); - FF h = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }); + FF h = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }); // This is safe since BN254_Fr < GRUMPKIN_Fr so we know there is no modulo reduction grumpkin::fr h_fq = grumpkin::fr(h); BB_ASSERT(contract_instance.public_keys.incoming_viewing_key.on_curve(), diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/hinting_dbs.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/hinting_dbs.cpp index 71f55503510f..937aa2098302 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/hinting_dbs.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/hinting_dbs.cpp @@ -31,11 +31,11 @@ std::optional HintingContractsDB::get_contract_instance(const .current_contract_class_id = instance->current_contract_class_id, .original_contract_class_id = instance->original_contract_class_id, .initialization_hash = instance->initialization_hash, - .public_keys = - PublicKeysHint{ .master_nullifier_public_key = instance->public_keys.nullifier_key, - .master_incoming_viewing_public_key = instance->public_keys.incoming_viewing_key, - .master_outgoing_viewing_public_key = instance->public_keys.outgoing_viewing_key, - .master_tagging_public_key = instance->public_keys.tagging_key } + .immutables_hash = instance->immutables_hash, + .public_keys = PublicKeysHint{ .npk_m_hash = instance->public_keys.nullifier_key_hash, + .ivpk_m = instance->public_keys.incoming_viewing_key, + .ovpk_m_hash = instance->public_keys.outgoing_viewing_key_hash, + .tpk_m_hash = instance->public_keys.tagging_key_hash } }; } diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp index 43789d46d53e..31656d511065 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp @@ -113,12 +113,13 @@ std::optional HintedRawContractDB::get_contract_instance(const .current_contract_class_id = contract_instance_hint.current_contract_class_id, .original_contract_class_id = contract_instance_hint.original_contract_class_id, .initialization_hash = contract_instance_hint.initialization_hash, + .immutables_hash = contract_instance_hint.immutables_hash, .public_keys = PublicKeys{ - .nullifier_key = contract_instance_hint.public_keys.master_nullifier_public_key, - .incoming_viewing_key = contract_instance_hint.public_keys.master_incoming_viewing_public_key, - .outgoing_viewing_key = contract_instance_hint.public_keys.master_outgoing_viewing_public_key, - .tagging_key = contract_instance_hint.public_keys.master_tagging_public_key, + .nullifier_key_hash = contract_instance_hint.public_keys.npk_m_hash, + .incoming_viewing_key = contract_instance_hint.public_keys.ivpk_m, + .outgoing_viewing_key_hash = contract_instance_hint.public_keys.ovpk_m_hash, + .tagging_key_hash = contract_instance_hint.public_keys.tpk_m_hash, }, }); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp index 54446cb8fe27..b879a8ff1ea3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp @@ -188,10 +188,8 @@ const std::unordered_map>& get_wire_opcode_ { OperandType::INDIRECT16, OperandType::UINT16, // lhs.x OperandType::UINT16, // lhs.y - OperandType::UINT16, // lhs.is_infinite OperandType::UINT16, // rhs.x OperandType::UINT16, // rhs.y - OperandType::UINT16, // rhs.is_infinite OperandType::UINT16 } }, // dst_offset // Gadget - Conversion { WireOpCode::TORADIXBE, diff --git a/barretenberg/cpp/src/barretenberg/vm2/testing/avm_inputs.testdata.bin b/barretenberg/cpp/src/barretenberg/vm2/testing/avm_inputs.testdata.bin index 515bb19cc8da277e82a21918549876e8753e9e1a..1a42b7d8a10febafd5e6d8ef0c14e23c2235aaed 100644 GIT binary patch delta 1936 zcmZ|PTS(JU90zc>_IEBTXEp0&Mh`ZEh>YxI1p&sTz16&UC;R?7Cu7U;72n*qAxCX9;CRha5!Syk)IG{1ae-D5in*3<6 zqoc34r8U&nqqckorK;{SFe;JG?!%t+dmbtq3LYhInlLb{+lN7^zIL=L{R{bCk1Ubi ze;+HzmdY{2KMYFc)Q}*TXXP&u;M7|<)XJiEf=+~`Xd)t@yR+z#Vc^Q;OdD%DhA zW|~mNSa)A*D0s-#cDyH*qhs5sVB46C;sR`3h@FNQkrRiEvt=Y(yTeo3czd<{PqZe%%ss_OLl0V`7e*<|xQZ7D(QdE--srfNNOT zGl;8kbJciQxsJ#q38@^tE6BA}cIrJG>SfV-f}Wa`qGulns3nV5-xKe89c%iCdEmax zG$HHKcil>7HmjdTaT|5q;Po`bh#GJRz3Ww(^K74%ooD%DVGkP{RQympPan-ucTT78 zdch;vHfqsRLAJB<`D=IuAGbmSr4{5SJ$-#5mA}mhvLh?ckK;eD1`gdzQ6p;Pda23u zvhYmS%S=+paI({nJ{NoO(;Njgk>M}BkPaVyCBQBgE=k~8{M-hOtQ;Wnv6oW$#9Kjj zXXV#-a4n4-+Qg#G1ogdi_@% delta 3702 zcmb7`TSyd97=U$K%P!u!&atc`OjZxkTTrQ`mAbRK>v~yTqX(01+wf9eh=Q=8sU!lY+pxhFX_^0$ZV zOWrkfuIp5DxXB&7*s+l09B*mt=nS@dx|*BAr^CVaO7lzY%YBmPIMk?P@h!<%pN76|aVd8oI?h$59*LJm(5Il~2z182gmognqSx?js$B)hfo z2V~inY_uoSLILnRP3adEjTWUc%QO6(1knnLp6j<+h(Zqw@!lE`AD-myIlqgO& zqNY8>CiV<)n?P4GJtBnpaZnT!ok>a}O#JU?m!?2#IkNhOkhNuy&kCMoTEt`h@rZES z)lik>wj_*BL%bDn@gCIUee>9Eyr52|#XRzun1*3d%cxK)w>*Pm1}uBf^5CU5qa+mY{NCdZv)p5EfeB} z(JIDk`Xg$UC3CgTtc^s86JCSPzeMPplYD60MbyQEhC$0OI`%eY$RldCC2x(+o2k~u z;T^-=S%U5jsYI=@JWH+FiywRWGi4+3*ao9+A#NDFg4~8&qSjh+ z`%UgT7GKQ!P+zmRnLp^a_nI~{%!?hKzZE)p8l=#>pw>X{LrL#%ac>i53PaW|k=?X-3A0sYaHj z7O5$zhGqtdDW)lDW)>#N$(F_z$rh=mW}D|R9$``tKd@$o*lCBzz3Y}tx>DYo7}v|r zdwz;Sd9$i(#)V2I{>cx5Z8z^{QD(B>T%M7cSK^&o$+$c*C8a2}xcCS`-AjrSbEYpm z%cMNnmi;pKy3E|%(vrlaoYdmU6P;8Y7*`dPCgo%%1I;YH$H1~8uOQpkBe6K+h=Ss} z%@aIMJ8!<(9P(mtQY1J8^xc6vyq} z{vGf0lM^K+C%@)NGn))_KP-IiF)%GD%Fi!3qM(`JAHvhndwB26JsV`2cW63%?=vt@ zSt@UIZQD+zue0NU+9f8>=T%bR{90<)X*TaC+jlv(m_UB>tudz-(r^8XN0W@{BNS=n8M;yzK11FuM;umBKckU=wJ2hu6>#cv5eqoINBi;$pDvoYsch2` z1--j|8B=`Mls3628kqlnc}?l~q27doj~PjuU(86Dut`1)hhkT zZx>fA{mrEn>SXWhs}PwfA!&F-L3sx+-$&aLub^M6zorVNT zd3i?^B##Ghw<(8bFOp$xKPIdmmc+-)AELbNqicv~(p#=?d)zl)5OH8(21dZ-OsSB~ ztAwYs5)*H=#KsQSWCba91wF3R_xlWUC&p=KO%GZxDG>8Ga<#a)-Q?Rf73DT5`|eI| zl$M{ICKac^{eG#?fyF(lg4PdwFE5!GQpECamzMw2KaZj>P5rZDg7@TAk|vX@r97uE zI>V$mxk=iIWzszcW}wr(WtL{=IsLf>v^}znmy> zcF*VKocvpR5<&Ynuho%aR8UoC5vkB+U)2Bc7-RD8?_c^A53;App8ED&PSu6W>xtIp z^L#BVle3LhDX`C;+7y_jc)?(zQl o5a*%SJVBc`+wzJLEb%r!2%h3dl;4}zOl@B?m2vx;sZ5J~0RC8s7XSbN delta 1296 zcmex_Mu|q2 zN#=$YmT5-j29|~+~I_oFp!%K}e z-(Eg#Pt$ReXV+(j?wai2DZ6<-i!+l2$MTHKyb|x!O2*}hDJey%#l=Sm>RwWum@{4R zDwFbLTlUNKs|re!ax#;FMik#;VA+wISX`1?YdA1v92(k*uzZI1}x<*)p?XI0#@0N)3fwk@nYq9A%YYx#dQ!8b0u{`Ih~TzK5< z@2A|DV(!^LWh6dV{q5Yc4`PRBUUGhJrchpbSY~Q@W?nkns>ux;-t|yL{-q`9`9Mi@ zHBjd$1_k(jGI;;KQ*llSng1&_>@-1wOv&6U$cikz4F{57~aqy65j z%}SiVm=sjQC5}k=DQw_$Ybl~dT^6ul|txJK5MCR0!Ha)PNMv7$NbCRr diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.cpp index cc0cf036fe3a..eb9579da5105 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.cpp @@ -17,13 +17,17 @@ namespace bb::avm2::tracegen { * Corresponds to the subtrace address_derivation.pil. * * This trace is non memory-aware and does not handle any errors. It relies on the poseidon2, - * scalar_mul, and ecc traces to constrain correctness of the address, which is derived as: - * 1. salted_init_hash = Poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr) - * 2. partial_address = Poseidon2(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash) - * 3. public_keys_hash = Poseidon2(DOM_SEP__PUBLIC_KEYS_HASH, [...public_keys.to_fields()]) - * 4. preaddress = Poseidon2(DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address) - * 5. preaddress_public_key = preaddress * G1 (Grumpkin scalar multiplication) - * 6. address = (preaddress_public_key + incoming_viewing_key).x (Grumpkin EC add) + * scalar_mul, and ecc traces to constrain correctness of the address. Only the + * incoming_viewing_key is held as a Grumpkin point; the other three master public keys are + * exposed as their hashes (DOM_SEP__SINGLE_PUBLIC_KEY_HASH). The address is derived as: + * 1. salted_init_hash = Poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr, + * immutables_hash) + * 2. partial_address = Poseidon2(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash) + * 3. incoming_viewing_key_hash = Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, ivpk.x, ivpk.y) + * 4. public_keys_hash = Poseidon2(DOM_SEP__PUBLIC_KEYS_HASH, npk_hash, ivpk_m_hash, ovpk_hash, tpk_hash) + * 5. preaddress = Poseidon2(DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address) + * 6. preaddress_public_key = preaddress * G1 (Grumpkin scalar multiplication) + * 7. address = (preaddress_public_key + incoming_viewing_key).x (Grumpkin EC add) * * @param events The container of address derivation events to process. * @param trace The trace container. @@ -48,18 +52,18 @@ void AddressDerivationTraceBuilder::process( { C::address_derivation_deployer_addr, event.instance.deployer }, { C::address_derivation_class_id, event.instance.original_contract_class_id }, { C::address_derivation_init_hash, event.instance.initialization_hash }, - // Public keys (Grumpkin curve points). - { C::address_derivation_nullifier_key_x, event.instance.public_keys.nullifier_key.x }, - { C::address_derivation_nullifier_key_y, event.instance.public_keys.nullifier_key.y }, + { C::address_derivation_immutables_hash, event.instance.immutables_hash }, + // Public keys: only ivpk_m as a point, the other three as hashes. + { C::address_derivation_nullifier_key_hash, event.instance.public_keys.nullifier_key_hash }, { C::address_derivation_incoming_viewing_key_x, event.instance.public_keys.incoming_viewing_key.x }, { C::address_derivation_incoming_viewing_key_y, event.instance.public_keys.incoming_viewing_key.y }, - { C::address_derivation_outgoing_viewing_key_x, event.instance.public_keys.outgoing_viewing_key.x }, - { C::address_derivation_outgoing_viewing_key_y, event.instance.public_keys.outgoing_viewing_key.y }, - { C::address_derivation_tagging_key_x, event.instance.public_keys.tagging_key.x }, - { C::address_derivation_tagging_key_y, event.instance.public_keys.tagging_key.y }, + { C::address_derivation_outgoing_viewing_key_hash, + event.instance.public_keys.outgoing_viewing_key_hash }, + { C::address_derivation_tagging_key_hash, event.instance.public_keys.tagging_key_hash }, // Intermediate hash results. { C::address_derivation_salted_init_hash, event.salted_initialization_hash }, { C::address_derivation_partial_address, event.partial_address }, + { C::address_derivation_incoming_viewing_key_hash, event.incoming_viewing_key_hash }, { C::address_derivation_public_keys_hash, event.public_keys_hash }, { C::address_derivation_preaddress, event.preaddress }, // Intermediate EC results. @@ -69,14 +73,13 @@ void AddressDerivationTraceBuilder::process( // Constant columns (this is temp because aliasing is not allowed in lookups). { C::address_derivation_salted_init_hash_domain_separator, DOM_SEP__SALTED_INITIALIZATION_HASH }, { C::address_derivation_partial_address_domain_separator, DOM_SEP__PARTIAL_ADDRESS }, + { C::address_derivation_single_public_key_hash_domain_separator, DOM_SEP__SINGLE_PUBLIC_KEY_HASH }, { C::address_derivation_public_keys_hash_domain_separator, DOM_SEP__PUBLIC_KEYS_HASH }, - { C::address_derivation_preaddress_domain_separator, DOM_SEP__CONTRACT_ADDRESS_V1 }, + { C::address_derivation_preaddress_domain_separator, DOM_SEP__CONTRACT_ADDRESS_V2 }, { C::address_derivation_g1_x, g1.x() }, { C::address_derivation_g1_y, g1.y() }, - { C::address_derivation_const_two, 2 }, { C::address_derivation_const_three, 3 }, - { C::address_derivation_const_four, 4 }, - { C::address_derivation_const_thirteen, 13 } } }); + { C::address_derivation_const_five, 5 } } }); row++; } } @@ -88,11 +91,9 @@ const InteractionDefinition AddressDerivationTraceBuilder::interactions = .add() .add() + .add() .add() .add() - .add() - .add() - .add() .add() .add() .add(); diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.test.cpp index 42fc8dda7bae..febf919118c3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.test.cpp @@ -35,6 +35,7 @@ TEST(AddressDerivationTraceGenTest, TraceGeneration) .instance = instance, .salted_initialization_hash = FF(12), .partial_address = FF(23), + .incoming_viewing_key_hash = FF(56), .public_keys_hash = FF(34), .preaddress = FF(45), .preaddress_public_key = preaddress_public_key, @@ -52,16 +53,16 @@ TEST(AddressDerivationTraceGenTest, TraceGeneration) ROW_FIELD_EQ(address_derivation_deployer_addr, instance.deployer), ROW_FIELD_EQ(address_derivation_class_id, instance.original_contract_class_id), ROW_FIELD_EQ(address_derivation_init_hash, instance.initialization_hash), - ROW_FIELD_EQ(address_derivation_nullifier_key_x, instance.public_keys.nullifier_key.x), - ROW_FIELD_EQ(address_derivation_nullifier_key_y, instance.public_keys.nullifier_key.y), + ROW_FIELD_EQ(address_derivation_immutables_hash, instance.immutables_hash), + ROW_FIELD_EQ(address_derivation_nullifier_key_hash, instance.public_keys.nullifier_key_hash), ROW_FIELD_EQ(address_derivation_incoming_viewing_key_x, instance.public_keys.incoming_viewing_key.x), ROW_FIELD_EQ(address_derivation_incoming_viewing_key_y, instance.public_keys.incoming_viewing_key.y), - ROW_FIELD_EQ(address_derivation_outgoing_viewing_key_x, instance.public_keys.outgoing_viewing_key.x), - ROW_FIELD_EQ(address_derivation_outgoing_viewing_key_y, instance.public_keys.outgoing_viewing_key.y), - ROW_FIELD_EQ(address_derivation_tagging_key_x, instance.public_keys.tagging_key.x), - ROW_FIELD_EQ(address_derivation_tagging_key_y, instance.public_keys.tagging_key.y), + ROW_FIELD_EQ(address_derivation_outgoing_viewing_key_hash, + instance.public_keys.outgoing_viewing_key_hash), + ROW_FIELD_EQ(address_derivation_tagging_key_hash, instance.public_keys.tagging_key_hash), ROW_FIELD_EQ(address_derivation_salted_init_hash, FF(12)), ROW_FIELD_EQ(address_derivation_partial_address, FF(23)), + ROW_FIELD_EQ(address_derivation_incoming_viewing_key_hash, FF(56)), ROW_FIELD_EQ(address_derivation_public_keys_hash, FF(34)), ROW_FIELD_EQ(address_derivation_preaddress, FF(45)), ROW_FIELD_EQ(address_derivation_preaddress_public_key_x, preaddress_public_key.x()), @@ -69,14 +70,14 @@ TEST(AddressDerivationTraceGenTest, TraceGeneration) ROW_FIELD_EQ(address_derivation_address_y, address_point.y()), ROW_FIELD_EQ(address_derivation_salted_init_hash_domain_separator, DOM_SEP__SALTED_INITIALIZATION_HASH), ROW_FIELD_EQ(address_derivation_partial_address_domain_separator, DOM_SEP__PARTIAL_ADDRESS), + ROW_FIELD_EQ(address_derivation_single_public_key_hash_domain_separator, + DOM_SEP__SINGLE_PUBLIC_KEY_HASH), ROW_FIELD_EQ(address_derivation_public_keys_hash_domain_separator, DOM_SEP__PUBLIC_KEYS_HASH), - ROW_FIELD_EQ(address_derivation_preaddress_domain_separator, DOM_SEP__CONTRACT_ADDRESS_V1), + ROW_FIELD_EQ(address_derivation_preaddress_domain_separator, DOM_SEP__CONTRACT_ADDRESS_V2), ROW_FIELD_EQ(address_derivation_g1_x, EmbeddedCurvePoint::one().x()), ROW_FIELD_EQ(address_derivation_g1_y, EmbeddedCurvePoint::one().y()), - ROW_FIELD_EQ(address_derivation_const_two, 2), ROW_FIELD_EQ(address_derivation_const_three, 3), - ROW_FIELD_EQ(address_derivation_const_four, 4), - ROW_FIELD_EQ(address_derivation_const_thirteen, 13)))); + ROW_FIELD_EQ(address_derivation_const_five, 5)))); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.cpp index 1ca1e17954c2..827c6cbbaee4 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.cpp @@ -62,20 +62,20 @@ void ContractInstanceRetrievalTraceBuilder::process( { C::contract_instance_retrieval_original_class_id, event.contract_instance.original_contract_class_id }, { C::contract_instance_retrieval_init_hash, event.contract_instance.initialization_hash }, + { C::contract_instance_retrieval_immutables_hash, event.contract_instance.immutables_hash }, - // Public keys (hinted) - { C::contract_instance_retrieval_nullifier_key_x, event.contract_instance.public_keys.nullifier_key.x }, - { C::contract_instance_retrieval_nullifier_key_y, event.contract_instance.public_keys.nullifier_key.y }, + // Public keys (hinted). Only ivpk_m is held as a Grumpkin point; + // the others are field-element hashes computed off-circuit by the PXE. + { C::contract_instance_retrieval_nullifier_key_hash, + event.contract_instance.public_keys.nullifier_key_hash }, { C::contract_instance_retrieval_incoming_viewing_key_x, event.contract_instance.public_keys.incoming_viewing_key.x }, { C::contract_instance_retrieval_incoming_viewing_key_y, event.contract_instance.public_keys.incoming_viewing_key.y }, - { C::contract_instance_retrieval_outgoing_viewing_key_x, - event.contract_instance.public_keys.outgoing_viewing_key.x }, - { C::contract_instance_retrieval_outgoing_viewing_key_y, - event.contract_instance.public_keys.outgoing_viewing_key.y }, - { C::contract_instance_retrieval_tagging_key_x, event.contract_instance.public_keys.tagging_key.x }, - { C::contract_instance_retrieval_tagging_key_y, event.contract_instance.public_keys.tagging_key.y }, + { C::contract_instance_retrieval_outgoing_viewing_key_hash, + event.contract_instance.public_keys.outgoing_viewing_key_hash }, + { C::contract_instance_retrieval_tagging_key_hash, + event.contract_instance.public_keys.tagging_key_hash }, // Tree context { C::contract_instance_retrieval_public_data_tree_root, event.public_data_tree_root }, diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.test.cpp index 865470f908cd..7c7857e7c49d 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.test.cpp @@ -28,12 +28,13 @@ ContractInstance create_test_contract_instance(uint32_t salt_value = 123) .current_contract_class_id = FF(0xdeadbeefULL), .original_contract_class_id = FF(0xcafebabeULL), .initialization_hash = FF(0x11111111ULL), + .immutables_hash = FF(0x22222222ULL), .public_keys = PublicKeys{ - .nullifier_key = { FF(0x100), FF(0x101) }, + .nullifier_key_hash = FF(0x100), .incoming_viewing_key = { FF(0x200), FF(0x201) }, - .outgoing_viewing_key = { FF(0x300), FF(0x301) }, - .tagging_key = { FF(0x400), FF(0x401) }, + .outgoing_viewing_key_hash = FF(0x300), + .tagging_key_hash = FF(0x400), }, }; } @@ -98,16 +99,14 @@ TEST(ContractInstanceRetrievalTraceGenTest, SingleEvent) ROW_FIELD_EQ(contract_instance_retrieval_current_class_id, 0xdeadbeefULL), ROW_FIELD_EQ(contract_instance_retrieval_original_class_id, 0xcafebabeULL), ROW_FIELD_EQ(contract_instance_retrieval_init_hash, 0x11111111ULL), + ROW_FIELD_EQ(contract_instance_retrieval_immutables_hash, 0x22222222ULL), - // Public keys - ROW_FIELD_EQ(contract_instance_retrieval_nullifier_key_x, 0x100), - ROW_FIELD_EQ(contract_instance_retrieval_nullifier_key_y, 0x101), + // Public keys (ivpk_m as a point, others as hashes) + ROW_FIELD_EQ(contract_instance_retrieval_nullifier_key_hash, 0x100), ROW_FIELD_EQ(contract_instance_retrieval_incoming_viewing_key_x, 0x200), ROW_FIELD_EQ(contract_instance_retrieval_incoming_viewing_key_y, 0x201), - ROW_FIELD_EQ(contract_instance_retrieval_outgoing_viewing_key_x, 0x300), - ROW_FIELD_EQ(contract_instance_retrieval_outgoing_viewing_key_y, 0x301), - ROW_FIELD_EQ(contract_instance_retrieval_tagging_key_x, 0x400), - ROW_FIELD_EQ(contract_instance_retrieval_tagging_key_y, 0x401), + ROW_FIELD_EQ(contract_instance_retrieval_outgoing_viewing_key_hash, 0x300), + ROW_FIELD_EQ(contract_instance_retrieval_tagging_key_hash, 0x400), // Tree context ROW_FIELD_EQ(contract_instance_retrieval_public_data_tree_root, public_data_tree_root), diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp index 4c494f898176..8860f534f83e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp @@ -131,7 +131,6 @@ void EccTraceBuilder::process_add(const simulation::EventEmitterInterface(event.dst_address); // Error handling, check if the destination address is out of range. - // The max write address is dst_addr + 2, since we write 3 values for R (x, y, is_inf). - bool dst_out_of_range_err = dst_addr + 2 > AVM_HIGHEST_MEM_ADDRESS; + // The max write address is dst_addr + 1, since we write 2 values for R (x, y). + bool dst_out_of_range_err = dst_addr + 1 > AVM_HIGHEST_MEM_ADDRESS; // Error handling, check if the points are on the curve. // We do not use batch inversions as we do not need to invert in the happy path. @@ -297,10 +295,6 @@ void EccTraceBuilder::process_add_with_memory( bool error = dst_out_of_range_err || !p_is_on_curve || !q_is_on_curve; - // Normalized points, ensures that input infinity points are represented by (0, 0) in the ecc subtrace. - EmbeddedCurvePoint p_n = event.p.is_infinity() ? EmbeddedCurvePoint::infinity() : event.p; - EmbeddedCurvePoint q_n = event.q.is_infinity() ? EmbeddedCurvePoint::infinity() : event.q; - trace.set(row, { { { C::ecc_add_mem_sel, 1 }, @@ -322,26 +316,19 @@ void EccTraceBuilder::process_add_with_memory( // Memory Writes { C::ecc_add_mem_dst_addr_0_, dst_addr }, { C::ecc_add_mem_dst_addr_1_, dst_addr + 1 }, - { C::ecc_add_mem_dst_addr_2_, dst_addr + 2 }, // Input - Point P { C::ecc_add_mem_p_x, event.p.x() }, { C::ecc_add_mem_p_y, event.p.y() }, - { C::ecc_add_mem_p_is_inf, event.p.is_infinity() ? 1 : 0 }, // Input - Point Q { C::ecc_add_mem_q_x, event.q.x() }, { C::ecc_add_mem_q_y, event.q.y() }, + // Input - Infinity flags required for ECC trace + { C::ecc_add_mem_p_is_inf, event.p.is_infinity() ? 1 : 0 }, { C::ecc_add_mem_q_is_inf, event.q.is_infinity() ? 1 : 0 }, - // Normalized input - Point P - { C::ecc_add_mem_p_x_n, p_n.x() }, - { C::ecc_add_mem_p_y_n, p_n.y() }, - // Normalized input - Point Q - { C::ecc_add_mem_q_x_n, q_n.x() }, - { C::ecc_add_mem_q_y_n, q_n.y() }, // Output { C::ecc_add_mem_sel_should_exec, error ? 0 : 1 }, { C::ecc_add_mem_res_x, event.result.x() }, { C::ecc_add_mem_res_y, event.result.y() }, - { C::ecc_add_mem_res_is_inf, event.result.is_infinity() ? 1 : 0 }, } }); row++; diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.test.cpp index fd639b225c27..9296470c388c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.test.cpp @@ -21,13 +21,13 @@ TEST(EccTraceGenTest, TraceGenerationAdd) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); builder.process_add({ { .p = p, .q = q, .result = r } }, trace); EXPECT_THAT(trace.as_rows(), @@ -45,10 +45,9 @@ TEST(EccTraceGenTest, TraceGenerationAdd) ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()), ROW_FIELD_EQ(ecc_q_x, q.x()), ROW_FIELD_EQ(ecc_q_y, q.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 0), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 0), ROW_FIELD_EQ(ecc_y_match, 0)))); @@ -61,11 +60,11 @@ TEST(EccTraceGenTest, TraceGenerationDouble) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); EmbeddedCurvePoint q = p; FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); builder.process_add({ { .p = p, .q = q, .result = r } }, trace); @@ -84,10 +83,9 @@ TEST(EccTraceGenTest, TraceGenerationDouble) ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()), ROW_FIELD_EQ(ecc_q_x, p.x()), ROW_FIELD_EQ(ecc_q_y, p.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 0), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 1), ROW_FIELD_EQ(ecc_y_match, 1)))); @@ -100,9 +98,9 @@ TEST(EccTraceGenTest, TraceGenerationInfResult) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); - EmbeddedCurvePoint q(p.x(), -p.y(), false); + EmbeddedCurvePoint q(p.x(), -p.y()); EmbeddedCurvePoint r = p + q; builder.process_add({ { .p = p, .q = q, .result = r } }, trace); @@ -122,10 +120,9 @@ TEST(EccTraceGenTest, TraceGenerationInfResult) ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()), ROW_FIELD_EQ(ecc_q_x, q.x()), ROW_FIELD_EQ(ecc_q_y, q.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 1), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 1), ROW_FIELD_EQ(ecc_y_match, 0)))); @@ -138,7 +135,7 @@ TEST(EccTraceGenTest, TraceGenerationInfAdd) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); // We always assume infinity coordinates have been normalized to (0,0) before reaching tracegen EmbeddedCurvePoint q = EmbeddedCurvePoint::infinity(); @@ -161,10 +158,9 @@ TEST(EccTraceGenTest, TraceGenerationInfAdd) ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()), ROW_FIELD_EQ(ecc_q_x, q.x()), ROW_FIELD_EQ(ecc_q_y, q.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 0), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 0), ROW_FIELD_EQ(ecc_y_match, 0)))); @@ -195,10 +191,9 @@ TEST(EccTraceGenTest, TraceGenerationInfDouble) ROW_FIELD_EQ(ecc_q_is_inf, p.is_infinity()), ROW_FIELD_EQ(ecc_q_x, p.x()), ROW_FIELD_EQ(ecc_q_y, p.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 1), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 1), ROW_FIELD_EQ(ecc_y_match, 1)))); diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.cpp index 3522e60e2187..4fef6af7e196 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.cpp @@ -9,7 +9,7 @@ namespace bb::avm2::tracegen { * Returns boolean selectors indicating whether the enum is valid and which member it selects. * See the ASCII table in get_contract_instance.pil for the full mapping. * - * @param member_enum The member enum value (0=deployer, 1=class_id, 2=init_hash, 3+=invalid). + * @param member_enum The member enum value (0=deployer, 1=class_id, 2=init_hash, 3=immutables_hash, 4+=invalid). * @return A Table struct with is_valid_member_enum and the per-member selector flags. */ GetContractInstanceSpec::Table GetContractInstanceSpec::get_table(uint8_t member_enum) @@ -20,6 +20,7 @@ GetContractInstanceSpec::Table GetContractInstanceSpec::get_table(uint8_t member .is_deployer = false, .is_class_id = false, .is_init_hash = false, + .is_immutables_hash = false, }; switch (static_cast(member_enum)) { @@ -35,6 +36,10 @@ GetContractInstanceSpec::Table GetContractInstanceSpec::get_table(uint8_t member table.is_valid_member_enum = true; table.is_init_hash = true; return table; + case ContractInstanceMember::IMMUTABLES_HASH: + table.is_valid_member_enum = true; + table.is_immutables_hash = true; + return table; default: // Invalid enum - return defaults (all false) return table; diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.hpp index 18509f022d31..b925c9c85c59 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.hpp @@ -11,6 +11,7 @@ class GetContractInstanceSpec { bool is_deployer; bool is_class_id; bool is_init_hash; + bool is_immutables_hash; }; static Table get_table(uint8_t member_enum); diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.cpp index 23832be47578..78b9226168d7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.cpp @@ -8,20 +8,25 @@ namespace bb::avm2::tracegen { void order_jobs_by_destination_columns(std::vector>& jobs) { - // Identify first occurrences of each fingerprint. + // Tag each job with whether its destination-columns fingerprint is being seen for the first + // time. The tag is captured up front so the partition predicate doesn't depend on the + // unique_ptrs, which the partition implementation may null out via moves. unordered_flat_set seen_fingerprints; - unordered_flat_set first_occurrence_jobs; + std::vector>> tagged; + tagged.reserve(jobs.size()); - for (const auto& job : jobs) { + for (auto& job : jobs) { auto fp = job->get_destination_columns_fingerprint(); auto [_, inserted] = seen_fingerprints.insert(fp); - if (inserted) { - first_occurrence_jobs.insert(job.get()); - } + tagged.emplace_back(inserted, std::move(job)); } // Stable partition: first occurrences come first. - std::ranges::stable_partition(jobs, [&](const auto& job) { return first_occurrence_jobs.contains(job.get()); }); + std::ranges::stable_partition(tagged, [](const auto& t) { return t.first; }); + + for (size_t i = 0; i < tagged.size(); ++i) { + jobs[i] = std::move(tagged[i].second); + } } } // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.hpp index 2aacdf9239b1..bc6331c97fb1 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.hpp @@ -1,9 +1,13 @@ #pragma once +#include #include #include +#include #include +#include "barretenberg/common/tuple.hpp" +#include "barretenberg/vm2/common/field.hpp" #include "barretenberg/vm2/generated/columns.hpp" #include "barretenberg/vm2/tracegen/lib/shared_index_cache.hpp" #include "barretenberg/vm2/tracegen/trace_container.hpp" @@ -20,6 +24,20 @@ template struct RefTupleHelper using RefTuple = typename detail::RefTupleHelper::type; +// Same as TraceContainer::get_multiple but copies the values into an owning std::array. Use when +// the result must outlive a subsequent column write (e.g. when stored as a hash-map key): the +// references returned by get_multiple point into column storage and can dangle on reallocation. +template +std::array get_multiple_as_array(const TraceContainer& trace, + const std::array& cols, + uint32_t row) +{ + auto refs = trace.get_multiple(cols, row); + return [&](std::index_sequence) { + return std::array{ flat_tuple::get(refs)... }; + }(std::make_index_sequence{}); +} + class InteractionBuilderInterface { public: virtual ~InteractionBuilderInterface() = default; @@ -33,8 +51,9 @@ class InteractionBuilderInterface { // A concatenate that works with movable objects. template std::vector concatenate_jobs(std::vector&& first, auto&&... rest) { + const size_t total_size = first.size() + (rest.size() + ...); std::vector result = std::move(first); - result.reserve(first.size() + (rest.size() + ...)); + result.reserve(total_size); (std::move(rest.begin(), rest.end(), std::back_inserter(result)), ...); return result; } diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_def.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_def.hpp index 73410b4e21fa..dbb36f7c613e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_def.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_def.hpp @@ -5,10 +5,11 @@ #include #include +#include "barretenberg/common/assert.hpp" #include "barretenberg/vm2/tracegen/lib/interaction_builder.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_builder.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_into_bitwise.hpp" -#include "barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp" +#include "barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_row.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_into_p_decomposition.hpp" #include "barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp" #include "barretenberg/vm2/tracegen/lib/permutation_builder.hpp" @@ -34,8 +35,12 @@ class InteractionDefinition { template InteractionDefinition& add(auto&&... args) { std::string name = (std::string(InteractionSettings::NAME) + ...); - interactions[name] = - get_interaction_factory(std::forward(args)...); + auto [_, inserted] = interactions.emplace( + name, get_interaction_factory(std::forward(args)...)); + + // Safeguard detecting a collision in the interaction names (we do not use separators to have an injective + // serialization). + BB_ASSERT_DEBUG(inserted, "InteractionDefinition::add: collision in interaction name: " + name); return *this; } diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_row.hpp similarity index 100% rename from barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp rename to barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_row.hpp diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp index 1598321f08ca..488aaea46aca 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp @@ -55,7 +55,7 @@ template class MultiPermutationBuilder : publ { // Find each source tuple in the destination table, and set a 1 in the destination selector. trace.visit_column(PermutationSettings::SRC_SELECTOR, [&](uint32_t row, const FF&) { - auto src_values = trace.get_multiple(PermutationSettings::SRC_COLUMNS, row); + auto src_values = get_multiple_as_array(trace, PermutationSettings::SRC_COLUMNS, row); auto index_it = row_idx.find(src_values); if (index_it == row_idx.end() || index_it->second.empty()) { throw std::runtime_error("Failed setting selectors for " + std::string(PermutationSettings::NAME) + @@ -82,8 +82,7 @@ template class MultiPermutationBuilder : publ // and add the row number to the index. See the comment on `row_idx` for more details. row_idx.reserve(trace.get_column_rows(dst_table_selector)); trace.visit_column(dst_table_selector, [&](uint32_t row, const FF&) { - auto dst_values = trace.get_multiple(DST_COLUMNS, row); - row_idx[dst_values].push_back(row); + row_idx[get_multiple_as_array(trace, DST_COLUMNS, row)].push_back(row); }); } @@ -97,11 +96,12 @@ template class MultiPermutationBuilder : publ // We need an extra "destination TABLE selector" which is the selector of the whole table. Column dst_table_selector; - // In a permutation (or lookup) you are trying to find a src suple of values + // In a permutation (or lookup) you are trying to find a src tuple of values // (a, b, c, ...) in some destination table. That is, you want a row number in the destination table. // The following map contains (a, b, c, ...) -> [row_number_1, row_number_2, ...]. // That is, you can efficiently find all the rows in the destination table that match the src tuple. - unordered_flat_map, /*rows*/ std::vector> row_idx; + // Keys are stored as owning value arrays (see get_multiple_as_array in interaction_builder.hpp for rationale). + unordered_flat_map, /*rows*/ std::vector> row_idx; }; } // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/shared_index_cache.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/shared_index_cache.hpp index bf0679b8c40e..8082c19b3c21 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/shared_index_cache.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/shared_index_cache.hpp @@ -80,7 +80,21 @@ class SharedIndexCache { promise->set_value(index); return *index; } catch (...) { - promise->set_exception(std::current_exception()); + // Evict the failed entry so a subsequent get_or_build can retry rather than + // re-throwing the cached exception forever (and broadcasting it to all jobs + // that share this destination). + { + std::unique_lock lock(mutex_); + cache_.erase(key); + } + // Wake any threads already waiting on this future with the build error. + // Swallow any secondary failure here (e.g. promise_already_satisfied if + // set_value partially completed) so the original exception always + // propagates and we never leave waiters blocked. + try { + promise->set_exception(std::current_exception()); + } catch (...) { + } throw; } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/test_interaction_builder.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/test_interaction_builder.hpp index 867ecf31c03e..5db4a345e6e4 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/test_interaction_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/test_interaction_builder.hpp @@ -53,7 +53,7 @@ template class AddChecksToBuilder : public BaseBuilder { template class CheckingPermutationBuilder : public PermutationBuilder { public: - // Use array for storage in map keys (tuples of references can't be stored). + // Owning value array; see get_multiple_as_array in interaction_builder.hpp for why we can't key on RefTuple. using ArrayTuple = std::array; void process(TraceContainer& trace) override @@ -63,13 +63,11 @@ class CheckingPermutationBuilder : public PermutationBuilder static ArrayTuple to_array(const flat_tuple::tuple& tup) - { - return [&](std::index_sequence) { - return ArrayTuple{ flat_tuple::get(tup)... }; - }(std::make_index_sequence{}); - } - unordered_flat_map> source_tuples; unordered_flat_map> destination_tuples; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/memory_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/memory_trace.cpp index 5e62de95961a..8830923b6efd 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/memory_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/memory_trace.cpp @@ -174,7 +174,6 @@ const InteractionDefinition MemoryTraceBuilder::interactions = // ECADD perm_ecc_mem_write_mem_0_settings, perm_ecc_mem_write_mem_1_settings, - perm_ecc_mem_write_mem_2_settings, // To Radix. perm_to_radix_mem_write_mem_settings // Others. diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.cpp index 2801db9e1b02..58e4b9d8b0a0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.cpp @@ -45,6 +45,7 @@ void GetContractInstanceTraceBuilder::process( bool is_deployer = false; bool is_class_id = false; bool is_init_hash = false; + bool is_immutables_hash = false; if (writes_are_in_bounds) { // Get precomputed table values for this member enum @@ -54,14 +55,16 @@ void GetContractInstanceTraceBuilder::process( is_deployer = spec.is_deployer; is_class_id = spec.is_class_id; is_init_hash = spec.is_init_hash; + is_immutables_hash = spec.is_immutables_hash; } bool has_error = !(writes_are_in_bounds && is_valid_member_enum); - FF selected_member = is_deployer ? event.retrieved_deployer_addr - : is_class_id ? event.retrieved_class_id - : is_init_hash ? event.retrieved_init_hash - : FF(0); + FF selected_member = is_deployer ? event.retrieved_deployer_addr + : is_class_id ? event.retrieved_class_id + : is_init_hash ? event.retrieved_init_hash + : is_immutables_hash ? event.retrieved_immutables_hash + : FF(0); trace.set( row, @@ -86,11 +89,13 @@ void GetContractInstanceTraceBuilder::process( { C::get_contract_instance_is_deployer, is_deployer ? 1 : 0 }, { C::get_contract_instance_is_class_id, is_class_id ? 1 : 0 }, { C::get_contract_instance_is_init_hash, is_init_hash ? 1 : 0 }, + { C::get_contract_instance_is_immutables_hash, is_immutables_hash ? 1 : 0 }, // Retrieval results { C::get_contract_instance_instance_exists, event.instance_exists ? 1 : 0 }, { C::get_contract_instance_retrieved_deployer_addr, event.retrieved_deployer_addr }, { C::get_contract_instance_retrieved_class_id, event.retrieved_class_id }, { C::get_contract_instance_retrieved_init_hash, event.retrieved_init_hash }, + { C::get_contract_instance_retrieved_immutables_hash, event.retrieved_immutables_hash }, { C::get_contract_instance_selected_member, selected_member }, // Memory writing { C::get_contract_instance_member_write_offset, writes_are_in_bounds ? (event.dst_offset + 1) : 0 }, diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.test.cpp index 84a2177fdfbf..776bed4461ea 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.test.cpp @@ -205,5 +205,79 @@ TEST(GetContractInstanceTraceTest, OutOfBoundsWrite) ))); } +TEST(GetContractInstanceTraceTest, ValidImmutablesHashEnum) +{ + // Test constants + const uint32_t execution_clk = 42; + const FF nullifier_tree_root = 0x1234; + const FF public_data_tree_root = 0x5678; + const FF contract_address = 0x1234; + const uint32_t dst_offset = 100; + const uint16_t space_id = 1; + const FF deployer_addr = 0x5678; + const FF class_id = 0x9ABC; + const FF init_hash = 0xDEF0; + const FF immutables_hash = 0xCAFE; + const uint32_t dst_offset_plus_one = dst_offset + 1; + const uint8_t immutables_hash_enum = static_cast(ContractInstanceMember::IMMUTABLES_HASH); + const uint8_t u1_tag = static_cast(ValueTag::U1); + const uint8_t ff_tag = static_cast(ValueTag::FF); + + TestTraceContainer trace; + GetContractInstanceTraceBuilder builder; + simulation::EventEmitter emitter; + + simulation::GetContractInstanceEvent event = { + .execution_clk = execution_clk, + .contract_address = contract_address, + .dst_offset = dst_offset, + .member_enum = immutables_hash_enum, + .space_id = space_id, + .nullifier_tree_root = nullifier_tree_root, + .public_data_tree_root = public_data_tree_root, + .instance_exists = true, + .retrieved_deployer_addr = deployer_addr, + .retrieved_class_id = class_id, + .retrieved_init_hash = init_hash, + .retrieved_immutables_hash = immutables_hash, + }; + + emitter.emit(std::move(event)); + auto events = emitter.dump_events(); + + builder.process(events, trace); + + EXPECT_THAT(trace.as_rows(), + ElementsAre( + // Row 0: Skippable gadget selector + AllOf(ROW_FIELD_EQ(get_contract_instance_sel, 0)), + // Row 1: Active GetContractInstance gadget for IMMUTABLES_HASH + AllOf(ROW_FIELD_EQ(get_contract_instance_sel, 1), + ROW_FIELD_EQ(get_contract_instance_clk, execution_clk), + ROW_FIELD_EQ(get_contract_instance_contract_address, contract_address), + ROW_FIELD_EQ(get_contract_instance_dst_offset, dst_offset), + ROW_FIELD_EQ(get_contract_instance_member_enum, immutables_hash_enum), + ROW_FIELD_EQ(get_contract_instance_space_id, space_id), + // Member selection flags + ROW_FIELD_EQ(get_contract_instance_is_valid_member_enum, 1), + ROW_FIELD_EQ(get_contract_instance_is_deployer, 0), + ROW_FIELD_EQ(get_contract_instance_is_class_id, 0), + ROW_FIELD_EQ(get_contract_instance_is_init_hash, 0), + ROW_FIELD_EQ(get_contract_instance_is_immutables_hash, 1), + // Error flags + ROW_FIELD_EQ(get_contract_instance_sel_error, 0), + // Retrieved members + ROW_FIELD_EQ(get_contract_instance_retrieved_deployer_addr, deployer_addr), + ROW_FIELD_EQ(get_contract_instance_retrieved_class_id, class_id), + ROW_FIELD_EQ(get_contract_instance_retrieved_init_hash, init_hash), + ROW_FIELD_EQ(get_contract_instance_retrieved_immutables_hash, immutables_hash), + // Selected member is the immutables hash + ROW_FIELD_EQ(get_contract_instance_selected_member, immutables_hash), + // Memory write columns + ROW_FIELD_EQ(get_contract_instance_member_write_offset, dst_offset_plus_one), + ROW_FIELD_EQ(get_contract_instance_exists_tag, u1_tag), + ROW_FIELD_EQ(get_contract_instance_member_tag, ff_tag)))); +} + } // namespace } // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp index f39415ef39df..e83d96f7b9e8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp @@ -466,7 +466,7 @@ void PrecomputedTraceBuilder::process_get_env_var_table(TraceContainer& trace) /** * @brief Populate the GETCONTRACTINSTANCE lookup table. - * @details One row per ContractInstanceMember enum value (DEPLOYER=0, CLASS_ID=1, INIT_HASH=2). + * @details One row per ContractInstanceMember enum value (DEPLOYER=0, CLASS_ID=1, INIT_HASH=2, IMMUTABLES_HASH=3). * Each row holds a validity flag and one-hot member selectors. See * `opcodes/get_contract_instance.pil` for an ascii version of this table. */ @@ -482,6 +482,7 @@ void PrecomputedTraceBuilder::process_get_contract_instance_table(TraceContainer { C::precomputed_is_deployer, spec.is_deployer ? 1 : 0 }, { C::precomputed_is_class_id, spec.is_class_id ? 1 : 0 }, { C::precomputed_is_init_hash, spec.is_init_hash ? 1 : 0 }, + { C::precomputed_is_immutables_hash, spec.is_immutables_hash ? 1 : 0 }, } }); } } diff --git a/bootstrap.sh b/bootstrap.sh index 2d231035ebb6..e3f209b4fc3a 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -724,21 +724,24 @@ case "$cmd" in ;; "ci-network-bench") # Args: [docker_image] - # Deploys network and runs benchmarks. Cleanup should be done separately. + # Deploys network and runs benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI=1 env_file="${1:?env_file is required}" namespace="${2:?namespace is required}" docker_image="${3:-}" build - # If no docker image provided, build and push to aztecdev - if [ -z "$docker_image" ]; then - release-image/bootstrap.sh push_pr - docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" - fi - # Set up environment and deploy using spartan export NAMESPACE="$namespace" - export AZTEC_DOCKER_IMAGE="$docker_image" - spartan/bootstrap.sh network_deploy "${env_file}" + if [ "${SKIP_NETWORK_DEPLOY:-0}" != "1" ]; then + # If no docker image provided, build and push to aztecdev + if [ -z "$docker_image" ]; then + release-image/bootstrap.sh push_pr + docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" + fi + export AZTEC_DOCKER_IMAGE="$docker_image" + spartan/bootstrap.sh network_deploy "${env_file}" + else + echo "SKIP_NETWORK_DEPLOY=1, running benchmarks against existing network '$namespace'." + fi # Run benchmarks spartan/bootstrap.sh network_bench "${env_file}" rm -rf bench-out @@ -748,22 +751,24 @@ case "$cmd" in ;; "ci-network-proving-bench") # Args: [docker_image] - # Deploys network and runs proving benchmarks. Cleanup should be done separately. + # Deploys network and runs proving benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI=1 env_file="${1:?env_file is required}" namespace="${2:?namespace is required}" docker_image="${3:-}" build - # If no docker image provided, build and push to aztecdev - if [ -z "$docker_image" ]; then - release-image/bootstrap.sh push_pr - docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" - fi - # Set up environment and deploy using spartan export NAMESPACE="$namespace" - export AZTEC_DOCKER_IMAGE="$docker_image" - spartan/bootstrap.sh network_deploy "${env_file}" - # Run proving benchmarks + if [ "${SKIP_NETWORK_DEPLOY:-0}" != "1" ]; then + # If no docker image provided, build and push to aztecdev + if [ -z "$docker_image" ]; then + release-image/bootstrap.sh push_pr + docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" + fi + export AZTEC_DOCKER_IMAGE="$docker_image" + spartan/bootstrap.sh network_deploy "${env_file}" + else + echo "SKIP_NETWORK_DEPLOY=1, running proving benchmarks against existing network '$namespace'." + fi spartan/bootstrap.sh proving_bench "${env_file}" rm -rf bench-out mkdir -p bench-out @@ -772,21 +777,24 @@ case "$cmd" in ;; "ci-network-block-capacity-bench") # Args: [docker_image] - # Deploys network and runs block capacity benchmarks. Cleanup should be done separately. + # Deploys network and runs block capacity benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI=1 env_file="${1:?env_file is required}" namespace="${2:?namespace is required}" docker_image="${3:-}" build - # If no docker image provided, build and push to aztecdev - if [ -z "$docker_image" ]; then - release-image/bootstrap.sh push_pr - docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" - fi - # Set up environment and deploy using spartan export NAMESPACE="$namespace" - export AZTEC_DOCKER_IMAGE="$docker_image" - spartan/bootstrap.sh network_deploy "${env_file}" + if [ "${SKIP_NETWORK_DEPLOY:-0}" != "1" ]; then + # If no docker image provided, build and push to aztecdev + if [ -z "$docker_image" ]; then + release-image/bootstrap.sh push_pr + docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" + fi + export AZTEC_DOCKER_IMAGE="$docker_image" + spartan/bootstrap.sh network_deploy "${env_file}" + else + echo "SKIP_NETWORK_DEPLOY=1, running block capacity benchmarks against existing network '$namespace'." + fi # Run block capacity benchmarks spartan/bootstrap.sh block_capacity_bench "${env_file}" rm -rf bench-out @@ -797,21 +805,25 @@ case "$cmd" in "ci-network-bench-10tps") # Args: [docker_image] # Deploys bench-10tps and runs the 10-min sustained 10 TPS benchmark. + # Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. # Cleanup is done separately via ci-network-teardown. export CI=1 env_file="${1:?env_file is required}" namespace="${2:?namespace is required}" docker_image="${3:-}" build - # If no docker image provided, build and push to aztecdev - if [ -z "$docker_image" ]; then - release-image/bootstrap.sh push_pr - docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" - fi - # Set up environment and deploy using spartan export NAMESPACE="$namespace" - export AZTEC_DOCKER_IMAGE="$docker_image" - spartan/bootstrap.sh network_deploy "${env_file}" + if [ "${SKIP_NETWORK_DEPLOY:-0}" != "1" ]; then + # If no docker image provided, build and push to aztecdev + if [ -z "$docker_image" ]; then + release-image/bootstrap.sh push_pr + docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" + fi + export AZTEC_DOCKER_IMAGE="$docker_image" + spartan/bootstrap.sh network_deploy "${env_file}" + else + echo "SKIP_NETWORK_DEPLOY=1, running the 10 TPS benchmark against existing network '$namespace'." + fi # Run the 10 TPS benchmark spartan/bootstrap.sh bench_10tps "${env_file}" rm -rf bench-out diff --git a/ci.sh b/ci.sh index c1230d142a9e..837e98820ee3 100755 --- a/ci.sh +++ b/ci.sh @@ -31,6 +31,7 @@ function print_usage { echo_cmd "network-scenarios" "Spin up EC2 instances to run network scenario tests in parallel." echo_cmd "network-tests" "Spin up an EC2 instance to run tests on a network." echo_cmd "network-bench" "Spin up an EC2 instance to run benchmarks on a network." + echo_cmd "network-proving-bench" "Spin up an EC2 instance to deploy a network and run proving benchmarks. Set SKIP_NETWORK_DEPLOY=1 to skip deploy." echo_cmd "network-bench-10tps" "Spin up an EC2 instance to run the 10 TPS benchmark on bench-10tps." echo_cmd "network-teardown" "Spin up an EC2 instance to teardown a network deployment." echo_cmd "network-tests-kind" "Spin up an EC2 instance to run a KIND-based spartan test." @@ -250,38 +251,48 @@ case "$cmd" in network-bench) # Args: [docker_image] # If docker_image is not provided, ci-network-bench will build and push to aztecdev. + # Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI_DASHBOARD="network" export JOB_ID="x-${2:?namespace is required}-network-bench" export INSTANCE_POSTFIX="n-bench" # Enough for the build, which should have a lot of caching, and the test harness. # Resources are on GCP. export CPUS=16 - bootstrap_ec2 "./bootstrap.sh ci-network-bench $*" + skip_network_deploy=0 + [ "${SKIP_NETWORK_DEPLOY:-0}" = "1" ] && skip_network_deploy=1 + bootstrap_ec2 "SKIP_NETWORK_DEPLOY=$skip_network_deploy ./bootstrap.sh ci-network-bench $*" ;; network-proving-bench) # Args: [docker_image] - # Deploys network and runs proving benchmarks. + # Deploys network and runs proving benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI_DASHBOARD="network" export JOB_ID="x-${2:?namespace is required}-network-proving-bench" CPUS=16 export INSTANCE_POSTFIX="n-proving-bench" - bootstrap_ec2 "./bootstrap.sh ci-network-proving-bench $*" + skip_network_deploy=0 + [ "${SKIP_NETWORK_DEPLOY:-0}" = "1" ] && skip_network_deploy=1 + bootstrap_ec2 "SKIP_NETWORK_DEPLOY=$skip_network_deploy ./bootstrap.sh ci-network-proving-bench $*" ;; network-block-capacity-bench) # Args: [docker_image] - # Deploys network and runs block capacity benchmarks. + # Deploys network and runs block capacity benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI_DASHBOARD="network" export JOB_ID="x-${2:?namespace is required}-network-block-capacity-bench" CPUS=16 export INSTANCE_POSTFIX="n-block-cap-bench" - bootstrap_ec2 "./bootstrap.sh ci-network-block-capacity-bench $*" + skip_network_deploy=0 + [ "${SKIP_NETWORK_DEPLOY:-0}" = "1" ] && skip_network_deploy=1 + bootstrap_ec2 "SKIP_NETWORK_DEPLOY=$skip_network_deploy ./bootstrap.sh ci-network-block-capacity-bench $*" ;; network-bench-10tps) # Args: [docker_image] # Deploys the bench-10tps network and runs the 10-min 10 TPS benchmark. + # Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI_DASHBOARD="network" export JOB_ID="x-${2:?namespace is required}-network-bench-10tps" CPUS=16 export AWS_SHUTDOWN_TIME=${AWS_SHUTDOWN_TIME:-180} export INSTANCE_POSTFIX="n-bench-10tps" - bootstrap_ec2 "./bootstrap.sh ci-network-bench-10tps $*" + skip_network_deploy=0 + [ "${SKIP_NETWORK_DEPLOY:-0}" = "1" ] && skip_network_deploy=1 + bootstrap_ec2 "SKIP_NETWORK_DEPLOY=$skip_network_deploy ./bootstrap.sh ci-network-bench-10tps $*" ;; network-teardown) # Args: diff --git a/ci3/bootstrap_ec2 b/ci3/bootstrap_ec2 index 117ee3e1e321..39fb276d0f2c 100755 --- a/ci3/bootstrap_ec2 +++ b/ci3/bootstrap_ec2 @@ -346,6 +346,7 @@ start_build() { -e NPM_TOKEN=${NPM_TOKEN:-} \ -e CARGO_REGISTRY_TOKEN=${CARGO_REGISTRY_TOKEN:-} \ -e SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN:-} \ + -e AZTEC_FOUNDATION_CI_SLACK_BOT_TOKEN=${AZTEC_FOUNDATION_CI_SLACK_BOT_TOKEN:-} \ -e SOCKET_SECURITY_API_TOKEN=${SOCKET_SECURITY_API_TOKEN:-} \ -e AWS_TOKEN=\$aws_token \ -e NAMESPACE=${NAMESPACE:-} \ diff --git a/docs/developer_versioned_docs/version-v4.3.0/docs/aztec-nr/debugging.md b/docs/developer_versioned_docs/version-v4.3.0/docs/aztec-nr/debugging.md index f5980ea4aa85..cb9d5b3d32ba 100644 --- a/docs/developer_versioned_docs/version-v4.3.0/docs/aztec-nr/debugging.md +++ b/docs/developer_versioned_docs/version-v4.3.0/docs/aztec-nr/debugging.md @@ -19,7 +19,7 @@ Enable different levels of logging on the local network or node by setting `LOG_ ```bash # Set log level (options: fatal, error, warn, info, verbose, debug, trace) -LOG_LEVEL=debug aztec start --local-network +LOG_LEVEL="debug; info: json-rpc, simulator" aztec start --local-network # Different levels for different services LOG_LEVEL="verbose;info:sequencer" aztec start --local-network diff --git a/docs/docs-developers/docs/aztec-js/how_to_read_data.md b/docs/docs-developers/docs/aztec-js/how_to_read_data.md index 2fd4e438921d..2cc3b2ecca88 100644 --- a/docs/docs-developers/docs/aztec-js/how_to_read_data.md +++ b/docs/docs-developers/docs/aztec-js/how_to_read_data.md @@ -49,6 +49,10 @@ When simulating private functions, the caller must have access to any private st If the caller doesn't have access to another address's notes, the simulation will fail with an error. +:::tip +If `.simulate()` is prompting the user to sign every call, or failing with `min_revertible_side_effect_counter must not be 0` when you pass `from: AztecAddress.ZERO`, see [Simulate without signing prompts](./how_to_simulate_without_signing.md). +::: + :::warning Simulation runs locally without generating proofs. No correctness guarantees are provided on the result. See [Call Types](../foundational-topics/call_types.md#simulate) for more details. ::: diff --git a/docs/docs-developers/docs/aztec-js/how_to_simulate_without_signing.md b/docs/docs-developers/docs/aztec-js/how_to_simulate_without_signing.md new file mode 100644 index 000000000000..72daff7d9c0f --- /dev/null +++ b/docs/docs-developers/docs/aztec-js/how_to_simulate_without_signing.md @@ -0,0 +1,112 @@ +--- +title: Simulate without signing prompts +tags: [simulation, authwit, wallet] +sidebar_position: 6 +description: How to call .simulate() on a view function or estimate gas without prompting the user to sign authentication witnesses. +--- + +You want to call `.simulate()` from an app and not have the user's wallet pop up a signing prompt. This page covers the symptoms that lead to that prompt, why the obvious workarounds do not work, and the right fix. + +For the conceptual model of what kernelless simulation is, see [Kernelless simulations](../foundational-topics/pxe/kernelless_simulations.md). + +## Symptoms + +You are probably here because of one of these: + +- The wallet prompts the user for a signature on every `.simulate()` call, including reads of view-style functions. +- `.simulate()` fails with one of: + - `Account "0x0000…0000" does not exist on this wallet.` (from `EmbeddedWallet`) + - `Account not found in wallet for address: 0x0000…0000` (from other wallets built on `BaseWallet`) + - `Circuit execution failed: min_revertible_side_effect_counter must not be 0 for tail_to_public` (from a custom wallet that does not intercept the zero address, where the call reaches the kernel) + +All three are the same root cause: passing `from: AztecAddress.ZERO`. + +- A custom fee payment method breaks during simulation because `from` is `AztecAddress.ZERO`. +- Simulations take long enough that you want to skip the kernel circuits entirely. + +## The wrong fix + +Do not pass `from: AztecAddress.ZERO`. That value was the old way to express "no account context," and it is no longer a supported input for `.simulate()`. The replacement is `NO_FROM` (from `@aztec/aztec.js/account`), which tells the wallet to execute the payload through the default entrypoint with no account contract mediation. `NO_FROM` is still only appropriate for calls that genuinely have no sender; use a real account address for everything else. + +## The right fix + +A simulation uses a **stub account contract override**: the wallet provides a `SimulationOverrides` payload whose `contracts` map swaps the caller's account contract for a stub whose `is_valid` always returns true, and the PXE applies that override during the kernelless simulation. With the stub in place, authwit validity checks pass without a signature, and the wallet collects any `CallAuthorizationRequest` offchain effects emitted during the run to turn them into real authentication witnesses for the eventual `.send()`. + +`EmbeddedWallet` installs this override automatically on every `.simulate()` call, so most apps do not need to construct overrides themselves. The two ways to wire this up below correspond to "use the default" and "implement it in your own wallet." + +### Calling .simulate() from an app + +For a normal `.simulate()` you do not need to pass overrides yourself. The default simulation path is already kernelless, and wallets such as `EmbeddedWallet` install the stub-account override internally for you. Three things to remember: + +- Pass a real account address as `from`, or `NO_FROM` if the call genuinely has no sender. Do not use `AztecAddress.ZERO`. +- For simple reads, you can omit the `fee` block. +- For a transaction whose real fee path uses a fee payment contract (FPC) with private side effects (the FPC emits notes during fee payment), include that FPC in the simulation's fee options so gas estimation accounts for the FPC's side effects. Kernelless still applies; the gas number stays accurate. +- If you have a stale call site that uses `from: AztecAddress.ZERO` plus a no-op fee payment method as a workaround, replace it with a real `from` (or `NO_FROM`) and drop the no-op fee contract. + +#include_code simulate-view-without-signing /docs/examples/ts/aztecjs_kernelless_simulation/index.ts typescript + +If you genuinely need to construct your own `SimulationOverrides` (for example, to combine a contract-instance swap with a `fastForwardContractUpdate` for upgrade testing), you can pass them through `.simulate()`: + +```typescript +import { SimulationOverrides } from "@aztec/aztec.js/wallet"; + +const { result } = await contract.methods + .transfer_in_private(sender, recipient, amount, nonce) + .simulate({ + from: sender, + overrides: new SimulationOverrides({ + /* contracts and/or publicStorage */ + }), + }); +``` + +The override map itself has to be built by code that knows the contract class id and live contract instance. That is normally the wallet, not the app. Note that `overrides` does not apply to [utility functions](../foundational-topics/pxe/kernelless_simulations.md#where-kernelless-does-not-apply), those are simulated through `wallet.executeUtility`, which rejects `SimulationOverrides`. If your wallet does not handle the override path for you and you are tempted to reimplement it in app code, read the next section instead. + +### Implementing the override in a custom wallet + +`EmbeddedWallet` (`yarn-project/wallets/src/embedded/embedded_wallet.ts`, in `@aztec/wallets`) is the canonical implementation of the override pattern and the reference any custom wallet should follow. The three pieces it wires up are: + +1. **Register the stub contract class with the PXE at wallet startup.** Inside `initStubClasses`, `EmbeddedWallet` calls `pxe.registerContractClass` for each supported account type's stub artifact and caches the resulting class id by account type. +2. **Build an override map for every account in scope.** Inside `buildAccountOverrides`, it fetches the live contract instance for each scoped address and returns a `ContractOverrides` map that copies the instance with `currentContractClassId` rewritten to the stub class id. The map covers every account in scope, not only `from`. +3. **Use the stub entrypoint and pass the override to `pxe.simulateTx`.** Inside the overridden `simulateViaEntrypoint`, it constructs the `TxExecutionRequest` through the stub account's `DefaultAccountEntrypoint` (so the request is signed by the stub's empty-signature provider) and calls `pxe.simulateTx` with the resulting `SimulationOverrides`. + +The key constraints on this path: + +- `skipKernels` must be `true` to use `contracts` overrides. The PXE rejects the combination otherwise. `pxe.simulateTx` already defaults `skipKernels` to `true`. +- The stub contract class must be registered with the PXE before you reference it in an override. +- The override map must cover every scoped account, not only `from`. + +## Collecting authwit requests + +A simulation with the stub override active will reach `#[authorize_once]` call sites in app and token contracts without prompting for signatures. Each such site emits a `CallAuthorizationRequest` as an offchain effect, which the wallet can collect and turn into a real authentication witness for the eventual `.send()`. + +The example below uses the canonical contract-mediated pattern: Alice calls `Crowdfunding.donate(amount)`, which internally calls `transfer_in_private(alice, crowdfunding, amount, 0)` with `msg_sender = crowdfunding`. The token's `#[authorize_once]` macro requires an authwit from Alice authorizing the crowdfunding contract. Because Alice is the transaction sender, her PXE already has her notes and nullifier key, so the simulation can run end-to-end against her own state without any cross-wallet state sharing. + +Run the simulation and filter the offchain effects by the `CallAuthorizationRequest` selector: + +#include_code simulate-and-collect-effects /docs/examples/ts/aztecjs_kernelless_simulation/index.ts typescript + +Decode each effect into a `CallAuthorizationRequest`. The `innerHash` field is the piece the authorizing account needs to sign: + +#include_code decode-call-authorization /docs/examples/ts/aztecjs_kernelless_simulation/index.ts typescript + +Build a real authentication witness from each inner hash and send the transaction with the collected witnesses attached: + +#include_code build-authwits-and-send /docs/examples/ts/aztecjs_kernelless_simulation/index.ts typescript + +The app does not need to know which calls require authwits ahead of time. The simulation discovers them; the wallet signs them at send time. + +`EmbeddedWallet.sendTx` runs this same simulate-then-collect flow internally before delegating to `BaseWallet.sendTx`, so an app that uses `EmbeddedWallet` does not need to call `.simulate()` manually and pass `authWitnesses` to `.send()`. The explicit pattern above is the one a wallet that does not auto-collect must implement, either inside its `sendTx` (as `EmbeddedWallet` does) or inside the app call site. + +## Things to watch out for + +- **`AztecAddress.ZERO` is not "no sender".** Use `NO_FROM` (from `@aztec/aztec.js/account`) for calls that genuinely have no account context, and a real account address otherwise. +- **A private FPC needs to be included in fee options for accurate gas.** Kernelless simulation matches full simulation on gas, but only if the simulation sees the same fee path as the real transaction. If the user will pay through a fee payment contract (FPC) that emits private notes, pass that FPC in the simulation's fee options so its side effects are accounted for. Kernelless plus a private FPC is the supported path; you do not need a full simulation to get accurate gas. +- **`profile()` is not kernelless.** If you call `.profile()` to count circuit gates, the kernels run regardless. Use `.simulate()` if you only need return values, offchain effects, or gas estimates. +- **Utility functions reject overrides.** `FunctionType.UTILITY` calls go through `wallet.executeUtility`, and `ContractFunctionInteraction.simulate` throws `overrides are not supported for utility function simulation` if you pass non-empty `overrides.publicStorage` or `overrides.contracts`. Utility functions do not need an override anyway, since they do not run through an account contract. + +## Related + +- [Kernelless simulations](../foundational-topics/pxe/kernelless_simulations.md) for the conceptual model. +- [Reading contract data](./how_to_read_data.md) for the basic `.simulate()` API. +- [Authentication witnesses](../foundational-topics/advanced/authwit.md) for what `CallAuthorizationRequest` represents. diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md b/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md index d8ade3b69093..4abf4d9a75b0 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md @@ -162,8 +162,8 @@ impl NoteHash for CustomHashNote { note_hash_for_nullification: Field, ) -> Field { // Standard nullifier using owner's nullifier hiding key - let owner_npk_m = get_public_keys(owner).npk_m; - let secret = context.request_nhk_app(owner_npk_m.hash()); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; + let secret = context.request_nhk_app(owner_npk_m_hash); poseidon2_hash_with_separator( [note_hash_for_nullification, secret], DOM_SEP__NOTE_NULLIFIER, @@ -176,7 +176,7 @@ impl NoteHash for CustomHashNote { note_hash_for_nullification: Field, ) -> Option { try_get_public_keys(owner).map(|public_keys| { - let secret = get_nhk_app(public_keys.npk_m.hash()); + let secret = get_nhk_app(public_keys.npk_m_hash); poseidon2_hash_with_separator( [note_hash_for_nullification, secret], DOM_SEP__NOTE_NULLIFIER, diff --git a/docs/docs-developers/docs/foundational-topics/accounts/keys.md b/docs/docs-developers/docs/foundational-topics/accounts/keys.md index 0c673087ca92..70a064e2d124 100644 --- a/docs/docs-developers/docs/foundational-topics/accounts/keys.md +++ b/docs/docs-developers/docs/foundational-topics/accounts/keys.md @@ -68,9 +68,11 @@ The nullifier hiding key (`nhk`) — sometimes referred to in older documentatio To get the owner's master nullifier public key hash (needed as input): ```rust -let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); +let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; ``` +`PublicKeys` exposes the nullifier, outgoing-viewing, and tagging keys directly as their hashes; only `ivpk_m` is held as a Grumpkin point (it is required as a point for address derivation and encrypt-to-address). + :::warning Do not compute nullifier keys by hand or derive custom blinding factors. The protocol kernel validates that `nhk_app` derives correctly from the master key — a hand-rolled value will fail verification. ::: @@ -122,17 +124,23 @@ Your Aztec address is deterministically computed from your public keys and accou ![Address derivation](/img/address_derivation.svg) +:::note +The diagram above is being updated to reflect the new key-hashing scheme described below. Treat the text formulas as authoritative until a refresh lands. +::: + ```text pre_address = hash(public_keys_hash, partial_address) where: - public_keys_hash = hash(Npk_m, Ivpk_m, Ovpk_m, Tpk_m) - partial_address = hash(contract_class_id, salted_initialization_hash) + public_keys_hash = hash(npk_m_hash, ivpk_m_hash, ovpk_m_hash, tpk_m_hash) + ivpk_m_hash = hash(Ivpk_m.x, Ivpk_m.y) // computed in-circuit + npk_m_hash, ovpk_m_hash, tpk_m_hash // computed off-circuit (PXE) + partial_address = hash(contract_class_id, salted_initialization_hash) contract_class_id = hash(artifact_hash, fn_tree_root, public_bytecode_commitment) - salted_initialization_hash = hash(deployer_address, salt, constructor_hash) + salted_initialization_hash = hash(salt, constructor_hash, deployer_address, immutables_hash) ``` -The final address is derived as `address = (pre_address * G + Ivpk_m).x` - only the x-coordinate of the resulting elliptic curve point. +The final address is derived as `address = (pre_address * G + Ivpk_m).x` - only the x-coordinate of the resulting elliptic curve point. Note that `Ivpk_m` (the master incoming viewing key) is the only public key still represented as an elliptic curve point: address derivation needs it as a point so that anyone can encrypt to the address without further information. The other three master keys are exposed only as their hashes. This derivation ensures: diff --git a/docs/docs-developers/docs/foundational-topics/pxe/index.md b/docs/docs-developers/docs/foundational-topics/pxe/index.md index 93bbbb4e3efb..3323efa88a2f 100644 --- a/docs/docs-developers/docs/foundational-topics/pxe/index.md +++ b/docs/docs-developers/docs/foundational-topics/pxe/index.md @@ -40,7 +40,7 @@ flowchart TB ``` :::note[Privacy consideration] -When the PXE queries the node for world state (e.g., to check if a nullifier exists), the node learns which data the user is interested in. This is a known tradeoff—users can mitigate this by running their own node. +When the PXE queries the node for world state (e.g., to check if a nullifier exists), the node learns which data the user is interested in. This is a known tradeoff. Users can mitigate this by running their own node. ::: ## Components @@ -51,7 +51,7 @@ An application prompts the user's PXE to execute a transaction (e.g. execute fun The contract function simulator handles execution of smart contract functions by simulating transactions. It generates the required data and inputs for these functions, including partial witnesses and public inputs. -Until simulated simulations are implemented ([#9133](https://github.com/AztecProtocol/aztec-packages/issues/9133)), authentication witnesses are required for simulation before proving. +By default, the simulator runs in a [kernelless mode](./kernelless_simulations.md): it executes the private bytecode and computes the values the private kernels would have produced in TypeScript, instead of running the kernel circuits themselves. This is faster than a full simulation and lets the wallet capture authentication witness requests as offchain effects without prompting the user to sign during simulation. ### Proof Generation @@ -93,7 +93,7 @@ The set of oracles that the PXE exposes to private and utility functions is vers The version uses two components, `major.minor`, with the following compatibility rules: -- **`major`** must match exactly. A major bump is a breaking change — oracles were removed or their signatures changed — and a PXE on a different major cannot safely run the contract. +- **`major`** must match exactly. A major bump is a breaking change: oracles were removed or their signatures changed, and a PXE on a different major cannot safely run the contract. - **`minor`** indicates additive changes (new oracles). The PXE uses a best-effort approach here: a contract compiled against a higher `minor` than the PXE supports is still allowed to run, and an error is only thrown if the contract actually invokes an oracle the PXE does not know about. In practice, a contract built with a newer Aztec.nr may not use any of the newly added oracles at all, in which case it runs fine on an older PXE. The canonical version constants live in the PXE (`ORACLE_VERSION_MAJOR` / `ORACLE_VERSION_MINOR` in `yarn-project/pxe/src/oracle_version.ts`) and in Aztec.nr (`noir-projects/aztec-nr/aztec/src/oracle/version.nr`). The two are kept in lockstep as part of each release. diff --git a/docs/docs-developers/docs/foundational-topics/pxe/kernelless_simulations.md b/docs/docs-developers/docs/foundational-topics/pxe/kernelless_simulations.md new file mode 100644 index 000000000000..380ef3366348 --- /dev/null +++ b/docs/docs-developers/docs/foundational-topics/pxe/kernelless_simulations.md @@ -0,0 +1,98 @@ +--- +title: Kernelless simulations +sidebar_position: 2 +tags: [pxe, simulation, gas estimation] +description: How the PXE simulates transactions without running the private kernel circuits, why it is the default for .simulate(), and what it skips. +--- + +This page explains what kernelless simulation is in the Private eXecution Environment (PXE), how it differs from a full simulation, and where it does and does not apply. If you are looking for the recipe to make `.simulate()` succeed without signing prompts, see [Simulate without signing prompts](../../aztec-js/how_to_simulate_without_signing.md). + +## Overview + +A "full" simulation in the PXE runs the user's private function bytecode, then runs every private kernel circuit (init, inner, reset, tail) over the resulting execution trace. The kernels enforce protocol rules such as side-effect counter sequencing. + +A **kernelless simulation** runs the same private bytecode, but skips the kernel circuits. Instead, the PXE computes the values the kernel would have produced in TypeScript via `generateSimulatedProvingResult`. The output of a kernelless simulation is the same shape as a full simulation, so callers can read return values, offchain effects, and gas estimates from it without caring which path produced them. + +Kernelless simulation is the **default** for `PXE.simulateTx`. The `skipKernels` option in `SimulateTxOpts` defaults to `true`, and `BaseWallet` inherits that default. In normal use, every call to `.simulate()` on a contract method already runs without the kernels. + +The main consequence is speed. Skipping the kernels removes the most expensive part of simulation, so a kernelless run is faster than a full run on typical transactions. + +## What the PXE still does + +A kernelless simulation is not a partial execution. The PXE still: + +- runs the real ACIR bytecode for every private function in the call chain +- executes oracles, decrypts notes, builds nullifiers, and captures offchain effects +- simulates public calls against an ephemeral fork of public state +- runs `node.isValidTx` against the resulting transaction, unless `skipTxValidation` is set +- at the raw `PXE.simulateTx` level, enforces fee payer presence unless `skipFeeEnforcement` is set. Contract `.simulate()` calls through `BaseWallet` already pass `skipFeeEnforcement: true` for estimation, so you do not need to provide a fee block for normal read simulations + +What it skips with `skipKernels: true`: + +- the private kernel init, inner, reset, and tail circuits +- the proof generation associated with those kernels + +The kernels themselves do not check authentication witnesses. Authwit validity is checked by user-contract code (the `is_valid` call that the `#[authorize_once]` macro injects into the called function). What lets a kernelless simulation skip the signing prompt is the **stub-account override**, not the absence of the kernels: replacing the caller's account contract with a stub whose `is_valid` always returns true lets that user-contract check pass without a signature. + +## Simulation overrides + +A kernelless simulation accepts an optional `SimulationOverrides` payload that lets you replace pieces of the state the PXE would otherwise read from chain. The shape (in `yarn-project/stdlib/src/tx/simulated_tx.ts`) is: + +```typescript +type ContractOverrides = Record< + string, + { instance: ContractInstanceWithAddress } +>; + +class SimulationOverrides { + publicStorage?: PublicStorageOverride[]; + contracts?: ContractOverrides; +} +``` + +Two parts: + +- `publicStorage` rewrites slots in the ephemeral public-data fork before simulation. This is compatible with kernel execution; you can use it with or without `skipKernels`. +- `contracts` swaps a contract instance in the simulator's contract DB by replacing its `currentContractClassId`. There is no `artifact` field; the new class id must already be registered with the PXE via `pxe.registerContractClass(...)` so the simulator can resolve the bytecode. This requires `skipKernels: true`: PXE explicitly rejects contract overrides combined with kernel execution, because the kernels would fail validations against the swapped class. + +The `contracts` override path is what makes "simulate without signing" possible. Replacing the caller's account contract with a stub whose `is_valid` always returns true lets the simulation reach `#[authorize_once]` call sites without prompting the user to sign anything. + +For the cheat that simulates a contract as if it had already been upgraded to a new class, see [`fastForwardContractUpdate`](../../aztec-js/how_to_test.md#fast-forwarding-a-contract-update), which returns a `SimulationOverrides` covering both the registry storage rewrite and the upgraded instance entry. + +## Stub account contracts + +The stub-account pattern is the standard way to drive a kernelless simulation without authwit prompts. + +The Noir sources live at `noir-projects/noir-contracts/contracts/account/simulated_schnorr_account_contract/` and `simulated_ecdsa_account_contract/`. Both implement `is_valid` to always return `IS_VALID_SELECTOR`, so authwit validity checks pass without a real signature. Their constructors deliberately emit the same shape of side effects as the real account contracts (one nullifier for the contract init, one nullifier for the `SinglePrivateImmutable` signing-key state, one note hash for the key note, and a private log) so that gas estimation against the stub produces the same numbers as the real account. + +## Authwit requests come from the app, not the stub + +The `CallAuthorizationRequest` offchain effects you see during a kernelless simulation are emitted by the **app or token contract's `#[authorize_once]` macro** during private execution. The stub account's only job is to let the validity check pass so the simulation can reach those call sites in the first place. The wallet then collects the requests via `collectOffchainEffects(privateExecutionResult)`, filters them by `CallAuthorizationRequest.getSelector()`, and decodes each one to build a real `AuthWitness`. + +## Where kernelless does not apply + +The default applies to `simulateTx`, but not to every entry point that looks like simulation: + +- **`profileTx`** is not kernelless. `PXE.profileTx` always runs the private kernels after private execution; `skipProofGeneration` controls only whether a proof is produced, not whether kernel logic runs. If you call `.profile()` to measure circuit gates, expect the full kernel cost. +- **Public-only fast path**. When `BaseWallet.simulateTx` detects a leading run of public static calls, it sends them straight to `node.simulatePublicCalls` through `simulateViaNode`, bypassing the PXE private path entirely. There is no kernel to skip. `SimulationOverrides` still applies on that path. +- **Utility functions**. `FunctionType.UTILITY` calls go through `wallet.executeUtility`, not `pxe.simulateTx`. `ContractFunctionInteraction.simulate` rejects `overrides.publicStorage` and `overrides.contracts` for utility functions. + +## Gas estimation parity + +If the real transaction will pay through a fee payment contract (FPC) with private side effects (the FPC emits notes during fee payment), include that FPC in the simulation's fee options. The FPC's side effects feed into gas estimation, and you can run kernelless with the FPC attached to get both the speed benefit and accurate gas numbers. The default of "omit the fee block" only produces accurate gas for transactions whose fee path has no private side effects. + +## Multi-account scopes + +A simulation can run with multiple scoped accounts via `additionalScopes`. If you build a stub-account override for the sender only, the simulation will still prompt for authwits from any other in-scope account it touches. The override map must cover every account in scope, not just `from`. + +The canonical implementation is `EmbeddedWallet.buildAccountOverrides` in `yarn-project/wallets/src/embedded/embedded_wallet.ts`: for each scoped address, fetch the live contract instance from the PXE, copy it, and rewrite `currentContractClassId` to point at the stub class id registered at wallet startup. When implementing overrides in your own wallet, follow this pattern and make sure the scope list you build against matches the one the simulation will run with. + +## When you might still want a full simulation + +Kernelless is the right default. Reach for `skipKernels: false` only when you are validating kernel-level behavior itself. For everything else, including accurate gas estimation through a fee payment contract with private side effects, run kernelless with the appropriate fee options. + +## Related + +- [Simulate without signing prompts](../../aztec-js/how_to_simulate_without_signing.md) for the recipe-oriented version of this page. +- [Reading contract data](../../aztec-js/how_to_read_data.md) for the basic `.simulate()` API. +- [Wallets](../wallets.md) for the wallet's role in capturing private authorizations during simulation. diff --git a/docs/docs-developers/docs/foundational-topics/wallets.md b/docs/docs-developers/docs/foundational-topics/wallets.md index 4c0bc46c4457..895570670b5c 100644 --- a/docs/docs-developers/docs/foundational-topics/wallets.md +++ b/docs/docs-developers/docs/foundational-topics/wallets.md @@ -35,7 +35,7 @@ Private functions use a UTXO model, so their execution trace is determined entir Public functions use an account model (like Ethereum), so their execution trace depends on chain state at inclusion time, which may differ from simulation. ::: -Before sending, the wallet may run a **simulation** — a lightweight execution using a stub account contract that avoids expensive kernel circuit execution. This simulation estimates gas limits for the transaction and captures any required private authorization data (see [Authorizing actions](#authorizing-actions) below). The `EmbeddedWallet` runs this step automatically on every send. +Before sending, the wallet may run a **simulation**, a lightweight execution using a stub account contract that avoids expensive kernel circuit execution. This simulation estimates gas limits for the transaction and captures any required private authorization data (see [Authorizing actions](#authorizing-actions) below). The `EmbeddedWallet` runs this step automatically on every send. For details on what the PXE skips in this mode and how to wire it up in your own wallet, see [Kernelless simulations](./pxe/kernelless_simulations.md). Finally, the wallet **sends** the resulting _transaction_ object, which includes the proof of execution, to an Aztec Node. The transaction is then broadcasted through the peer-to-peer network, to be eventually picked up by a sequencer and included in a block. diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 42e923dd34ef..9963d2727a37 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -79,6 +79,82 @@ If you need to customize source or block range, construct the struct manually wi `source` controls which RPCs are queried: `LogSource.PRIVATE`, `LogSource.PUBLIC`, or `LogSource.PUBLIC_AND_PRIVATE`. `from_block` and `to_block` define a half-open `[from, to)` block range filter. Both are `Option` and default to `Option::none()` (no filtering). +### [Protocol] Public-key hashes replace points in `PublicKeys` + +Ships together with immutables hash changes (shown below). + +Per [AZIP-8](https://github.com/AztecProtocol/governance/blob/main/AZIPs/azip-8.md), `PublicKeys` no longer carries the four master public keys as elliptic curve points. Three of them (`npk_m`, `ovpk_m`, `tpk_m`) are now exposed only as their poseidon2 hash digests; only `ivpk_m` (the master incoming viewing key) remains a point because address derivation needs it as a curve point. + +**This is a hard fork:** every contract address and account address derived from a non-default `PublicKeys` changes. + +**Contract author migration.** Read the master nullifier hash directly off `PublicKeys` instead of computing it from a point: + +```diff +- let owner_npk_m = get_public_keys(owner).npk_m; +- let secret = context.request_nhk_app(owner_npk_m.hash()); ++ let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; ++ let secret = context.request_nhk_app(owner_npk_m_hash); +``` + +The same field-rename applies to `.ovpk_m` and `.tpk_m`: these are now `.ovpk_m_hash` and `.tpk_m_hash` respectively. Code that needed those keys as points will not compile; the points are no longer accessible to contract code. + +**Custom account contracts.** Wallets that ship their own Noir account contracts must recompile. Macro-generated calldata extraction and the `request_nsk_app` / `request_ovsk_app` paths use the hash form natively. + +**TS / wallet author migration.** The `PublicKeys` constructor signature changes from four `Point`s to `(npkMHash: Fr, ivpkM: Point, ovpkMHash: Fr, tpkMHash: Fr)`. `KeyValidationRequest` carries `pkMHash: Fr` instead of `pkM: Point`. `KeyStore.getMasterSecretKey` now takes a `pkMHash: Fr` rather than a `Point`. Callers using the auto-generated TS binding pick this up automatically; callers that hand-roll the arg buffer must update. + +**Wallet UI.** Any panel that displayed `masterNullifierPublicKey`, `masterOutgoingViewingPublicKey`, or `masterTaggingPublicKey` as Grumpkin points will no longer compile against the new `PublicKeys` class. The points themselves are no longer in `ContractInstancePublished` and cannot be recovered from the onchain record. Switch to displaying the hashes (`npkMHash`, `ovpkMHash`, `tpkMHash`) or drop the display. + +**PXE storage migration.** `DatabaseVersionManager` deletes pre-v6 databases on first open: users will see registered accounts, contacts, address aliases, and synced notes wiped. Wallets should surface a "your local state was reset, please re-register accounts and re-sync" path. There is no forward migration because the address derived from a given secret changes (the new `public_keys_hash` is over four single-key digests, not four raw points). Previous addresses are not recoverable from the same secret; assets and notes attached to them are inaccessible at the protocol level. + +**Indexer / event-decoder migration.** The `ContractInstancePublished` private log payload is now 13 fields: + +```text +[ MAGIC, address, version, salt, class_id, init_hash, + immutables_hash, + npk_m_hash, + ivpk_m.x, ivpk_m.y, + ovpk_m_hash, + tpk_m_hash, + deployer ] +``` + +`version` is `2`. v1 events should be rejected. + +**Security note (PXE side).** The kernel circuit no longer checks that `npk_m`, `ovpk_m`, `tpk_m` are on-curve or non-infinity (those points are no longer in the witness). The PXE / key store relies on `deriveKeys`'s by-construction guarantee that derived points are on-curve and non-infinity. Account-creation flows that bypass `deriveKeys` (e.g. importing pre-derived public keys from an external source) must validate this themselves, or risk producing unspendable notes. + +### [Contracts] `ContractInstance` gains `immutablesHash`, address derivation changes + +`ContractInstance` now has a new `immutablesHash: Fr` field that commits to a contract's immutable storage values. The field is folded into the salted initialization hash, so contract addresses are impacted: + +``` +salted_initialization_hash = poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, [salt, initialization_hash, deployer, immutables_hash]) +``` + +**You may need to act if:** + +- You hardcode contract addresses computed from instance fields outside the SDK. Recompute them under the new derivation. +- You parse the `ContractInstancePublished` private log directly. The event payload has an extra field, with `immutables_hash` inserted between `initialization_hash` and the public-keys block: + + ``` + [tag, address, version, salt, classId, initialization_hash, immutables_hash, ...publicKeys(5), deployer] + ``` + +- You call `ContractInstanceRegistry.publish_for_public_execution` directly. The function now takes 6 arguments instead of 5, with `immutables_hash` inserted between `initialization_hash` and `public_keys`: + + ```diff + - publish_for_public_execution(salt, contract_class_id, initialization_hash, public_keys, universal_deploy) + + publish_for_public_execution(salt, contract_class_id, initialization_hash, immutables_hash, public_keys, universal_deploy) + ``` + +- You call the `GetContractInstance` AVM opcode directly or use the per-member helpers in `aztec-nr`. A new enum value `ContractInstanceMember::IMMUTABLES_HASH = 3` selects `immutables_hash`. Use the wrapper helper from `aztec::oracle::get_contract_instance`: + + ```rust + use aztec::oracle::get_contract_instance::get_contract_instance_immutables_hash_avm; + let immutables_hash: Option = get_contract_instance_immutables_hash_avm(address); + ``` + +The `aztec.js` `publishInstance` helper handles this automatically. + ### [Aztec.nr] `emit_private_log_unsafe` / `emit_raw_note_log_unsafe` now take `BoundedVec` The old array-based `emit_private_log_unsafe(tag, log: [Field; N], length)` and `emit_raw_note_log_unsafe(tag, log: [Field; N], length, note_hash_counter)` have been removed. The temporary `_vec_unsafe` variants introduced in a prior release have been renamed to take their place. @@ -172,7 +248,7 @@ The `Schnorr` TypeScript API in `@aztec/foundation/crypto/schnorr` keeps the sam + env.call_public_incognito(SampleContract::at(addr).some_function()); ``` -If you need to call a public function *with* a sender, use `call_public` instead. +If you need to call a public function _with_ a sender, use `call_public` instead. ### [Aztec.nr] TXE `view_public_incognito` is deprecated @@ -325,7 +401,13 @@ If you set `Noir: Nargo Path` in the VS Code Noir extension to `$HOME/.aztec/cur ```typescript const result = await contract.methods.read_balance(account).simulate({ overrides: { - publicStorage: [{ contract: contract.address, slot: BALANCE_SLOT, value: new Fr(1_000_000n) }], + publicStorage: [ + { + contract: contract.address, + slot: BALANCE_SLOT, + value: new Fr(1_000_000n), + }, + ], }, }); ``` @@ -342,7 +424,7 @@ Direct callers of the `SimulationOverrides` constructor must switch from a posit `overrides.contracts` swaps contract instances in the simulator's contract DB — useful for simulating a contract being on a different class than the one it was deployed with. To simulate a complete onchain upgrade flow, use the `fastForwardContractUpdate` helper which returns a `SimulationOverrides` covering both registry storage rewrites and the upgraded instance entry: ```typescript -import { fastForwardContractUpdate } from '@aztec/aztec.js'; +import { fastForwardContractUpdate } from "@aztec/aztec.js"; const overrides = await fastForwardContractUpdate({ instanceAddress: contract.address, @@ -469,8 +551,8 @@ If you want the latest L1-confirmed checkpoint regardless of proposed state, swi ```ts // Throws BadRequestError when a proposed entry exists at the resolved number: -await node.getCheckpoint('proposed', { includeAttestations: true }); -await node.getCheckpoint('proposed', { includeL1PublishInfo: true }); +await node.getCheckpoint("proposed", { includeAttestations: true }); +await node.getCheckpoint("proposed", { includeL1PublishInfo: true }); // And when a by-number / by-slot lookup falls back to a proposed entry: await node.getCheckpoint({ number: N }, { includeAttestations: true }); diff --git a/docs/docs-operate/operators/reference/ethereum-rpc-reference.md b/docs/docs-operate/operators/reference/ethereum-rpc-reference.md index d8c56741a84c..51aedf0e8589 100644 --- a/docs/docs-operate/operators/reference/ethereum-rpc-reference.md +++ b/docs/docs-operate/operators/reference/ethereum-rpc-reference.md @@ -270,7 +270,7 @@ Aztec automatically retries failed requests on alternative endpoints when multip Enable detailed RPC logging: ```bash -LOG_LEVEL=debug # or verbose +LOG_LEVEL="debug; info: json-rpc, simulator" # or verbose ``` Look for log entries related to: diff --git a/docs/docs-operate/operators/sequencer-management/slashing-configuration.md b/docs/docs-operate/operators/sequencer-management/slashing-configuration.md index b6ccfee9757e..53a8d0008b62 100644 --- a/docs/docs-operate/operators/sequencer-management/slashing-configuration.md +++ b/docs/docs-operate/operators/sequencer-management/slashing-configuration.md @@ -161,7 +161,7 @@ SLASH_DATA_WITHHOLDING_PENALTY=0 # Set to >0 to enable # Invalid attestations and blocks SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY=2000000000000000000000 # 2000 tokens -SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY=2000000000000000000000 # 2000 tokens +SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY=2000000000000000000000 # 2000 tokens SLASH_INVALID_BLOCK_PENALTY=2000000000000000000000 # 2000 tokens # Offense expiration diff --git a/docs/docs-operate/operators/setup/registering-sequencer.md b/docs/docs-operate/operators/setup/registering-sequencer.md index cd7cd9d07d89..45a3483dc810 100644 --- a/docs/docs-operate/operators/setup/registering-sequencer.md +++ b/docs/docs-operate/operators/setup/registering-sequencer.md @@ -18,7 +18,7 @@ Before proceeding, ensure you have completed the [Sequencer Setup Guide](./seque - Completed sequencer node setup with keystore generated - Access to your **public keystore** file (`keyN_staker_output.json`) -- Sufficient ATP/ATV tokens for staking +- Sufficient **Aztec Token Position (ATP)** or **Aztec Token Vault (ATV)** balance for staking - Wallet with ETH for gas fees - Web browser for accessing the staking dashboard @@ -124,7 +124,7 @@ Follow these steps to register your sequencer(s) through the staking dashboard: 1. **Navigate to the staking dashboard** at https://stake.aztec.network -2. **Connect your wallet** with the account that holds your ATP/ATV tokens +2. **Connect your wallet** with the account that holds your Aztec Token Position (ATP) or Aztec Token Vault (ATV) balance 3. **Click "Stake"** @@ -136,7 +136,7 @@ Follow these steps to register your sequencer(s) through the staking dashboard: 5. **Click through "Start Registration"** after reviewing the requirements -6. **Select the ATP/ATV tokens you want to stake** +6. **Select the ATP or ATV balance you want to stake** 7. **Upload your keystore JSON file** (either single or combined multi-sequencer file) diff --git a/docs/docs-words.txt b/docs/docs-words.txt index 9bd7144a966b..1f2af786d273 100644 --- a/docs/docs-words.txt +++ b/docs/docs-words.txt @@ -182,6 +182,7 @@ jumpi JUMPI kalypso Keccakf +kernelless keypair knwon lbwop @@ -360,6 +361,7 @@ unncessary unreverted unrleated unshield +unspendable unstake unstakes usermod diff --git a/docs/examples/bootstrap.sh b/docs/examples/bootstrap.sh index fb7e32eec2dc..7f5efda660d2 100755 --- a/docs/examples/bootstrap.sh +++ b/docs/examples/bootstrap.sh @@ -210,7 +210,10 @@ function execute-examples { } function test_cmds { - echo "$hash:ONLY_TERM_PARENT=1 docs/examples/bootstrap.sh execute" + # Bumped from the default 600s by ~50% (now 15m) to absorb cumulative-runtime growth + # under merge-queue load — example_swap's `wait-for-proven` poll was tipping SIGTERM + # near the old limit. See PR #23253 dequeue log http://ci.aztec-labs.com/b08ac48286302949. + echo "$hash:ONLY_TERM_PARENT=1:TIMEOUT=15m docs/examples/bootstrap.sh execute" } function test { diff --git a/docs/examples/ts/aztecjs_kernelless_simulation/config.yaml b/docs/examples/ts/aztecjs_kernelless_simulation/config.yaml new file mode 100644 index 000000000000..103036595a84 --- /dev/null +++ b/docs/examples/ts/aztecjs_kernelless_simulation/config.yaml @@ -0,0 +1,16 @@ +# Configuration for aztecjs_kernelless_simulation example +# Demonstrates kernelless simulation with stub account overrides: +# - Calling .simulate() on a view function without signing prompts +# - Harvesting CallAuthorizationRequest offchain effects to build authwits + +# No custom contracts needed - using pre-built contracts from @aztec/noir-contracts.js +contracts: [] + +# Dependencies: +# - @aztec/* packages are auto-linked from yarn-project/ +# - Use npm:package-name for external npm packages +dependencies: + - "@aztec/aztec.js" + - "@aztec/accounts" + - "@aztec/wallets" + - "@aztec/noir-contracts.js" diff --git a/docs/examples/ts/aztecjs_kernelless_simulation/index.ts b/docs/examples/ts/aztecjs_kernelless_simulation/index.ts new file mode 100644 index 000000000000..c23a6222ebb8 --- /dev/null +++ b/docs/examples/ts/aztecjs_kernelless_simulation/index.ts @@ -0,0 +1,167 @@ +import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node"; +import { EmbeddedWallet } from "@aztec/wallets/embedded"; +import { getInitialTestAccountsData } from "@aztec/accounts/testing"; +import { TokenContract } from "@aztec/noir-contracts.js/Token"; +import { CrowdfundingContract } from "@aztec/noir-contracts.js/Crowdfunding"; +import { Fr } from "@aztec/aztec.js/fields"; +import { deriveKeys } from "@aztec/aztec.js/keys"; +import { CallAuthorizationRequest } from "@aztec/aztec.js/authorization"; + +// Setup: connect to network, create alice and bob, deploy a token, mint to alice. +// EmbeddedWallet runs every .simulate() call in kernelless mode with a stub-account +// override applied automatically. The examples below rely on that default. +const node = createAztecNodeClient( + process.env.AZTEC_NODE_URL ?? "http://localhost:8080", +); +await waitForNode(node); +const wallet = await EmbeddedWallet.create(node, { ephemeral: true }); + +const testAccounts = await getInitialTestAccountsData(); +const [aliceAddress, bobAddress] = await Promise.all( + testAccounts.slice(0, 2).map(async (account) => { + return ( + await wallet.createSchnorrAccount( + account.secret, + account.salt, + account.signingKey, + ) + ).address; + }), +); + +const { contract: tokenContract } = await TokenContract.deploy( + wallet, + aliceAddress, + "TestToken", + "TST", + 18, +).send({ from: aliceAddress }); + +await tokenContract.methods + .mint_to_private(aliceAddress, 1000n) + .send({ from: aliceAddress }); + +// docs:start:simulate-view-without-signing +// Reading a private view function would normally route through the account +// contract's entrypoint, whose is_valid check would prompt the user to sign. +// With EmbeddedWallet, .simulate() runs kernelless with a stub-account +// override applied to alice's account, so no signing prompt is triggered. +const { result: decimals } = await tokenContract.methods + .private_get_decimals() + .simulate({ from: aliceAddress }); + +console.log("Token decimals (read via private view):", decimals); +// docs:end:simulate-view-without-signing + +// Deploy a Crowdfunding contract with Bob as the operator and the previously +// deployed token as the donation token. The contract receives donation notes +// for donors, so it needs its own keys (a contract-account-style deployment). +const crowdfundingSecretKey = Fr.random(); +const crowdfundingPublicKeys = (await deriveKeys(crowdfundingSecretKey)) + .publicKeys; +const deadline = Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60; + +const crowdfundingDeployment = CrowdfundingContract.deploy( + wallet, + tokenContract.address, + bobAddress, + deadline, + { publicKeys: crowdfundingPublicKeys, deployer: aliceAddress }, +); +const crowdfundingInstance = await crowdfundingDeployment.getInstance(); +await wallet.registerContract( + crowdfundingInstance, + CrowdfundingContract.artifact, + crowdfundingSecretKey, +); +const { contract: crowdfundingContract } = await crowdfundingDeployment.send({ + from: aliceAddress, + additionalScopes: [crowdfundingInstance.address], +}); + +// docs:start:simulate-and-collect-effects +// Alice calls Crowdfunding.donate(amount). Internally the contract calls +// transfer_in_private(alice, crowdfunding, amount, 0) with msg_sender = +// crowdfunding, so the token's #[authorize_once] macro requires an authwit +// from Alice authorizing the crowdfunding contract. Alice is the sender, so +// her PXE has her notes and nullifier key — no cross-wallet state sharing +// is required. +// +// With kernelless + stub override (default in EmbeddedWallet), the simulation +// runs without prompting Alice to sign; the macro emits a +// CallAuthorizationRequest as an offchain effect that the wallet can turn +// into a real authwit before .send(). +const donationAmount = 100n; +const donateAction = crowdfundingContract.methods.donate(donationAmount); + +const { offchainEffects } = await donateAction.simulate({ + from: aliceAddress, + includeMetadata: true, +}); + +// Filter offchain effects for authwit requests by selector. +const authwitSelector = await CallAuthorizationRequest.getSelector(); +const authwitEffects = offchainEffects.filter( + (effect) => + effect.data.length > 0 && effect.data[0].equals(authwitSelector.toField()), +); + +if (authwitEffects.length !== 1) { + throw new Error( + `Expected exactly one CallAuthorizationRequest, got ${authwitEffects.length}`, + ); +} +// docs:end:simulate-and-collect-effects + +// docs:start:decode-call-authorization +// Decode each effect into a CallAuthorizationRequest. The inner hash is the +// piece the authorizing account (Alice) needs to sign. +const authorizationRequests = await Promise.all( + authwitEffects.map((effect) => + CallAuthorizationRequest.fromFields(effect.data), + ), +); + +for (const request of authorizationRequests) { + console.log("Authwit needed:", { + onBehalfOf: request.onBehalfOf.toString(), + msgSender: request.msgSender.toString(), + functionSelector: request.functionSelector.toString(), + }); +} + +if (!authorizationRequests[0].onBehalfOf.equals(aliceAddress)) { + throw new Error( + `Expected onBehalfOf to be alice (${aliceAddress.toString()}), got ${authorizationRequests[0].onBehalfOf.toString()}`, + ); +} +// docs:end:decode-call-authorization + +// docs:start:build-authwits-and-send +// Alice creates a real authentication witness from each inner hash. The +// `consumer` is the contract that consumes the authwit — here, the token, +// because that's where the inner transfer_in_private (and its #[authorize_once] +// site) runs. +const authWitnesses = await Promise.all( + authorizationRequests.map((request) => + wallet.createAuthWit(request.onBehalfOf, { + consumer: tokenContract.address, + innerHash: request.innerHash, + }), + ), +); + +// Alice now sends the real donate transaction with the collected authwits +// attached. +// +// Note: EmbeddedWallet.sendTx already runs this pre-simulation + authwit +// collection internally, so passing `authWitnesses` here is redundant for +// EmbeddedWallet. We pass them explicitly anyway because this is the pattern +// a wallet that does not auto-collect needs to follow. +await donateAction.send({ + from: aliceAddress, + authWitnesses, +}); +// docs:end:build-authwits-and-send + +console.log("Kernelless simulation example completed successfully"); diff --git a/docs/examples/ts/aztecjs_kernelless_simulation/yarn.lock b/docs/examples/ts/aztecjs_kernelless_simulation/yarn.lock new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/examples/ts/aztecjs_runner/run.sh b/docs/examples/ts/aztecjs_runner/run.sh index cb06cff29ac7..c7210f24c827 100755 --- a/docs/examples/ts/aztecjs_runner/run.sh +++ b/docs/examples/ts/aztecjs_runner/run.sh @@ -44,6 +44,26 @@ fi echo -e "${GREEN}✓ Network is running${NC}" echo "" +# Run `yarn add` with retries. Silences output on early attempts but lets +# stderr surface on the final attempt so transient flakes don't disappear +# under set -euo pipefail (silent rc=1 from setup_project was the root cause +# of the docs-examples merge-queue dequeue on aztecjs_advanced). +yarn_add_with_retry() { + local max_attempts=3 + local attempt=1 + while [ "$attempt" -lt "$max_attempts" ]; do + if yarn add "$@" > /dev/null 2>&1; then + return 0 + fi + echo -e "${YELLOW} yarn add attempt $attempt failed, retrying in 5s...${NC}" + sleep 5 + attempt=$((attempt + 1)) + done + # Final attempt: surface yarn's output so the failure is visible in CI logs. + echo -e "${YELLOW} yarn add attempt $attempt (final, output unsilenced):${NC}" + yarn add "$@" +} + # Setup function for a project setup_project() { local project_name=$1 @@ -91,11 +111,11 @@ setup_project() { parse_dependencies config.yaml "$REPO_ROOT" if [ "$PARSED_DEPS_FOUND" = true ]; then local all_link_deps=("${AZTEC_DEPS[@]}" "${EXPLICIT_LINK_DEPS[@]}") - [ ${#all_link_deps[@]} -gt 0 ] && yarn add "${all_link_deps[@]}" > /dev/null 2>&1 - [ ${#NPM_DEPS[@]} -gt 0 ] && yarn add "${NPM_DEPS[@]}" > /dev/null 2>&1 + [ ${#all_link_deps[@]} -gt 0 ] && yarn_add_with_retry "${all_link_deps[@]}" + [ ${#NPM_DEPS[@]} -gt 0 ] && yarn_add_with_retry "${NPM_DEPS[@]}" fi - yarn add -D typescript tsx > /dev/null 2>&1 + yarn_add_with_retry -D typescript tsx # Copy tsconfig cp "$EXAMPLES_DIR/tsconfig.template.json" tsconfig.json diff --git a/docs/examples/ts/docker-compose.yml b/docs/examples/ts/docker-compose.yml index d881961f4f74..247b321c6912 100644 --- a/docs/examples/ts/docker-compose.yml +++ b/docs/examples/ts/docker-compose.yml @@ -28,6 +28,7 @@ services: WS_BLOCK_CHECK_INTERVAL_MS: 500 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 P2P_MIN_TX_POOL_AGE_MS: 0 + SEQ_ENABLE_PROPOSER_PIPELINING: 'true' HARDWARE_CONCURRENCY: ${HARDWARE_CONCURRENCY:-} docs-examples: diff --git a/docs/network_versioned_docs/version-v4.3.0/operators/reference/ethereum-rpc-reference.md b/docs/network_versioned_docs/version-v4.3.0/operators/reference/ethereum-rpc-reference.md index a75fc770f303..2a6f2d29e8eb 100644 --- a/docs/network_versioned_docs/version-v4.3.0/operators/reference/ethereum-rpc-reference.md +++ b/docs/network_versioned_docs/version-v4.3.0/operators/reference/ethereum-rpc-reference.md @@ -270,7 +270,7 @@ Aztec automatically retries failed requests on alternative endpoints when multip Enable detailed RPC logging: ```bash -LOG_LEVEL=debug # or verbose +LOG_LEVEL="debug; info: json-rpc, simulator" # or verbose ``` Look for log entries related to: diff --git a/docs/network_versioned_docs/version-v4.3.0/operators/setup/registering-sequencer.md b/docs/network_versioned_docs/version-v4.3.0/operators/setup/registering-sequencer.md index cd7cd9d07d89..45a3483dc810 100644 --- a/docs/network_versioned_docs/version-v4.3.0/operators/setup/registering-sequencer.md +++ b/docs/network_versioned_docs/version-v4.3.0/operators/setup/registering-sequencer.md @@ -18,7 +18,7 @@ Before proceeding, ensure you have completed the [Sequencer Setup Guide](./seque - Completed sequencer node setup with keystore generated - Access to your **public keystore** file (`keyN_staker_output.json`) -- Sufficient ATP/ATV tokens for staking +- Sufficient **Aztec Token Position (ATP)** or **Aztec Token Vault (ATV)** balance for staking - Wallet with ETH for gas fees - Web browser for accessing the staking dashboard @@ -124,7 +124,7 @@ Follow these steps to register your sequencer(s) through the staking dashboard: 1. **Navigate to the staking dashboard** at https://stake.aztec.network -2. **Connect your wallet** with the account that holds your ATP/ATV tokens +2. **Connect your wallet** with the account that holds your Aztec Token Position (ATP) or Aztec Token Vault (ATV) balance 3. **Click "Stake"** @@ -136,7 +136,7 @@ Follow these steps to register your sequencer(s) through the staking dashboard: 5. **Click through "Start Registration"** after reviewing the requirements -6. **Select the ATP/ATV tokens you want to stake** +6. **Select the ATP or ATV balance you want to stake** 7. **Upload your keystore JSON file** (either single or combined multi-sequencer file) diff --git a/docs/static/typescript-api/mainnet/foundation.md b/docs/static/typescript-api/mainnet/foundation.md index 0ff014eea53b..b8c9f0b59ff3 100644 --- a/docs/static/typescript-api/mainnet/foundation.md +++ b/docs/static/typescript-api/mainnet/foundation.md @@ -1422,7 +1422,7 @@ type NetworkConfigMap = z.infer ### NetworkNames ```typescript -type NetworkNames = "local" | "staging-ignition" | "staging-public" | "testnet" | "mainnet" | "next-net" | "devnet" +type NetworkNames = "local" | "staging-public" | "testnet" | "mainnet" | "next-net" | "devnet" ``` ### PartialBy diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index 92a79ad91365..f00d4d5ffc48 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -18,8 +18,11 @@ function download_solc { echo_stderr "Downloading solc $solc_version via svm..." # svm-rs always uses ~/.svm if it exists. Make sure it does for a consistent path across OS/architecture. mkdir -p "$HOME/.svm" - # We build a minimal file to trigger svm download of solc. - forge build --use "$solc_version" src/core/libraries/ConstantsGen.sol 2>/dev/null + # We build a minimal file to trigger svm download of solc. svm fetches the + # binary from binaries.soliditylang.org, which intermittently fails to resolve + # under heavy parallel CI load; retry to ride out transient DNS drops. (The + # merge queue disables the cache above, so this download path runs every time.) + retry "forge build --use \"$solc_version\" src/core/libraries/ConstantsGen.sol 2>/dev/null" # Copy from svm cache to local path local svm_path="$HOME/.svm/$solc_version/solc-$solc_version" diff --git a/l1-contracts/src/core/slashing/SlashingProposer.sol b/l1-contracts/src/core/slashing/SlashingProposer.sol index 143220d1df60..6cf723ad6630 100644 --- a/l1-contracts/src/core/slashing/SlashingProposer.sol +++ b/l1-contracts/src/core/slashing/SlashingProposer.sol @@ -50,12 +50,11 @@ import {SafeCast} from "@oz/utils/math/SafeCast.sol"; * * About SLASH_OFFSET_IN_ROUNDS: * - This offset gives us time to detect an offense and then vote on it in a later - * round. For instance, an `VALID_EPOCH_PRUNED` offense for epoch N is only triggered after - * `PROOF_SUBMISSION_WINDOW` epochs. Consider the following: - * - Epoch 1 is valid - * - At the end of epoch 3, the proof for 1 has not landed, so epoch 1 is pruned - * - Network decides to slash the committee of epoch 1 - * - This means that only starting from epoch 4 we should be voting for slashing the committee of epoch 1 + * round. For instance, a `DATA_WITHHOLDING` offense for slot S is only triggered after + * `DATA_WITHHOLDING_TOLERANCE_SLOTS` slots. Consider: + * - Slot S publishes a checkpoint + * - At slot S + tolerance, observers find missing data and want to slash the attesters + * - Voting on that slash needs to happen in a round that starts after detection * - In terms of voting, this parameter means that in round R we are voting for the committee of epochs starting * from (R - SLASH_OFFSET_IN_ROUNDS) * ROUND_SIZE_IN_EPOCHS. * - For example, with SLASH_OFFSET_IN_ROUNDS=2, ROUND_SIZE=10, and EPOCH_DURATION=2 diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 7631593cefb5..47cf714965b3 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -42,7 +42,7 @@ use crate::protocol::{ hash::compute_contract_class_log_hash, messaging::l2_to_l1_message::L2ToL1Message, side_effect::{Counted, scoped::Scoped}, - traits::{Empty, Hash, ToField}, + traits::{Empty, ToField}, utils::arrays::{ClaimedLengthArray, trimmed_array_length_hint}, }; @@ -754,39 +754,42 @@ impl PrivateContext { /// request validation of this claim, by making a "key validation request" to the protocol's kernel circuits (which /// _are_ allowed to see certain master secret keys). /// - /// When a Key Validation Request tuple of (sk_app, Pk_m, app_address) is submitted to the kernel, it will perform - /// the following derivations to validate the relationship between the claimed sk_app and the user's Pk_m: + /// The app circuit only sees `pk_m_hash` (not the raw point). The kernel derives the + /// point from `sk_m`, hashes it, and asserts equality. When a Key Validation Request tuple of + /// (sk_app, pk_m_hash, app_address) is submitted to the kernel, it performs the following + /// derivations to validate the relationship between the claimed sk_app and the user's pk_m_hash: /// - /// (sk_m) ----> * G ----> Pk_m - /// | | - /// v We use the kernel to prove this - /// h(sk_m, app_address) | sk_app-Pk_m relationship, because app - /// | circuits must not be trusted to see sk_m. - /// v | - /// sk_app - - - - - - - - - + /// (sk_m) ----> * G ----> pk_m ----> hash_public_key(pk_m) + /// | | + /// v | We use the kernel to prove this + /// h(sk_m, app_address) | sk_app-pk_m_hash relationship, because app + /// | | circuits must not be trusted to see sk_m. + /// v | + /// sk_app - - - - - - - - - - - - - - - - - - /// /// The function is named "request_" instead of "get_" to remind the user that a Key Validation Request will be /// emitted to the kernel. /// fn request_sk_app(&mut self, pk_m_hash: Field, key_index: Field) -> Field { - let cached_request = - self.last_key_validation_requests[key_index as u32].unwrap_or(KeyValidationRequest::empty()); + // Match against the cache only when a request is actually present in the slot. + let cached_slot = self.last_key_validation_requests[key_index as u32]; + let cache_hit = cached_slot.is_some() & (cached_slot.unwrap_unchecked().pk_m_hash == pk_m_hash); - if cached_request.pk_m.hash() == pk_m_hash { + if cache_hit { // We get a match so the cached request is the latest one - cached_request.sk_app + cached_slot.unwrap_unchecked().sk_app } else { - // We didn't get a match meaning the cached result is stale Typically we'd validate keys by showing that - // they are the preimage of `pk_m_hash`, but that'd require the oracle returning the master secret keys, - // which could cause malicious contracts to leak it or learn about secrets from other contracts. We - // therefore silo secret keys, and rely on the private kernel to validate that we siloed secret key - // corresponds to correct siloing of the master secret key that hashes to `pk_m_hash`. + // We didn't get a match meaning the cached result is stale. Typically we'd validate keys by showing that + // the master secret key derives to a public key matching `pk_m_hash`, but that'd require the oracle + // returning the master secret keys, which could cause malicious contracts to leak it or learn about + // secrets from other contracts. We therefore silo secret keys, and rely on the private kernel to validate + // that the siloed secret key corresponds to correct siloing of the master secret key that hashes to + // `pk_m_hash`. // Safety: Kernels verify that the key validation request is valid and below we verify that a request for // the correct public key has been received. let request = unsafe { get_key_validation_request(pk_m_hash, key_index) }; - assert(!request.pk_m.is_infinite, "Infinite public key points are not allowed"); - assert_eq(request.pk_m.hash(), pk_m_hash, "Obtained invalid key validation request"); + assert_eq(request.pk_m_hash, pk_m_hash, "Obtained key validation request for wrong pk_m_hash"); self.key_validation_requests_and_separators.push( KeyValidationRequestAndSeparator { diff --git a/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr b/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr index 4770d3e7cc65..091ccff3161a 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr @@ -2,7 +2,7 @@ use crate::protocol::{ address::aztec_address::AztecAddress, constants::{DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY}, hash::poseidon2_hash_with_separator, - point::Point, + point::EmbeddedCurvePoint, scalar::Scalar, traits::{FromField, ToField}, }; @@ -18,16 +18,14 @@ use std::{embedded_curve_ops::multi_scalar_mul, ops::Neg}; /// Shared secret S = esk * Pk = sk * Epk /// /// See also: https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman -pub fn derive_ecdh_shared_secret(secret: Scalar, public_key: Point) -> Point { - // TODO(F-553): Drop the `.to_embedded()` / `.into()` round-trip once the custom `Point` wrapper is removed and we - // use `EmbeddedCurvePoint` directly. - multi_scalar_mul([public_key.to_embedded()], [secret]).into() +pub fn derive_ecdh_shared_secret(secret: Scalar, public_key: EmbeddedCurvePoint) -> EmbeddedCurvePoint { + multi_scalar_mul([public_key], [secret]) } /// Computes an app-siloed shared secret from a raw ECDH shared secret point and a contract address. /// /// `s_app = h(DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, S.x, S.y, contract_address)` -pub fn compute_app_siloed_shared_secret(shared_secret: Point, contract_address: AztecAddress) -> Field { +pub fn compute_app_siloed_shared_secret(shared_secret: EmbeddedCurvePoint, contract_address: AztecAddress) -> Field { poseidon2_hash_with_separator( [shared_secret.x, shared_secret.y, contract_address.to_field()], DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, @@ -54,10 +52,9 @@ unconstrained fn test_consistency_with_typescript() { lo: 0x00000000000000000000000000000000649e7ca01d9de27b21624098b897babd, hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06, }; - let point = Point { + let point = EmbeddedCurvePoint { x: 0x2688431c705a5ff3e6c6f2573c9e3ba1c1026d2251d0dbbf2d810aa53fd1d186, y: 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e, - is_infinite: false, }; let shared_secret = derive_ecdh_shared_secret(secret, point); @@ -65,10 +62,9 @@ unconstrained fn test_consistency_with_typescript() { // This is just pasted from a test run. The original typescript code from which this could be generated seems to // have been deleted by someone, and soon the typescript code for encryption and decryption won't be needed, so // this will have to do. - let hard_coded_shared_secret = Point { + let hard_coded_shared_secret = EmbeddedCurvePoint { x: 0x15d55a5b3b2caa6a6207f313f05c5113deba5da9927d6421bcaa164822b911bc, y: 0x0974c3d0825031ae933243d653ebb1a0b08b90ee7f228f94c5c74739ea3c871e, - is_infinite: false, }; assert_eq(shared_secret, hard_coded_shared_secret); } @@ -78,8 +74,8 @@ unconstrained fn test_shared_secret_computation_in_both_directions() { let secret_a = Scalar { lo: 0x1234, hi: 0x2345 }; let secret_b = Scalar { lo: 0x3456, hi: 0x4567 }; - let pk_a: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a).into(); - let pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b).into(); + let pk_a = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a); + let pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b); let shared_secret = derive_ecdh_shared_secret(secret_a, pk_b); let shared_secret_alt = derive_ecdh_shared_secret(secret_b, pk_a); @@ -92,8 +88,8 @@ unconstrained fn test_shared_secret_computation_from_address_in_both_directions( let secret_a = Scalar { lo: 0x1234, hi: 0x2345 }; let secret_b = Scalar { lo: 0x3456, hi: 0x4567 }; - let mut pk_a: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a).into(); - let mut pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b).into(); + let mut pk_a = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a); + let mut pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b); let address_b = AztecAddress::from_field(pk_b.x); @@ -120,7 +116,7 @@ unconstrained fn test_shared_secret_computation_from_address_in_both_directions( #[test] unconstrained fn test_app_siloed_shared_secret_differs_per_contract() { let secret_a = Scalar { lo: 0x1234, hi: 0x2345 }; - let pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(Scalar { lo: 0x3456, hi: 0x4567 }).into(); + let pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(Scalar { lo: 0x3456, hi: 0x4567 }); let shared_secret = derive_ecdh_shared_secret(secret_a, pk_b); diff --git a/noir-projects/aztec-nr/aztec/src/keys/ephemeral.nr b/noir-projects/aztec-nr/aztec/src/keys/ephemeral.nr index e7758e43579a..d0947c61d281 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/ephemeral.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/ephemeral.nr @@ -1,11 +1,11 @@ use std::embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul}; -use crate::protocol::{point::Point, scalar::Scalar}; +use crate::protocol::{point::EmbeddedCurvePoint, scalar::Scalar}; use crate::{oracle::random::random, utils::point::get_sign_of_point}; /// Generates a random ephemeral key pair. -pub fn generate_ephemeral_key_pair() -> (Scalar, Point) { +pub fn generate_ephemeral_key_pair() -> (Scalar, EmbeddedCurvePoint) { // @todo Need to draw randomness from the full domain of Fq not only Fr // Safety: we use the randomness to preserve the privacy of both the sender and recipient via encryption, so a @@ -17,9 +17,7 @@ pub fn generate_ephemeral_key_pair() -> (Scalar, Point) { // TODO(#12757): compute the key pair without constraining eph_sk twice (once in from_field, once in the black box // called by fixed_base_scalar_mul). let eph_sk = EmbeddedCurveScalar::from_field(randomness); - // TODO(F-553): Drop the `.into()` once the custom `Point` wrapper is removed and we use `EmbeddedCurvePoint` - // directly. Applies to the other `fixed_base_scalar_mul(...).into()` call sites in this file as well. - let eph_pk: Point = fixed_base_scalar_mul(eph_sk).into(); + let eph_pk = fixed_base_scalar_mul(eph_sk); (eph_sk, eph_pk) } @@ -31,13 +29,13 @@ pub fn generate_ephemeral_key_pair() -> (Scalar, Point) { /// /// This is useful as it means it is possible to just broadcast the x-coordinate as a single `Field` and then /// reconstruct the original public key using [`crate::utils::point::point_from_x_coord_and_sign`] with `sign: true`. -pub fn generate_positive_ephemeral_key_pair() -> (Scalar, Point) { +pub fn generate_positive_ephemeral_key_pair() -> (Scalar, EmbeddedCurvePoint) { // Safety: we use the randomness to preserve the privacy of both the sender and recipient via encryption, so a // malicious sender could use non-random values to reveal the plaintext. But they already know it themselves // anyway, and so the recipient already trusts them to not disclose this information. We can therefore assume that // the sender will cooperate in the random value generation. let eph_sk = unsafe { generate_secret_key_for_positive_public_key() }; - let eph_pk: Point = fixed_base_scalar_mul(eph_sk).into(); + let eph_pk = fixed_base_scalar_mul(eph_sk); assert(get_sign_of_point(eph_pk), "Got an ephemeral public key with a negative y coordinate"); @@ -53,7 +51,7 @@ unconstrained fn generate_secret_key_for_positive_public_key() -> EmbeddedCurveS // @todo Need to draw randomness from the full domain of Fq not only Fr sk = EmbeddedCurveScalar::from_field(random()); - let pk: Point = fixed_base_scalar_mul(sk).into(); + let pk = fixed_base_scalar_mul(sk); if get_sign_of_point(pk) { break; } diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr b/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr index d52b43d389e4..aa72b16d3da0 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr @@ -41,7 +41,7 @@ mod test { use crate::test::helpers::test_environment::TestEnvironment; use std::test::OracleMock; - global KEY_ORACLE_RESPONSE_LENGTH: u32 = 13; // 12 fields for the keys, one field for the partial address + global KEY_ORACLE_RESPONSE_LENGTH: u32 = 6; // 3 key hashes + 1 key point + 1 partial address #[test(should_fail_with = "Invalid public keys hint for address")] unconstrained fn get_public_keys_fails_with_bad_hint() { @@ -50,26 +50,19 @@ mod test { // Instead of querying for some unknown account, which would result in the oracle erroring out, we mock a bad // oracle response to check that the circuit properly checks the address derivation. + // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, partial_address]. let mut random_keys_and_partial_address = [0; KEY_ORACLE_RESPONSE_LENGTH]; - // We use randomly generated points on the curve, and a random partial address to ensure that this combination - // does not derive the address and we should see the assertion fail. npk_m + // npk_m_hash random_keys_and_partial_address[0] = 0x292364b852c6c6f01472951e76a39cbcf074591fd0e063a81965e7b51ad868a5; - random_keys_and_partial_address[1] = 0x0a687b46cdc9238f1c311f126aaaa4acbd7a737bff2efd7aeabdb8d805843a27; - random_keys_and_partial_address[2] = 0x0000000000000000000000000000000000000000000000000000000000000000; - // ivpk_m - random_keys_and_partial_address[3] = 0x173c5229a00c5425255680dd6edc27e278c48883991f348fe6985de43b4ec25f; - random_keys_and_partial_address[4] = 0x1698608e23b5f6c2f43c49a559108bb64e2247b8fc2da842296a416817f40b7f; - random_keys_and_partial_address[5] = 0x0000000000000000000000000000000000000000000000000000000000000000; - // ovpk_m - random_keys_and_partial_address[6] = 0x1bad2f7d1ad960a1bd0fe4d2c8d17f5ab4a86ef8b103e0a9e7f67ec0d3b4795e; - random_keys_and_partial_address[7] = 0x206db87110abbecc9fbaef2c865189d94ef2c106202f734ee4eba9257fd28bf1; - random_keys_and_partial_address[8] = 0x0000000000000000000000000000000000000000000000000000000000000000; - // tpk_m - random_keys_and_partial_address[9] = 0x05e3bd9cfe6b47daa139613619cf7d7fd8bb0112b6f2908caa6d9b536ed948ed; - random_keys_and_partial_address[10] = 0x051066f877c9df47552d02e7dc32127ff4edefc8498e813bca1cbd3f5d1be429; - random_keys_and_partial_address[11] = 0x0000000000000000000000000000000000000000000000000000000000000000; + // ivpk_m (x, y) -- arbitrary, doesn't have to be on-curve to make this test fail + random_keys_and_partial_address[1] = 0x173c5229a00c5425255680dd6edc27e278c48883991f348fe6985de43b4ec25f; + random_keys_and_partial_address[2] = 0x1698608e23b5f6c2f43c49a559108bb64e2247b8fc2da842296a416817f40b7f; + // ovpk_m_hash + random_keys_and_partial_address[3] = 0x1bad2f7d1ad960a1bd0fe4d2c8d17f5ab4a86ef8b103e0a9e7f67ec0d3b4795e; + // tpk_m_hash + random_keys_and_partial_address[4] = 0x05e3bd9cfe6b47daa139613619cf7d7fd8bb0112b6f2908caa6d9b536ed948ed; // partial address - random_keys_and_partial_address[12] = 0x236703e2cb00a182e024e98e9f759231b556d25ff19f98896cebb69e9e678cc9; + random_keys_and_partial_address[5] = 0x236703e2cb00a182e024e98e9f759231b556d25ff19f98896cebb69e9e678cc9; let _ = OracleMock::mock("aztec_utl_getPublicKeysAndPartialAddress").returns(Option::some( random_keys_and_partial_address, diff --git a/noir-projects/aztec-nr/aztec/src/macros/notes.nr b/noir-projects/aztec-nr/aztec/src/macros/notes.nr index 2836182df312..f50634480dab 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/notes.nr @@ -88,10 +88,7 @@ comptime fn generate_note_hash_trait_impl(s: TypeDefinition) -> Quoted { owner: aztec::protocol::address::AztecAddress, note_hash_for_nullification: Field, ) -> Field { - let owner_npk_m = aztec::keys::getters::get_public_keys(owner).npk_m; - // We invoke hash as a static trait function rather than calling owner_npk_m.hash() directly - // in the quote to avoid "trait not in scope" compiler warnings. - let owner_npk_m_hash = aztec::protocol::traits::Hash::hash(owner_npk_m); + let owner_npk_m_hash = aztec::keys::getters::get_public_keys(owner).npk_m_hash; let secret = context.request_nhk_app(owner_npk_m_hash); aztec::note::utils::compute_note_nullifier(note_hash_for_nullification, [secret]) } @@ -105,10 +102,7 @@ comptime fn generate_note_hash_trait_impl(s: TypeDefinition) -> Quoted { // hiding key (nhk) is also available, so we don't need to handle get_nhk_app potentially // failing. The Option is only needed for the try_get_public_keys call. aztec::keys::getters::try_get_public_keys(owner).map(|public_keys| { - let owner_npk_m = public_keys.npk_m; - // We invoke hash as a static trait function rather than calling owner_npk_m.hash() directly - // in the quote to avoid "trait not in scope" compiler warnings. - let owner_npk_m_hash = aztec::protocol::traits::Hash::hash(owner_npk_m); + let owner_npk_m_hash = public_keys.npk_m_hash; let secret = aztec::keys::getters::get_nhk_app(owner_npk_m_hash); aztec::note::utils::compute_note_nullifier(note_hash_for_nullification, [secret]) }) diff --git a/noir-projects/aztec-nr/aztec/src/messages/encryption/poseidon2.nr b/noir-projects/aztec-nr/aztec/src/messages/encryption/poseidon2.nr index 1704be0162b0..c2ecac779d3f 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/encryption/poseidon2.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/encryption/poseidon2.nr @@ -1,7 +1,7 @@ use std::hash::poseidon2_permutation; use std::option::Option; -use crate::protocol::point::Point; +use crate::protocol::point::EmbeddedCurvePoint; global TWO_POW_128: Field = 0x100000000000000000000000000000000; @@ -27,7 +27,7 @@ global TWO_POW_128: Field = 0x100000000000000000000000000000000; /// @param encryption_nonce is only needed if your use case needs to protect against replay attacks. pub fn poseidon2_encrypt( msg: [Field; L], - shared_secret: Point, + shared_secret: EmbeddedCurvePoint, encryption_nonce: Field, ) -> [Field; ((L + 2) / 3) * 3 + 1] { // TODO: assert(encryption_nonce < 2^128), assert(L < 2^120); @@ -78,7 +78,7 @@ pub fn poseidon2_encrypt( pub fn poseidon2_decrypt( ciphertext: [Field; ((L + 3 - 1) / 3) * 3 + 1], - shared_secret: Point, + shared_secret: EmbeddedCurvePoint, encryption_nonce: Field, ) -> Option<[Field; L]> { let mut s = [0, shared_secret.x, shared_secret.y, encryption_nonce + (L as Field) * TWO_POW_128]; @@ -139,7 +139,6 @@ pub fn poseidon2_decrypt( } mod test { - use crate::protocol::point::Point; use super::{poseidon2_decrypt, poseidon2_encrypt, TWO_POW_128}; use std::embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul, multi_scalar_mul}; @@ -152,7 +151,7 @@ mod test { let eph_sk = 0x5678; let eph_pk = fixed_base_scalar_mul(EmbeddedCurveScalar::from_field(eph_sk)); - let shared_secret: Point = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]).into(); + let shared_secret = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]); let encryption_nonce = 3; // TODO. Can even be a timestamp. Why is this even needed? @@ -162,7 +161,7 @@ mod test { // Bob sees: [Epk, ciphertext, encryption_nonce]: - let shared_secret: Point = multi_scalar_mul([eph_pk], [EmbeddedCurveScalar::from_field(bob_sk)]).into(); + let shared_secret = multi_scalar_mul([eph_pk], [EmbeddedCurveScalar::from_field(bob_sk)]); let result = poseidon2_decrypt(ciphertext, shared_secret, encryption_nonce); @@ -193,7 +192,7 @@ mod test { let eph_sk = 0x5678; let eph_pk = fixed_base_scalar_mul(EmbeddedCurveScalar::from_field(eph_sk)); - let shared_secret: Point = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]).into(); + let shared_secret = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]); let msg = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; @@ -205,7 +204,7 @@ mod test { // Bob sees: [Epk, ciphertext, encryption_nonce]: - let mut shared_secret: Point = multi_scalar_mul([eph_pk], [EmbeddedCurveScalar::from_field(bob_sk)]).into(); + let mut shared_secret = multi_scalar_mul([eph_pk], [EmbeddedCurveScalar::from_field(bob_sk)]); // Let's intentionally corrupt the shared secret, so that decryption should fail shared_secret.x += 1; @@ -222,7 +221,7 @@ mod test { let bob_pk = fixed_base_scalar_mul(EmbeddedCurveScalar::from_field(bob_sk)); let eph_sk = 0x5678; - let shared_secret: Point = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]).into(); + let shared_secret = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]); let encryption_nonce = 3; // TODO. Can even be a timestamp. Why is this even needed? diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr index 11eace998fa6..372729c37a9e 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr @@ -35,6 +35,10 @@ unconstrained fn get_contract_instance_class_id_oracle_avm(_address: AztecAddres unconstrained fn get_contract_instance_initialization_hash_oracle_avm( _address: AztecAddress, ) -> [GetContractInstanceResult; 1] {} +#[oracle(aztec_avm_getContractInstanceImmutablesHash)] +unconstrained fn get_contract_instance_immutables_hash_oracle_avm( + _address: AztecAddress, +) -> [GetContractInstanceResult; 1] {} unconstrained fn get_contract_instance_deployer_internal_avm(address: AztecAddress) -> [GetContractInstanceResult; 1] { get_contract_instance_deployer_oracle_avm(address) @@ -47,6 +51,11 @@ unconstrained fn get_contract_instance_initialization_hash_internal_avm( ) -> [GetContractInstanceResult; 1] { get_contract_instance_initialization_hash_oracle_avm(address) } +unconstrained fn get_contract_instance_immutables_hash_internal_avm( + address: AztecAddress, +) -> [GetContractInstanceResult; 1] { + get_contract_instance_immutables_hash_oracle_avm(address) +} pub fn get_contract_instance_deployer_avm(address: AztecAddress) -> Option { // Safety: AVM opcodes are constrained by the AVM itself @@ -78,3 +87,13 @@ pub fn get_contract_instance_initialization_hash_avm(address: AztecAddress) -> O Option::none() } } +pub fn get_contract_instance_immutables_hash_avm(address: AztecAddress) -> Option { + // Safety: AVM opcodes are constrained by the AVM itself + let GetContractInstanceResult { exists, member } = + unsafe { get_contract_instance_immutables_hash_internal_avm(address)[0] }; + if exists { + Option::some(member) + } else { + Option::none() + } +} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 8f3d2788bf7a..c1ba98a4794c 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -1,7 +1,7 @@ use crate::protocol::{ address::{AztecAddress, PartialAddress}, - point::Point, - public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, TpkM}, + point::EmbeddedCurvePoint, + public_keys::{IvpkM, PublicKeys}, }; // TODO(F-498): review naming consistency @@ -9,25 +9,27 @@ pub unconstrained fn get_public_keys_and_partial_address(address: AztecAddress) try_get_public_keys_and_partial_address(address).expect(f"Public keys not registered for account {address}") } -// TODO(F-553): The oracle returns 13 fields because each public key is serialized as 3 fields (x, y, is_infinite) by -// the custom `Point` wrapper. Once we drop the wrapper and use `EmbeddedCurvePoint` directly each point will -// serialize to 2 fields and this should become `[Field; 9]` again, with the indices below shifted accordingly. +/// Oracle wire format: `[npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, partial_address]`. +/// +/// Three of the four master public keys are exposed only as hashes; `ivpk_m` is sent +/// as its affine coordinates because address derivation and encrypt-to-address require the point +/// in-circuit. This point is assumed to be non-infinite. #[oracle(aztec_utl_getPublicKeysAndPartialAddress)] -unconstrained fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> Option<[Field; 13]> {} +unconstrained fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> Option<[Field; 6]> {} // TODO(F-498): review naming consistency pub unconstrained fn try_get_public_keys_and_partial_address( address: AztecAddress, ) -> Option<(PublicKeys, PartialAddress)> { - get_public_keys_and_partial_address_oracle(address).map(|result: [Field; 13]| { + get_public_keys_and_partial_address_oracle(address).map(|result: [Field; 6]| { let keys = PublicKeys { - npk_m: NpkM { inner: Point { x: result[0], y: result[1], is_infinite: result[2] != 0 } }, - ivpk_m: IvpkM { inner: Point { x: result[3], y: result[4], is_infinite: result[5] != 0 } }, - ovpk_m: OvpkM { inner: Point { x: result[6], y: result[7], is_infinite: result[8] != 0 } }, - tpk_m: TpkM { inner: Point { x: result[9], y: result[10], is_infinite: result[11] != 0 } }, + npk_m_hash: result[0], + ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: result[1], y: result[2] } }, + ovpk_m_hash: result[3], + tpk_m_hash: result[4], }; - let partial_address = PartialAddress::from_field(result[12]); + let partial_address = PartialAddress::from_field(result[5]); (keys, partial_address) }) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr b/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr index cbcd9390d71a..bc3780876922 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr @@ -1,20 +1,19 @@ use crate::ephemeral::EphemeralArray; -use crate::protocol::{address::AztecAddress, hash::sha256_to_field, point::Point}; +use crate::protocol::{address::AztecAddress, hash::sha256_to_field, point::EmbeddedCurvePoint}; -global GET_SHARED_SECRETS_REQUEST_SLOT: Field = - sha256_to_field("AZTEC_NR::GET_SHARED_SECRETS_REQUEST_SLOT".as_bytes()); +global GET_SHARED_SECRETS_REQUEST_SLOT: Field = sha256_to_field("AZTEC_NR::GET_SHARED_SECRETS_REQUEST_SLOT".as_bytes()); #[oracle(aztec_utl_getSharedSecrets)] unconstrained fn get_shared_secrets_oracle( address: AztecAddress, - eph_pks: EphemeralArray, + eph_pks: EphemeralArray, contract_address: AztecAddress, ) -> EphemeralArray {} /// Convenience wrapper around [`get_shared_secrets`] for a single ephemeral public key. pub unconstrained fn get_shared_secret( address: AztecAddress, - eph_pk: Point, + eph_pk: EmbeddedCurvePoint, contract_address: AztecAddress, ) -> Field { get_shared_secrets::<1>(address, BoundedVec::from_array([eph_pk]), contract_address).get(0) @@ -41,18 +40,14 @@ pub unconstrained fn get_shared_secret( /// [`derive_shared_secret_subkey`](crate::keys::ecdh_shared_secret::derive_shared_secret_subkey). pub unconstrained fn get_shared_secrets( address: AztecAddress, - eph_pks: BoundedVec, + eph_pks: BoundedVec, contract_address: AztecAddress, ) -> BoundedVec { - let request_array: EphemeralArray = - EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT).clear(); + let request_array: EphemeralArray = EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT).clear(); eph_pks.for_each(|pk| request_array.push(pk)); let response_array = get_shared_secrets_oracle(address, request_array, contract_address); - assert( - response_array.len() == eph_pks.len(), - "get_shared_secrets: response length does not match request length", - ); + assert(response_array.len() == eph_pks.len(), "get_shared_secrets: response length does not match request length"); let mut results: BoundedVec = BoundedVec::new(); for i in 0..eph_pks.len() { @@ -63,7 +58,7 @@ pub unconstrained fn get_shared_secrets( mod test { use crate::ephemeral::EphemeralArray; - use crate::oracle::shared_secret::{GET_SHARED_SECRETS_REQUEST_SLOT, get_shared_secrets}; + use crate::oracle::shared_secret::{get_shared_secrets, GET_SHARED_SECRETS_REQUEST_SLOT}; use crate::protocol::{address::AztecAddress, traits::FromField}; use crate::test::helpers::test_environment::TestEnvironment; use crate::utils::point::point_from_x_coord; @@ -85,8 +80,7 @@ mod test { AztecAddress::from_field(2), ); - let request_array: EphemeralArray<_> = - EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT); + let request_array: EphemeralArray<_> = EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT); assert_eq(request_array.get(0), pk_a); assert_eq(request_array.get(1), pk_b); assert_eq(request_array.get(2), pk_c); diff --git a/noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr b/noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr index 6cd429499339..07556ba42a95 100644 --- a/noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr +++ b/noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr @@ -19,30 +19,34 @@ pub fn publish_contract_instance_for_public_execution(context: &mut PrivateConte } // Adapted from - // noir-contracts/contracts/protocol/contract_instance_registry_contract/src/interface/ContractInstanceRegistry.nr + // noir-contracts/contracts/protocol/contract_instance_registry_contract/src/interface/ContractInstanceRegistry.ts // That file // was autogenerated running the following command from noir-projects/noir-contracts: - // ../../yarn-project/node_modules/.bin/aztec-cli codegen - // target/contract_instance_registry_contract-ContractInstanceRegistry.json --nr -o + // ../../yarn-project/node_modules/.bin/aztec codegen + // target/contract_instance_registry_contract-ContractInstanceRegistry.json -o // ./contracts/contract_instance_registry_contract/src/interface - let mut serialized_args = [0; 16]; + // + // PublicKeys serializes to 5 fields (npk_m_hash, ivpk_m as a 2-field point, ovpk_m_hash, tpk_m_hash). Total args: 4 + // (salt, class_id, init_hash, immutables_hash) + 5 (public_keys) + 1 (universal_deploy) = 10. + let mut serialized_args = [0; 10]; serialized_args[0] = instance.salt; serialized_args[1] = instance.contract_class_id.to_field(); serialized_args[2] = instance.initialization_hash; + serialized_args[3] = instance.immutables_hash; let serialized_public_keys = instance.public_keys.serialize(); - for i in 0..12 { - serialized_args[i + 3] = serialized_public_keys[i]; + for i in 0..5 { + serialized_args[i + 4] = serialized_public_keys[i]; } - serialized_args[15] = universal_deploy as Field; + serialized_args[9] = universal_deploy as Field; let _call_result = context.call_private_function( CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, comptime { FunctionSelector::from_signature( - "publish_for_public_execution(Field,(Field),Field,(((Field,Field,bool)),((Field,Field,bool)),((Field,Field,bool)),((Field,Field,bool))),bool)", + "publish_for_public_execution(Field,(Field),Field,Field,(Field,((Field,Field)),Field,Field),bool)", ) }, serialized_args, diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr index 019b8219cabc..2d797d503f59 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr @@ -12,10 +12,8 @@ use crate::{ }; use crate::protocol::{ - address::AztecAddress, - constants::DOM_SEP__INITIALIZATION_NULLIFIER, - hash::poseidon2_hash_with_separator, - traits::{Hash, Packable}, + address::AztecAddress, constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, + traits::Packable, }; mod test; @@ -82,8 +80,7 @@ impl PrivateImmutable { /// that need to check if a PrivateImmutable has been initialized. /// fn get_initialization_nullifier(self) -> Field { - let owner_npk_m = get_public_keys(self.owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(self.owner).npk_m_hash; let secret = self.context.request_nhk_app(owner_npk_m_hash); self.compute_initialization_nullifier(secret) } @@ -137,8 +134,7 @@ where { /// Computes the nullifier that will be created when this PrivateImmutable is first initialized. unconstrained fn get_initialization_nullifier(self) -> Field { - let owner_npk_m = get_public_keys(self.owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(self.owner).npk_m_hash; let secret = get_nhk_app(owner_npk_m_hash); self.compute_initialization_nullifier(secret) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr index 81a61aade5d9..bcf186e894ea 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr @@ -12,10 +12,8 @@ use crate::{ }; use crate::protocol::{ - address::AztecAddress, - constants::DOM_SEP__INITIALIZATION_NULLIFIER, - hash::poseidon2_hash_with_separator, - traits::{Hash, Packable}, + address::AztecAddress, constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, + traits::Packable, }; mod test; @@ -104,8 +102,7 @@ where /// also be useful for contracts that need to check if a PrivateMutable has been initialized. /// fn get_initialization_nullifier(self) -> Field { - let owner_npk_m = get_public_keys(self.owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(self.owner).npk_m_hash; let secret = self.context.request_nhk_app(owner_npk_m_hash); self.compute_initialization_nullifier(secret) } @@ -311,8 +308,7 @@ where { /// Computes the nullifier that will be created when this PrivateMutable is first initialized. unconstrained fn get_initialization_nullifier(self) -> Field { - let owner_npk_m = get_public_keys(self.owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(self.owner).npk_m_hash; let secret = get_nhk_app(owner_npk_m_hash); self.compute_initialization_nullifier(secret) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr index 6ae7103ee469..9e822bb64cea 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr @@ -12,9 +12,7 @@ use crate::{ }; use crate::protocol::{ - constants::DOM_SEP__INITIALIZATION_NULLIFIER, - hash::poseidon2_hash_with_separator, - traits::{Hash, Packable}, + constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, traits::Packable, }; mod test; @@ -87,8 +85,7 @@ impl SinglePrivateImmutable { /// that need to check if a SinglePrivateImmutable has been initialized. fn get_initialization_nullifier(self) -> Field { let contract_address = self.context.this_address(); - let contract_npk_m = get_public_keys(contract_address).npk_m; - let contract_npk_m_hash = contract_npk_m.hash(); + let contract_npk_m_hash = get_public_keys(contract_address).npk_m_hash; let secret = self.context.request_nhk_app(contract_npk_m_hash); self.compute_initialization_nullifier(secret) } @@ -152,8 +149,7 @@ where /// Computes the nullifier that will be created when this SinglePrivateImmutable is first initialized. unconstrained fn get_initialization_nullifier(self) -> Field { let contract_address = self.context.this_address(); - let contract_npk_m = get_public_keys(contract_address).npk_m; - let contract_npk_m_hash = contract_npk_m.hash(); + let contract_npk_m_hash = get_public_keys(contract_address).npk_m_hash; let secret = get_nhk_app(contract_npk_m_hash); self.compute_initialization_nullifier(secret) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr index 14feab03af3c..04951b29263d 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr @@ -12,10 +12,8 @@ use crate::{ }; use crate::protocol::{ - address::AztecAddress, - constants::DOM_SEP__INITIALIZATION_NULLIFIER, - hash::poseidon2_hash_with_separator, - traits::{Hash, Packable}, + address::AztecAddress, constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, + traits::Packable, }; mod test; @@ -122,8 +120,7 @@ where /// also be useful for contracts that need to check if a SinglePrivateMutable has been initialized. fn get_initialization_nullifier(self) -> Field { let contract_address = self.context.this_address(); - let contract_npk_m = get_public_keys(contract_address).npk_m; - let contract_npk_m_hash = contract_npk_m.hash(); + let contract_npk_m_hash = get_public_keys(contract_address).npk_m_hash; let secret = self.context.request_nhk_app(contract_npk_m_hash); self.compute_initialization_nullifier(secret) } @@ -243,8 +240,7 @@ where /// Computes the nullifier that will be created when this SinglePrivateMutable is first initialized. unconstrained fn get_initialization_nullifier(self) -> Field { let contract_address = self.context.this_address(); - let contract_npk_m = get_public_keys(contract_address).npk_m; - let contract_npk_m_hash = contract_npk_m.hash(); + let contract_npk_m_hash = get_public_keys(contract_address).npk_m_hash; let secret = get_nhk_app(contract_npk_m_hash); self.compute_initialization_nullifier(secret) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr index a97301415b21..5da2abb76b9b 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr @@ -1,6 +1,5 @@ use crate::protocol::{ address::AztecAddress, constants::DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, hash::poseidon2_hash_with_separator, - traits::Hash, }; use crate::{ @@ -104,7 +103,7 @@ impl SingleUseClaim<&mut PrivateContext> { /// The implementation of this function emits a nullifier derived from the `owner`'s nullifier hiding key and the /// storage slot of the underlying state variable. pub fn claim(self) { - let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m.hash()); + let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m_hash); self.context.push_nullifier_unsafe(self.compute_nullifier(owner_nhk_app)); } @@ -116,7 +115,7 @@ impl SingleUseClaim<&mut PrivateContext> { /// This function generates a kernel nullifier read request, so it can even assert the existence of pending claims, /// i.e. when [`SingleUseClaim::claim`] was called in the same transaction as [`SingleUseClaim::assert_claimed`]. pub fn assert_claimed(self) { - let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m.hash()); + let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m_hash); let nullifier = self.compute_nullifier(owner_nhk_app); // Safety: `check_nullifier_exists` is an unconstrained function - we can constrain a true value @@ -136,7 +135,7 @@ impl SingleUseClaim<&mut PrivateContext> { impl SingleUseClaim { /// Returns `true` if an owner has claimed this single use claim. pub unconstrained fn has_claimed(self) -> bool { - let owner_nhk_app = get_nhk_app(get_public_keys(self.owner).npk_m.hash()); + let owner_nhk_app = get_nhk_app(get_public_keys(self.owner).npk_m_hash); check_nullifier_exists(self.compute_nullifier(owner_nhk_app)) } } diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/misc.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/misc.nr index 26ab11663952..d03347ea83f4 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/misc.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/misc.nr @@ -60,8 +60,5 @@ unconstrained fn txe_oracle_version_is_checked_upon_env_creation() { let _env = TestEnvironment::new(); assert_eq(mock.times_called(), 1); - assert_eq( - mock.get_last_params::<(Field, Field)>(), - (TXE_ORACLE_VERSION_MAJOR, TXE_ORACLE_VERSION_MINOR), - ); + assert_eq(mock.get_last_params::<(Field, Field)>(), (TXE_ORACLE_VERSION_MAJOR, TXE_ORACLE_VERSION_MINOR)); } diff --git a/noir-projects/aztec-nr/aztec/src/utils/point.nr b/noir-projects/aztec-nr/aztec/src/utils/point.nr index ab5b90614ee8..7f2b3b54a7a0 100644 --- a/noir-projects/aztec-nr/aztec/src/utils/point.nr +++ b/noir-projects/aztec-nr/aztec/src/utils/point.nr @@ -1,11 +1,11 @@ -use crate::protocol::{point::Point, utils::field::sqrt}; +use crate::protocol::{point::EmbeddedCurvePoint, utils::field::sqrt}; // I am storing the modulus minus 1 divided by 2 here because full modulus would throw "String literal too large" error // Full modulus is 21888242871839275222246405745257275088548364400416034343698204186575808495617 global BN254_FR_MODULUS_DIV_2: Field = 10944121435919637611123202872628637544274182200208017171849102093287904247808; /// Returns: true if p.y <= MOD_DIV_2, else false. -pub fn get_sign_of_point(p: Point) -> bool { +pub fn get_sign_of_point(p: EmbeddedCurvePoint) -> bool { // We store only a "sign" of the y coordinate because the rest can be derived from the x coordinate. To get the // sign we check if the y coordinate is less or equal than the field's modulus minus 1 divided by 2. Ideally we'd // do `y <= MOD_DIV_2`, but there's no `lte` function, so instead we do `!(y > MOD_DIV_2)`, which is equivalent, @@ -13,18 +13,18 @@ pub fn get_sign_of_point(p: Point) -> bool { !BN254_FR_MODULUS_DIV_2.lt(p.y) } -/// Returns a `Point` in the Grumpkin curve given its x coordinate. +/// Returns an `EmbeddedCurvePoint` in the Grumpkin curve given its x coordinate. /// /// Because not all values in the field are valid x coordinates of points in the curve (i.e. there is no corresponding /// y value in the field that satisfies the curve equation), it may not be possible to reconstruct a `Point`. /// `Option::none()` is returned in such cases. -pub fn point_from_x_coord(x: Field) -> Option { +pub fn point_from_x_coord(x: Field) -> Option { // y ^ 2 = x ^ 3 - 17 let rhs = x * x * x - 17; - sqrt(rhs).map(|y| Point { x, y, is_infinite: false }) + sqrt(rhs).map(|y| EmbeddedCurvePoint { x, y }) } -/// Returns a `Point` in the Grumpkin curve given its x coordinate and sign for the y coordinate. +/// Returns an `EmbeddedCurvePoint` in the Grumpkin curve given its x coordinate and sign for the y coordinate. /// /// Because not all values in the field are valid x coordinates of points in the curve (i.e. there is no corresponding /// y value in the field that satisfies the curve equation), it may not be possible to reconstruct a `Point`. @@ -32,7 +32,7 @@ pub fn point_from_x_coord(x: Field) -> Option { /// /// @param x - The x coordinate of the point @param sign - The "sign" of the y coordinate - determines whether y <= /// (Fr.MODULUS - 1) / 2 -pub fn point_from_x_coord_and_sign(x: Field, sign: bool) -> Option { +pub fn point_from_x_coord_and_sign(x: Field, sign: bool) -> Option { // y ^ 2 = x ^ 3 - 17 let rhs = x * x * x - 17; @@ -40,12 +40,12 @@ pub fn point_from_x_coord_and_sign(x: Field, sign: bool) -> Option { // If there is a square root, we need to ensure it has the correct "sign" let y_is_positive = !BN254_FR_MODULUS_DIV_2.lt(y); let final_y = if y_is_positive == sign { y } else { -y }; - Point { x, y: final_y, is_infinite: false } + EmbeddedCurvePoint { x, y: final_y } }) } mod test { - use crate::protocol::point::Point; + use crate::protocol::point::EmbeddedCurvePoint; use crate::utils::point::{ BN254_FR_MODULUS_DIV_2, get_sign_of_point, point_from_x_coord, point_from_x_coord_and_sign, }; @@ -59,7 +59,7 @@ mod test { assert_eq(p.x, x); assert_eq(p.y, 0x07fc22c7f2c7057571f137fe46ea9c95114282bc95d37d71ec4bfb88de457d4a); - assert_eq(p.is_infinite, false); + assert_eq(p.is_infinite(), false); // Test negative y coordinate let x2 = 0x247371652e55dd74c9af8dbe9fb44931ba29a9229994384bd7077796c14ee2b5; @@ -68,7 +68,7 @@ mod test { assert_eq(p2.x, x2); assert_eq(p2.y, 0x26441aec112e1ae4cee374f42556932001507ad46e255ffb27369c7e3766e5c0); - assert_eq(p2.is_infinite, false); + assert_eq(p2.is_infinite(), false); } #[test] @@ -123,7 +123,7 @@ mod test { unconstrained fn test_get_sign_of_point() { // Derive a point from x = 8, then test both possible y values let point = point_from_x_coord(8).unwrap(); - let neg_point = Point { x: point.x, y: 0 - point.y, is_infinite: false }; + let neg_point = EmbeddedCurvePoint { x: point.x, y: 0 - point.y }; // One should be "positive" (y <= MOD_DIV_2) and one "negative" let sign1 = get_sign_of_point(point); @@ -131,15 +131,15 @@ mod test { assert(sign1 != sign2); // y = 0 should return true (0 <= MOD_DIV_2) - let zero_y_point = Point { x: 0, y: 0, is_infinite: false }; + let zero_y_point = EmbeddedCurvePoint { x: 0, y: 0 }; assert(get_sign_of_point(zero_y_point) == true); // y = MOD_DIV_2 should return true (exactly at boundary) - let boundary_point = Point { x: 0, y: BN254_FR_MODULUS_DIV_2, is_infinite: false }; + let boundary_point = EmbeddedCurvePoint { x: 0, y: BN254_FR_MODULUS_DIV_2 }; assert(get_sign_of_point(boundary_point) == true); // y = MOD_DIV_2 + 1 should return false (just over boundary) - let over_boundary_point = Point { x: 0, y: BN254_FR_MODULUS_DIV_2 + 1, is_infinite: false }; + let over_boundary_point = EmbeddedCurvePoint { x: 0, y: BN254_FR_MODULUS_DIV_2 + 1 }; assert(get_sign_of_point(over_boundary_point) == false); } diff --git a/noir-projects/aztec-nr/uint-note/src/uint_note.nr b/noir-projects/aztec-nr/uint-note/src/uint_note.nr index 00583d1e7d73..87fb76f7f4db 100644 --- a/noir-projects/aztec-nr/uint-note/src/uint_note.nr +++ b/noir-projects/aztec-nr/uint-note/src/uint_note.nr @@ -15,7 +15,7 @@ use aztec::{ DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, }, hash::{compute_log_tag, compute_siloed_nullifier, poseidon2_hash_with_separator}, - traits::{Deserialize, FromField, Hash, Packable, Serialize, ToField}, + traits::{Deserialize, FromField, Packable, Serialize, ToField}, }, }; @@ -64,8 +64,7 @@ impl NoteHash for UintNote { owner: AztecAddress, note_hash_for_nullification: Field, ) -> Field { - let owner_npk_m = get_public_keys(owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; let secret = context.request_nhk_app(owner_npk_m_hash); compute_note_nullifier(note_hash_for_nullification, [secret]) } @@ -76,8 +75,7 @@ impl NoteHash for UintNote { note_hash_for_nullification: Field, ) -> Option { try_get_public_keys(owner).map(|public_keys| { - let owner_npk_m = public_keys.npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = public_keys.npk_m_hash; let secret = get_nhk_app(owner_npk_m_hash); compute_note_nullifier(note_hash_for_nullification, [secret]) }) diff --git a/noir-projects/bootstrap.sh b/noir-projects/bootstrap.sh index 006f75495900..197e7cc8bbd3 100755 --- a/noir-projects/bootstrap.sh +++ b/noir-projects/bootstrap.sh @@ -10,9 +10,14 @@ function build { function prep { set -eu (cd noir-protocol-circuits && yarn && node ./scripts/generate_variants.js) - for dir in noir-contracts noir-protocol-circuits mock-protocol-circuits aztec-nr; do - (cd $dir && ../../noir/noir-repo/target/release/nargo fmt --check) - done + # nargo downloads its git dependencies (e.g. noir-lang/poseidon) on first use. + # Under heavy parallel CI load the VPC DNS resolver drops lookups + # ("Could not resolve host: github.com"), leaving a half-cloned dependency dir + # that then fails with "Cannot read file .../Nargo.toml". Retry the download, + # wiping the partial dependency cache after a failure so the next attempt + # re-clones cleanly. A warm cache is left intact on success. + local fmt_check='( set -e; for dir in noir-contracts noir-protocol-circuits mock-protocol-circuits aztec-nr; do (cd "$dir" && ../../noir/noir-repo/target/release/nargo fmt --check); done )' + RETRY_SLEEP=10 retry "$fmt_check || { rm -rf \"\$HOME/nargo\"; exit 1; }" } export -f prep diff --git a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr index 1886bf121746..104a9d2b6f88 100644 --- a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr +++ b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr @@ -9,7 +9,7 @@ use aztec::{ protocol::{ address::AztecAddress, constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - traits::{Deserialize, FromField, Hash, Packable, Serialize, ToField}, + traits::{Deserialize, FromField, Packable, Serialize, ToField}, }, state_vars::{Owned, PrivateSet, StateVariable}, }; @@ -181,7 +181,7 @@ impl Deck { global PACK_CARDS: u32 = 3; // Limited by number of write requests (max 4) pub fn get_pack_cards(seed: Field, owner: AztecAddress, context: &mut PrivateContext) -> [Card; PACK_CARDS] { - let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; // generate pseudo randomness deterministically from 'seed' and user secret let secret = context.request_nhk_app(owner_npk_m_hash); diff --git a/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr b/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr index 6f0e47db7085..183a85c618a3 100644 --- a/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr +++ b/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr @@ -15,7 +15,7 @@ use aztec::{ DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, }, hash::{compute_log_tag, poseidon2_hash_with_separator}, - traits::{Deserialize, Hash, Packable, Serialize, ToField}, + traits::{Deserialize, Packable, Serialize, ToField}, }, }; @@ -60,8 +60,7 @@ impl NoteHash for NFTNote { owner: AztecAddress, note_hash_for_nullification: Field, ) -> Field { - let owner_npk_m = get_public_keys(owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; let secret = context.request_nhk_app(owner_npk_m_hash); compute_note_nullifier(note_hash_for_nullification, [secret]) } @@ -72,8 +71,7 @@ impl NoteHash for NFTNote { note_hash_for_nullification: Field, ) -> Option { try_get_public_keys(owner).map(|public_keys| { - let owner_npk_m = public_keys.npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = public_keys.npk_m_hash; let secret = get_nhk_app(owner_npk_m_hash); compute_note_nullifier(note_hash_for_nullification, [secret]) }) diff --git a/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr index af84b0e17cf0..ded38bc11126 100644 --- a/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr +++ b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr @@ -1,7 +1,7 @@ use aztec::{ keys::ecdh_shared_secret::compute_app_siloed_shared_secret, macros::notes::note, - protocol::{address::AztecAddress, point::Point, traits::{Deserialize, Packable, Serialize}}, + protocol::{address::AztecAddress, point::EmbeddedCurvePoint, traits::{Deserialize, Packable, Serialize}}, }; /// A record of a handshake established by the note's owner (the sender). @@ -20,11 +20,11 @@ pub struct HandshakeNote { recipient: AztecAddress, /// The raw ECDH shared-secret point `S = eph_sk * recipient_address_point`. Only this module can read it for /// siloing, and it is never returned by an external function. - secret: Point, + secret: EmbeddedCurvePoint, } impl HandshakeNote { - pub(crate) fn new(shared_secret: Point, handshake_type: u8, recipient: AztecAddress) -> Self { + pub(crate) fn new(shared_secret: EmbeddedCurvePoint, handshake_type: u8, recipient: AztecAddress) -> Self { Self { handshake_type, recipient, secret: shared_secret } } diff --git a/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr b/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr index e8f1e8c0bb4a..48dafc745fd9 100644 --- a/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr @@ -32,14 +32,16 @@ pub contract ContractInstanceRegistry { salt: Field, contract_class_id: ContractClassId, initialization_hash: Field, + immutables_hash: Field, public_keys: PublicKeys, deployer: AztecAddress, } - // Custom serialization is required because we don't want to waste one field for the `is_infinite` flag of public - // key points (public key points will never be the infinity point). + // Custom serialization is required because: + // - npk_m, ovpk_m, and tpk_m are exposed only as hashes so we serialize the hashes directly. + // - For ivpk_m we drop the `is_infinite` flag (we assume non-infinity). impl ContractInstancePublished { - fn serialize_non_standard(self) -> [Field; 15] { + fn serialize_non_standard(self) -> [Field; 13] { [ self.CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE, self.address.to_field(), @@ -47,14 +49,12 @@ pub contract ContractInstanceRegistry { self.salt, self.contract_class_id.to_field(), self.initialization_hash, - self.public_keys.npk_m.serialize()[0], - self.public_keys.npk_m.serialize()[1], - self.public_keys.ivpk_m.serialize()[0], - self.public_keys.ivpk_m.serialize()[1], - self.public_keys.ovpk_m.serialize()[0], - self.public_keys.ovpk_m.serialize()[1], - self.public_keys.tpk_m.serialize()[0], - self.public_keys.tpk_m.serialize()[1], + self.immutables_hash, + self.public_keys.npk_m_hash, + self.public_keys.ivpk_m.inner.x, + self.public_keys.ivpk_m.inner.y, + self.public_keys.ovpk_m_hash, + self.public_keys.tpk_m_hash, self.deployer.to_field(), ] } @@ -77,13 +77,15 @@ pub contract ContractInstanceRegistry { /// Publishes a new contract instance. /// - /// The caller provides deployment parameters (salt, class_id, init_hash, public_keys, universal_deploy). + /// The caller provides deployment parameters (salt, class_id, init_hash, immutables_hash, public_keys, + /// universal_deploy). /// The `universal_deploy` flag controls whether the deployer address is bound into the contract address: /// when true, deployer is zero (anyone can deploy the same instance); when false, deployer is the caller. /// /// This function: /// 1. Verifies the contract class is registered in ContractClassRegistry (nullifier existence check). - /// 2. Validates public key points are on the Grumpkin curve (preventing AVM DoS via invalid points). + /// 2. Validates `ivpk_m` is on the Grumpkin curve and not the point at infinity (preventing AVM DoS via an invalid + /// point). `npk_m`, `ovpk_m`, and `tpk_m` are exposed only as hashes and are not validated in-circuit. /// 3. Computes the deterministic contract address from the deployment parameters. /// 4. Emits the address as a nullifier (proving publication preventing duplicate deployment) /// --> this address nullifier is then checked to exist by the AVM upon public function execution (if it doesn't @@ -95,6 +97,7 @@ pub contract ContractInstanceRegistry { salt: Field, contract_class_id: ContractClassId, initialization_hash: Field, + immutables_hash: Field, public_keys: PublicKeys, universal_deploy: bool, ) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { @@ -103,7 +106,9 @@ pub contract ContractInstanceRegistry { // body, I have removed that check. assert_compatible_oracle_version(); - let serialized_params: [Field; 16] = [salt, contract_class_id.to_field(), initialization_hash] + // 4 prefix fields (salt, class_id, init_hash, immutables_hash) + 5 public-key fields + 1 + // universal_deploy flag = 10. + let serialized_params: [Field; 10] = [salt, contract_class_id.to_field(), initialization_hash, immutables_hash] .concat(public_keys.serialize()) .concat([universal_deploy.to_field()]); @@ -126,9 +131,17 @@ pub contract ContractInstanceRegistry { context.maybe_msg_sender().unwrap() }; - let partial_address = PartialAddress::compute(contract_class_id, salt, initialization_hash, deployer); + let partial_address = PartialAddress::compute( + contract_class_id, + salt, + initialization_hash, + deployer, + immutables_hash, + ); - // Validate public key points lie on the Grumpkin curve and are non-0 to prevent AVM DoS attacks. + // Validate `ivpk_m` is on the Grumpkin curve and is not the point at infinity (preventing AVM + // DoS attacks). The other three master keys are exposed as hashes and have no + // curve-point to validate here. public_keys.validate_on_curve(); public_keys.validate_non_infinity(); @@ -138,23 +151,24 @@ pub contract ContractInstanceRegistry { // We use no domain separators because these are the only nullifiers this contract uses. context.push_nullifier(address.to_field()); - // Broadcast deployment event. Uses non-standard serialization (2 fields per point, - // omitting is_infinite) for TypeScript SDK compatibility. + // Broadcast deployment event. Version 2 carries hashes for npk/ovpk/tpk and the affine + // coordinates of ivpk only; see `serialize_non_standard`. let event = ContractInstancePublished { CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE, contract_class_id, address, public_keys, initialization_hash, + immutables_hash, salt, deployer, - version: 1, + version: 2, }; let payload = event.serialize_non_standard(); debug_log_format("ContractInstancePublished: {}", payload); - // We pad the payload with [0] to match the length required by emit_private_log. Since the log is not + // We pad the payload with zeros to match the length required by emit_private_log. Since the log is not // encrypted, padding with zero rather than a random value is acceptable (we don't care about privacy here). - let padded_log = payload.concat([0]); + let padded_log = payload.concat([0, 0, 0]); let length = payload.len(); context.emit_private_log(padded_log, length); @@ -307,6 +321,7 @@ pub contract ContractInstanceRegistry { pub _salt: Field, pub _contract_class_id: ContractClassId, pub _initialization_hash: Field, + pub _immutables_hash: Field, pub _public_keys: PublicKeys, pub _universal_deploy: bool, } diff --git a/noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface/src/main.nr b/noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface/src/main.nr index d672c3b7bf5b..43af16745a71 100644 --- a/noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface/src/main.nr @@ -25,6 +25,7 @@ pub contract ContractInstanceRegistry { salt: Field, contract_class_id: ContractClassId, initialization_hash: Field, + immutables_hash: Field, public_keys: PublicKeys, universal_deploy: bool, ) {} diff --git a/noir-projects/noir-contracts/contracts/test/avm_test_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/test/avm_test_contract/Nargo.toml index 5745846cfdbf..b29c5154badf 100644 --- a/noir-projects/noir-contracts/contracts/test/avm_test_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/test/avm_test_contract/Nargo.toml @@ -10,6 +10,7 @@ compressed_string = { path = "../../../../aztec-nr/compressed-string" } sha256 = { tag = "v0.3.0", git = "https://github.com/noir-lang/sha256" } keccak256 = { tag = "v0.1.3", git = "https://github.com/noir-lang/keccak256" } poseidon = { tag= "v0.3.0", git = "https://github.com/noir-lang/poseidon" } +schnorr = { tag = "v0.4.0", git = "https://github.com/noir-lang/schnorr" } fee_juice = { path = "../../protocol_interface/fee_juice_interface" } auth_contract = { path = "../../protocol/auth_registry_contract" } instance_contract = { path = "../../protocol_interface/contract_instance_registry_interface" } diff --git a/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr index 91e52f588160..d868087802c2 100644 --- a/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr @@ -16,10 +16,10 @@ pub contract AvmTest { use aztec::macros::{functions::{external, view}, storage::storage}; use aztec::oracle::get_contract_instance::{ get_contract_instance_class_id_avm, get_contract_instance_deployer_avm, - get_contract_instance_initialization_hash_avm, + get_contract_instance_immutables_hash_avm, get_contract_instance_initialization_hash_avm, }; use aztec::protocol::abis::function_selector::FunctionSelector; - use aztec::protocol::{address::{AztecAddress, EthAddress}, point::Point, scalar::Scalar}; + use aztec::protocol::{address::{AztecAddress, EthAddress}, point::EmbeddedCurvePoint, scalar::Scalar}; use aztec::protocol::{ constants::{ CANONICAL_AUTH_REGISTRY_ADDRESS, CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, FEE_JUICE_ADDRESS, @@ -195,13 +195,13 @@ pub contract AvmTest { } #[external("public")] - fn elliptic_curve_add(lhs: Point, rhs: Point) -> Point { + fn elliptic_curve_add(lhs: EmbeddedCurvePoint, rhs: EmbeddedCurvePoint) -> EmbeddedCurvePoint { lhs + rhs } #[external("public")] - fn elliptic_curve_add_and_double() -> Point { - let g = Point { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y, is_infinite: false }; + fn elliptic_curve_add_and_double() -> EmbeddedCurvePoint { + let g = EmbeddedCurvePoint { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y }; let doubled = g + g; let added = g + doubled; @@ -209,20 +209,23 @@ pub contract AvmTest { } #[external("public")] - fn variable_base_msm(scalar_lo: Field, scalar_hi: Field, scalar2_lo: Field, scalar2_hi: Field) -> Point { - let g = Point { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y, is_infinite: false }; + fn variable_base_msm( + scalar_lo: Field, + scalar_hi: Field, + scalar2_lo: Field, + scalar2_hi: Field, + ) -> EmbeddedCurvePoint { + let g = EmbeddedCurvePoint { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y }; - let triple_g = multi_scalar_mul( - [g.to_embedded(), g.to_embedded()], + multi_scalar_mul( + [g, g], [Scalar { lo: scalar_lo, hi: scalar_hi }, Scalar { lo: scalar2_lo, hi: scalar2_hi }], - ); - triple_g.into() + ) } #[external("public")] - fn pedersen_commit(x: Field, y: Field) -> Point { - let commitment = ::std::hash::pedersen_commitment_with_separator([x, y], 20); - commitment.into() + fn pedersen_commit(x: Field, y: Field) -> EmbeddedCurvePoint { + std::hash::pedersen_commitment_with_separator([x, y], 20) } #[external("public")] @@ -280,6 +283,26 @@ pub contract AvmTest { input.to_le_bits() } + // Exercises Schnorr signature verification in public. The grumpkin-Poseidon2 variant + // (schnorr v0.4.0+) only relies on EC arithmetic and Poseidon2, both of which the public AVM + // supports. Inputs are parameters rather than constants; when bulk_testing routes them in + // from calldata, Noir can't constant-fold the verify away and MSM+Poseidon2 actually execute. + #[contract_library_method] + fn _schnorr_verify_signature( + pubkey_x: Field, + pubkey_y: Field, + sig_s_lo: Field, + sig_s_hi: Field, + sig_e_lo: Field, + sig_e_hi: Field, + message: Field, + ) -> bool { + let public_key = std::embedded_curve_ops::EmbeddedCurvePoint::new(pubkey_x, pubkey_y); + let sig_s = std::embedded_curve_ops::EmbeddedCurveScalar::new(sig_s_lo, sig_s_hi); + let sig_e = std::embedded_curve_ops::EmbeddedCurveScalar::new(sig_e_lo, sig_e_hi); + schnorr::verify_signature(public_key, (sig_s, sig_e), message) + } + // Helper functions to demonstrate an internal call stack in error messages #[contract_library_method] fn inner_helper_with_failed_assertion() { @@ -389,20 +412,24 @@ pub contract AvmTest { [4, 5, 6] // Should not get here. } + // This function is called from avm/avm_simulator.test.ts to test retrieval #[external("public")] fn test_get_contract_instance(address: AztecAddress) { let deployer = get_contract_instance_deployer_avm(address); let class_id = get_contract_instance_class_id_avm(address); let initialization_hash = get_contract_instance_initialization_hash_avm(address); + let immutables_hash = get_contract_instance_immutables_hash_avm(address); assert(deployer.is_some(), "Contract instance not found when getting DEPLOYER!"); assert(class_id.is_some(), "Contract instance not found when getting CLASS_ID!"); assert(initialization_hash.is_some(), "Contract instance not found when getting INIT_HASH!"); + assert(immutables_hash.is_some(), "Contract instance not found when getting IMMUTABLES_HASH!"); // The values here should match those in `avm_simulator.test.ts` assert(deployer.unwrap().eq(AztecAddress::from_field(0x456))); assert(class_id.unwrap().eq(ContractClassId::from_field(0x789))); assert(initialization_hash.unwrap() == 0x101112); + assert(immutables_hash.unwrap() == 0x202221); } #[external("public")] @@ -411,12 +438,14 @@ pub contract AvmTest { expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, + expected_immutables_hash: Field, ) { _test_get_contract_instance_matches( address, expected_deployer, expected_class_id, expected_initialization_hash, + expected_immutables_hash, ); } @@ -426,19 +455,23 @@ pub contract AvmTest { expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, + expected_immutables_hash: Field, ) { let deployer = get_contract_instance_deployer_avm(address); let class_id = get_contract_instance_class_id_avm(address); let initialization_hash = get_contract_instance_initialization_hash_avm(address); + let immutables_hash = get_contract_instance_immutables_hash_avm(address); assert(deployer.is_some(), "Contract instance not found when getting DEPLOYER!"); assert(class_id.is_some(), "Contract instance not found when getting CLASS_ID!"); assert(initialization_hash.is_some(), "Contract instance not found when getting INIT_HASH!"); + assert(immutables_hash.is_some(), "Contract instance not found when getting IMMUTABLES_HASH!"); // The values here should match those in `avm_simulator.test.ts` assert(deployer.unwrap().eq(expected_deployer)); assert(class_id.unwrap().eq(expected_class_id)); assert(initialization_hash.unwrap().eq(expected_initialization_hash)); + assert(immutables_hash.unwrap().eq(expected_immutables_hash)); // Get a Protocol Contract and it should exist aztec::oracle::logging::debug_log("Get Contract Instance Protocol Contract Instance"); @@ -842,6 +875,8 @@ pub contract AvmTest { expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, + expected_immutables_hash: Field, + schnorr_inputs: [Field; 7], skip_strictly_limited_side_effects: bool, ) { aztec::oracle::logging::debug_log("biwise_ops"); @@ -863,6 +898,17 @@ pub contract AvmTest { let _ = sha256::sha256_var(args_u8, args_u8.len()); aztec::oracle::logging::debug_log("poseidon2_hash"); let _ = poseidon::poseidon2::Poseidon2::hash(args_field, args_field.len()); + aztec::oracle::logging::debug_log("schnorr_verify_signature"); + let schnorr_ok = _schnorr_verify_signature( + schnorr_inputs[0], + schnorr_inputs[1], + schnorr_inputs[2], + schnorr_inputs[3], + schnorr_inputs[4], + schnorr_inputs[5], + schnorr_inputs[6], + ); + assert(schnorr_ok, "Schnorr signature should verify"); aztec::oracle::logging::debug_log("pedersen_hash"); let _ = std::hash::pedersen_hash(args_field); aztec::oracle::logging::debug_log("pedersen_hash_with_index"); @@ -877,6 +923,7 @@ pub contract AvmTest { expected_deployer, expected_class_id, expected_initialization_hash, + expected_immutables_hash, ); aztec::oracle::logging::debug_log("get_address"); let _ = _get_address(self.address); @@ -935,3 +982,28 @@ pub contract AvmTest { //let _ = nested_call_to_nothing_recovers(); } } + +mod test { + use std::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar}; + + // Pins the same vector as `_schnorr_verify_signature` in the contract above (mirroring the C++ + // pinned_test_vector_large) so a regression in the schnorr lib or noir submodule is caught at + // `nargo test` time rather than only when running the AVM end-to-end test. + #[test] + unconstrained fn schnorr_pinned_vector_verifies() { + let public_key = EmbeddedCurvePoint::new( + 0x065812e335a97c2108ea8cf4ccfe2f9dd6b117a0714f5e18461575be93f61da6, + 0x1a915003e8ec534f9a15d926a7ded478e178468ccc4f28e236e67450a55ac622, + ); + let sig_s = EmbeddedCurveScalar::new( + 0xf3bc3b7147acb9c621fd9f72dbf15ffa, + 0x08599f379f0301dfefdbd0272554454d, + ); + let sig_e = EmbeddedCurveScalar::new( + 0x97065383ebbbd76620398792bd259bc2, + 0x2ceaee87f45b7a417f0ffb05451a8c92, + ); + let message: Field = 0x0123456789abcdef0fedcba9876543210123456789abcdef0fedcba987654321; + assert(schnorr::verify_signature(public_key, (sig_s, sig_e), message)); + } +} diff --git a/noir-projects/noir-contracts/contracts/test/returning_tuple_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/returning_tuple_contract/src/main.nr index b5887569e14e..0b7dee4ec40d 100644 --- a/noir-projects/noir-contracts/contracts/test/returning_tuple_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/returning_tuple_contract/src/main.nr @@ -5,7 +5,7 @@ use aztec::macros::aztec; pub contract ReturningTuple { use aztec::{ macros::functions::{external, view}, - protocol::{address::AztecAddress, point::Point, traits::{Deserialize, FromField}}, + protocol::{address::AztecAddress, point::EmbeddedCurvePoint, traits::{Deserialize, FromField}}, }; #[external("private")] @@ -40,8 +40,8 @@ pub contract ReturningTuple { #[external("private")] #[view] - fn fn_that_returns_6() -> (Field, u128, bool, str<3>, AztecAddress, Point) { - (1, 2, false, "xyz", AztecAddress::from_field(1), Point::deserialize([1, 2, 0])) + fn fn_that_returns_6() -> (Field, u128, bool, str<3>, AztecAddress, EmbeddedCurvePoint) { + (1, 2, false, "xyz", AztecAddress::from_field(1), EmbeddedCurvePoint::deserialize([1, 2])) } #[external("public")] @@ -76,8 +76,8 @@ pub contract ReturningTuple { #[external("public")] #[view] - fn fn_that_returns_6_public() -> (Field, u128, bool, str<3>, AztecAddress, Point) { - (1, 2, false, "xyz", AztecAddress::from_field(1), Point::deserialize([1, 2, 0])) + fn fn_that_returns_6_public() -> (Field, u128, bool, str<3>, AztecAddress, EmbeddedCurvePoint) { + (1, 2, false, "xyz", AztecAddress::from_field(1), EmbeddedCurvePoint::deserialize([1, 2])) } } diff --git a/noir-projects/noir-contracts/contracts/test/scope_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/scope_test_contract/src/main.nr index 27dd883cfed8..53a41d35fdde 100644 --- a/noir-projects/noir-contracts/contracts/test/scope_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/scope_test_contract/src/main.nr @@ -9,7 +9,7 @@ pub contract ScopeTest { keys::getters::{get_nhk_app, get_public_keys}, macros::{functions::{external, initializer, view}, storage::storage}, messages::message_delivery::MessageDelivery, - protocol::{address::AztecAddress, traits::Hash}, + protocol::address::AztecAddress, state_vars::{Owned, PrivateImmutable}, }; @@ -52,7 +52,7 @@ pub contract ScopeTest { /// Will fail if the caller is not authorized to access the owner's keys. #[external("private")] fn get_nhk(owner: AztecAddress) -> Field { - let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; self.context.request_nhk_app(owner_npk_m_hash) } @@ -67,7 +67,7 @@ pub contract ScopeTest { /// Will fail if the caller is not authorized to access the owner's keys. #[external("utility")] unconstrained fn get_nhk_utility(owner: AztecAddress) -> Field { - let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; get_nhk_app(owner_npk_m_hash) } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-2/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-2/Prover.toml new file mode 100644 index 000000000000..ad9bdf3b8638 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-2/Prover.toml @@ -0,0 +1,4016 @@ +vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" +is_private_only = true +first_nullifier_hint = "0x22c8f916474c9e4fbc086a9476c89c93120e1b8f7e32f1167216e7c3cb2e3308" +revertible_counter_hint = "0x0000000000000000000000000000000000000000000000000000000000000005" + +[tx_request] +args_hash = "0x02486714bcf7b63435b8818a646f5124643019b4d7a09497d20cca8d58ae946d" +salt = "0x0151ac979fc0d39f599d2b839d8bc37405936ad2d0d39b60185aa75a6d0e7336" + + [tx_request.origin] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [tx_request.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[tx_request.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[tx_request.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[tx_request.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[tx_request.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [tx_request.function_data] + is_private = true + + [tx_request.function_data.selector] + inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" + +[[protocol_contracts.derived_addresses]] +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" + +[[protocol_contracts.derived_addresses]] +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" + +[[protocol_contracts.derived_addresses]] +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" + +[[protocol_contracts.derived_addresses]] +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" + +[[protocol_contracts.derived_addresses]] +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" + +[[protocol_contracts.derived_addresses]] +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[private_call_0.vk] +key = [ + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000b61", + "0x0000000000000000000000000000007b6222b3a18551d60b847957202de6c8f5", + "0x00000000000000000000000000000000001e26b96548b9f12369e9c3ec0eee85", + "0x000000000000000000000000000000025aac0bbaf1beff1c0500e3ec38d34c8a", + "0x00000000000000000000000000000000002c498aff2f95b25bb92e2c9360aff5", + "0x00000000000000000000000000000039d32590e9d6e0be118712b9402c606156", + "0x000000000000000000000000000000000026588627e22f203f6399975fb67258", + "0x000000000000000000000000000000097282335613efda63abaeaddc915f44db", + "0x000000000000000000000000000000000021b51f545ea031ad8c826962f52545", + "0x00000000000000000000000000000035a0536197418c2ba2c29a1830f709420c", + "0x000000000000000000000000000000000020f8cabd08dfc29e045e0b80eb42d3", + "0x00000000000000000000000000000099e53cda88a63b8e751a2bc253f7a689a7", + "0x0000000000000000000000000000000000231a514e7a4dd0e23c4faf8d567c77", + "0x0000000000000000000000000000002dac12ff4e48e530611ceb7a400c099e4a", + "0x00000000000000000000000000000000001ad1cb6dbbe8ea3dd6c4f44ffdce56", + "0x000000000000000000000000000000dfd19e74f4e4c641b3b3f623825ccd495f", + "0x00000000000000000000000000000000000ce4453cef94251418336baa54e582", + "0x0000000000000000000000000000007ad93fd648d3587168e2ba9ee66dbbf918", + "0x00000000000000000000000000000000000a7680894366d3b1755d14152e528e", + "0x00000000000000000000000000000008bf43eecffcec9e31d916289a212b8f88", + "0x0000000000000000000000000000000000216620e5bd7b177f3fa15ceeb2526e", + "0x00000000000000000000000000000021db86993540e76c420c850640a25f7d94", + "0x000000000000000000000000000000000017418ee5d4d58a54e7728b755757a8", + "0x0000000000000000000000000000000cf5f978296643872c59d00be3c23ad68d", + "0x000000000000000000000000000000000013e45088158c3bf8ac1f8e71eec154", + "0x000000000000000000000000000000768cc857ea136153788ffa81c07daddaf2", + "0x000000000000000000000000000000000014b992148ee6906cb3a1989f3c4bb1", + "0x0000000000000000000000000000000127e074cd6ea24f75f86f3ab119f9ae5d", + "0x00000000000000000000000000000000001719d1f7fc4645193b8036cf9a3d52", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x000000000000000000000000000000622ac3715a21583a169b4c635c162bdc13", + "0x000000000000000000000000000000000012374104ee9056dfafba40f457c0a8", + "0x000000000000000000000000000000f6c09b75f7561f7fbbd272af5d3efa974b", + "0x00000000000000000000000000000000000e0a7bd7a377bca3ff6c89d68a3e5e", + "0x0000000000000000000000000000009d165e9a47e021ab9760d27339570655e5", + "0x0000000000000000000000000000000000000b204b0dc1f11b52bb345fb52145", + "0x000000000000000000000000000000d4c558b53b27cb4c171f8a5eb0bd1e3a2c", + "0x00000000000000000000000000000000002f6870272192d541c1b8887b15a95a", + "0x0000000000000000000000000000008f4c64ade1e7b515b074c100d489415d4c", + "0x00000000000000000000000000000000000f9aca92beccde2e1b08c99ab92a6c", + "0x0000000000000000000000000000008be6976e9870523051d19531843262ce4c", + "0x0000000000000000000000000000000000277419877e0ba35217f219676b5656", + "0x00000000000000000000000000000051ec180d05026f2f62b1674ca2e1a2c142", + "0x000000000000000000000000000000000022264cbd2ea66b7766612864c5108c", + "0x000000000000000000000000000000f137ae2b224915db0c43de1611134011d0", + "0x000000000000000000000000000000000011877af1a2b9b35d6ac04c489fe3ba", + "0x000000000000000000000000000000935ae3a5a2c4a7aad8e94a7cf1c4bec70e", + "0x00000000000000000000000000000000002a56488e09fd406c14aca4acf2b4c3", + "0x000000000000000000000000000000e770a6c5c0093eb5de2e5aa8d173e9ef05", + "0x000000000000000000000000000000000005522908d6e06b02d6938a789bb5c9", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000b139df614924ddb845d70d642d94873569", + "0x00000000000000000000000000000000000084d02351f0d2b405f3af6092edc0", + "0x0000000000000000000000000000006c1123c8d14bdfbfa99f95d1fd0d9674f7", + "0x00000000000000000000000000000000002be519d31aea4dac51b16b3655b459", + "0x00000000000000000000000000000035b52a2f19454b2d02086d012cfc44cbdb", + "0x000000000000000000000000000000000027f3e1c4d5482e3b1ebcbc5e43d1d2", + "0x000000000000000000000000000000bc81f2a307249de2d56c3c8151aa3a4179", + "0x000000000000000000000000000000000014745d0c8957b03309ffd69c523944", + "0x000000000000000000000000000000d90966909da4a8611a68a5b2544044ee27", + "0x00000000000000000000000000000000002dda368cf4f8ae011ba33953ccdbdc", + "0x00000000000000000000000000000099fd8e2a4efaa0e979e53c6360f11a3520", + "0x000000000000000000000000000000000029023563407bf604b94f3d3b82e32c", + "0x00000000000000000000000000000095ced0bf10b79aec2651f808812961ce57", + "0x0000000000000000000000000000000000204601f003e0e59d1865597a5cdcd4", + "0x000000000000000000000000000000fd07b0a28f8510ae42eefbbd2d0136dc4f", + "0x00000000000000000000000000000000001e3aba113eb2b6e0d9a07cb16188c0", + "0x0000000000000000000000000000004496315acb001bd07077d5e61a5fd28f1b", + "0x00000000000000000000000000000000001a39ca40a2fdca943fd7c57ea59fc9", + "0x0000000000000000000000000000001a6e9238224f825fbe059c173514ee0fe7", + "0x000000000000000000000000000000000022f701f63bad50d3161322f8d104b3", + "0x000000000000000000000000000000e7cb0e4c388d5b2b1350a0c1b259d7c4aa", + "0x0000000000000000000000000000000000216c09ccaf44298565b3e593e3a7bd", + "0x000000000000000000000000000000d840ba780d73076cfaadb07a9a1a2cad8b", + "0x00000000000000000000000000000000002a887121806c1166b16f3aa9de6716", + "0x0000000000000000000000000000000e3b5cb0fc3e09ea8b4059e2a6109ff857", + "0x00000000000000000000000000000000001794754a1a61af4fa7976eefdac79e", + "0x000000000000000000000000000000dfef9deedb32693d7cc279f72cdc785d1e", + "0x00000000000000000000000000000000000e55622ad6ca63ffde7f64ed504b16", + "0x000000000000000000000000000000d08df7bdd8d57cb1d65728efccbbfcf607", + "0x000000000000000000000000000000000005f2689ecd1c3bf58c28357d95d48a", + "0x0000000000000000000000000000002d7d2927cc7e65b41792f5745ba169663e", + "0x00000000000000000000000000000000002b5f2432471d8c12ea391ac1a0bd12", + "0x000000000000000000000000000000773d8fd379e59dbcbab02af010d195c779", + "0x000000000000000000000000000000000008826f48f7b0250873af38fa8f7500", + "0x0000000000000000000000000000006165595d9a271241c16e0472c174fba8f8", + "0x00000000000000000000000000000000001c673e22bf04c83bddc2f02ebaae36", + "0x0000000000000000000000000000008d6afb067ac5198bb372113d34c56552fa", + "0x00000000000000000000000000000000001e08cbe1d21feee99c841191e54333", + "0x0000000000000000000000000000007646a1a3ca480b5d7322e5e4bb688049f7", + "0x0000000000000000000000000000000000269f2465562733cff2488fe75060fe", + "0x0000000000000000000000000000005524b80d26a1d910532fda24c2383f979b", + "0x000000000000000000000000000000000023bf14a9a6153ade3200bcc787ba79", + "0x00000000000000000000000000000038d56d2f4e530f74fb02bb70d781488b16", + "0x00000000000000000000000000000000001d1731444ac607cb0623133a479871", + "0x000000000000000000000000000000fe08dc45003f859a25494ba5135502e42f", + "0x00000000000000000000000000000000001e6d7c5b53a5e88d78640651a5c6a0", + "0x000000000000000000000000000000ddf4dedac0a43ba687e608b3e6081b8546", + "0x000000000000000000000000000000000004c2446dcf61c32ba4b038fe7365fb", + "0x0000000000000000000000000000004557b361ff0d6568e896319c496fbe24b8", + "0x00000000000000000000000000000000000668a26f50d3354953d4b2766e8020", + "0x000000000000000000000000000000ea507b90f982c43d39d3f699d22b1f7c4a", + "0x00000000000000000000000000000000001429723650e7543325ff8bef1c4ffd", + "0x00000000000000000000000000000049c19043bd4f1ef29d5413b1f118d0f722", + "0x00000000000000000000000000000000001d7ad7b3a27a9bc7992d806af0ebc9", + "0x000000000000000000000000000000f291d1109ea1f48586582a3767b0392cbe", + "0x0000000000000000000000000000000000026df82a517f9dabb3c389c07aebc7", + "0x0000000000000000000000000000000999c4e1d13eba177baf97921ee863ca58", + "0x000000000000000000000000000000000002f7f537a4f96f2ca4eb19a57f0b9f", + "0x000000000000000000000000000000dea34b6c529204f209cd1420a81a3102bb", + "0x00000000000000000000000000000000001c53a430fcbd4b95ffc23b6461fa15", + "0x0000000000000000000000000000005c0cab22cbb5bdccf85116184958790eb4", + "0x00000000000000000000000000000000001b715af5e709bb9f06822082ee3120", + "0x000000000000000000000000000000c77eaa3f49d17dfe395648540f4cd0abc6", + "0x000000000000000000000000000000000007df3cadf5a234989c3f0b92052395", + "0x0000000000000000000000000000009c11b61aaa7a95751ddef148053d00a6e7", + "0x00000000000000000000000000000000000f65d42148106db82a9e434cb19459", + "0x000000000000000000000000000000f99b662c4e3bcd3fdffb75cad5deb632e6", + "0x0000000000000000000000000000000000284f78ec2bc1c17ffa75e285ad4529", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000059a5cd5c1c2d2e7cac107aaf0123ae4f84", + "0x0000000000000000000000000000000000170ffa45422a2680cd492bad46789d", + "0x0000000000000000000000000000003c91ea4fe538abe3c344c3603398af1cbc", + "0x0000000000000000000000000000000000295e7a3f8df6111a6bd51041d5179b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x11197593d62d0e7554158b832253460bcc00da8b6551eb5d955ef72444d95a3f" + +[private_call_0.verification_key_hints] +contract_class_artifact_hash = "0x1d9e0e30582ed207c6ba761454f1f542d807eb0a2b35a50b23297a6db34e3680" +contract_class_public_bytecode_commitment = "0x0ce4c618c3ed7f3a20410e618c06bb701e150af7fe28a3e92f68e7733809f33e" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_0.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x2cc233639ce62adaea3ec034abce91a0b008ca3b50da04eb0789bf1f438162ea", + "0x0f60b735d348fd08a8da88fe4b04361698e2bca73fbebb6cc1fdcb86a4d03c89", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_0.verification_key_hints.public_keys] + npk_m_hash = "0x2f1c4d79837ad500ede908112d4cc2af5d3af9fe982b8628035ccc97f15ee24c" + ovpk_m_hash = "0x1378ed60b21b30e7ad5260606275cd3b580932cef2ed8e95dcc953334277d28f" + tpk_m_hash = "0x25aed22eebf640703b2a68bc209562e3f5c5dadd47925e0bdd41df5e2102fb98" + +[private_call_0.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x17e45034ac640fd73c526836d47063c3158695ecd39fe841bd338ad7acf9f238" +y = "0x2b6dff182f1d814024994bce38d73c4ac9f7587b5e90b8351b08d65e1ed2a7ea" +is_infinite = false + + [private_call_0.verification_key_hints.salted_initialization_hash] + inner = "0x2de7750983e40a640c1540354955cbda141ba8ababbbabb93b83843a4a5c9e18" + + [private_call_0.verification_key_hints.updated_class_id_witness] + leaf_index = "123" + sibling_path = [ + "0x2848a1d7320b3bfb616ba2ff5b175f3dbbe07753e40389d913e60089060bca9e", + "0x0575020764758ac1e237d111ad2129b58c276979d075a2617d047edf1fa0af80", + "0x28d9c1b19a6d32ba2f59b1371ff35722075ccc81c08c306c0b2412697e18a906", + "0x13981cd7447462f1010ec3a2725d09dd4fad76d010fbc2cb1e6eaaf93f680abc", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x02c691e1474ab605965337b84f97e9ac2a34e1214040cf86d9e229f08f4494d5", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_0.verification_key_hints.updated_class_id_leaf] + slot = "0x1f29d351ad8d747c09020ea47be7a38833dccaaf378b55d7d8e6e79f1892c1a3" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x2511fb7ac309f6693b0411aac44ee65c49b46b778d669ad0a19168cc49f93d57" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000082" + +[private_call_1.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000f", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000001ecf", + "0x0000000000000000000000000000004e5d53d6b0dcb727fb0a33d6f23326ba13", + "0x0000000000000000000000000000000000270b1029efbcacf2ba8156be926f36", + "0x0000000000000000000000000000007600c8bfba70975b81933fa1375cc49525", + "0x0000000000000000000000000000000000265b4f40ec4362ecaa6574a26fb9e7", + "0x00000000000000000000000000000002a42259f84697487cf0c806cff78d376b", + "0x00000000000000000000000000000000000a6da882cb12c7c9c8851044af46fd", + "0x0000000000000000000000000000000900fa9df2854c361a2b8ebb4204bc11e2", + "0x0000000000000000000000000000000000143a6867f9c677696dfc6145c0c2c2", + "0x0000000000000000000000000000005c613b43829a134f234301805866bff5c4", + "0x000000000000000000000000000000000013475408680fcccaf629834bd8e7ef", + "0x000000000000000000000000000000d41c74cb34c4413784a7fe1a3282b8ac71", + "0x0000000000000000000000000000000000208a8fea14e1035198fa205027c3aa", + "0x000000000000000000000000000000214caa5099e30bd4a4e7c1e951df172823", + "0x000000000000000000000000000000000010d4ddfb284638abb946bb5ea54ce8", + "0x000000000000000000000000000000b8eccfd963140d75ef69510d499e067c38", + "0x000000000000000000000000000000000022601a5ccbb6f31253dfb90449ea30", + "0x000000000000000000000000000000e62806cc11817d65af2ca51f43374683d9", + "0x0000000000000000000000000000000000217caebd3a47049f39f536f74363dd", + "0x0000000000000000000000000000008675da1f10d0a3ac0694740302e4c151d9", + "0x0000000000000000000000000000000000063c9ac7b0c51b14ea568b914ddb81", + "0x000000000000000000000000000000c849ad93ed5bb6e903001c8afc4d0839cf", + "0x00000000000000000000000000000000000a6b6070a20448dcdfa172b42f4ec2", + "0x000000000000000000000000000000d868ec79d642032bfcb95ae042b6f1ac2f", + "0x000000000000000000000000000000000020a1badffea327b0c2382295e2bf37", + "0x00000000000000000000000000000096a76c0e5d034f551c375f3e163cda5ba5", + "0x000000000000000000000000000000000004377ed9eb4ad9a1f79a2c5f294687", + "0x00000000000000000000000000000026c41b380a9fe2218f43552af149474957", + "0x00000000000000000000000000000000000615923fe00c15504bb1df8742dea4", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x00000000000000000000000000000009f6c6c04f9663d4a48f223d1249b2be6a", + "0x00000000000000000000000000000000002ff1eba1b37fdea02479c1e08d4d9a", + "0x00000000000000000000000000000048eacfade5f40fa7633579d12282f34788", + "0x00000000000000000000000000000000000c1d432a61ced2e150052be1bdcbdc", + "0x000000000000000000000000000000fbb81a2a7bfda945d91e8bbf67859e2558", + "0x00000000000000000000000000000000000c5cf53ad125e9e20a43f4ba1b49e3", + "0x000000000000000000000000000000253f23492f5e66c4a71242b6065814d6be", + "0x000000000000000000000000000000000023aed5cc445240ea7e33642f388c0f", + "0x0000000000000000000000000000004e7b1102cb6629ce1c142b72b28d4121ec", + "0x00000000000000000000000000000000000be005e3dd35052d36f1618a30871c", + "0x000000000000000000000000000000d90c80545e6168100c5b30f2cd3ed03619", + "0x000000000000000000000000000000000025a3812bfb861f4f004b772688f421", + "0x0000000000000000000000000000008e81605a5541040e1f2ec3750c9cc1ad91", + "0x000000000000000000000000000000000022e98685d97495dd44d59443a4ddf7", + "0x000000000000000000000000000000bc71506d95e3eb7ccfc3f274c99ff4b4a7", + "0x0000000000000000000000000000000000164b75e08b8d331120c23eadfca1e2", + "0x000000000000000000000000000000d4cdc90349d20a48a3e8ca44261cc4d5d9", + "0x00000000000000000000000000000000002ca5fac829cab6e119a24a7549cbdd", + "0x0000000000000000000000000000001887ff5bf46b7fefa8e7e305115c8ecb82", + "0x0000000000000000000000000000000000246f6db366525ceafcc2bd631bcdda", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000cd0ea7c07146a4f133bec5927e060bc57", + "0x000000000000000000000000000000000008366b1a0b90d771f72558197500b0", + "0x000000000000000000000000000000511886d35341446044afbc3f131db62ef7", + "0x000000000000000000000000000000000018ed754624197b0ade7b09f979f764", + "0x0000000000000000000000000000002ddab298f8f8f4e5601e3e5b2d0502f5b4", + "0x000000000000000000000000000000000019aaba272386a074151b33e7573b7a", + "0x000000000000000000000000000000526847ceeeeabd41693ed875f287c0172a", + "0x00000000000000000000000000000000000a6ab59df9f9f596112cc75e7ad0e1", + "0x000000000000000000000000000000c7dcabda3081bd36cd3728c290d35f049a", + "0x00000000000000000000000000000000002f5adb48cf156083022ff35b8dea57", + "0x000000000000000000000000000000100d5b11bbd6a432f89a7661ee462f4fd0", + "0x00000000000000000000000000000000000a6db230819796b38024f7ac3652af", + "0x000000000000000000000000000000faf8c3a8115abf040a7987e13562d25823", + "0x00000000000000000000000000000000000766baad18942e49b8513a2598f024", + "0x00000000000000000000000000000065343c030b950f495ef279c3ae6fa8cf8e", + "0x0000000000000000000000000000000000004195275abab416e6285e7fef5c42", + "0x000000000000000000000000000000a4d73493608bf60776185cb54569d37884", + "0x00000000000000000000000000000000000d2294694cde8c2b80f26954c9654c", + "0x0000000000000000000000000000002c883362a20769983f3001e037dadf85aa", + "0x0000000000000000000000000000000000305e619e436bc34d062dd828db185e", + "0x0000000000000000000000000000001a24b6aca234e5b59fee9c5f5799bca8c8", + "0x0000000000000000000000000000000000263d9ec2c0e4fd83010bcf422e073a", + "0x000000000000000000000000000000d5a18905211738ce550bd5df1e6f651e6b", + "0x000000000000000000000000000000000006849a1a5a4ae4bd50b85f57b79ff3", + "0x0000000000000000000000000000007085114bdad689e95391baa4e1199ceb32", + "0x000000000000000000000000000000000016d5d494b1c50f319e77e3be309979", + "0x000000000000000000000000000000258d56a0e151bf30b8744bb9401e8d8e8a", + "0x0000000000000000000000000000000000050dde6b5d9c72348fa2f2095e5ee8", + "0x000000000000000000000000000000676b88185357d24cb206fc939d7a7b13eb", + "0x0000000000000000000000000000000000242d174d168d7f057cc67a38cd4554", + "0x000000000000000000000000000000c9247a8333e75b895693b3a746f9c0fe63", + "0x000000000000000000000000000000000016f81cfda626001669e616e793146c", + "0x000000000000000000000000000000082e949fec7d6423b2c0fb406b2cee538e", + "0x0000000000000000000000000000000000089fd3f1823232561b1b9247fec27b", + "0x0000000000000000000000000000001b70523f6729991b2187b0c6fd61bac5a8", + "0x00000000000000000000000000000000001a1036f5381975fa25b6c7d78cd3d3", + "0x0000000000000000000000000000007b21e17d5b6e5851a9e14e08561b54647b", + "0x000000000000000000000000000000000013f459b5b6220fd49e4b86fa2cf759", + "0x0000000000000000000000000000000abe91579c6b726e246955c9d64a21109b", + "0x00000000000000000000000000000000001318f7e0b6149e80d854e0f175357e", + "0x0000000000000000000000000000004a33bf4661d63052dd2a8aba3a2ca31c6f", + "0x000000000000000000000000000000000018e73a3b131452a25fd8eba6d9bf11", + "0x000000000000000000000000000000b2f9e03f56e553b01741e7797773b63ae0", + "0x00000000000000000000000000000000000e0e1faf47f04536946ea7f4b9add9", + "0x000000000000000000000000000000d4801c1612d60931ff9acaf1c4e3da5f11", + "0x000000000000000000000000000000000024fdcc1a51fe3ff2087b655b20caf5", + "0x0000000000000000000000000000004cbf700c9e4dffe3436c402ef2763a9d82", + "0x00000000000000000000000000000000001ad39a65f5e94beb8f4aa4a4eb72e5", + "0x000000000000000000000000000000ae5f6f0773eea4e72673c43f98f59c77bc", + "0x000000000000000000000000000000000017e6d8fba023937a7c9dcc496f97cb", + "0x0000000000000000000000000000007de8ad390b0d705cd3935bd3b0ab7b4702", + "0x000000000000000000000000000000000020f6d9c94dfee2edb5ffdc6d73a9cb", + "0x00000000000000000000000000000009b9e999e33b4eefa6bf7f32ec014cf07d", + "0x00000000000000000000000000000000000b19c397850a390fae5e2aae8478b7", + "0x0000000000000000000000000000008018e7399b887105f9b220042a598cb537", + "0x00000000000000000000000000000000000dfc609597d01c19940874c4f45ea8", + "0x0000000000000000000000000000007b51a05d7a2c5523f0231f4b47d6602cb0", + "0x000000000000000000000000000000000012d37368bab765c45e538db3ba336b", + "0x0000000000000000000000000000003425dcfe2083a93586c7d4ab95ea10bfc5", + "0x00000000000000000000000000000000002c4225a6d08ba0bc43964a7b93a360", + "0x000000000000000000000000000000141e28a99bfffc1133051bda380a6a2492", + "0x00000000000000000000000000000000000a67f6456af27a15c4cc7bd3cfa3d3", + "0x00000000000000000000000000000078ef6f7fe4e465da00834b45dfdd49d921", + "0x00000000000000000000000000000000002ed6911e528e948d8e9dd33c411ad4", + "0x0000000000000000000000000000004021a31886522f571c4105a3493d4902f5", + "0x00000000000000000000000000000000002c5d54fd117985469cae7c46f00bd2", + "0x0000000000000000000000000000009f4db1d104e923ee0be0180b9481ad7353", + "0x00000000000000000000000000000000001d80d0ccf52aba1ca04d3d93b7465a", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000339b9ff46aac534bec7cbabf748cc261bb", + "0x00000000000000000000000000000000001a79a371ba6e290aae903c62d93d38", + "0x000000000000000000000000000000e8ba9f98cbba842d599752ff3bdb58a1dc", + "0x00000000000000000000000000000000002060d719336689061cd0e72794e35f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x103b5b395e745292eb788f93c2f8700433cdf9b3113e086984e70fd6df2b932b" + +[private_call_1.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_1.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x011238ee64b18828d55242673008fae81f12fc8d61617d35f910c8cb0683f665", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_1.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_1.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_1.verification_key_hints.salted_initialization_hash] + inner = "0x18f60f80bfefaaf0fae5a0505bc6ae3d0240a1bd010a0bc3fe55c20a05c924de" + + [private_call_1.verification_key_hints.updated_class_id_witness] + leaf_index = "134" + sibling_path = [ + "0x04faeb1fbcaba22bb78f190827a5dd614409f548340279badeb318d58f40c003", + "0x22f1b4d319f851468b77a99c6bde547499fc0dafc3676279d0724f0cff0186a2", + "0x02863b9ba1de6f80706d154369db20f4660240d04c2588e80259928737caa007", + "0x072c485f46fea63147c965f3bf2ae2a16a6cef7035c1a8140796c225f7b502b2", + "0x1d52af9cd9f69c1286e9a96fd498e736789a5bc463fceb1c176a4f9292f7cbe3", + "0x1ff1d5db01572c915915a22173c73d8073df9af4e4c57f6af29df5315da44419", + "0x070dcbac794fa663bc71b42d80775c0cea8c3ed7580207cfd30fd1285813ce07", + "0x23133cdd5344591bc2ab830355d7972651d536892416317c4f6ceef63e4eb068", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_1.verification_key_hints.updated_class_id_leaf] + slot = "0x00636bd5b0883a2a1830afcbc6b4b41d16f9639ece8274acc27154705f3b8276" + value = "0x0000000000000000000000000000000000000000000000000000000000000012" + next_slot = "0x01a19f390779d3a125f11b7c60ce770979b067defbc52b8f0f898bbbc3454c6f" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000080" + +[app_public_inputs_0] +args_hash = "0x02486714bcf7b63435b8818a646f5124643019b4d7a09497d20cca8d58ae946d" +returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000002" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" +is_fee_payer = true +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d77eb" + + [app_public_inputs_0.call_context] + is_static_call = false + + [app_public_inputs_0.call_context.msg_sender] + inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + + [app_public_inputs_0.call_context.contract_address] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" + + [app_public_inputs_0.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x2dd746d2f347ebd8d2f591aaf062159b2cceeadb449a919ada77febe9b940e78" +counter = "0x0000000000000000000000000000000000000000000000000000000000000003" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x20f721110cd2674df07fe76cb6f6d43b9704d876ec3a63e8213ccc98a791d3b9" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0603f2bc643a4bf06692b6ea01af9cc928ebf24c8b9f8f359afdc60db9d40e3c" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000000cca003a" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header] + sponge_blob_hash = "0x2f558adc653a6a683f54170a4e3dae8e0d4ba2c84cd9f344d503fe330cb35e31" + total_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + total_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" + + [app_public_inputs_0.anchor_block_header.last_archive] + root = "0x10be4ebc997dc24abc6485ffe1083eece538d2c803bdbbf84a57eb22b99f4e0d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + +[app_public_inputs_0.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" + +[app_public_inputs_0.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_0.anchor_block_header.state.partial.nullifier_tree] +root = "0x2dd3f55fc629452f3b9e9af072058cbb8cdac165fe9b362ccaed7a6ca31fc22e" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" + +[app_public_inputs_0.anchor_block_header.state.partial.public_data_tree] +root = "0x230f9d4acea01315bfa2dd1733846f3f5c6a2e24f73d2c502cac359cb4a64c05" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_0.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c266b" + + [app_public_inputs_0.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_0.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_0.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_0.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_0.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_0.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_0.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1] +args_hash = "0x20f721110cd2674df07fe76cb6f6d43b9704d876ec3a63e8213ccc98a791d3b9" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" +end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000007" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d77eb" + + [app_public_inputs_1.call_context] + is_static_call = false + + [app_public_inputs_1.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_1.call_context.contract_address] + inner = "0x0603f2bc643a4bf06692b6ea01af9cc928ebf24c8b9f8f359afdc60db9d40e3c" + + [app_public_inputs_1.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000000cca003a" + + [app_public_inputs_1.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x187e53c08c6177e7be8e18cd1511a7b02fac95d620a7349072f8c986b4aa193c" + counter = "0x0000000000000000000000000000000000000000000000000000000000000007" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000007" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x27f7908974fa11bc63765f7a1b114d07d9ad578813f4d0bd17d9813ca6b27d7e", + "0x2b4f001ce369a77d37023f59330365467ee04d275c895aedb8694611542d94d9", + "0x08ab102205d6d7cdc51b690d90dbaeae75deee6f290cfd0f16d4f5f76c6c107b", + "0x075fe0ac96f29e3c3fddb3ae675d0b61832a9312d86bc21d7ddd178f2fe7a18b", + "0x1a8d36da37286095e016128c77667d821885a35c428c2a5a8d3d7027613d63b2", + "0x0c2abcb09984b5ac2ff447fb27c9d44680d2d1a7f388309464fd86e54c12096e", + "0x021d186c82a2da8eda6c7dd59d9f5077f63945e66c22a6fdce79703ef90ed0e5", + "0x232182781c34950c9a3d0b394017d4656a64b90b58cf0e6b994573576180df46", + "0x132bd5a7c2d3ca8a3257057b54c8c37152ee21c6c1365b1b9710198ed5212f92", + "0x147ccd354ce72dda084dbb9dc934bc12df8e572aafd7d5ac5a4465bd7b9129eb", + "0x0f1fe8876cf409abae1e327fb730f9b5aa06290c89efb0e95d3eee9c30c8d6fe", + "0x011da20d31c9ab9a33f3c961f804ebfee1d16fb1fbacc4b5a6a84cdc9f976433", + "0x00504bd1efa46596911c37ebd9be8fb98c8061008af020d503b7cb145229aa0b", + "0x1dca533ae55a689ce6546d8e3bc1e37f1db389ddc02fc8819c1db3d2157891e7", + "0x0d7510b19f7d59fc1c93dd530a39b8c5d435c788f840e11d93a55ef03a281009", + "0x1961fbc5069d8d9c5da1d25951827876da2fa0e58de781dc30b3f5da5d9e6621" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000010" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header] + sponge_blob_hash = "0x2f558adc653a6a683f54170a4e3dae8e0d4ba2c84cd9f344d503fe330cb35e31" + total_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + total_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" + + [app_public_inputs_1.anchor_block_header.last_archive] + root = "0x10be4ebc997dc24abc6485ffe1083eece538d2c803bdbbf84a57eb22b99f4e0d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + +[app_public_inputs_1.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" + +[app_public_inputs_1.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_1.anchor_block_header.state.partial.nullifier_tree] +root = "0x2dd3f55fc629452f3b9e9af072058cbb8cdac165fe9b362ccaed7a6ca31fc22e" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" + +[app_public_inputs_1.anchor_block_header.state.partial.public_data_tree] +root = "0x230f9d4acea01315bfa2dd1733846f3f5c6a2e24f73d2c502cac359cb4a64c05" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_1.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c266b" + + [app_public_inputs_1.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_1.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_1.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_1.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_1.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_1.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_1.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-3/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-3/Prover.toml new file mode 100644 index 000000000000..19c3001432f0 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-3/Prover.toml @@ -0,0 +1,5989 @@ +vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" +is_private_only = true +first_nullifier_hint = "0x0376cca63c52eaa5f415738d2b371223600cabef83495b4c6a9e0c3c0a647a3d" +revertible_counter_hint = "0x0000000000000000000000000000000000000000000000000000000000000005" + +[tx_request] +args_hash = "0x0e4a049212502ddf801e6de7e638cc14cfa74a583afb5b0112958f1f263384b0" +salt = "0x1a2fd2df752551a143f27fc16a54deac89bfe6f0a31f8ccf68a1ca86369e72eb" + + [tx_request.origin] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [tx_request.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[tx_request.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[tx_request.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[tx_request.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" + +[tx_request.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [tx_request.function_data] + is_private = true + + [tx_request.function_data.selector] + inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" + +[[protocol_contracts.derived_addresses]] +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" + +[[protocol_contracts.derived_addresses]] +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" + +[[protocol_contracts.derived_addresses]] +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" + +[[protocol_contracts.derived_addresses]] +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" + +[[protocol_contracts.derived_addresses]] +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" + +[[protocol_contracts.derived_addresses]] +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[private_call_0.vk] +key = [ + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000b61", + "0x0000000000000000000000000000007b6222b3a18551d60b847957202de6c8f5", + "0x00000000000000000000000000000000001e26b96548b9f12369e9c3ec0eee85", + "0x000000000000000000000000000000025aac0bbaf1beff1c0500e3ec38d34c8a", + "0x00000000000000000000000000000000002c498aff2f95b25bb92e2c9360aff5", + "0x00000000000000000000000000000039d32590e9d6e0be118712b9402c606156", + "0x000000000000000000000000000000000026588627e22f203f6399975fb67258", + "0x000000000000000000000000000000097282335613efda63abaeaddc915f44db", + "0x000000000000000000000000000000000021b51f545ea031ad8c826962f52545", + "0x00000000000000000000000000000035a0536197418c2ba2c29a1830f709420c", + "0x000000000000000000000000000000000020f8cabd08dfc29e045e0b80eb42d3", + "0x00000000000000000000000000000099e53cda88a63b8e751a2bc253f7a689a7", + "0x0000000000000000000000000000000000231a514e7a4dd0e23c4faf8d567c77", + "0x0000000000000000000000000000002dac12ff4e48e530611ceb7a400c099e4a", + "0x00000000000000000000000000000000001ad1cb6dbbe8ea3dd6c4f44ffdce56", + "0x000000000000000000000000000000dfd19e74f4e4c641b3b3f623825ccd495f", + "0x00000000000000000000000000000000000ce4453cef94251418336baa54e582", + "0x0000000000000000000000000000007ad93fd648d3587168e2ba9ee66dbbf918", + "0x00000000000000000000000000000000000a7680894366d3b1755d14152e528e", + "0x00000000000000000000000000000008bf43eecffcec9e31d916289a212b8f88", + "0x0000000000000000000000000000000000216620e5bd7b177f3fa15ceeb2526e", + "0x00000000000000000000000000000021db86993540e76c420c850640a25f7d94", + "0x000000000000000000000000000000000017418ee5d4d58a54e7728b755757a8", + "0x0000000000000000000000000000000cf5f978296643872c59d00be3c23ad68d", + "0x000000000000000000000000000000000013e45088158c3bf8ac1f8e71eec154", + "0x000000000000000000000000000000768cc857ea136153788ffa81c07daddaf2", + "0x000000000000000000000000000000000014b992148ee6906cb3a1989f3c4bb1", + "0x0000000000000000000000000000000127e074cd6ea24f75f86f3ab119f9ae5d", + "0x00000000000000000000000000000000001719d1f7fc4645193b8036cf9a3d52", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x000000000000000000000000000000622ac3715a21583a169b4c635c162bdc13", + "0x000000000000000000000000000000000012374104ee9056dfafba40f457c0a8", + "0x000000000000000000000000000000f6c09b75f7561f7fbbd272af5d3efa974b", + "0x00000000000000000000000000000000000e0a7bd7a377bca3ff6c89d68a3e5e", + "0x0000000000000000000000000000009d165e9a47e021ab9760d27339570655e5", + "0x0000000000000000000000000000000000000b204b0dc1f11b52bb345fb52145", + "0x000000000000000000000000000000d4c558b53b27cb4c171f8a5eb0bd1e3a2c", + "0x00000000000000000000000000000000002f6870272192d541c1b8887b15a95a", + "0x0000000000000000000000000000008f4c64ade1e7b515b074c100d489415d4c", + "0x00000000000000000000000000000000000f9aca92beccde2e1b08c99ab92a6c", + "0x0000000000000000000000000000008be6976e9870523051d19531843262ce4c", + "0x0000000000000000000000000000000000277419877e0ba35217f219676b5656", + "0x00000000000000000000000000000051ec180d05026f2f62b1674ca2e1a2c142", + "0x000000000000000000000000000000000022264cbd2ea66b7766612864c5108c", + "0x000000000000000000000000000000f137ae2b224915db0c43de1611134011d0", + "0x000000000000000000000000000000000011877af1a2b9b35d6ac04c489fe3ba", + "0x000000000000000000000000000000935ae3a5a2c4a7aad8e94a7cf1c4bec70e", + "0x00000000000000000000000000000000002a56488e09fd406c14aca4acf2b4c3", + "0x000000000000000000000000000000e770a6c5c0093eb5de2e5aa8d173e9ef05", + "0x000000000000000000000000000000000005522908d6e06b02d6938a789bb5c9", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000b139df614924ddb845d70d642d94873569", + "0x00000000000000000000000000000000000084d02351f0d2b405f3af6092edc0", + "0x0000000000000000000000000000006c1123c8d14bdfbfa99f95d1fd0d9674f7", + "0x00000000000000000000000000000000002be519d31aea4dac51b16b3655b459", + "0x00000000000000000000000000000035b52a2f19454b2d02086d012cfc44cbdb", + "0x000000000000000000000000000000000027f3e1c4d5482e3b1ebcbc5e43d1d2", + "0x000000000000000000000000000000bc81f2a307249de2d56c3c8151aa3a4179", + "0x000000000000000000000000000000000014745d0c8957b03309ffd69c523944", + "0x000000000000000000000000000000d90966909da4a8611a68a5b2544044ee27", + "0x00000000000000000000000000000000002dda368cf4f8ae011ba33953ccdbdc", + "0x00000000000000000000000000000099fd8e2a4efaa0e979e53c6360f11a3520", + "0x000000000000000000000000000000000029023563407bf604b94f3d3b82e32c", + "0x00000000000000000000000000000095ced0bf10b79aec2651f808812961ce57", + "0x0000000000000000000000000000000000204601f003e0e59d1865597a5cdcd4", + "0x000000000000000000000000000000fd07b0a28f8510ae42eefbbd2d0136dc4f", + "0x00000000000000000000000000000000001e3aba113eb2b6e0d9a07cb16188c0", + "0x0000000000000000000000000000004496315acb001bd07077d5e61a5fd28f1b", + "0x00000000000000000000000000000000001a39ca40a2fdca943fd7c57ea59fc9", + "0x0000000000000000000000000000001a6e9238224f825fbe059c173514ee0fe7", + "0x000000000000000000000000000000000022f701f63bad50d3161322f8d104b3", + "0x000000000000000000000000000000e7cb0e4c388d5b2b1350a0c1b259d7c4aa", + "0x0000000000000000000000000000000000216c09ccaf44298565b3e593e3a7bd", + "0x000000000000000000000000000000d840ba780d73076cfaadb07a9a1a2cad8b", + "0x00000000000000000000000000000000002a887121806c1166b16f3aa9de6716", + "0x0000000000000000000000000000000e3b5cb0fc3e09ea8b4059e2a6109ff857", + "0x00000000000000000000000000000000001794754a1a61af4fa7976eefdac79e", + "0x000000000000000000000000000000dfef9deedb32693d7cc279f72cdc785d1e", + "0x00000000000000000000000000000000000e55622ad6ca63ffde7f64ed504b16", + "0x000000000000000000000000000000d08df7bdd8d57cb1d65728efccbbfcf607", + "0x000000000000000000000000000000000005f2689ecd1c3bf58c28357d95d48a", + "0x0000000000000000000000000000002d7d2927cc7e65b41792f5745ba169663e", + "0x00000000000000000000000000000000002b5f2432471d8c12ea391ac1a0bd12", + "0x000000000000000000000000000000773d8fd379e59dbcbab02af010d195c779", + "0x000000000000000000000000000000000008826f48f7b0250873af38fa8f7500", + "0x0000000000000000000000000000006165595d9a271241c16e0472c174fba8f8", + "0x00000000000000000000000000000000001c673e22bf04c83bddc2f02ebaae36", + "0x0000000000000000000000000000008d6afb067ac5198bb372113d34c56552fa", + "0x00000000000000000000000000000000001e08cbe1d21feee99c841191e54333", + "0x0000000000000000000000000000007646a1a3ca480b5d7322e5e4bb688049f7", + "0x0000000000000000000000000000000000269f2465562733cff2488fe75060fe", + "0x0000000000000000000000000000005524b80d26a1d910532fda24c2383f979b", + "0x000000000000000000000000000000000023bf14a9a6153ade3200bcc787ba79", + "0x00000000000000000000000000000038d56d2f4e530f74fb02bb70d781488b16", + "0x00000000000000000000000000000000001d1731444ac607cb0623133a479871", + "0x000000000000000000000000000000fe08dc45003f859a25494ba5135502e42f", + "0x00000000000000000000000000000000001e6d7c5b53a5e88d78640651a5c6a0", + "0x000000000000000000000000000000ddf4dedac0a43ba687e608b3e6081b8546", + "0x000000000000000000000000000000000004c2446dcf61c32ba4b038fe7365fb", + "0x0000000000000000000000000000004557b361ff0d6568e896319c496fbe24b8", + "0x00000000000000000000000000000000000668a26f50d3354953d4b2766e8020", + "0x000000000000000000000000000000ea507b90f982c43d39d3f699d22b1f7c4a", + "0x00000000000000000000000000000000001429723650e7543325ff8bef1c4ffd", + "0x00000000000000000000000000000049c19043bd4f1ef29d5413b1f118d0f722", + "0x00000000000000000000000000000000001d7ad7b3a27a9bc7992d806af0ebc9", + "0x000000000000000000000000000000f291d1109ea1f48586582a3767b0392cbe", + "0x0000000000000000000000000000000000026df82a517f9dabb3c389c07aebc7", + "0x0000000000000000000000000000000999c4e1d13eba177baf97921ee863ca58", + "0x000000000000000000000000000000000002f7f537a4f96f2ca4eb19a57f0b9f", + "0x000000000000000000000000000000dea34b6c529204f209cd1420a81a3102bb", + "0x00000000000000000000000000000000001c53a430fcbd4b95ffc23b6461fa15", + "0x0000000000000000000000000000005c0cab22cbb5bdccf85116184958790eb4", + "0x00000000000000000000000000000000001b715af5e709bb9f06822082ee3120", + "0x000000000000000000000000000000c77eaa3f49d17dfe395648540f4cd0abc6", + "0x000000000000000000000000000000000007df3cadf5a234989c3f0b92052395", + "0x0000000000000000000000000000009c11b61aaa7a95751ddef148053d00a6e7", + "0x00000000000000000000000000000000000f65d42148106db82a9e434cb19459", + "0x000000000000000000000000000000f99b662c4e3bcd3fdffb75cad5deb632e6", + "0x0000000000000000000000000000000000284f78ec2bc1c17ffa75e285ad4529", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000059a5cd5c1c2d2e7cac107aaf0123ae4f84", + "0x0000000000000000000000000000000000170ffa45422a2680cd492bad46789d", + "0x0000000000000000000000000000003c91ea4fe538abe3c344c3603398af1cbc", + "0x0000000000000000000000000000000000295e7a3f8df6111a6bd51041d5179b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x11197593d62d0e7554158b832253460bcc00da8b6551eb5d955ef72444d95a3f" + +[private_call_0.verification_key_hints] +contract_class_artifact_hash = "0x1d9e0e30582ed207c6ba761454f1f542d807eb0a2b35a50b23297a6db34e3680" +contract_class_public_bytecode_commitment = "0x0ce4c618c3ed7f3a20410e618c06bb701e150af7fe28a3e92f68e7733809f33e" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_0.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x2cc233639ce62adaea3ec034abce91a0b008ca3b50da04eb0789bf1f438162ea", + "0x0f60b735d348fd08a8da88fe4b04361698e2bca73fbebb6cc1fdcb86a4d03c89", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_0.verification_key_hints.public_keys] + npk_m_hash = "0x2f1c4d79837ad500ede908112d4cc2af5d3af9fe982b8628035ccc97f15ee24c" + ovpk_m_hash = "0x1378ed60b21b30e7ad5260606275cd3b580932cef2ed8e95dcc953334277d28f" + tpk_m_hash = "0x25aed22eebf640703b2a68bc209562e3f5c5dadd47925e0bdd41df5e2102fb98" + +[private_call_0.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x17e45034ac640fd73c526836d47063c3158695ecd39fe841bd338ad7acf9f238" +y = "0x2b6dff182f1d814024994bce38d73c4ac9f7587b5e90b8351b08d65e1ed2a7ea" +is_infinite = false + + [private_call_0.verification_key_hints.salted_initialization_hash] + inner = "0x2de7750983e40a640c1540354955cbda141ba8ababbbabb93b83843a4a5c9e18" + + [private_call_0.verification_key_hints.updated_class_id_witness] + leaf_index = "123" + sibling_path = [ + "0x2848a1d7320b3bfb616ba2ff5b175f3dbbe07753e40389d913e60089060bca9e", + "0x0575020764758ac1e237d111ad2129b58c276979d075a2617d047edf1fa0af80", + "0x197c46bd1868465bea0e1ca4eb0c791d4d43dcfa5ec01979117a2d968636c8f1", + "0x13981cd7447462f1010ec3a2725d09dd4fad76d010fbc2cb1e6eaaf93f680abc", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x02c691e1474ab605965337b84f97e9ac2a34e1214040cf86d9e229f08f4494d5", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_0.verification_key_hints.updated_class_id_leaf] + slot = "0x1f29d351ad8d747c09020ea47be7a38833dccaaf378b55d7d8e6e79f1892c1a3" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x2511fb7ac309f6693b0411aac44ee65c49b46b778d669ad0a19168cc49f93d57" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000082" + +[private_call_1.vk] +key = [ + "0x0000000000000000000000000000000000000000000000000000000000000012", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000d78842d18da378b75ea5ecba09e24ba714", + "0x00000000000000000000000000000000002614d3b3afd5c98cc271bb129aa4bb", + "0x000000000000000000000000000000dcb5d6e5f2dc6a6dafbac3d99e47a24119", + "0x0000000000000000000000000000000000175d55301ed1c5b1c62da959d3fc6f", + "0x0000000000000000000000000000009ee8ccc66f353c3e7bdcd350ac4998dc90", + "0x00000000000000000000000000000000001fa45e6bb1b43b70150d132ad729b3", + "0x000000000000000000000000000000d9f8955545361a6a22980bc0f7b651d7f1", + "0x0000000000000000000000000000000000274fa1311795d3fb681f38da2f4b5e", + "0x00000000000000000000000000000091be5017efe75c83eda91ec4bd1b42baf8", + "0x00000000000000000000000000000000001e1320cf89e65f8059750bd3e6b9de", + "0x000000000000000000000000000000b0e3421324eb3d1e8d315e02dd5e3bb069", + "0x000000000000000000000000000000000020b7707896a1118a547874cd3d80f6", + "0x0000000000000000000000000000005aef4684fb42d4e382c97c38cfd4b843e2", + "0x00000000000000000000000000000000002dc76f6be8447d41aeeb5f8fbe56ce", + "0x000000000000000000000000000000291eaf624ea58ac49bb2966a00767c1bee", + "0x0000000000000000000000000000000000061c5512bff8ca586035bc8c7ccb29", + "0x0000000000000000000000000000005a2c1a95ca457f8a3e52ef27330df96092", + "0x00000000000000000000000000000000001b500485cff873b5722090a4fd39bc", + "0x00000000000000000000000000000045cfcb9dba052df46fd0909a62c7f83a85", + "0x000000000000000000000000000000000013d8218b28b1cefe69df2445eee754", + "0x0000000000000000000000000000004256d472632ec7880e32b87785d837de9b", + "0x000000000000000000000000000000000024fcaff42d72e45ec189cc0b090c08", + "0x000000000000000000000000000000a5998134f404e813099347fbc65e520ffb", + "0x00000000000000000000000000000000002e84db533ec72a5aed8e08c5bb2e4c", + "0x0000000000000000000000000000002c8af6b50cb7b3a1b5c9f42321383ac95f", + "0x00000000000000000000000000000000001b77619171b002d76b7d7084c0c4a3", + "0x0000000000000000000000000000001f74c98dd4249922d3882988a92d23f0a2", + "0x00000000000000000000000000000000001c0b2de307a80de2addfd628a37371", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000009294bfa73402e7d7f181253c64739c4e57", + "0x000000000000000000000000000000000012eb8c51856dd3dac0290a2cf2f2ac", + "0x0000000000000000000000000000003652676c6f29515781b4f2e9107a3ad802", + "0x00000000000000000000000000000000002358ca9e65f12e25d9269a3daa3867", + "0x00000000000000000000000000000010132bea790e06b24ec62c94c9739bf7fc", + "0x00000000000000000000000000000000000b5413bcabe6b86f13aa5e58caefc8", + "0x000000000000000000000000000000f3237b868b577980a9e8c5bfe705c02b3f", + "0x00000000000000000000000000000000001713038b46367ec42e6e3f890c5c9c", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000235c9995c3bdb6ab05bfca8c4049d2c847", + "0x00000000000000000000000000000000000afc8fc26b080a90461cbe02e9a6d0", + "0x000000000000000000000000000000173de4469e782937b09e8dcd77b50d1704", + "0x00000000000000000000000000000000000720f74870fef7ce9c03a59b27c7c7", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000009be835eed95bf0cc42300a68f5358b9bb2", + "0x00000000000000000000000000000000001f34644d7229734b59b90f401278a6", + "0x000000000000000000000000000000e4bb4606126464c38ce411a355feefe834", + "0x0000000000000000000000000000000000090cff50304d6d56f40552fe8fbc43", + "0x000000000000000000000000000000878f9b15b540d6b97936ff6f7fcbc40369", + "0x00000000000000000000000000000000000107632f87301cfc69893652ebff38", + "0x0000000000000000000000000000008b441474e5363738eedbe070487f6777b9", + "0x00000000000000000000000000000000002797248ef1768570cf11bd6c3f2cd5", + "0x00000000000000000000000000000082ead96c117b51634c284d114f577257f4", + "0x0000000000000000000000000000000000147cc59c4e253f962c751eea2813a6", + "0x000000000000000000000000000000d456e249e3d9448cbdcdacd2a882671f52", + "0x00000000000000000000000000000000002981e0bdcc199c7d64806f20b36fa0", + "0x000000000000000000000000000000abfc90b4471135ca2ab8ba7c405edbc4e3", + "0x000000000000000000000000000000000023cfe401afd6bbfa4d35b6007170b4", + "0x000000000000000000000000000000c9ce5aded190329ae1a889665442ad7cd9", + "0x00000000000000000000000000000000000d708b930b128365c05717683bb86d", + "0x000000000000000000000000000000b823096a368099e4a5d6862151a7549148", + "0x00000000000000000000000000000000000d503250145a3efda57c6d32a4908a", + "0x000000000000000000000000000000f17e7bf93cfb998cd43bbd2ad3050125b9", + "0x00000000000000000000000000000000000930e7a51e277067f5271e46dc1252", + "0x00000000000000000000000000000038cfe8a840de63616a7362610bd3578168", + "0x00000000000000000000000000000000001c8141e7febc0876e0fe25d2579d62", + "0x000000000000000000000000000000152c755dee390a0c43ebf06a142061bd1e", + "0x00000000000000000000000000000000002c55e5fe44bef19e878f10b91e109d", + "0x000000000000000000000000000000ed38501369c52c2d563fdee920fa81afed", + "0x00000000000000000000000000000000002c0040967b7c6a962ddbb2773e40ac", + "0x0000000000000000000000000000008b720a162b659c1d6b99ff7f5ea1943bf0", + "0x00000000000000000000000000000000002037f64217f765367a73dc8809a402", + "0x000000000000000000000000000000333ce1795d12def27b282c7e9d940377d1", + "0x0000000000000000000000000000000000222e04a026255b1716e250489c02be", + "0x0000000000000000000000000000000fb2c89741afacaee5671840d555ee6200", + "0x00000000000000000000000000000000002b8b656e09e7a782aedb62ab07c4de", + "0x000000000000000000000000000000b8d83eee65d8da3867d44e479895cd3885", + "0x0000000000000000000000000000000000005290388f5c314efc8786ca753020", + "0x000000000000000000000000000000d962ca29ad326f0ca366e48b1094c90ba6", + "0x00000000000000000000000000000000002667dc84b31ddb50e7cbe8117469e1", + "0x000000000000000000000000000000edf193bc38e0bde8a4247cb94aac7c3453", + "0x0000000000000000000000000000000000130e46d1e5b5054183bbf59f75d5f1", + "0x000000000000000000000000000000d76ec7bf0b5b79acbcfa8fdcc4b7e1f43e", + "0x0000000000000000000000000000000000205b8db525acd7ad31210b279cf5aa", + "0x000000000000000000000000000000fa94df30aa6642a201c24b4ff9c513e7b4", + "0x000000000000000000000000000000000020ea9468339e4a650306e096fc7eb8", + "0x000000000000000000000000000000b67f58244f388df32f1c53d4e80d390c72", + "0x00000000000000000000000000000000001566a4116792031cf65c94bdfe703e", + "0x000000000000000000000000000000a6a0281f1c337f8b6e2c2ceb786ee11a82", + "0x00000000000000000000000000000000000921dbb00839427d1bbf18977b5e90", + "0x00000000000000000000000000000031e8e63905e4a45e4933e971d14318e6eb", + "0x00000000000000000000000000000000001e0193b93c681de90ee266c1c96ea9", + "0x0000000000000000000000000000002b5e19e56d15c9e6b6fe9067ee99196975", + "0x00000000000000000000000000000000002ad08af4cdb0b92223ccf588748fa6", + "0x0000000000000000000000000000003e5a1bd944e4c82fa00876f1dab8617c72", + "0x00000000000000000000000000000000001adc187328e0e2842fee7ba44727cc", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000a4bc612c9919e31850cacbdb2c0ebee136", + "0x00000000000000000000000000000000000a68940d7f098fcba91e5d2543efc5", + "0x000000000000000000000000000000c2036981811af6499bb28cf5780bff85a0", + "0x00000000000000000000000000000000001d7867c0364339f803e83b9073fe73", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x1531ed0e20d6d05f1aeb06f746c8c4b8f467174836d6edf915b0c45099b393ed" + +[private_call_1.verification_key_hints] +contract_class_artifact_hash = "0x23e12e098d940ef2795fc61735ed268fdd624134af96a39ec20efd4da8253a5a" +contract_class_public_bytecode_commitment = "0x0ce4c618c3ed7f3a20410e618c06bb701e150af7fe28a3e92f68e7733809f33e" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_1.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x0b63a53787021a4a962a452c2921b3663aff1ffd8d5510540f8e659e782956f1", + "0x1eeeb8fb2c3d5ed2bdeb4545deda4551d41e22e63ebfe4e47e98d83847870dc9", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_1.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_1.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_1.verification_key_hints.salted_initialization_hash] + inner = "0x28acc8124b398dcb4bfe1e23a886d244156df682b7bc2ee00132e80e21ade98d" + + [private_call_1.verification_key_hints.updated_class_id_witness] + leaf_index = "119" + sibling_path = [ + "0x0367624bc197266ce056aec8d19a5f089edceb4f0901727a0b128da357b67e1b", + "0x25e343ef927ea3980db5fdc788830d0b84a1dc80052cfac2dec9f5666716bfe9", + "0x2523970382de270c1acd87f98b4ed454353257f9c689dc608f7dc1b6ca23741a", + "0x06e7dff9596de301b2b1de0d823f50f5d5b7eec918ba502edd702a3b4351da32", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x02c691e1474ab605965337b84f97e9ac2a34e1214040cf86d9e229f08f4494d5", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_1.verification_key_hints.updated_class_id_leaf] + slot = "0x15d83fc6aef4d33787e8b2f45f47282217f56eedafe4c3456f98211053ee38af" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x18d8563211a45773494e257e92d4c8fdac1d0d7d4d533ac158523f4e37744230" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000083" + +[private_call_2.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000939ecc7e0238ba4538d07d06515106b715", + "0x000000000000000000000000000000000027f7faae22e35882db334002325b9a", + "0x0000000000000000000000000000005b7135656f7af02984fc29f460c2a39618", + "0x000000000000000000000000000000000015221e93ac7028e30bbf11170c8af7", + "0x000000000000000000000000000000d725982b5326885c8dbd7db7737acde886", + "0x0000000000000000000000000000000000096c86aff7dc8e83432bf71d155e54", + "0x000000000000000000000000000000b52a552f2377e7ad8de1275a5fab15b09c", + "0x00000000000000000000000000000000002921048ee5922f5021bf3414d233cb", + "0x000000000000000000000000000000c7cf0ad69cb6b47c7f5a005582eb4c0d5c", + "0x0000000000000000000000000000000000088d4215fd4cb39439928a35c36826", + "0x000000000000000000000000000000fa0549dd5c225f4523cd33dfdaa35a6d08", + "0x00000000000000000000000000000000001a5c6875705097231840579a7abe46", + "0x000000000000000000000000000000a53e503273acac0c370811e406798da8cb", + "0x0000000000000000000000000000000000263d9dd6253344f0b0f0d32aebd392", + "0x00000000000000000000000000000077fce21217a229537a0fe2347b7497c667", + "0x00000000000000000000000000000000002bc83252d459bcaa9a65d5f851ebc1", + "0x000000000000000000000000000000582db2c2b5419a8949d4a040faaae2d90c", + "0x0000000000000000000000000000000000272efacb35c7e6ef1b1c87b23b1986", + "0x000000000000000000000000000000c56053e996805d61c3087f426b76d05d91", + "0x00000000000000000000000000000000001a5dde0d931482170055089c35182d", + "0x0000000000000000000000000000005b20c5c214ec1bac8c86b04411d459ec25", + "0x0000000000000000000000000000000000059b95f533b5615af11b06773f3559", + "0x0000000000000000000000000000008ab521c6ee63c1f56d3e0e05cb23080a98", + "0x0000000000000000000000000000000000055c3afbbd2da250ac604a24bb2ef9", + "0x000000000000000000000000000000b02119ad4ce7d63abb9510f1ddff318823", + "0x000000000000000000000000000000000029a492a4d6587d8589814704f58870", + "0x000000000000000000000000000000e7c4b069553db68acdd0c13aec0d682052", + "0x00000000000000000000000000000000000fdedea57a1d5532c8074aa04fa4b1", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000c1324a637ac6aa9cce6d2f9458f6dfb351", + "0x0000000000000000000000000000000000091b6347806ddbaffc97bddc7a30dd", + "0x000000000000000000000000000000fe95016d73b67c279bba4e66e8d9703537", + "0x000000000000000000000000000000000005f0d9f14086df89040735f71fa7b7", + "0x00000000000000000000000000000005efa022dc2e8eb479b2b78d83c8765d5e", + "0x000000000000000000000000000000000018619d74d1bcaa0904107337bd012e", + "0x0000000000000000000000000000007546da679d2f3fa476de4b4caac4f8e720", + "0x0000000000000000000000000000000000022c0dbbf61f2b793f2d7e1a14f7ea", + "0x000000000000000000000000000000377837418627c78b9c5581cc090fa58e38", + "0x00000000000000000000000000000000001382a8f9f8f16c26c6fb5623a58a6e", + "0x0000000000000000000000000000000e6b1306d2ee4c0e782f794233e8cbef0e", + "0x000000000000000000000000000000000015b08ca4c24b72dce50f64314d5da9", + "0x0000000000000000000000000000008cb1ed0e54e2be1b693e7930db7cb80ab3", + "0x0000000000000000000000000000000000239d76e639d9cdf7dfabf6c51f899c", + "0x0000000000000000000000000000000ae1f82ad50cbd733f08e432946514a350", + "0x0000000000000000000000000000000000295d7b2a57a16c715033860938fd50", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e24abed3d841d011ef73411a094875efcb", + "0x0000000000000000000000000000000000214dda13d13241bacb5802308722ac", + "0x000000000000000000000000000000e199a3fb1785a3aec260f70f8e375a1a2b", + "0x0000000000000000000000000000000000069692a44d75d315feef84b77236e2", + "0x000000000000000000000000000000f14079d90bffc6fbec385022d0458981ad", + "0x0000000000000000000000000000000000061e4d15aea9c20c425c89f3f2fb4d", + "0x000000000000000000000000000000bc69945a1c97d6970f8069c46e47282b46", + "0x00000000000000000000000000000000002756f7fde3edd1c8f306f63df0237c", + "0x0000000000000000000000000000003697ab9c36685cc97805a81d7d2c9135b6", + "0x00000000000000000000000000000000002dfe72fbb64b8bf80041637521df7f", + "0x000000000000000000000000000000ba93cf80ee63038d9cbb53e8028c2171b2", + "0x00000000000000000000000000000000000d1cfd416d77e90cebf25b135b75c7", + "0x000000000000000000000000000000b8d64485c600b5bdc5aeaf70405edf46a8", + "0x0000000000000000000000000000000000211e94dafb97ac2bf1fc042e75e30e", + "0x0000000000000000000000000000007b3535533bf23ebc5e93f72f3178e40167", + "0x00000000000000000000000000000000000297f06e65bd27d0af59e48e282d13", + "0x000000000000000000000000000000e1575bec02ddb89a48eb03929177e08295", + "0x0000000000000000000000000000000000129d4383c4e0b52d70655b8f6dd3c1", + "0x000000000000000000000000000000c20bd4ea75f38d2e6b41161274a4a9bff9", + "0x00000000000000000000000000000000000d10237adc48d09824b74c0bf30af8", + "0x0000000000000000000000000000005bc3d742bc3521ee9bfd22eca4fe041d4f", + "0x00000000000000000000000000000000000dd34305439efd31d8f1069f2f1298", + "0x000000000000000000000000000000724a171fe6ee9412cdc4f2ff3d25849659", + "0x00000000000000000000000000000000001ae910663d2ca08ca35718d11c7ebf", + "0x00000000000000000000000000000075ffa7853e4e65151b0a07a653a4deff20", + "0x00000000000000000000000000000000002a899e407fe87d860ec446a9b9d50e", + "0x0000000000000000000000000000009f811b594a5ca4e03abfac98d71c4cad52", + "0x00000000000000000000000000000000002c4577b0ffa13c22944caeef4aeb7b", + "0x000000000000000000000000000000b22122da5120631c81ae7c090fab5c4eb4", + "0x000000000000000000000000000000000014ddbc63b8e87cf38d5f1bdedf8932", + "0x000000000000000000000000000000e79feec7013b1298f980ee48a3951c46ea", + "0x0000000000000000000000000000000000144a09988130e955b0f991671fc734", + "0x000000000000000000000000000000fccadf005dcf11dfae7e16251da139c64c", + "0x00000000000000000000000000000000000e2455a5b1f5bb6808f9c69e1b4b83", + "0x000000000000000000000000000000cad73f1e10fe30f6c3c6604462a9ad39e5", + "0x000000000000000000000000000000000023af407ebb2ebbb916b19f5e1806bd", + "0x000000000000000000000000000000358c8f99a29f2dcc8d936d1537bb16215f", + "0x00000000000000000000000000000000002f321ab6de1f6a2c179488e418d570", + "0x000000000000000000000000000000fc501808c7eeac2a8f1a94ba2d24be4281", + "0x00000000000000000000000000000000000abc0fe411716883c4a7cd5df8c5af", + "0x000000000000000000000000000000ea4b9a97a081f3d16f86c349dc23079367", + "0x00000000000000000000000000000000000a9606176049cae0de6c5847c80222", + "0x00000000000000000000000000000061d6ccdec76d72dc64ada1a81f788664c1", + "0x00000000000000000000000000000000000c0408321acfdf3367b63b83b33a9e", + "0x000000000000000000000000000000c570f10738530d83d30ed979bbc4acbf18", + "0x0000000000000000000000000000000000157eccb3d3c1c095eb8edbeec669b4", + "0x000000000000000000000000000000aab92fa5f685cbf4f8720464e2232dbe5e", + "0x00000000000000000000000000000000002c51b29180e84ca25a542c74b13be9", + "0x000000000000000000000000000000bf4ae6cdd940147e48440e3155e3e4d90b", + "0x00000000000000000000000000000000002068fd4b37ed9dc0f51780c6bbc319", + "0x00000000000000000000000000000010b17735f490af682367ecbaea8f46ede8", + "0x000000000000000000000000000000000023783618dae8e3dad244ee5b4fa5bf", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006cbfd45394e5c611c0c1ce272ee3cc6e47", + "0x0000000000000000000000000000000000224fe3dc1b6636cee421f29842b37a", + "0x0000000000000000000000000000003dae50a4473ffe62298a434d706481e6c8", + "0x00000000000000000000000000000000001c6855a0c6a537f41c9ed7a5c1b7e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x073f4bb2a667f5058abfb94949c5a8d5b1977df83de82a05390a90f8bb420751" + +[private_call_2.verification_key_hints] +contract_class_artifact_hash = "0x114be567f8aa3cadf98ceedfadbe6edb25681584cfdda8dd44acf0437b1ddc54" +contract_class_public_bytecode_commitment = "0x260735cf6645c6f07d2f0ebe2bfbd3062e95ddc820661329a5422bc239261bba" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_2.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x0b63a53787021a4a962a452c2921b3663aff1ffd8d5510540f8e659e782956f1", + "0x1eeeb8fb2c3d5ed2bdeb4545deda4551d41e22e63ebfe4e47e98d83847870dc9", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_2.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_2.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_2.verification_key_hints.salted_initialization_hash] + inner = "0x0afe58e6645b396d31e0de341c28e73e0eee8c2d5fa7bd89a905a8c77cfc45b7" + + [private_call_2.verification_key_hints.updated_class_id_witness] + leaf_index = "134" + sibling_path = [ + "0x04faeb1fbcaba22bb78f190827a5dd614409f548340279badeb318d58f40c003", + "0x22f1b4d319f851468b77a99c6bde547499fc0dafc3676279d0724f0cff0186a2", + "0x02863b9ba1de6f80706d154369db20f4660240d04c2588e80259928737caa007", + "0x072c485f46fea63147c965f3bf2ae2a16a6cef7035c1a8140796c225f7b502b2", + "0x1d52af9cd9f69c1286e9a96fd498e736789a5bc463fceb1c176a4f9292f7cbe3", + "0x1ff1d5db01572c915915a22173c73d8073df9af4e4c57f6af29df5315da44419", + "0x070dcbac794fa663bc71b42d80775c0cea8c3ed7580207cfd30fd1285813ce07", + "0x1e40bcb76d2b688cff569abcc238c9f6bc9960fa9b07dd12652117fe819b1626", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_2.verification_key_hints.updated_class_id_leaf] + slot = "0x00636bd5b0883a2a1830afcbc6b4b41d16f9639ece8274acc27154705f3b8276" + value = "0x0000000000000000000000000000000000000000000000000000000000000012" + next_slot = "0x01a19f390779d3a125f11b7c60ce770979b067defbc52b8f0f898bbbc3454c6f" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000080" + +[app_public_inputs_0] +args_hash = "0x0e4a049212502ddf801e6de7e638cc14cfa74a583afb5b0112958f1f263384b0" +returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000002" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" +is_fee_payer = true +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d700b" + + [app_public_inputs_0.call_context] + is_static_call = false + + [app_public_inputs_0.call_context.msg_sender] + inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + + [app_public_inputs_0.call_context.contract_address] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" + + [app_public_inputs_0.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x2dd746d2f347ebd8d2f591aaf062159b2cceeadb449a919ada77febe9b940e78" +counter = "0x0000000000000000000000000000000000000000000000000000000000000003" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0ebd7eba73dc20bf082971c1d7211dc1ea94d1955f3f8bdfcb6ffe5555dfb502" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000006934ed0d" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0e251fbf263324b797960cb40a76612db073a017b0c373f8bcad29f31877b767" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000e" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x00000000000000000000000000000000000000000000000000000000a59b4137" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header] + sponge_blob_hash = "0x0536a4ab22763da9987147107b1502cd6c0f5100c5057af90cc913dfb7555a97" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" + + [app_public_inputs_0.anchor_block_header.last_archive] + root = "0x07b049e8df80c5fcaf98c5f5e83697da80766abb0aed71e3e8269717cdf0ce8d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" + +[app_public_inputs_0.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" + +[app_public_inputs_0.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" + +[app_public_inputs_0.anchor_block_header.state.partial.nullifier_tree] +root = "0x2b5af9d9cfd13b27d7e5971722fd8e4139011ea9f30375f3e2bd633d64e7293f" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_0.anchor_block_header.state.partial.public_data_tree] +root = "0x17494afd96414c3d5543c103ea394725d765efb8b615fcbb273725c82a6d2e68" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_0.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c1e8b" + + [app_public_inputs_0.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_0.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_0.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_0.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_0.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_0.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" + +[app_public_inputs_0.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1] +args_hash = "0x0ebd7eba73dc20bf082971c1d7211dc1ea94d1955f3f8bdfcb6ffe5555dfb502" +returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" +end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d700b" + + [app_public_inputs_1.call_context] + is_static_call = false + + [app_public_inputs_1.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_1.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [app_public_inputs_1.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000006934ed0d" + + [app_public_inputs_1.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000007" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + + [app_public_inputs_1.contract_class_logs_hashes.array.inner] + value = "0x242b9549d1e2c420a764a5aa2ba58d98b77e35fef8ffa5aa787f9b325f2b5005" + length = "0x0000000000000000000000000000000000000000000000000000000000000068" + + [app_public_inputs_1.anchor_block_header] + sponge_blob_hash = "0x0536a4ab22763da9987147107b1502cd6c0f5100c5057af90cc913dfb7555a97" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" + + [app_public_inputs_1.anchor_block_header.last_archive] + root = "0x07b049e8df80c5fcaf98c5f5e83697da80766abb0aed71e3e8269717cdf0ce8d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" + +[app_public_inputs_1.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" + +[app_public_inputs_1.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" + +[app_public_inputs_1.anchor_block_header.state.partial.nullifier_tree] +root = "0x2b5af9d9cfd13b27d7e5971722fd8e4139011ea9f30375f3e2bd633d64e7293f" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_1.anchor_block_header.state.partial.public_data_tree] +root = "0x17494afd96414c3d5543c103ea394725d765efb8b615fcbb273725c82a6d2e68" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_1.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c1e8b" + + [app_public_inputs_1.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_1.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_1.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_1.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_1.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_1.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" + +[app_public_inputs_1.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2] +args_hash = "0x0e251fbf263324b797960cb40a76612db073a017b0c373f8bcad29f31877b767" +returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000e" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d700b" + + [app_public_inputs_2.call_context] + is_static_call = false + + [app_public_inputs_2.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_2.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [app_public_inputs_2.call_context.function_selector] + inner = "0x00000000000000000000000000000000000000000000000000000000a59b4137" + + [app_public_inputs_2.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15" +counter = "0x000000000000000000000000000000000000000000000000000000000000000b" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x000000000000000000000000000000000000000000000000000000000000000c" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0603f2bc643a4bf06692b6ea01af9cc928ebf24c8b9f8f359afdc60db9d40e3c" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x000000000000000000000000000000000000000000000000000000000000000d" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x174c6b3d0fd14728e4fc5e53f7b262ab943546a7e125e2ed5e9fde3cf0b3e22f", + "0x0603f2bc643a4bf06692b6ea01af9cc928ebf24c8b9f8f359afdc60db9d40e3c", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x1032ac682578d498c2288d1726fd4eafc40634ef1248e4a0218d27e98013091c", + "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", + "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", + "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", + "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", + "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", + "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x000000000000000000000000000000000000000000000000000000000000000d" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.anchor_block_header] + sponge_blob_hash = "0x0536a4ab22763da9987147107b1502cd6c0f5100c5057af90cc913dfb7555a97" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" + + [app_public_inputs_2.anchor_block_header.last_archive] + root = "0x07b049e8df80c5fcaf98c5f5e83697da80766abb0aed71e3e8269717cdf0ce8d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" + +[app_public_inputs_2.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" + +[app_public_inputs_2.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" + +[app_public_inputs_2.anchor_block_header.state.partial.nullifier_tree] +root = "0x2b5af9d9cfd13b27d7e5971722fd8e4139011ea9f30375f3e2bd633d64e7293f" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_2.anchor_block_header.state.partial.public_data_tree] +root = "0x17494afd96414c3d5543c103ea394725d765efb8b615fcbb273725c82a6d2e68" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_2.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c1e8b" + + [app_public_inputs_2.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_2.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_2.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_2.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_2.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_2.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" + +[app_public_inputs_2.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/Prover.toml index 11d2e8ee0b13..2c9c13b491fc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/Prover.toml @@ -1,18 +1,18 @@ -vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" +vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" is_private_only = false -first_nullifier_hint = "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef" +first_nullifier_hint = "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb" revertible_counter_hint = "0x0000000000000000000000000000000000000000000000000000000000000005" [tx_request] -args_hash = "0x2237e42a84e35fc9371ec568e04d6db13130f02f527e0cce6f78ebf038f70f5f" -salt = "0x0dcc552c9a204fa5c60481076f34e420fdd64d81a8c273ad1c336f00b6912f8c" +args_hash = "0x04a65dff28c7219e24a65785e4145db8afe036681c48c8348314e2eeba1c56d3" +salt = "0x2ebfaeadfb0e170b136b798638f54796e2ba938a2566a404a6ef114a7313194e" [tx_request.origin] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [tx_request.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [tx_request.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -37,22 +37,22 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" [[protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -73,152 +73,152 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key = [ "0x0000000000000000000000000000000000000000000000000000000000000010", "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000b81", - "0x000000000000000000000000000000323d5a3bacf46ff720167bfa82f1d3a470", - "0x00000000000000000000000000000000000109869e9ff89595121baa1badc56f", - "0x00000000000000000000000000000028564096270cb8849cc3552446a7787f44", - "0x00000000000000000000000000000000002c0182a1646ff1fe580199388a6e67", - "0x000000000000000000000000000000e207084f39d03f0b9d49d65a831a476bdc", - "0x00000000000000000000000000000000002aac72303765a3fadee7fa1db1be05", - "0x0000000000000000000000000000005e8598ff5e2c6cd7dc473187b18a60e56e", - "0x00000000000000000000000000000000002a412cc07438f09a0dd6201ad2c845", - "0x0000000000000000000000000000005946521ae9065d5a2f1e7016a837d41720", - "0x00000000000000000000000000000000000ea66d443ec8deb6a04dc4f974a8e0", - "0x0000000000000000000000000000006d72fbabcf2fb19129b47b1cea05b6fbea", - "0x0000000000000000000000000000000000093da4177e03b9ceffde6bfcba715b", - "0x00000000000000000000000000000073b9e515320060a26b76a2585026e35095", - "0x00000000000000000000000000000000001d0acd33c22a462a2f19a01731d7d1", - "0x000000000000000000000000000000ddce5c2135081e4f770a66abb583c2d173", - "0x0000000000000000000000000000000000157776c2b29efb55f9a8431e76ae1c", - "0x0000000000000000000000000000001bca989328d1c9116bb16813323cecba31", - "0x00000000000000000000000000000000001b5dc4ef90e0723fdc7945ef4c54ce", - "0x0000000000000000000000000000004e18c66149c3b7ac47179461f6e195cc80", - "0x00000000000000000000000000000000001281bbcfe7ef0f2fccf4cd92272414", - "0x0000000000000000000000000000003c8e508f2ffeb91e6f3f83c3f6c86d56ba", - "0x0000000000000000000000000000000000064d022b5e2c394f45dcd33af07326", - "0x00000000000000000000000000000002cafc1f9a92a5ee32f170622efede1b43", - "0x00000000000000000000000000000000000aceb2867aa9d36e777e91c8af94e4", - "0x0000000000000000000000000000009de7a9cc413e4291453c88d92591e15064", - "0x00000000000000000000000000000000002a99adc4aea9cf55b7adb21dc2d7b5", - "0x000000000000000000000000000000c5c063499d6beb3c15a568f0eb3b9accfb", - "0x0000000000000000000000000000000000085343e51f8e54f7e4b3bca5b8ccdb", - "0x0000000000000000000000000000004df9e2c11487e96cde4a354328c2322b7e", - "0x00000000000000000000000000000000001e71380507bf8f7a65f542a668967e", - "0x000000000000000000000000000000387a87e1fd5a4d755a72bf4223e72cf175", - "0x0000000000000000000000000000000000140d1d6145c78a4cd60b85534d174f", - "0x00000000000000000000000000000009dd5aa20682fbbc7e632f8a1db534e9b3", - "0x00000000000000000000000000000000000634427a3afc7faeb13b2d9dfb819f", - "0x000000000000000000000000000000b4197b6332dcded183750122f25b0a2519", - "0x000000000000000000000000000000000027607abc7388bbdbd2d7f96188fbb4", - "0x00000000000000000000000000000003d113f92b1cd5b3ff63420794e03ef685", - "0x0000000000000000000000000000000000207b2aef1ef8b28ace8c83aecf7e28", - "0x000000000000000000000000000000450f7e6b497cd2a96ae6b92be64fae5c6b", - "0x00000000000000000000000000000000002120f64101472951f06f632de5145f", - "0x000000000000000000000000000000debece59d8788da9e5f8d8dc220168c1d2", - "0x000000000000000000000000000000000015786f0aad65395b2bc4b537336ede", - "0x00000000000000000000000000000060a0d6c54c73c3690cecc86bddbfbcc42b", - "0x000000000000000000000000000000000000e01e5f4b5f9c61b6b572d6a489a8", - "0x00000000000000000000000000000051925bb85f77dc843e87768cad13898c66", - "0x00000000000000000000000000000000001d2e8c943486f2d8077ca3a545e58e", - "0x0000000000000000000000000000001eae3f40b556ff78fd87a9f0bf9835f121", - "0x000000000000000000000000000000000001a9ddb01e083df4fa7944b38b1d66", - "0x0000000000000000000000000000000a71144260f9510eea1b6b164635f58a85", - "0x00000000000000000000000000000000002450da73f6d16c22bbfee6979c1aa5", - "0x000000000000000000000000000000a05fce07c3de8206138c6fff56b0384a77", - "0x00000000000000000000000000000000001413ce1460c3807fa23afc23048488", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000fa598d6d181474b0f0bc69f2183b523e80", - "0x00000000000000000000000000000000000d8c40ab9e154226f73e321ea0aadd", - "0x000000000000000000000000000000d279bcf5f49b4e581e307f708085120acc", - "0x00000000000000000000000000000000000b7a923678250450f635555bd4cd46", - "0x000000000000000000000000000000cc727ba574f665e0eb1b68de979a694028", - "0x00000000000000000000000000000000000a6f019b23bb4dc91aa9fa1c549e8f", - "0x00000000000000000000000000000048e4410bd774618ebb93dddc7ad9cb3ea4", - "0x000000000000000000000000000000000023dd18195483e82d97eb518a8c3ba4", - "0x000000000000000000000000000000bb65ab115ceeb8fb08e90f292f09d0cef2", - "0x00000000000000000000000000000000000eb1879efc776a7cac9ccb88550a4f", - "0x0000000000000000000000000000001d331e0112dd2d8cd8ce94e7b32843751b", - "0x000000000000000000000000000000000011e69febc35e19e3d67d16f534ec53", - "0x000000000000000000000000000000919614fa3ba8ef2dacf8ea9a6805df8e9f", - "0x000000000000000000000000000000000021f21cdf5a4aa72e8ff57923e8543b", - "0x000000000000000000000000000000708a9164194ce14fac9d0386a3adcb4bc0", - "0x000000000000000000000000000000000028d7bc88df3ad73259787bf5d7d01a", - "0x0000000000000000000000000000002964cf46a5183cb04145d9a8b439a32df1", - "0x00000000000000000000000000000000001539ee0fec0781bc1760b30e479b1e", - "0x000000000000000000000000000000ba5f4a89c83775cb92fcc3ff4c358a7553", - "0x00000000000000000000000000000000002640734ef86775f76d689e95814fc3", - "0x0000000000000000000000000000009c2f263653c7e2af7401216151678eade5", - "0x000000000000000000000000000000000022cac24cb9b9c0bd20263c02178a74", - "0x0000000000000000000000000000009b91b2b9cd766ab9d54d4e0ce5b31b2df9", - "0x000000000000000000000000000000000021feeed9c2bbeaf1b31b97bd475898", - "0x000000000000000000000000000000b167db6919d49e56465b96227e40c83b61", - "0x00000000000000000000000000000000001382f4cd681ca5a3b409cc27c9622f", - "0x0000000000000000000000000000004459ed40f5cbfa7d6a37b8ea44d6cbd6dc", - "0x00000000000000000000000000000000001bd5f7d5688bb20ed13a7d6c96ef7a", - "0x000000000000000000000000000000ca992efecefafda29e202a7a347d81367e", - "0x00000000000000000000000000000000001db9c5d73ac26232863ae012269306", - "0x0000000000000000000000000000008ee5b3d7b16d5fe16702aa8885d4b96219", - "0x00000000000000000000000000000000000e59f4b3fd78b0fb4ac7e9c2172cb4", - "0x000000000000000000000000000000ae1a100ea1870b38b32d117cfddb7963f6", - "0x00000000000000000000000000000000002e373869e16038a011dcbd14cd4f01", - "0x0000000000000000000000000000005a5fe1304e6aeac934bddd72a03ebc626b", - "0x00000000000000000000000000000000002a21976f3e8487fb635ad21e9ffe2c", - "0x000000000000000000000000000000217dfe935e944ba7075acde9faa6cb5173", - "0x00000000000000000000000000000000000e5ad22ef54fc104806cd546d25b9a", - "0x000000000000000000000000000000d0760a836a218a69ae33c7172912f1d331", - "0x0000000000000000000000000000000000248701194b3dad90a302030dd3ed4c", - "0x00000000000000000000000000000015771863f13527395472cdbefc01ce7d50", - "0x000000000000000000000000000000000025b39680b4a83bfcbb03bbef9286d9", - "0x00000000000000000000000000000015172ac2d95099e3de8feae18d349ed077", - "0x00000000000000000000000000000000002f0e6eb33c7a8589eb4aa0a58e4948", - "0x000000000000000000000000000000bc4ffdb2d7a1280fc2ce31024a5f4028f8", - "0x00000000000000000000000000000000000f8b150ff8204297433768c07af62b", - "0x0000000000000000000000000000003b337a09da46d718fdbb452d16e1c3355f", - "0x0000000000000000000000000000000000209451e38476922aff2f5e89d9050c", - "0x0000000000000000000000000000003204c8b80470419acd48ab8cfc4ee4edcd", - "0x00000000000000000000000000000000000e6382ea5ec96629b90c530219c3cb", - "0x000000000000000000000000000000573110e5e30f83f2b1cdbf6021589f56d4", - "0x00000000000000000000000000000000002153342158e09047429d5ff0cf2814", - "0x0000000000000000000000000000000c87cc7ea9f19d895b531f173f10e1fb7a", - "0x000000000000000000000000000000000028ce104aa04c8883606e30145396ca", - "0x000000000000000000000000000000091bf18675b31c2ca35cd6d9c4c61980f6", - "0x00000000000000000000000000000000001e4a1ac80c95b28bd73997aa8be018", - "0x00000000000000000000000000000027ac5003261c40666193e97d00708290e6", - "0x0000000000000000000000000000000000155026062b8202477e26ea5692a700", - "0x000000000000000000000000000000cf95c483603fd34a07e7e0aaa6ddedf5aa", - "0x00000000000000000000000000000000001ed0d7dc69f72e8055cbe26bc2ce26", - "0x000000000000000000000000000000bd27f2a517da170087251aface1dbc9172", - "0x0000000000000000000000000000000000201a01367b862c45ba57aabe90a276", - "0x0000000000000000000000000000006242c06ca6844877f622da669895d8081a", - "0x000000000000000000000000000000000007e008d692476d4eb814fb8f610fba", - "0x00000000000000000000000000000013de6e7df5135ff688efa9d436ed802342", - "0x0000000000000000000000000000000000291c207e9ad4c322aa0711d30bde2f", - "0x000000000000000000000000000000dd165b3f058369e880294dc2d3f1548ffc", - "0x000000000000000000000000000000000017829ab7f82e60e0e4da95135e6e84", + "0x0000000000000000000000000000000000000000000000000000000000000b61", + "0x0000000000000000000000000000007b6222b3a18551d60b847957202de6c8f5", + "0x00000000000000000000000000000000001e26b96548b9f12369e9c3ec0eee85", + "0x000000000000000000000000000000025aac0bbaf1beff1c0500e3ec38d34c8a", + "0x00000000000000000000000000000000002c498aff2f95b25bb92e2c9360aff5", + "0x00000000000000000000000000000039d32590e9d6e0be118712b9402c606156", + "0x000000000000000000000000000000000026588627e22f203f6399975fb67258", + "0x000000000000000000000000000000097282335613efda63abaeaddc915f44db", + "0x000000000000000000000000000000000021b51f545ea031ad8c826962f52545", + "0x00000000000000000000000000000035a0536197418c2ba2c29a1830f709420c", + "0x000000000000000000000000000000000020f8cabd08dfc29e045e0b80eb42d3", + "0x00000000000000000000000000000099e53cda88a63b8e751a2bc253f7a689a7", + "0x0000000000000000000000000000000000231a514e7a4dd0e23c4faf8d567c77", + "0x0000000000000000000000000000002dac12ff4e48e530611ceb7a400c099e4a", + "0x00000000000000000000000000000000001ad1cb6dbbe8ea3dd6c4f44ffdce56", + "0x000000000000000000000000000000dfd19e74f4e4c641b3b3f623825ccd495f", + "0x00000000000000000000000000000000000ce4453cef94251418336baa54e582", + "0x0000000000000000000000000000007ad93fd648d3587168e2ba9ee66dbbf918", + "0x00000000000000000000000000000000000a7680894366d3b1755d14152e528e", + "0x00000000000000000000000000000008bf43eecffcec9e31d916289a212b8f88", + "0x0000000000000000000000000000000000216620e5bd7b177f3fa15ceeb2526e", + "0x00000000000000000000000000000021db86993540e76c420c850640a25f7d94", + "0x000000000000000000000000000000000017418ee5d4d58a54e7728b755757a8", + "0x0000000000000000000000000000000cf5f978296643872c59d00be3c23ad68d", + "0x000000000000000000000000000000000013e45088158c3bf8ac1f8e71eec154", + "0x000000000000000000000000000000768cc857ea136153788ffa81c07daddaf2", + "0x000000000000000000000000000000000014b992148ee6906cb3a1989f3c4bb1", + "0x0000000000000000000000000000000127e074cd6ea24f75f86f3ab119f9ae5d", + "0x00000000000000000000000000000000001719d1f7fc4645193b8036cf9a3d52", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x000000000000000000000000000000622ac3715a21583a169b4c635c162bdc13", + "0x000000000000000000000000000000000012374104ee9056dfafba40f457c0a8", + "0x000000000000000000000000000000f6c09b75f7561f7fbbd272af5d3efa974b", + "0x00000000000000000000000000000000000e0a7bd7a377bca3ff6c89d68a3e5e", + "0x0000000000000000000000000000009d165e9a47e021ab9760d27339570655e5", + "0x0000000000000000000000000000000000000b204b0dc1f11b52bb345fb52145", + "0x000000000000000000000000000000d4c558b53b27cb4c171f8a5eb0bd1e3a2c", + "0x00000000000000000000000000000000002f6870272192d541c1b8887b15a95a", + "0x0000000000000000000000000000008f4c64ade1e7b515b074c100d489415d4c", + "0x00000000000000000000000000000000000f9aca92beccde2e1b08c99ab92a6c", + "0x0000000000000000000000000000008be6976e9870523051d19531843262ce4c", + "0x0000000000000000000000000000000000277419877e0ba35217f219676b5656", + "0x00000000000000000000000000000051ec180d05026f2f62b1674ca2e1a2c142", + "0x000000000000000000000000000000000022264cbd2ea66b7766612864c5108c", + "0x000000000000000000000000000000f137ae2b224915db0c43de1611134011d0", + "0x000000000000000000000000000000000011877af1a2b9b35d6ac04c489fe3ba", + "0x000000000000000000000000000000935ae3a5a2c4a7aad8e94a7cf1c4bec70e", + "0x00000000000000000000000000000000002a56488e09fd406c14aca4acf2b4c3", + "0x000000000000000000000000000000e770a6c5c0093eb5de2e5aa8d173e9ef05", + "0x000000000000000000000000000000000005522908d6e06b02d6938a789bb5c9", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000b139df614924ddb845d70d642d94873569", + "0x00000000000000000000000000000000000084d02351f0d2b405f3af6092edc0", + "0x0000000000000000000000000000006c1123c8d14bdfbfa99f95d1fd0d9674f7", + "0x00000000000000000000000000000000002be519d31aea4dac51b16b3655b459", + "0x00000000000000000000000000000035b52a2f19454b2d02086d012cfc44cbdb", + "0x000000000000000000000000000000000027f3e1c4d5482e3b1ebcbc5e43d1d2", + "0x000000000000000000000000000000bc81f2a307249de2d56c3c8151aa3a4179", + "0x000000000000000000000000000000000014745d0c8957b03309ffd69c523944", + "0x000000000000000000000000000000d90966909da4a8611a68a5b2544044ee27", + "0x00000000000000000000000000000000002dda368cf4f8ae011ba33953ccdbdc", + "0x00000000000000000000000000000099fd8e2a4efaa0e979e53c6360f11a3520", + "0x000000000000000000000000000000000029023563407bf604b94f3d3b82e32c", + "0x00000000000000000000000000000095ced0bf10b79aec2651f808812961ce57", + "0x0000000000000000000000000000000000204601f003e0e59d1865597a5cdcd4", + "0x000000000000000000000000000000fd07b0a28f8510ae42eefbbd2d0136dc4f", + "0x00000000000000000000000000000000001e3aba113eb2b6e0d9a07cb16188c0", + "0x0000000000000000000000000000004496315acb001bd07077d5e61a5fd28f1b", + "0x00000000000000000000000000000000001a39ca40a2fdca943fd7c57ea59fc9", + "0x0000000000000000000000000000001a6e9238224f825fbe059c173514ee0fe7", + "0x000000000000000000000000000000000022f701f63bad50d3161322f8d104b3", + "0x000000000000000000000000000000e7cb0e4c388d5b2b1350a0c1b259d7c4aa", + "0x0000000000000000000000000000000000216c09ccaf44298565b3e593e3a7bd", + "0x000000000000000000000000000000d840ba780d73076cfaadb07a9a1a2cad8b", + "0x00000000000000000000000000000000002a887121806c1166b16f3aa9de6716", + "0x0000000000000000000000000000000e3b5cb0fc3e09ea8b4059e2a6109ff857", + "0x00000000000000000000000000000000001794754a1a61af4fa7976eefdac79e", + "0x000000000000000000000000000000dfef9deedb32693d7cc279f72cdc785d1e", + "0x00000000000000000000000000000000000e55622ad6ca63ffde7f64ed504b16", + "0x000000000000000000000000000000d08df7bdd8d57cb1d65728efccbbfcf607", + "0x000000000000000000000000000000000005f2689ecd1c3bf58c28357d95d48a", + "0x0000000000000000000000000000002d7d2927cc7e65b41792f5745ba169663e", + "0x00000000000000000000000000000000002b5f2432471d8c12ea391ac1a0bd12", + "0x000000000000000000000000000000773d8fd379e59dbcbab02af010d195c779", + "0x000000000000000000000000000000000008826f48f7b0250873af38fa8f7500", + "0x0000000000000000000000000000006165595d9a271241c16e0472c174fba8f8", + "0x00000000000000000000000000000000001c673e22bf04c83bddc2f02ebaae36", + "0x0000000000000000000000000000008d6afb067ac5198bb372113d34c56552fa", + "0x00000000000000000000000000000000001e08cbe1d21feee99c841191e54333", + "0x0000000000000000000000000000007646a1a3ca480b5d7322e5e4bb688049f7", + "0x0000000000000000000000000000000000269f2465562733cff2488fe75060fe", + "0x0000000000000000000000000000005524b80d26a1d910532fda24c2383f979b", + "0x000000000000000000000000000000000023bf14a9a6153ade3200bcc787ba79", + "0x00000000000000000000000000000038d56d2f4e530f74fb02bb70d781488b16", + "0x00000000000000000000000000000000001d1731444ac607cb0623133a479871", + "0x000000000000000000000000000000fe08dc45003f859a25494ba5135502e42f", + "0x00000000000000000000000000000000001e6d7c5b53a5e88d78640651a5c6a0", + "0x000000000000000000000000000000ddf4dedac0a43ba687e608b3e6081b8546", + "0x000000000000000000000000000000000004c2446dcf61c32ba4b038fe7365fb", + "0x0000000000000000000000000000004557b361ff0d6568e896319c496fbe24b8", + "0x00000000000000000000000000000000000668a26f50d3354953d4b2766e8020", + "0x000000000000000000000000000000ea507b90f982c43d39d3f699d22b1f7c4a", + "0x00000000000000000000000000000000001429723650e7543325ff8bef1c4ffd", + "0x00000000000000000000000000000049c19043bd4f1ef29d5413b1f118d0f722", + "0x00000000000000000000000000000000001d7ad7b3a27a9bc7992d806af0ebc9", + "0x000000000000000000000000000000f291d1109ea1f48586582a3767b0392cbe", + "0x0000000000000000000000000000000000026df82a517f9dabb3c389c07aebc7", + "0x0000000000000000000000000000000999c4e1d13eba177baf97921ee863ca58", + "0x000000000000000000000000000000000002f7f537a4f96f2ca4eb19a57f0b9f", + "0x000000000000000000000000000000dea34b6c529204f209cd1420a81a3102bb", + "0x00000000000000000000000000000000001c53a430fcbd4b95ffc23b6461fa15", + "0x0000000000000000000000000000005c0cab22cbb5bdccf85116184958790eb4", + "0x00000000000000000000000000000000001b715af5e709bb9f06822082ee3120", + "0x000000000000000000000000000000c77eaa3f49d17dfe395648540f4cd0abc6", + "0x000000000000000000000000000000000007df3cadf5a234989c3f0b92052395", + "0x0000000000000000000000000000009c11b61aaa7a95751ddef148053d00a6e7", + "0x00000000000000000000000000000000000f65d42148106db82a9e434cb19459", + "0x000000000000000000000000000000f99b662c4e3bcd3fdffb75cad5deb632e6", + "0x0000000000000000000000000000000000284f78ec2bc1c17ffa75e285ad4529", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000c5c5fddc6d03b2bb9af543e73695863c77", - "0x00000000000000000000000000000000002b03df11145d0fa2c23bdd7fb7066b", - "0x000000000000000000000000000000211136d196e61c110edd7e581be8645373", - "0x00000000000000000000000000000000000a2fb7ada300644cbf7b7d7f36de36", + "0x00000000000000000000000000000059a5cd5c1c2d2e7cac107aaf0123ae4f84", + "0x0000000000000000000000000000000000170ffa45422a2680cd492bad46789d", + "0x0000000000000000000000000000003c91ea4fe538abe3c344c3603398af1cbc", + "0x0000000000000000000000000000000000295e7a3f8df6111a6bd51041d5179b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000585fcdfa31b424adfe685b43435cdc567", - "0x00000000000000000000000000000000002717439949acf883c385bc7c246dc6", - "0x000000000000000000000000000000b97f0f863a1005a5c88ba628c1d8bb1740", - "0x000000000000000000000000000000000001f73676f90fa92e0bd9ce8716cfb9" + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" ] -hash = "0x103023eab6f953f6b7b9525f412e0bc1655bd72d5e4b46ded148c6137deb9006" +hash = "0x11197593d62d0e7554158b832253460bcc00da8b6551eb5d955ef72444d95a3f" [private_call.verification_key_hints] -contract_class_artifact_hash = "0x1d8791271c09cabf2ac9aaa6bd8095b473d90e367f72c6df771aa7a4ec960f9e" +contract_class_artifact_hash = "0x1d9e0e30582ed207c6ba761454f1f542d807eb0a2b35a50b23297a6db34e3680" contract_class_public_bytecode_commitment = "0x0ce4c618c3ed7f3a20410e618c06bb701e150af7fe28a3e92f68e7733809f33e" updated_class_id_delayed_public_mutable_values = [ "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -229,8 +229,8 @@ updated_class_id_delayed_public_mutable_values = [ [private_call.verification_key_hints.function_leaf_membership_witness] leaf_index = "0" sibling_path = [ - "0x238e2af83a65aa19075bf14aa7aeb0f681204a09f3756757b334f3061e238757", - "0x25ce89a823f16f35f08b6081a3ea3197c468941e46b7400ac6b33280b19cf251", + "0x2cc233639ce62adaea3ec034abce91a0b008ca3b50da04eb0789bf1f438162ea", + "0x0f60b735d348fd08a8da88fe4b04361698e2bca73fbebb6cc1fdcb86a4d03c89", "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", @@ -238,40 +238,30 @@ updated_class_id_delayed_public_mutable_values = [ "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" ] -[private_call.verification_key_hints.public_keys.npk_m.inner] -x = "0x025f9f657095ad240d89a28336e0f7be994c9f270d62c6a3228aa8bada12d01d" -y = "0x1a7e0782cbdd3ebc39b0bd4a33b5894cb3451bc52c2fadd70371ed8d81db479f" -is_infinite = false + [private_call.verification_key_hints.public_keys] + npk_m_hash = "0x00b1aa481847b00c84520d8703150e4ffcabef37bd6c690e2b2f0def0d234412" + ovpk_m_hash = "0x2f06e183807ba9785e51fc03048ad8578bc00a26557c98d6395da6d0a222ff05" + tpk_m_hash = "0x2a5642d242500c1704918b9a0b8273080ed77a05eb814254711ee48459fb417e" [private_call.verification_key_hints.public_keys.ivpk_m.inner] -x = "0x22f40cddddbd77c2aa6fead1b876909111a45ab1b5f69a48df1440764a7dcd90" -y = "0x1a6c5d7af83395c1e6c82ef8cb26ec6674f65cfb52521dae0b54130764bdf10d" -is_infinite = false - -[private_call.verification_key_hints.public_keys.ovpk_m.inner] -x = "0x2d41c74462094b1d13ed19ce294c4a39cdc7635080f32399494e5e796b663933" -y = "0x19944298156083d73fc78b3e628123fccead0fec542f0a55cfd319f2b77047ca" -is_infinite = false - -[private_call.verification_key_hints.public_keys.tpk_m.inner] -x = "0x2b8dc3a19be872d7c3b215f6b1716e586cdc99c79320ec3f5989233e0957fc39" -y = "0x13eec92e41aeeec0598539fbf7d94629cc58515f87507cb2638264f68be7c432" +x = "0x2c7112e002424a07f386ee65ea79eb477c96ca5b30a00a5a98360c0b9c33dafe" +y = "0x0459c95061c10cdb6d2e6a55872d820a1101881d8d07625d524cac97710a1373" is_infinite = false [private_call.verification_key_hints.salted_initialization_hash] - inner = "0x26ec6a326bed489e479823ab0ea1152729bcec7cbe15048c3e02a1e4309d4a68" + inner = "0x17a48cd849b95dbc8a26ff209bd1d3e80d011e9473beed095fa5a5d92def57fd" [private_call.verification_key_hints.updated_class_id_witness] - leaf_index = "132" + leaf_index = "118" sibling_path = [ - "0x10a274cd78b609bb9ff5960dfac7a0add8ccae279c81ec05441bbb8165d517dd", - "0x27047bd2479bc929cd5250e32e3b3e05f8cef863f7c8a349df77a9b2bf85588d", - "0x1d36a7e02b793d41e28f57b4480fe48b3f169b794f73d57683c7bfc4253da367", - "0x25c533089637cf9ecd3633dfcb0ee03be91faff3e02f51778cd5738264514c88", - "0x1d52af9cd9f69c1286e9a96fd498e736789a5bc463fceb1c176a4f9292f7cbe3", - "0x1ff1d5db01572c915915a22173c73d8073df9af4e4c57f6af29df5315da44419", - "0x070dcbac794fa663bc71b42d80775c0cea8c3ed7580207cfd30fd1285813ce07", - "0x2027713f7323f965c6751ce6c41f7759c9501fe781928b9507814d749cb86f25", + "0x013c095d61087adcef13cfdeb887287dba3806baf73093ee460023cfb7730f22", + "0x060b5c8a3d6c10c09c2c4ef7897592f838ac2433c4ca664adc73ae6bf507aff4", + "0x2523970382de270c1acd87f98b4ed454353257f9c689dc608f7dc1b6ca23741a", + "0x12bef12e0e192e65178ebf9707e29797e5afdace0a42a17d796d1c40e5b7501c", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x1ff2ba9f5f44162476e89f994a79debf4b9af550a887b5b484d18f5997553566", "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", @@ -307,13 +297,13 @@ is_infinite = false ] [private_call.verification_key_hints.updated_class_id_leaf] - slot = "0x1dbe81fde1f18bf3e8828a3595c65a1ee32397477e23d9c5c9e4c0386bbb4a2b" - value = "0x0055534400000000000000000000000000000000000000000000000000000000" - next_slot = "0x213a03911d28297ad85626532672b56d721f6e4af4e78d6f156cf1cb98482089" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000086" + slot = "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969" + value = "0x00000000000000000000000000000000000000000000021e01e389dbb1028c00" + next_slot = "0x07e3196f3e5be886c078da1e359a784f0451f3b454344a3c6482a090708f2547" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000087" [app_public_inputs] -args_hash = "0x2237e42a84e35fc9371ec568e04d6db13130f02f527e0cce6f78ebf038f70f5f" +args_hash = "0x04a65dff28c7219e24a65785e4145db8afe036681c48c8348314e2eeba1c56d3" returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000002" end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000007" @@ -321,7 +311,7 @@ expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000 expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" is_fee_payer = true -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff2940" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7f3f" [app_public_inputs.call_context] is_static_call = false @@ -330,7 +320,7 @@ expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000 inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" [app_public_inputs.call_context.contract_address] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [app_public_inputs.call_context.function_selector] inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" @@ -340,7 +330,7 @@ expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000 [[app_public_inputs.note_hash_read_requests.array]] [app_public_inputs.note_hash_read_requests.array.inner] -inner = "0x29ecb485abf1e4a9963bb4dada6e8b67bda9c6bb09527ecb8d0c64a0d119e0fd" +inner = "0x302a86bd5883e95684cbcd46af941e62a60b0416ee605f00eae4a0189b8af2ee" counter = "0x0000000000000000000000000000000000000000000000000000000000000003" [app_public_inputs.note_hash_read_requests.array.contract_address] @@ -604,178 +594,114 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [app_public_inputs.note_hashes] length = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1113,13 +1039,13 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.public_call_requests.array.inner] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x00a5e40cab902df3efe088094577e83eb92103581c990f351edf1dfba3778905" [app_public_inputs.public_call_requests.array.inner.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [app_public_inputs.public_call_requests.array.inner.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x1be490a4b344f41827e94113f628fb311efc1abac19bc1e84b08fd578708964a" [[app_public_inputs.public_call_requests.array]] counter = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2055,50 +1981,50 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" length = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [app_public_inputs.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [app_public_inputs.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [app_public_inputs.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [app_public_inputs.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [app_public_inputs.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [app_public_inputs.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [app_public_inputs.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [app_public_inputs.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [app_public_inputs.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [app_public_inputs.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-2/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-2/Prover.toml new file mode 100644 index 000000000000..d52c721bb422 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-2/Prover.toml @@ -0,0 +1,10000 @@ +[previous_kernel.vk_data] +leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000041" +sibling_path = [ + "0x12c59c16ed84032f7c5273ff19d7a05e8e861c23959fb71cf4b2c6ac45d21f8c", + "0x225eef52a484280b0f1c6cb9f90a84dc301536c01bfa4d61bd6496b3eaf19052", + "0x0e084e8198288b2ff94eaf4d6f37fba06e430a879dd37c726a3b5a65416fe6b6", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x0e9cb07dc8495e2adab02c5db0e34a0dbe42e9b473e0462641c54f73a4a4fdd3" +] + + [previous_kernel.vk_data.vk] + key = [ + "0x0000000000000000000000000000000000000000000000000000000000000011", + "0x000000000000000000000000000000000000000000000000000000000000001a", + "0x0000000000000000000000000000000000000000000000000000000000000cbd", + "0x000000000000000000000000000000c4d62213b081c8e90e6c8f3587321997f5", + "0x00000000000000000000000000000000002236a0b9f0654f7cd634c9c34280f1", + "0x0000000000000000000000000000007cb00736872fd50e291ec99fb640f1f7d9", + "0x00000000000000000000000000000000002d1b1b74b74ddf7d6f964a7bdb2af3", + "0x000000000000000000000000000000f26bcf89c86dcbce68a4f1b5b73505dcec", + "0x000000000000000000000000000000000011a128ae6c7be3a962485534f27786", + "0x00000000000000000000000000000088278f8cce72a5f698601f11a1532a9dad", + "0x00000000000000000000000000000000000d9caeabde23d8c2a0bd2cdef54193", + "0x0000000000000000000000000000001cfb29930f6753e5cb6a60342c16fe5e4f", + "0x00000000000000000000000000000000001022a2847e12bdd43b96342e5b8e16", + "0x000000000000000000000000000000fefee7789c5b50b89ce3ac6155975c4319", + "0x000000000000000000000000000000000002e25d02799b225c89aba3a667d7e5", + "0x0000000000000000000000000000006e210889b06205312234c097f979fca3b5", + "0x00000000000000000000000000000000000566396dc1f8e15f3a1c3729bb3393", + "0x0000000000000000000000000000009790f776d7aaecbcaf977d3aad6070c4e4", + "0x00000000000000000000000000000000002dcdeaf93e01c780512d9950fbfd94", + "0x000000000000000000000000000000d2ef194a7b605db9c6df08b9576c97735e", + "0x00000000000000000000000000000000001ff98ab3818a3d5fdc538a7bbeb87e", + "0x000000000000000000000000000000be40a925ee773bfc3923df01da59a497d7", + "0x00000000000000000000000000000000001fb52b895f997b5a90ea722d9a4140", + "0x000000000000000000000000000000dd5a7d1074be39e4451795f983d45b5be3", + "0x00000000000000000000000000000000001cbfd5b0d763096343af10ed1f3496", + "0x0000000000000000000000000000007cc56b953bb8ef24745e9200896ee10ee1", + "0x000000000000000000000000000000000001ef96b3ae0b2677b21939012dcc17", + "0x0000000000000000000000000000004ba56f98fc7d6d956bd6302ef6941f9239", + "0x000000000000000000000000000000000010bf82473c11a65eb2ac193002bfe4", + "0x00000000000000000000000000000072739ba831885d7f767251b9cc444961e5", + "0x0000000000000000000000000000000000256ea7e1dc188341f8692fd52454cf", + "0x000000000000000000000000000000a284c1c0bd5602eb7242fda659dc49ff99", + "0x000000000000000000000000000000000002e5e663dd3bf5f961173646b8e7b3", + "0x000000000000000000000000000000194cc54081bb3ffba3c67547dcb2db4d37", + "0x00000000000000000000000000000000002377042c75bab3ceee3b186c40b8b6", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000f0af57d5589fc84e1f8897bb5a62ec0ea9", + "0x000000000000000000000000000000000016583df9856bef930ef0a81d3357f0", + "0x000000000000000000000000000000e0a92aecf729c58fa7672c82066409d090", + "0x000000000000000000000000000000000010085406672c105a10ddee00634540", + "0x00000000000000000000000000000036b650e61cb6e0ec6ff6b1aef12c8c81e3", + "0x00000000000000000000000000000000000049ced3703b6736736daa8d94d66c", + "0x00000000000000000000000000000024e41b443846d1b9d969a739fe9ec5544d", + "0x0000000000000000000000000000000000251ef94ce2811e61503920adc1a548", + "0x000000000000000000000000000000ab378c4d63d86a750348adbd4cbc2c6883", + "0x0000000000000000000000000000000000079aee0bbaec8a7e39acda8a2bfd44", + "0x000000000000000000000000000000c4996ccb316a1671fa17ac0ec536c08aee", + "0x00000000000000000000000000000000000087a93f4353d8c6e85d6c58c7af49", + "0x0000000000000000000000000000002754983ee3f30f64f3ef3d6a27f671032d", + "0x00000000000000000000000000000000001b77b7da696321894ac402dc70a471", + "0x00000000000000000000000000000065a8c950362ff55e55d6006254e4cb8f60", + "0x00000000000000000000000000000000000a0eb81f69be92cc51ba479d4d4b2d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003a6dc78277b2838aca18adc58385b4a7f0", + "0x0000000000000000000000000000000000132c99e752833cae9473e7dfe278d0", + "0x0000000000000000000000000000003ec707e1f4369d5f99a3bac8eaa16ec4ba", + "0x00000000000000000000000000000000001cd77155c0a5e65f942f719c8e73f5", + "0x00000000000000000000000000000084604af6454cd074b40340a0900f8e47cc", + "0x0000000000000000000000000000000000077d31bdfcd802cd5aa1a457b97f10", + "0x00000000000000000000000000000099c886edf1320d2f8eef9c059a2495598d", + "0x00000000000000000000000000000000001400c2b452cd839ce363493a76312b", + "0x00000000000000000000000000000090681337eb7720ddc934e8bcc81bd9ae2b", + "0x000000000000000000000000000000000006ab19688014b0f0cf860c615759af", + "0x0000000000000000000000000000007165a99470ed5af56e75a9636be648e93d", + "0x000000000000000000000000000000000009dbbccaa2350bd92c5ce19b5d290a", + "0x0000000000000000000000000000000e1e042ed81d839a9f0ead9d291b6a8f32", + "0x00000000000000000000000000000000001a205aec8c334db49f816f4b5dafcd", + "0x000000000000000000000000000000ebb4edb0db1dcdf348033a7901a3680b6a", + "0x000000000000000000000000000000000011aae86275b822ebd3fa82c7315eff", + "0x000000000000000000000000000000e97eee8ec09b50e69135709916aba933c6", + "0x000000000000000000000000000000000010e2e96f78a68fc25ba2e4dafd04cc", + "0x000000000000000000000000000000b214f0a5321e8817d78adb6e0c20d7319e", + "0x000000000000000000000000000000000025bc9ba17b749d567d90e8f13af9a2", + "0x00000000000000000000000000000066fba7ba25f999f6f2838e553a29901fa7", + "0x000000000000000000000000000000000020711b883c2eb028f9d2d3da010519", + "0x000000000000000000000000000000a140d481bdc261d13949520f9ec7371c20", + "0x0000000000000000000000000000000000020bfe682fa3abc7653ce6853b0112", + "0x0000000000000000000000000000001b2bf2cbcde5d02c025a94db3378725693", + "0x000000000000000000000000000000000023e613dfd6966df7487e58fd52480c", + "0x0000000000000000000000000000006e2eb63e8f0cbcbd7a88665a53e119e428", + "0x00000000000000000000000000000000002e70d3962ba79ea7ae10b168c1c7d9", + "0x00000000000000000000000000000030517d9ecfee899135ff976333894660c2", + "0x000000000000000000000000000000000007417244ffad99a470ba89eb0ff90e", + "0x0000000000000000000000000000009bac28f405d40e017edf00277102b49c3d", + "0x000000000000000000000000000000000006b41a5fb6e909b8be3ff0dd952728", + "0x0000000000000000000000000000006683ae1c70f7eb680544f4c342c93087f1", + "0x000000000000000000000000000000000025f0aabdb61ed9c3922c0edfb358ec", + "0x000000000000000000000000000000351b5aea3d5e9850880e66335bcae23e94", + "0x00000000000000000000000000000000000ee72d3f7aca6bbe97267028d6abf9", + "0x0000000000000000000000000000008928d9a8e7f72b161cbe49ae95aa21ae63", + "0x0000000000000000000000000000000000185c141dba0abcf1e6d7db09787ca1", + "0x0000000000000000000000000000003e245e17b3e7805608abb6a2350fa6a847", + "0x00000000000000000000000000000000000cf54864a0d0738294136903b96823", + "0x000000000000000000000000000000f11eab4aad68f934214988cc4f58d5a6a2", + "0x000000000000000000000000000000000022f67f7b7d5406007bb7ddae120884", + "0x000000000000000000000000000000c05dc37331557bb9a3f702d92cfe090666", + "0x0000000000000000000000000000000000264629b4e2c6c2614bd57046d2ac8b", + "0x00000000000000000000000000000017305f321100b05a42b9014b4b5f033fd9", + "0x00000000000000000000000000000000000300f05e18d0c58963b144d3d28da6", + "0x00000000000000000000000000000039e8490810fc737b4a353bb67d95baa83c", + "0x00000000000000000000000000000000001b8f101b87ef8f67f87224f50b4e86", + "0x00000000000000000000000000000048da15030eaa7e0cc01567e721d66ead43", + "0x0000000000000000000000000000000000126b3927169eb104827c842837f462", + "0x00000000000000000000000000000008b500094a5820c680fb1db8c125502e1e", + "0x000000000000000000000000000000000000660eef61b7d219f439ec4fbfff1b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000001115e1df83c7f85610477a243a350ad610", + "0x000000000000000000000000000000000016b525f879d97a8d50cab6d1a41d58", + "0x0000000000000000000000000000005545bbd9cc9de7a79986b650103736492e", + "0x00000000000000000000000000000000000aac06f3452ec0a5be2b5e3060f108", + "0x000000000000000000000000000000c6e13ef9aedec4af73a577a6dd72dda690", + "0x000000000000000000000000000000000016b603e70199deaa1eff742257259f", + "0x000000000000000000000000000000dd7902c16a885b205f012abf38e3f9f470", + "0x00000000000000000000000000000000002a45b4a48e9544c186e119184fd191", + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" +] + hash = "0x1e580df70c4374ef9942846936ab5fc2d7da61ca21bd0576f269746152a782c4" + +[previous_kernel_public_inputs] +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c1" +is_private_only = true +claimed_first_nullifier = "0x0f03b3ad77a1cb11c580c3ed7f69278d1374df07f295fbb4d71640819c7732cf" +claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" + + [previous_kernel_public_inputs.constants] + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + + [previous_kernel_public_inputs.constants.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [previous_kernel_public_inputs.constants.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x01d1d92b90682f39cf6b9ed768d21409cc7142c7b1dc75f647c0f3680bc71695" +counter = "0x0000000000000000000000000000000000000000000000000000000000000003" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers] +length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x04868546b55cd61db182599d47524c126a6cb4acc069435e1bac39c4920db227" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.contract_class_logs_hashes] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.contract_class_logs_hashes.array]] +[previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.contract_class_logs_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.public_call_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_call_stack] +length = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000d" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = true + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x023a62eaf4ce3a8f2752add0746950be81e1f647953b1c21f038c8c2f5d94f4a" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.fee_payer] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + +[private_call_0.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_0.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_0.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_0.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_0.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_0.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_0.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_0.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[private_call_1.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_1.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_1.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_1.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_1.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_1.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_1.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_1.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[app_public_inputs_0] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_0.call_context] + is_static_call = true + + [app_public_inputs_0.call_context.msg_sender] + inner = "0x023a62eaf4ce3a8f2752add0746950be81e1f647953b1c21f038c8c2f5d94f4a" + + [app_public_inputs_0.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_0.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_0.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_0.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_0.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_0.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_0.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_0.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_0.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_0.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_0.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_0.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_0.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_0.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_0.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_0.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000d" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000e" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_1.call_context] + is_static_call = false + + [app_public_inputs_1.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [app_public_inputs_1.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_1.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_1.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x000000000000000000000000000000000000000000000000000000000000000e" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_1.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_1.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_1.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_1.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_1.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_1.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_1.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_1.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_1.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_1.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_1.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_1.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_1.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-3/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-3/Prover.toml new file mode 100644 index 000000000000..e8ec43aaea12 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-3/Prover.toml @@ -0,0 +1,11973 @@ +[previous_kernel.vk_data] +leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000041" +sibling_path = [ + "0x12c59c16ed84032f7c5273ff19d7a05e8e861c23959fb71cf4b2c6ac45d21f8c", + "0x225eef52a484280b0f1c6cb9f90a84dc301536c01bfa4d61bd6496b3eaf19052", + "0x0e084e8198288b2ff94eaf4d6f37fba06e430a879dd37c726a3b5a65416fe6b6", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x0e9cb07dc8495e2adab02c5db0e34a0dbe42e9b473e0462641c54f73a4a4fdd3" +] + + [previous_kernel.vk_data.vk] + key = [ + "0x0000000000000000000000000000000000000000000000000000000000000011", + "0x000000000000000000000000000000000000000000000000000000000000001a", + "0x0000000000000000000000000000000000000000000000000000000000000cbd", + "0x000000000000000000000000000000c4d62213b081c8e90e6c8f3587321997f5", + "0x00000000000000000000000000000000002236a0b9f0654f7cd634c9c34280f1", + "0x0000000000000000000000000000007cb00736872fd50e291ec99fb640f1f7d9", + "0x00000000000000000000000000000000002d1b1b74b74ddf7d6f964a7bdb2af3", + "0x000000000000000000000000000000f26bcf89c86dcbce68a4f1b5b73505dcec", + "0x000000000000000000000000000000000011a128ae6c7be3a962485534f27786", + "0x00000000000000000000000000000088278f8cce72a5f698601f11a1532a9dad", + "0x00000000000000000000000000000000000d9caeabde23d8c2a0bd2cdef54193", + "0x0000000000000000000000000000001cfb29930f6753e5cb6a60342c16fe5e4f", + "0x00000000000000000000000000000000001022a2847e12bdd43b96342e5b8e16", + "0x000000000000000000000000000000fefee7789c5b50b89ce3ac6155975c4319", + "0x000000000000000000000000000000000002e25d02799b225c89aba3a667d7e5", + "0x0000000000000000000000000000006e210889b06205312234c097f979fca3b5", + "0x00000000000000000000000000000000000566396dc1f8e15f3a1c3729bb3393", + "0x0000000000000000000000000000009790f776d7aaecbcaf977d3aad6070c4e4", + "0x00000000000000000000000000000000002dcdeaf93e01c780512d9950fbfd94", + "0x000000000000000000000000000000d2ef194a7b605db9c6df08b9576c97735e", + "0x00000000000000000000000000000000001ff98ab3818a3d5fdc538a7bbeb87e", + "0x000000000000000000000000000000be40a925ee773bfc3923df01da59a497d7", + "0x00000000000000000000000000000000001fb52b895f997b5a90ea722d9a4140", + "0x000000000000000000000000000000dd5a7d1074be39e4451795f983d45b5be3", + "0x00000000000000000000000000000000001cbfd5b0d763096343af10ed1f3496", + "0x0000000000000000000000000000007cc56b953bb8ef24745e9200896ee10ee1", + "0x000000000000000000000000000000000001ef96b3ae0b2677b21939012dcc17", + "0x0000000000000000000000000000004ba56f98fc7d6d956bd6302ef6941f9239", + "0x000000000000000000000000000000000010bf82473c11a65eb2ac193002bfe4", + "0x00000000000000000000000000000072739ba831885d7f767251b9cc444961e5", + "0x0000000000000000000000000000000000256ea7e1dc188341f8692fd52454cf", + "0x000000000000000000000000000000a284c1c0bd5602eb7242fda659dc49ff99", + "0x000000000000000000000000000000000002e5e663dd3bf5f961173646b8e7b3", + "0x000000000000000000000000000000194cc54081bb3ffba3c67547dcb2db4d37", + "0x00000000000000000000000000000000002377042c75bab3ceee3b186c40b8b6", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000f0af57d5589fc84e1f8897bb5a62ec0ea9", + "0x000000000000000000000000000000000016583df9856bef930ef0a81d3357f0", + "0x000000000000000000000000000000e0a92aecf729c58fa7672c82066409d090", + "0x000000000000000000000000000000000010085406672c105a10ddee00634540", + "0x00000000000000000000000000000036b650e61cb6e0ec6ff6b1aef12c8c81e3", + "0x00000000000000000000000000000000000049ced3703b6736736daa8d94d66c", + "0x00000000000000000000000000000024e41b443846d1b9d969a739fe9ec5544d", + "0x0000000000000000000000000000000000251ef94ce2811e61503920adc1a548", + "0x000000000000000000000000000000ab378c4d63d86a750348adbd4cbc2c6883", + "0x0000000000000000000000000000000000079aee0bbaec8a7e39acda8a2bfd44", + "0x000000000000000000000000000000c4996ccb316a1671fa17ac0ec536c08aee", + "0x00000000000000000000000000000000000087a93f4353d8c6e85d6c58c7af49", + "0x0000000000000000000000000000002754983ee3f30f64f3ef3d6a27f671032d", + "0x00000000000000000000000000000000001b77b7da696321894ac402dc70a471", + "0x00000000000000000000000000000065a8c950362ff55e55d6006254e4cb8f60", + "0x00000000000000000000000000000000000a0eb81f69be92cc51ba479d4d4b2d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003a6dc78277b2838aca18adc58385b4a7f0", + "0x0000000000000000000000000000000000132c99e752833cae9473e7dfe278d0", + "0x0000000000000000000000000000003ec707e1f4369d5f99a3bac8eaa16ec4ba", + "0x00000000000000000000000000000000001cd77155c0a5e65f942f719c8e73f5", + "0x00000000000000000000000000000084604af6454cd074b40340a0900f8e47cc", + "0x0000000000000000000000000000000000077d31bdfcd802cd5aa1a457b97f10", + "0x00000000000000000000000000000099c886edf1320d2f8eef9c059a2495598d", + "0x00000000000000000000000000000000001400c2b452cd839ce363493a76312b", + "0x00000000000000000000000000000090681337eb7720ddc934e8bcc81bd9ae2b", + "0x000000000000000000000000000000000006ab19688014b0f0cf860c615759af", + "0x0000000000000000000000000000007165a99470ed5af56e75a9636be648e93d", + "0x000000000000000000000000000000000009dbbccaa2350bd92c5ce19b5d290a", + "0x0000000000000000000000000000000e1e042ed81d839a9f0ead9d291b6a8f32", + "0x00000000000000000000000000000000001a205aec8c334db49f816f4b5dafcd", + "0x000000000000000000000000000000ebb4edb0db1dcdf348033a7901a3680b6a", + "0x000000000000000000000000000000000011aae86275b822ebd3fa82c7315eff", + "0x000000000000000000000000000000e97eee8ec09b50e69135709916aba933c6", + "0x000000000000000000000000000000000010e2e96f78a68fc25ba2e4dafd04cc", + "0x000000000000000000000000000000b214f0a5321e8817d78adb6e0c20d7319e", + "0x000000000000000000000000000000000025bc9ba17b749d567d90e8f13af9a2", + "0x00000000000000000000000000000066fba7ba25f999f6f2838e553a29901fa7", + "0x000000000000000000000000000000000020711b883c2eb028f9d2d3da010519", + "0x000000000000000000000000000000a140d481bdc261d13949520f9ec7371c20", + "0x0000000000000000000000000000000000020bfe682fa3abc7653ce6853b0112", + "0x0000000000000000000000000000001b2bf2cbcde5d02c025a94db3378725693", + "0x000000000000000000000000000000000023e613dfd6966df7487e58fd52480c", + "0x0000000000000000000000000000006e2eb63e8f0cbcbd7a88665a53e119e428", + "0x00000000000000000000000000000000002e70d3962ba79ea7ae10b168c1c7d9", + "0x00000000000000000000000000000030517d9ecfee899135ff976333894660c2", + "0x000000000000000000000000000000000007417244ffad99a470ba89eb0ff90e", + "0x0000000000000000000000000000009bac28f405d40e017edf00277102b49c3d", + "0x000000000000000000000000000000000006b41a5fb6e909b8be3ff0dd952728", + "0x0000000000000000000000000000006683ae1c70f7eb680544f4c342c93087f1", + "0x000000000000000000000000000000000025f0aabdb61ed9c3922c0edfb358ec", + "0x000000000000000000000000000000351b5aea3d5e9850880e66335bcae23e94", + "0x00000000000000000000000000000000000ee72d3f7aca6bbe97267028d6abf9", + "0x0000000000000000000000000000008928d9a8e7f72b161cbe49ae95aa21ae63", + "0x0000000000000000000000000000000000185c141dba0abcf1e6d7db09787ca1", + "0x0000000000000000000000000000003e245e17b3e7805608abb6a2350fa6a847", + "0x00000000000000000000000000000000000cf54864a0d0738294136903b96823", + "0x000000000000000000000000000000f11eab4aad68f934214988cc4f58d5a6a2", + "0x000000000000000000000000000000000022f67f7b7d5406007bb7ddae120884", + "0x000000000000000000000000000000c05dc37331557bb9a3f702d92cfe090666", + "0x0000000000000000000000000000000000264629b4e2c6c2614bd57046d2ac8b", + "0x00000000000000000000000000000017305f321100b05a42b9014b4b5f033fd9", + "0x00000000000000000000000000000000000300f05e18d0c58963b144d3d28da6", + "0x00000000000000000000000000000039e8490810fc737b4a353bb67d95baa83c", + "0x00000000000000000000000000000000001b8f101b87ef8f67f87224f50b4e86", + "0x00000000000000000000000000000048da15030eaa7e0cc01567e721d66ead43", + "0x0000000000000000000000000000000000126b3927169eb104827c842837f462", + "0x00000000000000000000000000000008b500094a5820c680fb1db8c125502e1e", + "0x000000000000000000000000000000000000660eef61b7d219f439ec4fbfff1b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000001115e1df83c7f85610477a243a350ad610", + "0x000000000000000000000000000000000016b525f879d97a8d50cab6d1a41d58", + "0x0000000000000000000000000000005545bbd9cc9de7a79986b650103736492e", + "0x00000000000000000000000000000000000aac06f3452ec0a5be2b5e3060f108", + "0x000000000000000000000000000000c6e13ef9aedec4af73a577a6dd72dda690", + "0x000000000000000000000000000000000016b603e70199deaa1eff742257259f", + "0x000000000000000000000000000000dd7902c16a885b205f012abf38e3f9f470", + "0x00000000000000000000000000000000002a45b4a48e9544c186e119184fd191", + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" +] + hash = "0x1e580df70c4374ef9942846936ab5fc2d7da61ca21bd0576f269746152a782c4" + +[previous_kernel_public_inputs] +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c1" +is_private_only = true +claimed_first_nullifier = "0x2b17c43e24196724833491ef10cd2e263c2541b0a2ce69df8cb6f80afcaa89da" +claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" + + [previous_kernel_public_inputs.constants] + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + + [previous_kernel_public_inputs.constants.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [previous_kernel_public_inputs.constants.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x01d1d92b90682f39cf6b9ed768d21409cc7142c7b1dc75f647c0f3680bc71695" +counter = "0x0000000000000000000000000000000000000000000000000000000000000003" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers] +length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x1f2d325e53b36b047c5d53521b42951773c7b94e77d80b6c1a6ac3badfd68ccd" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.contract_class_logs_hashes] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.contract_class_logs_hashes.array]] +[previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.contract_class_logs_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.public_call_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_call_stack] +length = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000010" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000012" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000d" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = true + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x023a62eaf4ce3a8f2752add0746950be81e1f647953b1c21f038c8c2f5d94f4a" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.fee_payer] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + +[private_call_0.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_0.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_0.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_0.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_0.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_0.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_0.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_0.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[private_call_1.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_1.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_1.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_1.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_1.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_1.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_1.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_1.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[private_call_2.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_2.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_2.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_2.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_2.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_2.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_2.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_2.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[app_public_inputs_0] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_0.call_context] + is_static_call = true + + [app_public_inputs_0.call_context.msg_sender] + inner = "0x023a62eaf4ce3a8f2752add0746950be81e1f647953b1c21f038c8c2f5d94f4a" + + [app_public_inputs_0.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_0.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_0.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_0.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_0.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_0.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_0.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_0.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_0.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_0.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_0.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_0.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_0.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_0.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_0.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_0.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000d" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000e" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_1.call_context] + is_static_call = false + + [app_public_inputs_1.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [app_public_inputs_1.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_1.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_1.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x000000000000000000000000000000000000000000000000000000000000000e" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_1.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_1.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_1.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_1.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_1.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_1.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_1.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_1.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_1.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_1.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_1.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_1.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_1.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000010" +end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000012" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000011" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_2.call_context] + is_static_call = false + + [app_public_inputs_2.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [app_public_inputs_2.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_2.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_2.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x0000000000000000000000000000000000000000000000000000000000000011" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_2.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_2.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_2.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_2.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_2.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_2.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_2.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_2.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_2.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_2.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_2.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_2.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_2.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/Prover.toml index 91f33eeac7c0..8b18e90b3cd2 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/Prover.toml @@ -1,128 +1,128 @@ [previous_kernel.vk_data] -leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000041" sibling_path = [ - "0x0ddc610a21615b2984181082c3de07058b9f7d4be62806c4fd475161f8bd2be3", - "0x0f92d54d29bddf6ec768db2c0b4685fb325d248b3ad9a3c6adda76c6c5004224", - "0x0656bbf5e3f4cc4fa5e2fa46e7fd370db0bee05586a1849c37c77d05abe2d8a5", - "0x166399703d23a5c22febc6185f8eb93c72b65906eefef226e643c35fa0022adb", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x12c59c16ed84032f7c5273ff19d7a05e8e861c23959fb71cf4b2c6ac45d21f8c", + "0x225eef52a484280b0f1c6cb9f90a84dc301536c01bfa4d61bd6496b3eaf19052", + "0x0e084e8198288b2ff94eaf4d6f37fba06e430a879dd37c726a3b5a65416fe6b6", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x0e9cb07dc8495e2adab02c5db0e34a0dbe42e9b473e0462641c54f73a4a4fdd3" ] [previous_kernel.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000011", "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000c11", - "0x000000000000000000000000000000b56b478d39fe1ea8636ca1c5f7efe26465", - "0x00000000000000000000000000000000002ce8a9b4b8b40012f631f6a39b6121", - "0x000000000000000000000000000000e90605e79e3b491b4e35bed971ffe40f20", - "0x000000000000000000000000000000000014aac08af29b80ea5e82169bde9f1b", - "0x000000000000000000000000000000f23100dd9e774faa9da6adabb0a5e868d1", - "0x00000000000000000000000000000000000675d3fb2db13df5feb7837a996202", - "0x0000000000000000000000000000002d41a263946c21172989f16b6c3eabd14b", - "0x00000000000000000000000000000000002f76f5733e8a0b6e45ad715c844fa3", - "0x0000000000000000000000000000009906b77efd02f89dd64543cb41b2ee7dc0", - "0x000000000000000000000000000000000011990c3a05d603a15abfdd104b7f45", - "0x000000000000000000000000000000b68418cb6eb350097b81ceebf7216de49f", - "0x0000000000000000000000000000000000193b041e80721ea6304e3edc45a55a", - "0x0000000000000000000000000000007f41793e8f1a2fbe4047a8c9b3ea8a7eba", - "0x000000000000000000000000000000000004ad79eb6e09a672b49359e429d4b2", - "0x00000000000000000000000000000084b9e57a26da81e52f9d96f484a3d8a6ae", - "0x00000000000000000000000000000000001b4cff12b3ca2c242b1cb101ca1f62", - "0x00000000000000000000000000000051285e317a9d17f2180bf8ec1f3e31c266", - "0x00000000000000000000000000000000002f79f4597dc1cbdfe8060d1d92c7fc", - "0x000000000000000000000000000000bfdd478df770ff0d6a9f5d30c6380e3bb2", - "0x00000000000000000000000000000000000f6c52e2949dd6fa7eff016e2e5bb6", - "0x0000000000000000000000000000001cba707dc36043107ad882453ae5d8b129", - "0x0000000000000000000000000000000000059cc841348db66a31d2dfa33b89a0", - "0x0000000000000000000000000000000e2b2caaf1a1eda41d509cc5221c984b51", - "0x0000000000000000000000000000000000037cc127472715a44cac19993d448a", - "0x0000000000000000000000000000003cc6bfe8250e54d57ce7daedc9a7095bc8", - "0x00000000000000000000000000000000001c95108bb4f2494bfef842093c3b36", - "0x0000000000000000000000000000008313e6a820b2f5c2a7de8028cd31798633", - "0x000000000000000000000000000000000027be294c15550f339b0839d5860142", - "0x00000000000000000000000000000060338657a29bcf8c13a4b50294e337ef11", - "0x00000000000000000000000000000000001569de523f46c6226a398155490417", - "0x000000000000000000000000000000163a5d9281ca7ac774da33d1bd5e32dd54", - "0x00000000000000000000000000000000001cea3677784e36b40d3084060d7486", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000008a36ca53543c7bd871dd8974dda60ec04e", - "0x000000000000000000000000000000000028fcc75fb20c13fa73b0b5dd1a9df0", - "0x000000000000000000000000000000646eccdb4bcb213d9d9867f291bc4cc715", - "0x0000000000000000000000000000000000239e0bfd2fe8666da2541d2b7e9242", - "0x00000000000000000000000000000057b0434a909bdd123f328dd722f50de441", - "0x0000000000000000000000000000000000056e909ead4cc889ca4ae259618b9e", - "0x000000000000000000000000000000cce3583f4dbdf7f0ea96b8413114530b7f", - "0x0000000000000000000000000000000000029d93569d5fb4eccfe54516bbfc2c", - "0x0000000000000000000000000000000202259bdd735f5d0996b36a14296dd956", - "0x00000000000000000000000000000000001c9a81340c0ef1a3f8ab9378b45228", - "0x000000000000000000000000000000bb9541231ccc05d3210933db9b2cfd662a", - "0x00000000000000000000000000000000002e90121d7079020ef60bf83a167d82", - "0x0000000000000000000000000000008e531da6a57f645193723255cc3949f2a6", - "0x000000000000000000000000000000000023d3bfa481c11731a958ae003b7049", - "0x0000000000000000000000000000005d505cd2a7715559ab2fb8ffa94fac158b", - "0x0000000000000000000000000000000000283299e0b6841cadaef68c90af63b3", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a50e32219d22dc5bc0a2a3afa8d1c963bf", - "0x00000000000000000000000000000000001b05579d422ec3526b639fa813b3db", - "0x000000000000000000000000000000931e9ee47cc6828d015bfd807445f50921", - "0x000000000000000000000000000000000005283cabb6b55f9baa597d00d3f46f", - "0x000000000000000000000000000000f14ecdef3987001b29e5574b25db85e726", - "0x00000000000000000000000000000000002b26e84ba3e9db90b9b761fbd5ba48", - "0x00000000000000000000000000000054401c158e8bfa1eac201ac628df1458d3", - "0x000000000000000000000000000000000028b61261027652e8ca3b29fb567872", - "0x0000000000000000000000000000005ddf21ec29f762249f79a86d986723b259", - "0x000000000000000000000000000000000020d889a78eaaeeced668f7a5e6a155", - "0x000000000000000000000000000000fbf31736f1c118ed779b00b56effa82f84", - "0x00000000000000000000000000000000001c10198fa65839280c9a4df0d48c69", - "0x000000000000000000000000000000ae45bd31909c920cd302c1833dc9dac27c", - "0x00000000000000000000000000000000000b5e828a1794bb52b1ef28384f36c3", - "0x000000000000000000000000000000623a32eccef6d3f192c9090e2c8d211339", - "0x000000000000000000000000000000000017dbcb62b1ef67a30ab74432100e03", - "0x0000000000000000000000000000008e75c04775713fe2b95076a7a5e1036c46", - "0x0000000000000000000000000000000000070ea9b40827062280d6e3cc9609a6", - "0x000000000000000000000000000000c70577cdcada107c62a7732ef0d2bbc15f", - "0x00000000000000000000000000000000002e57c64ac76e0a1e1c5980782cb606", - "0x000000000000000000000000000000902c14297534b09b2a8072cd93a9489887", - "0x00000000000000000000000000000000000cb983d7cc09d74a951dbf12ad432b", - "0x00000000000000000000000000000012bff816b24bc7a97ad6b1549515d6b28e", - "0x00000000000000000000000000000000000467570dff77ca3a342e4fc4d1a66b", - "0x00000000000000000000000000000080a63925457f739d70103395ccb7dcd29d", - "0x00000000000000000000000000000000000249558e7e5b5d6473ec5a9a980688", - "0x0000000000000000000000000000006cd74958767b5d51a95549a316e285ab74", - "0x0000000000000000000000000000000000091261933d2e12b6818f72bdc3e0c2", - "0x000000000000000000000000000000f97e56f24f292a230cf6c8350df6989d74", - "0x0000000000000000000000000000000000191f5e720c5ae2ded820c5e22cf23f", - "0x000000000000000000000000000000d3659c79160cc300c1726cdfe0a093bc08", - "0x000000000000000000000000000000000028e8e8952512f8006336791f90f01d", - "0x0000000000000000000000000000007ee7b8782f98bb5d90cbdc6fe174a42009", - "0x00000000000000000000000000000000000ae0ee6c55535140057064aa3fc5f0", - "0x000000000000000000000000000000d2bb98513b84e1e6f4e0b606bc025f9c48", - "0x00000000000000000000000000000000000b21f9d209054956c0524fababf1e9", - "0x000000000000000000000000000000d81d8ac019f7fed05a6b57f7845f56e44f", - "0x00000000000000000000000000000000002971c35ad470594c9a15abfc0e25a6", - "0x000000000000000000000000000000415d3a9385f247cc4092e3aad3382acd35", - "0x000000000000000000000000000000000025f0852ecc99395598d1e68d0ca89f", - "0x0000000000000000000000000000004f32605fa17fb311a06f7fb843c15d558a", - "0x000000000000000000000000000000000005071f43d210d49c73d5f25a18a596", - "0x0000000000000000000000000000000a679653df2810b4ec4c7adcd1cd7c97c8", - "0x000000000000000000000000000000000013c145ee6755ca17c398dafb88a569", - "0x00000000000000000000000000000083bace0537b2947643af96ab4b4aa8c478", - "0x000000000000000000000000000000000011ae383aeafc332a329462493ac315", - "0x000000000000000000000000000000a18bcfba0739bc5f71bd74ec53b6837fea", - "0x00000000000000000000000000000000001c2a9a991c7dbcd75129f92ff372b1", - "0x0000000000000000000000000000002c80b406fa46ad088b2e8d4f5a5701d47c", - "0x00000000000000000000000000000000001879ed897e504955597f01336b1d86", - "0x000000000000000000000000000000655b7a8802d367044c042458a17a0aeab4", - "0x000000000000000000000000000000000021be3e235af1a949dbf105cbe725d0", + "0x0000000000000000000000000000000000000000000000000000000000000cbd", + "0x000000000000000000000000000000c4d62213b081c8e90e6c8f3587321997f5", + "0x00000000000000000000000000000000002236a0b9f0654f7cd634c9c34280f1", + "0x0000000000000000000000000000007cb00736872fd50e291ec99fb640f1f7d9", + "0x00000000000000000000000000000000002d1b1b74b74ddf7d6f964a7bdb2af3", + "0x000000000000000000000000000000f26bcf89c86dcbce68a4f1b5b73505dcec", + "0x000000000000000000000000000000000011a128ae6c7be3a962485534f27786", + "0x00000000000000000000000000000088278f8cce72a5f698601f11a1532a9dad", + "0x00000000000000000000000000000000000d9caeabde23d8c2a0bd2cdef54193", + "0x0000000000000000000000000000001cfb29930f6753e5cb6a60342c16fe5e4f", + "0x00000000000000000000000000000000001022a2847e12bdd43b96342e5b8e16", + "0x000000000000000000000000000000fefee7789c5b50b89ce3ac6155975c4319", + "0x000000000000000000000000000000000002e25d02799b225c89aba3a667d7e5", + "0x0000000000000000000000000000006e210889b06205312234c097f979fca3b5", + "0x00000000000000000000000000000000000566396dc1f8e15f3a1c3729bb3393", + "0x0000000000000000000000000000009790f776d7aaecbcaf977d3aad6070c4e4", + "0x00000000000000000000000000000000002dcdeaf93e01c780512d9950fbfd94", + "0x000000000000000000000000000000d2ef194a7b605db9c6df08b9576c97735e", + "0x00000000000000000000000000000000001ff98ab3818a3d5fdc538a7bbeb87e", + "0x000000000000000000000000000000be40a925ee773bfc3923df01da59a497d7", + "0x00000000000000000000000000000000001fb52b895f997b5a90ea722d9a4140", + "0x000000000000000000000000000000dd5a7d1074be39e4451795f983d45b5be3", + "0x00000000000000000000000000000000001cbfd5b0d763096343af10ed1f3496", + "0x0000000000000000000000000000007cc56b953bb8ef24745e9200896ee10ee1", + "0x000000000000000000000000000000000001ef96b3ae0b2677b21939012dcc17", + "0x0000000000000000000000000000004ba56f98fc7d6d956bd6302ef6941f9239", + "0x000000000000000000000000000000000010bf82473c11a65eb2ac193002bfe4", + "0x00000000000000000000000000000072739ba831885d7f767251b9cc444961e5", + "0x0000000000000000000000000000000000256ea7e1dc188341f8692fd52454cf", + "0x000000000000000000000000000000a284c1c0bd5602eb7242fda659dc49ff99", + "0x000000000000000000000000000000000002e5e663dd3bf5f961173646b8e7b3", + "0x000000000000000000000000000000194cc54081bb3ffba3c67547dcb2db4d37", + "0x00000000000000000000000000000000002377042c75bab3ceee3b186c40b8b6", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000f0af57d5589fc84e1f8897bb5a62ec0ea9", + "0x000000000000000000000000000000000016583df9856bef930ef0a81d3357f0", + "0x000000000000000000000000000000e0a92aecf729c58fa7672c82066409d090", + "0x000000000000000000000000000000000010085406672c105a10ddee00634540", + "0x00000000000000000000000000000036b650e61cb6e0ec6ff6b1aef12c8c81e3", + "0x00000000000000000000000000000000000049ced3703b6736736daa8d94d66c", + "0x00000000000000000000000000000024e41b443846d1b9d969a739fe9ec5544d", + "0x0000000000000000000000000000000000251ef94ce2811e61503920adc1a548", + "0x000000000000000000000000000000ab378c4d63d86a750348adbd4cbc2c6883", + "0x0000000000000000000000000000000000079aee0bbaec8a7e39acda8a2bfd44", + "0x000000000000000000000000000000c4996ccb316a1671fa17ac0ec536c08aee", + "0x00000000000000000000000000000000000087a93f4353d8c6e85d6c58c7af49", + "0x0000000000000000000000000000002754983ee3f30f64f3ef3d6a27f671032d", + "0x00000000000000000000000000000000001b77b7da696321894ac402dc70a471", + "0x00000000000000000000000000000065a8c950362ff55e55d6006254e4cb8f60", + "0x00000000000000000000000000000000000a0eb81f69be92cc51ba479d4d4b2d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003a6dc78277b2838aca18adc58385b4a7f0", + "0x0000000000000000000000000000000000132c99e752833cae9473e7dfe278d0", + "0x0000000000000000000000000000003ec707e1f4369d5f99a3bac8eaa16ec4ba", + "0x00000000000000000000000000000000001cd77155c0a5e65f942f719c8e73f5", + "0x00000000000000000000000000000084604af6454cd074b40340a0900f8e47cc", + "0x0000000000000000000000000000000000077d31bdfcd802cd5aa1a457b97f10", + "0x00000000000000000000000000000099c886edf1320d2f8eef9c059a2495598d", + "0x00000000000000000000000000000000001400c2b452cd839ce363493a76312b", + "0x00000000000000000000000000000090681337eb7720ddc934e8bcc81bd9ae2b", + "0x000000000000000000000000000000000006ab19688014b0f0cf860c615759af", + "0x0000000000000000000000000000007165a99470ed5af56e75a9636be648e93d", + "0x000000000000000000000000000000000009dbbccaa2350bd92c5ce19b5d290a", + "0x0000000000000000000000000000000e1e042ed81d839a9f0ead9d291b6a8f32", + "0x00000000000000000000000000000000001a205aec8c334db49f816f4b5dafcd", + "0x000000000000000000000000000000ebb4edb0db1dcdf348033a7901a3680b6a", + "0x000000000000000000000000000000000011aae86275b822ebd3fa82c7315eff", + "0x000000000000000000000000000000e97eee8ec09b50e69135709916aba933c6", + "0x000000000000000000000000000000000010e2e96f78a68fc25ba2e4dafd04cc", + "0x000000000000000000000000000000b214f0a5321e8817d78adb6e0c20d7319e", + "0x000000000000000000000000000000000025bc9ba17b749d567d90e8f13af9a2", + "0x00000000000000000000000000000066fba7ba25f999f6f2838e553a29901fa7", + "0x000000000000000000000000000000000020711b883c2eb028f9d2d3da010519", + "0x000000000000000000000000000000a140d481bdc261d13949520f9ec7371c20", + "0x0000000000000000000000000000000000020bfe682fa3abc7653ce6853b0112", + "0x0000000000000000000000000000001b2bf2cbcde5d02c025a94db3378725693", + "0x000000000000000000000000000000000023e613dfd6966df7487e58fd52480c", + "0x0000000000000000000000000000006e2eb63e8f0cbcbd7a88665a53e119e428", + "0x00000000000000000000000000000000002e70d3962ba79ea7ae10b168c1c7d9", + "0x00000000000000000000000000000030517d9ecfee899135ff976333894660c2", + "0x000000000000000000000000000000000007417244ffad99a470ba89eb0ff90e", + "0x0000000000000000000000000000009bac28f405d40e017edf00277102b49c3d", + "0x000000000000000000000000000000000006b41a5fb6e909b8be3ff0dd952728", + "0x0000000000000000000000000000006683ae1c70f7eb680544f4c342c93087f1", + "0x000000000000000000000000000000000025f0aabdb61ed9c3922c0edfb358ec", + "0x000000000000000000000000000000351b5aea3d5e9850880e66335bcae23e94", + "0x00000000000000000000000000000000000ee72d3f7aca6bbe97267028d6abf9", + "0x0000000000000000000000000000008928d9a8e7f72b161cbe49ae95aa21ae63", + "0x0000000000000000000000000000000000185c141dba0abcf1e6d7db09787ca1", + "0x0000000000000000000000000000003e245e17b3e7805608abb6a2350fa6a847", + "0x00000000000000000000000000000000000cf54864a0d0738294136903b96823", + "0x000000000000000000000000000000f11eab4aad68f934214988cc4f58d5a6a2", + "0x000000000000000000000000000000000022f67f7b7d5406007bb7ddae120884", + "0x000000000000000000000000000000c05dc37331557bb9a3f702d92cfe090666", + "0x0000000000000000000000000000000000264629b4e2c6c2614bd57046d2ac8b", + "0x00000000000000000000000000000017305f321100b05a42b9014b4b5f033fd9", + "0x00000000000000000000000000000000000300f05e18d0c58963b144d3d28da6", + "0x00000000000000000000000000000039e8490810fc737b4a353bb67d95baa83c", + "0x00000000000000000000000000000000001b8f101b87ef8f67f87224f50b4e86", + "0x00000000000000000000000000000048da15030eaa7e0cc01567e721d66ead43", + "0x0000000000000000000000000000000000126b3927169eb104827c842837f462", + "0x00000000000000000000000000000008b500094a5820c680fb1db8c125502e1e", + "0x000000000000000000000000000000000000660eef61b7d219f439ec4fbfff1b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -143,76 +143,76 @@ sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000006ab4e9fba1bb0c45d30796e0c19546192e", - "0x00000000000000000000000000000000000b1447f3413f687009608e1c55b192", - "0x000000000000000000000000000000567498365d293b6c0532b94c33d0e937a5", - "0x000000000000000000000000000000000006c4fabfa5194704563bcc508d234e", - "0x00000000000000000000000000000009835f11bc7b963372a60d92370980b183", - "0x00000000000000000000000000000000000d898f5e8487e3ed90a10fc50db186", - "0x000000000000000000000000000000b66ee3d15932d652c3b54801748e89da9f", - "0x000000000000000000000000000000000024899f4b6ba56af0e1128c4a431ba7", - "0x00000000000000000000000000000064dd7da7637cf2116a18531edc7fea829a", - "0x0000000000000000000000000000000000162e867465b02e01bbabb15c59b84d", - "0x00000000000000000000000000000071f09c1d3d2c8f9499c838fc966b04ada9", - "0x00000000000000000000000000000000000f4504ac6f302739e9f2c7aa824d12" + "0x0000000000000000000000000000001115e1df83c7f85610477a243a350ad610", + "0x000000000000000000000000000000000016b525f879d97a8d50cab6d1a41d58", + "0x0000000000000000000000000000005545bbd9cc9de7a79986b650103736492e", + "0x00000000000000000000000000000000000aac06f3452ec0a5be2b5e3060f108", + "0x000000000000000000000000000000c6e13ef9aedec4af73a577a6dd72dda690", + "0x000000000000000000000000000000000016b603e70199deaa1eff742257259f", + "0x000000000000000000000000000000dd7902c16a885b205f012abf38e3f9f470", + "0x00000000000000000000000000000000002a45b4a48e9544c186e119184fd191", + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" ] - hash = "0x051d17b4a7efa4af82e7c6b71f2a5cf71ee015e6d9edbcd39d326a5463aac1e6" + hash = "0x1e580df70c4374ef9942846936ab5fc2d7da61ca21bd0576f269746152a782c4" [previous_kernel_public_inputs] min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff293f" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7f3e" is_private_only = true -claimed_first_nullifier = "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c" +claimed_first_nullifier = "0x1b684937417a003a0e2c1602203b7630f3c2b65c422dfa2653acb1215dc0c852" claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" [previous_kernel_public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" [previous_kernel_public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [previous_kernel_public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -231,22 +231,22 @@ fee_per_da_gas = "0x000000000000000000000000000000000000000000000000000000000000 fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -268,7 +268,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] [previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] -inner = "0x29ecb485abf1e4a9963bb4dada6e8b67bda9c6bb09527ecb8d0c64a0d119e0fd" +inner = "0x302a86bd5883e95684cbcd46af941e62a60b0416ee605f00eae4a0189b8af2ee" counter = "0x0000000000000000000000000000000000000000000000000000000000000003" [previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] @@ -1301,13 +1301,9 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1316,13 +1312,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1331,13 +1323,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1346,13 +1334,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1361,13 +1345,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1376,13 +1356,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1391,13 +1367,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1406,13 +1378,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1421,13 +1389,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1436,13 +1400,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1451,13 +1411,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1466,13 +1422,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1481,13 +1433,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1496,13 +1444,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1511,13 +1455,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1526,13 +1466,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1541,13 +1477,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1556,13 +1488,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1571,13 +1499,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1586,13 +1510,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1601,13 +1521,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1616,13 +1532,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1631,13 +1543,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1646,13 +1554,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1661,13 +1565,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1676,13 +1576,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1691,13 +1587,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1706,13 +1598,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1721,13 +1609,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1736,13 +1620,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1751,13 +1631,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1766,13 +1642,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1781,13 +1653,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1796,13 +1664,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1811,13 +1675,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1826,13 +1686,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1841,13 +1697,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1856,13 +1708,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1871,13 +1719,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1886,13 +1730,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1901,13 +1741,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1916,13 +1752,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1931,13 +1763,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1946,13 +1774,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1961,13 +1785,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1976,13 +1796,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1991,13 +1807,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2006,13 +1818,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2021,13 +1829,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2036,13 +1840,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2051,13 +1851,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2066,13 +1862,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2081,13 +1873,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2096,13 +1884,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2111,13 +1895,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2126,13 +1906,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2141,13 +1917,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2156,13 +1928,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2171,13 +1939,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2186,13 +1950,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2201,13 +1961,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2216,13 +1972,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2231,13 +1983,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2246,13 +1994,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2779,7 +2523,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" counter = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x1f9942757ace032bb97eaa996ab3756544b55ccf805fdbf6f5093a5b8037e138" + value = "0x17479bfa3540b0edace48659f4f97a2f4dc9d4023b9c08bba4a1819e0ef21beb" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -6009,22 +5753,22 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.private_call_stack.array]] - args_hash = "0x00fdacb86277b5caac1f0395131955d3d7ddd5988f117d742d59ecdeef9db7a5" - returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" - end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000010" + args_hash = "0x05eabce2b553dfa52a6b3f33cd603318310b2f9f56a14d6eefbd3bbf640cb107" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" [previous_kernel_public_inputs.end.private_call_stack.array.call_context] - is_static_call = false + is_static_call = true [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x09d3e27b2b71e2140366b7b610129b819b841efe0dc06bf715e3eb5b68f65571" [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c" [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] - inner = "0x00000000000000000000000000000000000000000000000000000000754fb767" + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" [[previous_kernel_public_inputs.end.private_call_stack.array]] args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6307,121 +6051,121 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [private_call.vk] key = [ - "0x000000000000000000000000000000000000000000000000000000000000000f", + "0x000000000000000000000000000000000000000000000000000000000000000d", "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000367", - "0x00000000000000000000000000000077c298f63acd57d13cd760f1b09e733bc3", - "0x000000000000000000000000000000000026a287c4760845db19abbc695ff36a", - "0x00000000000000000000000000000069e321196774777d330d8c47b62018ee30", - "0x0000000000000000000000000000000000295262e94218827820d221f1a676f2", - "0x000000000000000000000000000000257dbf8aaa5e15520c24e9f783198f1cfe", - "0x0000000000000000000000000000000000190713b989ee2b0ecde498ce10b549", - "0x0000000000000000000000000000002295cabfb39afdc4509c3dd66e4c75da5e", - "0x000000000000000000000000000000000027507b50fee92f2d43690c874e86a2", - "0x000000000000000000000000000000aa13c08a3a7c1467715828adcb937c2043", - "0x00000000000000000000000000000000000f8a1543c6677019dc01eb2ce85dc8", - "0x0000000000000000000000000000001675deda7e3dafff4e33979da4ebd705c4", - "0x0000000000000000000000000000000000289905e8a6dc218db585b427eb056e", - "0x0000000000000000000000000000005ca36b42f5d503af3510645776a182509a", - "0x00000000000000000000000000000000002dd8eef985765f468fae90d96ba6fc", - "0x000000000000000000000000000000cea81c59bacc58df526b5e5f65fef5b74d", - "0x00000000000000000000000000000000001c6fb7347dc56d363c90b8d4488579", - "0x00000000000000000000000000000031fde8e713e9e8fc77842379f6745e401e", - "0x00000000000000000000000000000000002a4395c65a14e549b33900648d7960", - "0x0000000000000000000000000000005c83438275fadd9a66b48380362607b9ec", - "0x00000000000000000000000000000000001b2c0ed48bd9ac3b17f36ced09b85a", - "0x0000000000000000000000000000005a3fbe86fc074463d664ec1028991daf15", - "0x00000000000000000000000000000000001c2bca0518d0dc405eecc6c9b66511", - "0x00000000000000000000000000000058fb55a413b7865807590827cbb9007644", - "0x000000000000000000000000000000000009d6fc59acc8a61214589672dcea3d", - "0x00000000000000000000000000000006e868544e82268dc595a57ee6d88aaa33", - "0x00000000000000000000000000000000002de9cde4733c1f06fdb8ac10fda985", - "0x00000000000000000000000000000061bad33649e2767633ba30e687da7b70ac", - "0x00000000000000000000000000000000002c0b0343148e6beab80557d74f318e", - "0x0000000000000000000000000000004df9e2c11487e96cde4a354328c2322b7e", - "0x00000000000000000000000000000000001e71380507bf8f7a65f542a668967e", - "0x000000000000000000000000000000387a87e1fd5a4d755a72bf4223e72cf175", - "0x0000000000000000000000000000000000140d1d6145c78a4cd60b85534d174f", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000009ebab60fa5dc47e1914fda39298f7e6ac7", - "0x0000000000000000000000000000000000110e8c462632d85486fb2b573bb0ff", - "0x0000000000000000000000000000007d5067869e4f6c37bf78d104a880ad37e8", - "0x00000000000000000000000000000000001b8a3f8dbb8f2a3ecdd71594aca606", - "0x000000000000000000000000000000780fb7de9447ebdaf30ee24fbe3cba1300", - "0x0000000000000000000000000000000000084d032f1ae838a33a86164a6541df", - "0x000000000000000000000000000000c359ee0159370b1406940ba9db56dc4ff2", - "0x00000000000000000000000000000000001cfb12b15f63bd6b2c321b0a84f51f", - "0x00000000000000000000000000000073f32650074f87a7b77470996beeacdfe4", - "0x000000000000000000000000000000000005647aa1addd19b3136ec411e71431", - "0x000000000000000000000000000000258e47dcc86acc1d400247381ab87d4725", - "0x0000000000000000000000000000000000295e68d808cf3b272d91be2fd2ae37", - "0x0000000000000000000000000000003ba26fee14fb99c3515f5bbf524129e34f", - "0x00000000000000000000000000000000000466b9f8edd37c3fa3c7d06d1a7986", - "0x0000000000000000000000000000008318efe19eaaca4d497ad4912aa208ecee", - "0x0000000000000000000000000000000000013e5dc7040c7f8b74cec4df5572bd", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000708a99a1df6e2f08c37655b04da1516fb", - "0x0000000000000000000000000000000000200f93be3bb23204915ddf19a6102b", - "0x0000000000000000000000000000003ff62e27b5552bbe8742ef48a1ce956a38", - "0x00000000000000000000000000000000002eb0dfb213e5244c19612993acc338", - "0x0000000000000000000000000000000c97bab3896ad5ed1bdbc6811f35b52088", - "0x000000000000000000000000000000000024ed3a2bfaf9b9620f0cf2c2210117", - "0x00000000000000000000000000000010515c3eda29482356a09bc84a2f1455b6", - "0x00000000000000000000000000000000000a473218b2415232276d99ee32b8ee", - "0x000000000000000000000000000000caed4590a347c4d3079e1d47713f5b83e1", - "0x000000000000000000000000000000000017405dec66fa4028a4f662a5b3bc5e", - "0x0000000000000000000000000000000c1444e30937299c89f8208ffe290cc18c", - "0x00000000000000000000000000000000001ebb18f648670cdd53f595444360e2", - "0x00000000000000000000000000000080b476643287925a5f4195f56b06fdd3ed", - "0x00000000000000000000000000000000001ca4ac04e44de10be2048a9bebcc62", - "0x000000000000000000000000000000cc5c01a1dc52e751c01dd9ba1cb9b49cb7", - "0x000000000000000000000000000000000022a62f4ddacd5cff46b90a535daa0a", - "0x000000000000000000000000000000dad72ff673733fba291f0d57a41d942e0a", - "0x000000000000000000000000000000000021a56ad22274e1b58118768b538104", - "0x0000000000000000000000000000005a34af8d8c8aa47da41eb1e75a0dfb8fd0", - "0x000000000000000000000000000000000026707f18815730d1a64214fcbfcc1f", - "0x000000000000000000000000000000d646a8a65170a6b78d80190d8a21ea1dff", - "0x000000000000000000000000000000000014bb9f8b9321b456fd18feafe1e161", - "0x0000000000000000000000000000001d878bb4be89e69a6688949dcaf0ce7ea4", - "0x00000000000000000000000000000000000f536993bd0cba9f0585f1df277c57", - "0x000000000000000000000000000000748b419096289f75352c8d5d112f7fdae2", - "0x0000000000000000000000000000000000022790c5c22cbd4366b0ad6e2b4519", - "0x000000000000000000000000000000fbaaa9a8b489397bc3e4d7f1056574b2e2", - "0x00000000000000000000000000000000000fae47872873bb913289047ed5610c", - "0x000000000000000000000000000000d9609f0d20812e6577cf8f21f2625e3172", - "0x00000000000000000000000000000000001b995278cd324d1fb4ec16ad835993", - "0x00000000000000000000000000000048894f6e04feabafb53f7a7b67c9e4c0e5", - "0x000000000000000000000000000000000027ec0d2be1c42a0a90b0ea2af01861", - "0x00000000000000000000000000000003e5fa4bc70fe52643ca6985c073c70dc3", - "0x0000000000000000000000000000000000038e1e0276e2e6dfe9a9d8aa596b76", - "0x00000000000000000000000000000065526bfbb668d3f936d18df508e43bccb3", - "0x00000000000000000000000000000000001f65337846109ac55e93e42a9fa3cc", - "0x000000000000000000000000000000585161baf0203d961615740c9ba7c9e707", - "0x000000000000000000000000000000000005728984358785c066c4cd63845858", - "0x0000000000000000000000000000002ff9899e736c45e4f04a866d93f57c116b", - "0x00000000000000000000000000000000002c4d422fd03c9a5b2e329d93362757", - "0x0000000000000000000000000000002cf70e3a6f9fe963cc77d1520d5d4edee6", - "0x000000000000000000000000000000000005f00e31445a7a9cd4219d268a06d4", - "0x00000000000000000000000000000025a2bc22bef7d083c5f847e80f943c189d", - "0x00000000000000000000000000000000001239130781e0d914daca12578a2b41", - "0x000000000000000000000000000000f3696d80095221316a91e185aec90d4607", - "0x00000000000000000000000000000000001469812dd8efeca285ecc964c4e02c", - "0x000000000000000000000000000000b9583e757e383f8ac91620436cfd8b488b", - "0x0000000000000000000000000000000000086edbc84ee73808efb9a82a2f806e", - "0x000000000000000000000000000000d8b0ecd6e3cddb9c693c8bf1d32795968e", - "0x00000000000000000000000000000000002757dfd7d21719de99dd25b8fc095a", - "0x000000000000000000000000000000684a589b8e853856d7cffbbf4293bf3571", - "0x00000000000000000000000000000000001c280b47d50b66bc53b6b635dc9827", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -6442,24 +6186,24 @@ key = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000b91c3664d3270a60931c471928222bf6b", - "0x00000000000000000000000000000000001a702fa77522ea7356d9d6ed1c9b9e", - "0x00000000000000000000000000000032f9984b982de6753a3668f46872fee3db", - "0x00000000000000000000000000000000003036d9814a9753be22125d50c268e7", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000585fcdfa31b424adfe685b43435cdc567", - "0x00000000000000000000000000000000002717439949acf883c385bc7c246dc6", - "0x000000000000000000000000000000b97f0f863a1005a5c88ba628c1d8bb1740", - "0x000000000000000000000000000000000001f73676f90fa92e0bd9ce8716cfb9" + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" ] -hash = "0x147ef2802ee4a878790fc89ab3a742a3f9e794df4ba16a3c013856118e5e54d7" +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" [private_call.verification_key_hints] -contract_class_artifact_hash = "0x17936c22a18e1310c8a71802414ad55bbea4d490023a55358f249edace43f2fb" -contract_class_public_bytecode_commitment = "0x1e88df4d0fb9c20b21bce0f5067f3f4c9a9da39101d2936741eb5b0cfcfc9a40" +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" updated_class_id_delayed_public_mutable_values = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -6467,51 +6211,41 @@ updated_class_id_delayed_public_mutable_values = [ ] [private_call.verification_key_hints.function_leaf_membership_witness] - leaf_index = "3" + leaf_index = "1" sibling_path = [ - "0x1768f4ffe236f2d0d6f6e42ad30d7c9ace25c145ede7b699e3a551e0f90f65de", - "0x0a83a13c3704cbec2a1c8aeab69534367d70b291243f955cf1aea1caa6092382", - "0x04f1d72b0df1c0b8759643e6ae23442a5cdfe090978072dd559a8319c0811952", - "0x29e60d7288e9b28c0d1e6f4c7244c3b92efdd2de4e7042b85a1291c2ec910b1f", + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" ] -[private_call.verification_key_hints.public_keys.npk_m.inner] -x = "0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd" -y = "0x170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e344" -is_infinite = false + [private_call.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" [private_call.verification_key_hints.public_keys.ivpk_m.inner] x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" -is_infinite = false - -[private_call.verification_key_hints.public_keys.ovpk_m.inner] -x = "0x1b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287" -y = "0x080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833" -is_infinite = false - -[private_call.verification_key_hints.public_keys.tpk_m.inner] -x = "0x019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb" -y = "0x2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f" is_infinite = false [private_call.verification_key_hints.salted_initialization_hash] - inner = "0x283b87e95914a45f14ba1dbc2445f080d54b98ca600ca9c8a09bf4e6059b8e4b" + inner = "0x2c34a9418dab220d2f208289abd62de8f7eb8abca9e10988c48eccc4424221ac" [private_call.verification_key_hints.updated_class_id_witness] - leaf_index = "117" + leaf_index = "131" sibling_path = [ - "0x0371d4f7e5e7a3a1bc6eb35796ae80686c69151d345a495f9a6b43b11f13120c", - "0x015f1e689c2e78468161bdc9d10fabf2ce528bc217db9dc422ba929a70b5e860", - "0x2523970382de270c1acd87f98b4ed454353257f9c689dc608f7dc1b6ca23741a", - "0x2fa84a2c6fb5f1b544d9acb5620c87e8930bcc2f6411312fcc5d580ab4883a92", - "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", - "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", - "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", - "0x27c696ad87d2ae17e4005225c67d015eaca8a9c6e97dec181f97f15e2c1ff894", + "0x03a2485ed0c18f1f0b27f8cb762f330dc41f2fc280d4d3f073b4d72304ffe4fa", + "0x1d12604d1468fe48df2d32605da5dc60d5f557903d21f08ea292c9c4f0e5c939", + "0x1701fbabc2818af0649d35ba0bc29213fc7509835e081c1cab5501f63aae6757", + "0x2c82e75f6b16fa4ea9b4f7d46757ced7ac33905daa90ce61a6eea6a315fa79c8", + "0x1d52af9cd9f69c1286e9a96fd498e736789a5bc463fceb1c176a4f9292f7cbe3", + "0x1ff1d5db01572c915915a22173c73d8073df9af4e4c57f6af29df5315da44419", + "0x070dcbac794fa663bc71b42d80775c0cea8c3ed7580207cfd30fd1285813ce07", + "0x0202d252c8608f54b289d11e2ee5c49b48f809e3d008c80de0da1409f19d20a1", "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", @@ -6547,41 +6281,41 @@ is_infinite = false ] [private_call.verification_key_hints.updated_class_id_leaf] - slot = "0x00d9d7e98b29d1f3eadd6bcce14809b2ca27ba47b772ef0401455915ab91d062" - value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" - next_slot = "0x09667a49b892551e41d7ace7350264dab6567641a5096948a522f8e57069a8c0" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000076" + slot = "0x21217fba0620ad412df7954c1e33104958d3bd37f436672fdd7e0a42b47b29a4" + value = "0x05208323f49682fc3367ed42a0212854a797b5372b0cc6bc5493b00e96ff256d" + next_slot = "0x264534c4e6c3e98e04eb89dc84eac7e5a46ff6d391ab9eb97f44cc862bf0df7d" + next_index = "0x000000000000000000000000000000000000000000000000000000000000007d" [app_public_inputs] -args_hash = "0x00fdacb86277b5caac1f0395131955d3d7ddd5988f117d742d59ecdeef9db7a5" -returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" -start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" -end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000010" +args_hash = "0x05eabce2b553dfa52a6b3f33cd603318310b2f9f56a14d6eefbd3bbf640cb107" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" -expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000007" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" is_fee_payer = false -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff2940" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7f3f" [app_public_inputs.call_context] - is_static_call = false + is_static_call = true [app_public_inputs.call_context.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x09d3e27b2b71e2140366b7b610129b819b841efe0dc06bf715e3eb5b68f65571" [app_public_inputs.call_context.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c" [app_public_inputs.call_context.function_selector] - inner = "0x00000000000000000000000000000000000000000000000000000000754fb767" + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" [app_public_inputs.note_hash_read_requests] length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[app_public_inputs.note_hash_read_requests.array]] [app_public_inputs.note_hash_read_requests.array.inner] -inner = "0x14d24541deb5dd2fb77037cada005cc9755e7cdde176fafaa83d4038e6ffe551" -counter = "0x0000000000000000000000000000000000000000000000000000000000000008" +inner = "0x21c7e2027864f293ff502b26ca73419fb7de391a18467849bba3e7debd669312" +counter = "0x0000000000000000000000000000000000000000000000000000000000000009" [app_public_inputs.note_hash_read_requests.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6707,12 +6441,12 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifier_read_requests] - length = "0x0000000000000000000000000000000000000000000000000000000000000001" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.nullifier_read_requests.array]] [app_public_inputs.nullifier_read_requests.array.inner] -inner = "0x16c07a80d3d164d5d8082a5dda9fb5d5f0de35fc2bc4ac2fa36182ed91ce381f" -counter = "0x0000000000000000000000000000000000000000000000000000000000000007" +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifier_read_requests.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6838,194 +6572,130 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators] - length = "0x0000000000000000000000000000000000000000000000000000000000000001" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.key_validation_requests_and_separators.array]] - key_type_domain_separator = "0x000000000000000000000000000000000000000000000000000000000e6ebabc" + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] - sk_app = "0x06676b93f3cec2a77597fadc4704afee9dc237873051a7e2638df02f77e35be9" - - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x025f9f657095ad240d89a28336e0f7be994c9f270d62c6a3228aa8bada12d01d" - y = "0x1a7e0782cbdd3ebc39b0bd4a33b5894cb3451bc52c2fadd70371ed8d81db479f" - is_infinite = false + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [app_public_inputs.note_hashes] - length = "0x0000000000000000000000000000000000000000000000000000000000000002" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.note_hashes.array]] - inner = "0x00def7bf22ad78b9b414af8c6b920730b29275a17b6c869a3e9ad3929c416c6f" - counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.note_hashes.array]] - inner = "0x1552be33f460bfea48702663acfd93ed46d02df9080308666dccf3eec187faa8" - counter = "0x000000000000000000000000000000000000000000000000000000000000000c" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.note_hashes.array]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -7084,20 +6754,20 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifiers] - length = "0x0000000000000000000000000000000000000000000000000000000000000002" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.nullifiers.array]] - counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifiers.array.inner] - value = "0x0c3f7479d44d8ec07d6aa92e715150ec4366e314b2fca5b309e6cb9e9948f56a" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.nullifiers.array]] - counter = "0x000000000000000000000000000000000000000000000000000000000000000e" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifiers.array.inner] - value = "0x265ec541731007783d79c1154c1bf3c5a3a11617bf2d3bf679d939f52d140b8c" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.nullifiers.array]] @@ -7850,88 +7520,88 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs] - length = "0x0000000000000000000000000000000000000000000000000000000000000003" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.private_logs.array]] - counter = "0x000000000000000000000000000000000000000000000000000000000000000b" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner] - note_hash_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner.log] fields = [ - "0x0a19e21c4ab1897aa638eb354bb44aaccdb24a11525f3186595e2d2271248d15", - "0x10433733db106ed8336b9b799ec2debee9fe2da75f114f567eefde5abf9f74d3", - "0x17440c522b009a136c2207db86790b05464774690523c7fbf949ad381664d0ea", - "0x0a5e8928a4d74ad3256e8a697cfdf84b7baae32abad67b2de7c36ffd67acb665", - "0x0b1200621e156c6d79f463e17e81b96f11d18d716ca5222e7276e07d45845a26", - "0x04b2b64d09e487d10d557106046a94a97f2c40f4316e6667a2c2d9a99db05385", - "0x193da3d713c24b85e1c8f22dd8ef575e88d19c6732f8fd17e370cf64e65b3e04", - "0x08569203e8f3d028234ed200df77bca848c9b4b015ad8797c37669a5e5d1ee0c", - "0x13a9b2003409ad3d4f38caba797acc77092ddd431af25a955a83dc6f5b92cc93", - "0x16fece01bc0b0205bcbaca2904d5674d10573bfef038f94d3e5d526596da2ae9", - "0x0a438177a05071eaeb1862f154b187315de4dc804e275b0f2258baf4700c6d64", - "0x0959244a76e5e861ce5b8833101b91e19d758109d68cc174a6f9eec9c7afa008", - "0x03533d18a1c3ebcf22f820a243be161c9798ea59a506572e32e125c53b7aee7e", - "0x1e2b22ea302597bfcbcfdefcda48b60e35fce9c70f46c6cb90fa6db6e8d4dc6d", - "0x28fab93b8cd28d8d2a993badc3d1a080902feecfab019dc7c00af0ea9f6f403d", - "0x104c4c81c135af94af35a1eeb49b1262e5c53e25ee513731ddeb9f6496eea2ab" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.private_logs.array]] - counter = "0x000000000000000000000000000000000000000000000000000000000000000d" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner] - note_hash_counter = "0x000000000000000000000000000000000000000000000000000000000000000c" + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner.log] fields = [ - "0x009ca00e8f7d20a40d1266a37a186cd96c78b285a2506210cabc2fa353489be2", - "0x2320e89fb76918e7dc48b13861302dbf78af5ba8d5a20da77d19781ac32b9bc2", - "0x2a99619c0d4d380dbc3d53d03ed35011aa9c296a507fabcf712f43a0e5a10850", - "0x02e5d98e7dfbe7653dafb14afddd7e00f403b5a60816d7ab961823bd3cc4b628", - "0x223b37d6caffe87e91cddafdf65c4f641a609ff13350d02654b0fed1443088ab", - "0x2846b9aa4544f8f8851554f5d0c189c188756d734112e1eedd6840c8aeb0e66f", - "0x21cda3f228d55fb1b37f2b7c7a5d42066007143db17645669521ff58956fa7bf", - "0x1d8d79951d7389e5f9dfa963f93e399aebaa346e9ce3b3a5da1b45e4600a1553", - "0x15eabc8ed921f60621fa4fa35214748a7593f1c06a1e66b76092f789b4960bc5", - "0x16babb28d68725cb64d6d7558d49fb921c480359488fcdfb5292019239a50563", - "0x015e561b49da425d081b87bac01336defa1e29ee50d01b7be798ac28e05b24d6", - "0x04bf1a23807cb0711511a6140caf195df55fcf029842652243034ae2ca740648", - "0x2789cc422a86395739004c513cf6a15024e3adf5f2e238b18e1b4f1211a9383a", - "0x00c4e950cfe804e8a3623fe768c82b7340b0216f93c00351c53e2144364cfb51", - "0x2fd9827b4118b7ef401dff1727785e46fdd31947d2e733f4b39076f43652c18a", - "0x158ca7fba6e7fa7b3eb7c062751182d93b4e36b5c77d2e609e246b810650e59e" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.private_logs.array]] - counter = "0x000000000000000000000000000000000000000000000000000000000000000f" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner] note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner.log] fields = [ - "0x145c6a232e670e3f0babf2a60ced437e3b543087bb24e9d398e05add3513dfa4", - "0x127157561e774918ba656738fb61ad37f92086431bd4f1e4842ab11928b0f8d2", - "0x2e5cf59c8f2eee7a06d14cdedb8fe58945357cb16f4c792094325909a12924b2", - "0x0e29376c31f2aa7a156c6ce6d1fc9529998251d8500604658f173ff86adffa98", - "0x20761b8be9a186cf6a1730b8a1e99049a07e45c005e66d27b6e0ef15a2833e2f", - "0x1adf679b2441cf3535241924a35164cf8309256721e3f9fcb860bc2acc462b46", - "0x06a613741497b7b7ee978a495bfed7d19bbf76c462d268cee17a3920b1b1abe0", - "0x10ade06e253c1cfd65f24246211fb703c157fd9b563ffaf6ab01b6fba4635155", - "0x2311c6b104555d4d9afc7d66be6b47a41f8aa96eb77f613a75fc952da5975ccf", - "0x08431c3838d7ad6198c1d33ff138953ace3520551bd95b69692609ee11ded216", - "0x1822c33cf8097138c896bb9f7aad7def909a6859d5e640919fd16ebcf153a0db", - "0x11203b31ef49d39fb85a5ea474116c334c156091ab468493a480f13ad1ec1849", - "0x207a4712bacadd2f631fe253cb62932a7acb586dd6dd1b10e0fbe733f61a8f11", - "0x2c862b0eb14b1325a0ca63dda4570f718541d998fb4aba96339b7913b80757c9", - "0x1bf17ee7d3cf2487dcf1eb7a3647b0920c9e68aacc0a33c9a424d4ee6601ded3", - "0x2c70c9b7da7d7df78fcae182d124d7041209070f76d920e5d5c2d7590c385ea1" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.private_logs.array]] counter = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -8295,50 +7965,50 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" length = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [app_public_inputs.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [app_public_inputs.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [app_public_inputs.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [app_public_inputs.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [app_public_inputs.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [app_public_inputs.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [app_public_inputs.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [app_public_inputs.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [app_public_inputs.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [app_public_inputs.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/key_validation_request_validator_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/key_validation_request_validator_tests.nr index 79cb6194f051..a637c416730a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/key_validation_request_validator_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/key_validation_request_validator_tests.nr @@ -12,7 +12,7 @@ fn clear_all_succeeds() { assert(propagated.array.is_empty()); } -#[test(should_fail_with = "Failed to derive matching master public key from the secret key")] +#[test(should_fail_with = "Failed to derive matching master public key hash from the secret key")] fn wrong_secret_key_hint_fails() { let mut builder = TestBuilder::new_clear_all(); @@ -45,12 +45,13 @@ fn amount_to_validate_smaller_than_hints_fails() { builder.validate_with_amount::(); } -#[test(should_fail_with = "Failed to derive matching master public key from the secret key")] +#[test(should_fail_with = "Derived master public key cannot be the point at infinity")] fn hints_fewer_than_requests_fails() { let mut builder = TestBuilder::empty(); builder.add_request_and_hint(11); - // Add an extra request without a hint. + // Add an extra request without a hint. The missing hint slot is implicitly sk_m = 0, which + // derives the point at infinity and is rejected by the kernel. builder.add_request(22); builder.validate(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/mod.nr index 1f5d66b0d683..d17e3e0d56f3 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/mod.nr @@ -10,7 +10,8 @@ use types::{ abis::validation_requests::{KeyValidationRequest, KeyValidationRequestAndSeparator}, address::AztecAddress, hash::compute_app_siloed_secret_key, - point::Point, + point::EmbeddedCurvePoint, + public_keys::hash_public_key, scalar::Scalar, side_effect::Scoped, traits::{Empty, FromField}, @@ -73,14 +74,15 @@ impl TestBuilder { let contract_address = AztecAddress::from_field(456654); let sk_m = Scalar::from_field(sk); - let pk_m: Point = derive_public_key(sk_m).into(); + let pk_m = derive_public_key(sk_m); + let pk_m_hash = hash_public_key(pk_m); let key_type_domain_separator = 123321; let sk_app = compute_app_siloed_secret_key(sk_m, contract_address, key_type_domain_separator); let request = KeyValidationRequestAndSeparator { - request: KeyValidationRequest { pk_m, sk_app }, + request: KeyValidationRequest { pk_m_hash, sk_app }, key_type_domain_separator, } .scope(contract_address); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/validate_key_validation_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/validate_key_validation_request.nr index d8c0ff6f4abe..35063c20692f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/validate_key_validation_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/validate_key_validation_request.nr @@ -1,7 +1,8 @@ use std::embedded_curve_ops::fixed_base_scalar_mul as derive_public_key; use types::{ abis::validation_requests::KeyValidationRequestAndSeparator, - hash::compute_app_siloed_secret_key, point::Point, scalar::Scalar, side_effect::Scoped, + hash::compute_app_siloed_secret_key, point::EmbeddedCurvePoint, public_keys::hash_public_key, + scalar::Scalar, side_effect::Scoped, }; /// Validates a Key Validation Request that an app circuit has submitted to the kernel. @@ -16,22 +17,22 @@ use types::{ /// validation request" to the protocol's kernel circuits (which _are_ /// allowed to see certain master secret keys (sk_m)). /// -/// When a Key Validation Request tuple of (sk_app, Pk_m, app_address) is -/// submitted to the kernel, it will perform the following derivations -/// to validate the relationship between the claimed sk_app and the user's -/// Pk_m: +/// The app circuit only sees `pk_m_hash` (not the raw point). The kernel derives the +/// point from `sk_m`, hashes it, and asserts equality. When a Key Validation Request tuple of +/// (sk_app, pk_m_hash, app_address) is submitted to the kernel, it performs the following +/// derivations to validate the relationship between the claimed sk_app and the user's pk_m: /// -/// (sk_m) ----> * G ----> Pk_m -/// | | -/// v We use the kernel to prove this -/// h(sk_m, app_address) | sk_app-Pk_m relationship, because app -/// | circuits must not be trusted to see sk_m. -/// v | -/// sk_app - - - - - - - - - +/// (sk_m) ----> * G ----> pk_m ----> hash_public_key(pk_m) +/// | | +/// v | We use the kernel to prove this +/// h(sk_m, app_address) | sk_app-pk_m_hash relationship, because app +/// | | circuits must not be trusted to see sk_m. +/// v | +/// sk_app - - - - - - - - - - - - - - - - - - /// /// Where G is a hard-coded, protocol-defined generator for deriving user public keys. /// -/// The fact that the user is able to furnish a sk_m that derives both the Pk_m and +/// The fact that the user is able to furnish a sk_m that derives both the pk_m_hash and the /// sk_app of the key_validation_request proves that this sk_m is the correct one. /// If the wrong sk_m were used, then the assertions below would fail, and the user's /// tx would not contain a valid proof and so would not be includable in a block. @@ -44,7 +45,6 @@ use types::{ /// of a secret key). Key validation requests are slightly more efficient (although /// the overhead of managing arrays of key validation requests in the kernels might /// counter that claim). -/// pub fn validate_key_validation_request( scoped_request: Scoped, sk_m: Scalar, @@ -54,12 +54,20 @@ pub fn validate_key_validation_request( let request = request_and_separator.request; let key_type_domain_separator = request_and_separator.key_type_domain_separator; - // First we check that the derived public key matches the master public key from the request. - let pk_m: Point = derive_public_key(sk_m).into(); + // First we check that the hash of the derived public key matches the requested pk_m_hash. + let pk_m = derive_public_key(sk_m); + + // Safeguard against using a secret key equals to zero. + assert_eq( + pk_m.is_infinite(), + false, + "Derived master public key cannot be the point at infinity", + ); + assert_eq( - pk_m, - request.pk_m, - "Failed to derive matching master public key from the secret key", + hash_public_key(pk_m), + request.pk_m_hash, + "Failed to derive matching master public key hash from the secret key", ); // Then we check that siloing the master secret key with the contract address gives the app-siloed secret key. diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_init/private_call_data/validate_contract_address_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_init/private_call_data/validate_contract_address_tests.nr index 574ae4cceeef..ab3428dedccb 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_init/private_call_data/validate_contract_address_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_init/private_call_data/validate_contract_address_tests.nr @@ -89,7 +89,7 @@ fn incorrect_address_preimage() { let mut builder = TestBuilder::new_with_regular_contract(); builder.private_call.public_keys.ivpk_m.inner = - derive_public_key(EmbeddedCurveScalar::from_field(69)).into(); + derive_public_key(EmbeddedCurveScalar::from_field(69)); builder.execute_and_fail(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_inner/output_composition_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_inner/output_composition_tests.nr index 672ad79dbd3e..35086fd530f5 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_inner/output_composition_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_inner/output_composition_tests.nr @@ -13,7 +13,6 @@ use types::{ MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_LOGS_PER_CALL, MAX_PRIVATE_LOGS_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS, }, - point::Point, traits::{Empty, FromField}, utils::arrays::subarray, }; @@ -732,7 +731,7 @@ fn with_allowed_empty_values_from_private_call() { let _ = builder.private_call.add_nullifier_read_request(0); let empty_nullifier_read_request = builder.private_call.nullifier_read_requests.storage()[0]; - builder.private_call.add_request_for_key_validation(Point::empty(), 0, 0); + builder.private_call.add_request_for_key_validation(0, 0, 0); let empty_key_validation_request = builder.private_call.scoped_key_validation_requests_and_separators.storage()[0]; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/key_validation_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/key_validation_tests.nr index ec05925a20cf..6b6970ddc918 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/key_validation_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/key_validation_tests.nr @@ -28,7 +28,7 @@ fn validate_and_propagate_key_validation_requests() { ); } -#[test(should_fail_with = "Failed to derive matching master public key from the secret key")] +#[test(should_fail_with = "Failed to derive matching master public key hash from the secret key")] fn wrong_order_for_key_validation_request() { let mut builder = TestBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/mod.nr index 18b177e70e18..56a503ae2cc4 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/mod.nr @@ -34,7 +34,8 @@ use types::{ merkle_tree::{ LeafPreimage, MembershipWitness, nullifier_merkle_hash, test_utils::SingleSubtreeMerkleTree, }, - point::Point, + point::EmbeddedCurvePoint, + public_keys::hash_public_key, side_effect::{Counted, Scoped}, traits::Empty, utils::arrays::find_first_index, @@ -199,14 +200,19 @@ impl TestBuilder { pub fn add_key_validation_request(&mut self, sk: Field) { let sk_m = EmbeddedCurveScalar::from_field(sk); - let pk_m: Point = derive_public_key(sk_m).into(); + let pk_m = derive_public_key(sk_m); + let pk_m_hash = hash_public_key(pk_m); let key_type_domain_separator = 123321; let contract_address = self.previous_kernel.contract_address; let sk_app = compute_app_siloed_secret_key(sk_m, contract_address, key_type_domain_separator); - self.previous_kernel.add_request_for_key_validation(pk_m, sk_app, key_type_domain_separator); + self.previous_kernel.add_request_for_key_validation( + pk_m_hash, + sk_app, + key_type_domain_separator, + ); } pub fn add_key_validation_request_and_hint(&mut self, sk: Field) { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail/previous_kernel_validation_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail/previous_kernel_validation_tests.nr index 2e33f970918f..8cf8526d0597 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail/previous_kernel_validation_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail/previous_kernel_validation_tests.nr @@ -5,7 +5,6 @@ use types::{ CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, DOM_SEP__IVSK_M, PRIVATE_KERNEL_TAIL_VK_INDEX, PRIVATE_LOG_SIZE_IN_FIELDS, }, - point::Point, side_effect::Scoped, traits::{Empty, FromField}, }; @@ -31,11 +30,7 @@ fn non_empty_nullifier_read_requests() { #[test(should_fail_with = "Non empty key validation requests")] fn non_empty_key_validations() { let mut builder = TestBuilder::new(); - builder.previous_kernel.add_request_for_key_validation( - Point { x: 1, y: 2, is_infinite: false }, - 27, - DOM_SEP__IVSK_M as Field, - ); + builder.previous_kernel.add_request_for_key_validation(12345, 27, DOM_SEP__IVSK_M as Field); let _ = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail_to_public/previous_kernel_validation_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail_to_public/previous_kernel_validation_tests.nr index 88c70307d89d..9f8bb43390d6 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail_to_public/previous_kernel_validation_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail_to_public/previous_kernel_validation_tests.nr @@ -5,7 +5,6 @@ use types::{ CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, DOM_SEP__TSK_M, PRIVATE_KERNEL_TAIL_VK_INDEX, PRIVATE_LOG_SIZE_IN_FIELDS, }, - point::Point, side_effect::Scoped, traits::{Empty, FromField}, }; @@ -40,11 +39,7 @@ fn non_empty_nullifier_read_requests() { #[test(should_fail_with = "Non empty key validation requests")] fn non_empty_key_validations() { let mut builder = TestBuilder::new(); - builder.previous_kernel.add_request_for_key_validation( - Point { x: 1, y: 2, is_infinite: false }, - 27, - DOM_SEP__TSK_M as Field, - ); + builder.previous_kernel.add_request_for_key_validation(12345, 27, DOM_SEP__TSK_M as Field); let _ = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/Prover.toml index 2743b35323d1..b8e9f10ef706 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/Prover.toml @@ -1,128 +1,128 @@ [previous_kernel.vk_data] -leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000041" sibling_path = [ - "0x0ddc610a21615b2984181082c3de07058b9f7d4be62806c4fd475161f8bd2be3", - "0x0f92d54d29bddf6ec768db2c0b4685fb325d248b3ad9a3c6adda76c6c5004224", - "0x0656bbf5e3f4cc4fa5e2fa46e7fd370db0bee05586a1849c37c77d05abe2d8a5", - "0x166399703d23a5c22febc6185f8eb93c72b65906eefef226e643c35fa0022adb", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x12c59c16ed84032f7c5273ff19d7a05e8e861c23959fb71cf4b2c6ac45d21f8c", + "0x225eef52a484280b0f1c6cb9f90a84dc301536c01bfa4d61bd6496b3eaf19052", + "0x0e084e8198288b2ff94eaf4d6f37fba06e430a879dd37c726a3b5a65416fe6b6", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x0e9cb07dc8495e2adab02c5db0e34a0dbe42e9b473e0462641c54f73a4a4fdd3" ] [previous_kernel.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000011", "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000c11", - "0x000000000000000000000000000000b56b478d39fe1ea8636ca1c5f7efe26465", - "0x00000000000000000000000000000000002ce8a9b4b8b40012f631f6a39b6121", - "0x000000000000000000000000000000e90605e79e3b491b4e35bed971ffe40f20", - "0x000000000000000000000000000000000014aac08af29b80ea5e82169bde9f1b", - "0x000000000000000000000000000000f23100dd9e774faa9da6adabb0a5e868d1", - "0x00000000000000000000000000000000000675d3fb2db13df5feb7837a996202", - "0x0000000000000000000000000000002d41a263946c21172989f16b6c3eabd14b", - "0x00000000000000000000000000000000002f76f5733e8a0b6e45ad715c844fa3", - "0x0000000000000000000000000000009906b77efd02f89dd64543cb41b2ee7dc0", - "0x000000000000000000000000000000000011990c3a05d603a15abfdd104b7f45", - "0x000000000000000000000000000000b68418cb6eb350097b81ceebf7216de49f", - "0x0000000000000000000000000000000000193b041e80721ea6304e3edc45a55a", - "0x0000000000000000000000000000007f41793e8f1a2fbe4047a8c9b3ea8a7eba", - "0x000000000000000000000000000000000004ad79eb6e09a672b49359e429d4b2", - "0x00000000000000000000000000000084b9e57a26da81e52f9d96f484a3d8a6ae", - "0x00000000000000000000000000000000001b4cff12b3ca2c242b1cb101ca1f62", - "0x00000000000000000000000000000051285e317a9d17f2180bf8ec1f3e31c266", - "0x00000000000000000000000000000000002f79f4597dc1cbdfe8060d1d92c7fc", - "0x000000000000000000000000000000bfdd478df770ff0d6a9f5d30c6380e3bb2", - "0x00000000000000000000000000000000000f6c52e2949dd6fa7eff016e2e5bb6", - "0x0000000000000000000000000000001cba707dc36043107ad882453ae5d8b129", - "0x0000000000000000000000000000000000059cc841348db66a31d2dfa33b89a0", - "0x0000000000000000000000000000000e2b2caaf1a1eda41d509cc5221c984b51", - "0x0000000000000000000000000000000000037cc127472715a44cac19993d448a", - "0x0000000000000000000000000000003cc6bfe8250e54d57ce7daedc9a7095bc8", - "0x00000000000000000000000000000000001c95108bb4f2494bfef842093c3b36", - "0x0000000000000000000000000000008313e6a820b2f5c2a7de8028cd31798633", - "0x000000000000000000000000000000000027be294c15550f339b0839d5860142", - "0x00000000000000000000000000000060338657a29bcf8c13a4b50294e337ef11", - "0x00000000000000000000000000000000001569de523f46c6226a398155490417", - "0x000000000000000000000000000000163a5d9281ca7ac774da33d1bd5e32dd54", - "0x00000000000000000000000000000000001cea3677784e36b40d3084060d7486", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000008a36ca53543c7bd871dd8974dda60ec04e", - "0x000000000000000000000000000000000028fcc75fb20c13fa73b0b5dd1a9df0", - "0x000000000000000000000000000000646eccdb4bcb213d9d9867f291bc4cc715", - "0x0000000000000000000000000000000000239e0bfd2fe8666da2541d2b7e9242", - "0x00000000000000000000000000000057b0434a909bdd123f328dd722f50de441", - "0x0000000000000000000000000000000000056e909ead4cc889ca4ae259618b9e", - "0x000000000000000000000000000000cce3583f4dbdf7f0ea96b8413114530b7f", - "0x0000000000000000000000000000000000029d93569d5fb4eccfe54516bbfc2c", - "0x0000000000000000000000000000000202259bdd735f5d0996b36a14296dd956", - "0x00000000000000000000000000000000001c9a81340c0ef1a3f8ab9378b45228", - "0x000000000000000000000000000000bb9541231ccc05d3210933db9b2cfd662a", - "0x00000000000000000000000000000000002e90121d7079020ef60bf83a167d82", - "0x0000000000000000000000000000008e531da6a57f645193723255cc3949f2a6", - "0x000000000000000000000000000000000023d3bfa481c11731a958ae003b7049", - "0x0000000000000000000000000000005d505cd2a7715559ab2fb8ffa94fac158b", - "0x0000000000000000000000000000000000283299e0b6841cadaef68c90af63b3", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a50e32219d22dc5bc0a2a3afa8d1c963bf", - "0x00000000000000000000000000000000001b05579d422ec3526b639fa813b3db", - "0x000000000000000000000000000000931e9ee47cc6828d015bfd807445f50921", - "0x000000000000000000000000000000000005283cabb6b55f9baa597d00d3f46f", - "0x000000000000000000000000000000f14ecdef3987001b29e5574b25db85e726", - "0x00000000000000000000000000000000002b26e84ba3e9db90b9b761fbd5ba48", - "0x00000000000000000000000000000054401c158e8bfa1eac201ac628df1458d3", - "0x000000000000000000000000000000000028b61261027652e8ca3b29fb567872", - "0x0000000000000000000000000000005ddf21ec29f762249f79a86d986723b259", - "0x000000000000000000000000000000000020d889a78eaaeeced668f7a5e6a155", - "0x000000000000000000000000000000fbf31736f1c118ed779b00b56effa82f84", - "0x00000000000000000000000000000000001c10198fa65839280c9a4df0d48c69", - "0x000000000000000000000000000000ae45bd31909c920cd302c1833dc9dac27c", - "0x00000000000000000000000000000000000b5e828a1794bb52b1ef28384f36c3", - "0x000000000000000000000000000000623a32eccef6d3f192c9090e2c8d211339", - "0x000000000000000000000000000000000017dbcb62b1ef67a30ab74432100e03", - "0x0000000000000000000000000000008e75c04775713fe2b95076a7a5e1036c46", - "0x0000000000000000000000000000000000070ea9b40827062280d6e3cc9609a6", - "0x000000000000000000000000000000c70577cdcada107c62a7732ef0d2bbc15f", - "0x00000000000000000000000000000000002e57c64ac76e0a1e1c5980782cb606", - "0x000000000000000000000000000000902c14297534b09b2a8072cd93a9489887", - "0x00000000000000000000000000000000000cb983d7cc09d74a951dbf12ad432b", - "0x00000000000000000000000000000012bff816b24bc7a97ad6b1549515d6b28e", - "0x00000000000000000000000000000000000467570dff77ca3a342e4fc4d1a66b", - "0x00000000000000000000000000000080a63925457f739d70103395ccb7dcd29d", - "0x00000000000000000000000000000000000249558e7e5b5d6473ec5a9a980688", - "0x0000000000000000000000000000006cd74958767b5d51a95549a316e285ab74", - "0x0000000000000000000000000000000000091261933d2e12b6818f72bdc3e0c2", - "0x000000000000000000000000000000f97e56f24f292a230cf6c8350df6989d74", - "0x0000000000000000000000000000000000191f5e720c5ae2ded820c5e22cf23f", - "0x000000000000000000000000000000d3659c79160cc300c1726cdfe0a093bc08", - "0x000000000000000000000000000000000028e8e8952512f8006336791f90f01d", - "0x0000000000000000000000000000007ee7b8782f98bb5d90cbdc6fe174a42009", - "0x00000000000000000000000000000000000ae0ee6c55535140057064aa3fc5f0", - "0x000000000000000000000000000000d2bb98513b84e1e6f4e0b606bc025f9c48", - "0x00000000000000000000000000000000000b21f9d209054956c0524fababf1e9", - "0x000000000000000000000000000000d81d8ac019f7fed05a6b57f7845f56e44f", - "0x00000000000000000000000000000000002971c35ad470594c9a15abfc0e25a6", - "0x000000000000000000000000000000415d3a9385f247cc4092e3aad3382acd35", - "0x000000000000000000000000000000000025f0852ecc99395598d1e68d0ca89f", - "0x0000000000000000000000000000004f32605fa17fb311a06f7fb843c15d558a", - "0x000000000000000000000000000000000005071f43d210d49c73d5f25a18a596", - "0x0000000000000000000000000000000a679653df2810b4ec4c7adcd1cd7c97c8", - "0x000000000000000000000000000000000013c145ee6755ca17c398dafb88a569", - "0x00000000000000000000000000000083bace0537b2947643af96ab4b4aa8c478", - "0x000000000000000000000000000000000011ae383aeafc332a329462493ac315", - "0x000000000000000000000000000000a18bcfba0739bc5f71bd74ec53b6837fea", - "0x00000000000000000000000000000000001c2a9a991c7dbcd75129f92ff372b1", - "0x0000000000000000000000000000002c80b406fa46ad088b2e8d4f5a5701d47c", - "0x00000000000000000000000000000000001879ed897e504955597f01336b1d86", - "0x000000000000000000000000000000655b7a8802d367044c042458a17a0aeab4", - "0x000000000000000000000000000000000021be3e235af1a949dbf105cbe725d0", + "0x0000000000000000000000000000000000000000000000000000000000000cbd", + "0x000000000000000000000000000000c4d62213b081c8e90e6c8f3587321997f5", + "0x00000000000000000000000000000000002236a0b9f0654f7cd634c9c34280f1", + "0x0000000000000000000000000000007cb00736872fd50e291ec99fb640f1f7d9", + "0x00000000000000000000000000000000002d1b1b74b74ddf7d6f964a7bdb2af3", + "0x000000000000000000000000000000f26bcf89c86dcbce68a4f1b5b73505dcec", + "0x000000000000000000000000000000000011a128ae6c7be3a962485534f27786", + "0x00000000000000000000000000000088278f8cce72a5f698601f11a1532a9dad", + "0x00000000000000000000000000000000000d9caeabde23d8c2a0bd2cdef54193", + "0x0000000000000000000000000000001cfb29930f6753e5cb6a60342c16fe5e4f", + "0x00000000000000000000000000000000001022a2847e12bdd43b96342e5b8e16", + "0x000000000000000000000000000000fefee7789c5b50b89ce3ac6155975c4319", + "0x000000000000000000000000000000000002e25d02799b225c89aba3a667d7e5", + "0x0000000000000000000000000000006e210889b06205312234c097f979fca3b5", + "0x00000000000000000000000000000000000566396dc1f8e15f3a1c3729bb3393", + "0x0000000000000000000000000000009790f776d7aaecbcaf977d3aad6070c4e4", + "0x00000000000000000000000000000000002dcdeaf93e01c780512d9950fbfd94", + "0x000000000000000000000000000000d2ef194a7b605db9c6df08b9576c97735e", + "0x00000000000000000000000000000000001ff98ab3818a3d5fdc538a7bbeb87e", + "0x000000000000000000000000000000be40a925ee773bfc3923df01da59a497d7", + "0x00000000000000000000000000000000001fb52b895f997b5a90ea722d9a4140", + "0x000000000000000000000000000000dd5a7d1074be39e4451795f983d45b5be3", + "0x00000000000000000000000000000000001cbfd5b0d763096343af10ed1f3496", + "0x0000000000000000000000000000007cc56b953bb8ef24745e9200896ee10ee1", + "0x000000000000000000000000000000000001ef96b3ae0b2677b21939012dcc17", + "0x0000000000000000000000000000004ba56f98fc7d6d956bd6302ef6941f9239", + "0x000000000000000000000000000000000010bf82473c11a65eb2ac193002bfe4", + "0x00000000000000000000000000000072739ba831885d7f767251b9cc444961e5", + "0x0000000000000000000000000000000000256ea7e1dc188341f8692fd52454cf", + "0x000000000000000000000000000000a284c1c0bd5602eb7242fda659dc49ff99", + "0x000000000000000000000000000000000002e5e663dd3bf5f961173646b8e7b3", + "0x000000000000000000000000000000194cc54081bb3ffba3c67547dcb2db4d37", + "0x00000000000000000000000000000000002377042c75bab3ceee3b186c40b8b6", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000f0af57d5589fc84e1f8897bb5a62ec0ea9", + "0x000000000000000000000000000000000016583df9856bef930ef0a81d3357f0", + "0x000000000000000000000000000000e0a92aecf729c58fa7672c82066409d090", + "0x000000000000000000000000000000000010085406672c105a10ddee00634540", + "0x00000000000000000000000000000036b650e61cb6e0ec6ff6b1aef12c8c81e3", + "0x00000000000000000000000000000000000049ced3703b6736736daa8d94d66c", + "0x00000000000000000000000000000024e41b443846d1b9d969a739fe9ec5544d", + "0x0000000000000000000000000000000000251ef94ce2811e61503920adc1a548", + "0x000000000000000000000000000000ab378c4d63d86a750348adbd4cbc2c6883", + "0x0000000000000000000000000000000000079aee0bbaec8a7e39acda8a2bfd44", + "0x000000000000000000000000000000c4996ccb316a1671fa17ac0ec536c08aee", + "0x00000000000000000000000000000000000087a93f4353d8c6e85d6c58c7af49", + "0x0000000000000000000000000000002754983ee3f30f64f3ef3d6a27f671032d", + "0x00000000000000000000000000000000001b77b7da696321894ac402dc70a471", + "0x00000000000000000000000000000065a8c950362ff55e55d6006254e4cb8f60", + "0x00000000000000000000000000000000000a0eb81f69be92cc51ba479d4d4b2d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003a6dc78277b2838aca18adc58385b4a7f0", + "0x0000000000000000000000000000000000132c99e752833cae9473e7dfe278d0", + "0x0000000000000000000000000000003ec707e1f4369d5f99a3bac8eaa16ec4ba", + "0x00000000000000000000000000000000001cd77155c0a5e65f942f719c8e73f5", + "0x00000000000000000000000000000084604af6454cd074b40340a0900f8e47cc", + "0x0000000000000000000000000000000000077d31bdfcd802cd5aa1a457b97f10", + "0x00000000000000000000000000000099c886edf1320d2f8eef9c059a2495598d", + "0x00000000000000000000000000000000001400c2b452cd839ce363493a76312b", + "0x00000000000000000000000000000090681337eb7720ddc934e8bcc81bd9ae2b", + "0x000000000000000000000000000000000006ab19688014b0f0cf860c615759af", + "0x0000000000000000000000000000007165a99470ed5af56e75a9636be648e93d", + "0x000000000000000000000000000000000009dbbccaa2350bd92c5ce19b5d290a", + "0x0000000000000000000000000000000e1e042ed81d839a9f0ead9d291b6a8f32", + "0x00000000000000000000000000000000001a205aec8c334db49f816f4b5dafcd", + "0x000000000000000000000000000000ebb4edb0db1dcdf348033a7901a3680b6a", + "0x000000000000000000000000000000000011aae86275b822ebd3fa82c7315eff", + "0x000000000000000000000000000000e97eee8ec09b50e69135709916aba933c6", + "0x000000000000000000000000000000000010e2e96f78a68fc25ba2e4dafd04cc", + "0x000000000000000000000000000000b214f0a5321e8817d78adb6e0c20d7319e", + "0x000000000000000000000000000000000025bc9ba17b749d567d90e8f13af9a2", + "0x00000000000000000000000000000066fba7ba25f999f6f2838e553a29901fa7", + "0x000000000000000000000000000000000020711b883c2eb028f9d2d3da010519", + "0x000000000000000000000000000000a140d481bdc261d13949520f9ec7371c20", + "0x0000000000000000000000000000000000020bfe682fa3abc7653ce6853b0112", + "0x0000000000000000000000000000001b2bf2cbcde5d02c025a94db3378725693", + "0x000000000000000000000000000000000023e613dfd6966df7487e58fd52480c", + "0x0000000000000000000000000000006e2eb63e8f0cbcbd7a88665a53e119e428", + "0x00000000000000000000000000000000002e70d3962ba79ea7ae10b168c1c7d9", + "0x00000000000000000000000000000030517d9ecfee899135ff976333894660c2", + "0x000000000000000000000000000000000007417244ffad99a470ba89eb0ff90e", + "0x0000000000000000000000000000009bac28f405d40e017edf00277102b49c3d", + "0x000000000000000000000000000000000006b41a5fb6e909b8be3ff0dd952728", + "0x0000000000000000000000000000006683ae1c70f7eb680544f4c342c93087f1", + "0x000000000000000000000000000000000025f0aabdb61ed9c3922c0edfb358ec", + "0x000000000000000000000000000000351b5aea3d5e9850880e66335bcae23e94", + "0x00000000000000000000000000000000000ee72d3f7aca6bbe97267028d6abf9", + "0x0000000000000000000000000000008928d9a8e7f72b161cbe49ae95aa21ae63", + "0x0000000000000000000000000000000000185c141dba0abcf1e6d7db09787ca1", + "0x0000000000000000000000000000003e245e17b3e7805608abb6a2350fa6a847", + "0x00000000000000000000000000000000000cf54864a0d0738294136903b96823", + "0x000000000000000000000000000000f11eab4aad68f934214988cc4f58d5a6a2", + "0x000000000000000000000000000000000022f67f7b7d5406007bb7ddae120884", + "0x000000000000000000000000000000c05dc37331557bb9a3f702d92cfe090666", + "0x0000000000000000000000000000000000264629b4e2c6c2614bd57046d2ac8b", + "0x00000000000000000000000000000017305f321100b05a42b9014b4b5f033fd9", + "0x00000000000000000000000000000000000300f05e18d0c58963b144d3d28da6", + "0x00000000000000000000000000000039e8490810fc737b4a353bb67d95baa83c", + "0x00000000000000000000000000000000001b8f101b87ef8f67f87224f50b4e86", + "0x00000000000000000000000000000048da15030eaa7e0cc01567e721d66ead43", + "0x0000000000000000000000000000000000126b3927169eb104827c842837f462", + "0x00000000000000000000000000000008b500094a5820c680fb1db8c125502e1e", + "0x000000000000000000000000000000000000660eef61b7d219f439ec4fbfff1b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -143,65 +143,65 @@ sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000006ab4e9fba1bb0c45d30796e0c19546192e", - "0x00000000000000000000000000000000000b1447f3413f687009608e1c55b192", - "0x000000000000000000000000000000567498365d293b6c0532b94c33d0e937a5", - "0x000000000000000000000000000000000006c4fabfa5194704563bcc508d234e", - "0x00000000000000000000000000000009835f11bc7b963372a60d92370980b183", - "0x00000000000000000000000000000000000d898f5e8487e3ed90a10fc50db186", - "0x000000000000000000000000000000b66ee3d15932d652c3b54801748e89da9f", - "0x000000000000000000000000000000000024899f4b6ba56af0e1128c4a431ba7", - "0x00000000000000000000000000000064dd7da7637cf2116a18531edc7fea829a", - "0x0000000000000000000000000000000000162e867465b02e01bbabb15c59b84d", - "0x00000000000000000000000000000071f09c1d3d2c8f9499c838fc966b04ada9", - "0x00000000000000000000000000000000000f4504ac6f302739e9f2c7aa824d12" -] - hash = "0x051d17b4a7efa4af82e7c6b71f2a5cf71ee015e6d9edbcd39d326a5463aac1e6" + "0x0000000000000000000000000000001115e1df83c7f85610477a243a350ad610", + "0x000000000000000000000000000000000016b525f879d97a8d50cab6d1a41d58", + "0x0000000000000000000000000000005545bbd9cc9de7a79986b650103736492e", + "0x00000000000000000000000000000000000aac06f3452ec0a5be2b5e3060f108", + "0x000000000000000000000000000000c6e13ef9aedec4af73a577a6dd72dda690", + "0x000000000000000000000000000000000016b603e70199deaa1eff742257259f", + "0x000000000000000000000000000000dd7902c16a885b205f012abf38e3f9f470", + "0x00000000000000000000000000000000002a45b4a48e9544c186e119184fd191", + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" +] + hash = "0x1e580df70c4374ef9942846936ab5fc2d7da61ca21bd0576f269746152a782c4" [previous_kernel_public_inputs] min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff293f" -is_private_only = false -claimed_first_nullifier = "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7716" +is_private_only = true +claimed_first_nullifier = "0x1268b93c2a6a4d3780d6cb2b948cc3884e65336ef39eb7202b4de102b9cb3748" claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" [previous_kernel_public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" [previous_kernel_public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x1f8e9213a0888fe29bbbc5c39db80f4b9f1575e375c6a0932a13ca2b8e2fced2" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x1d706e11585e9d3ecfd4d2ead7a52c2a783a92adfbe3419e8671011fe5016491" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" [previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x0835e9ab1ea355f270408857dfd5647ca56d588ab4a7d573e67566f6324821d1" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1f860209ee462b9c30510a063670044f005084362ce71f528205a17ee048fc7d" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2597" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -212,7 +212,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [previous_kernel_public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -224,29 +224,29 @@ l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" [previous_kernel_public_inputs.constants.tx_context.gas_settings.max_fees_per_gas] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" -fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" [previous_kernel_public_inputs.constants.tx_context.gas_settings.max_priority_fees_per_gas] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -268,7 +268,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] [previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] -inner = "0x29ecb485abf1e4a9963bb4dada6e8b67bda9c6bb09527ecb8d0c64a0d119e0fd" +inner = "0x302a86bd5883e95684cbcd46af941e62a60b0416ee605f00eae4a0189b8af2ee" counter = "0x0000000000000000000000000000000000000000000000000000000000000003" [previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] @@ -779,15 +779,15 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.nullifier_read_requests] -length = "0x0000000000000000000000000000000000000000000000000000000000000000" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] [previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15" +counter = "0x000000000000000000000000000000000000000000000000000000000000000b" [previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] [previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] @@ -1301,13 +1301,9 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1316,13 +1312,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1331,13 +1323,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1346,13 +1334,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1361,13 +1345,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1376,13 +1356,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1391,13 +1367,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1406,13 +1378,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1421,13 +1389,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1436,13 +1400,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1451,13 +1411,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1466,13 +1422,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1481,13 +1433,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1496,13 +1444,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1511,13 +1455,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1526,13 +1466,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1541,13 +1477,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1556,13 +1488,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1571,13 +1499,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1586,13 +1510,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1601,13 +1521,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1616,13 +1532,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1631,13 +1543,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1646,13 +1554,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1661,13 +1565,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1676,13 +1576,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1691,13 +1587,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1706,13 +1598,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1721,13 +1609,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1736,13 +1620,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1751,13 +1631,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1766,13 +1642,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1781,13 +1653,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1796,13 +1664,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1811,13 +1675,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1826,13 +1686,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1841,13 +1697,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1856,13 +1708,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1871,13 +1719,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1886,13 +1730,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1901,13 +1741,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1916,13 +1752,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1931,13 +1763,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1946,13 +1774,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1961,13 +1785,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1976,13 +1796,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1991,13 +1807,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2006,13 +1818,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2021,13 +1829,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2036,13 +1840,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2051,13 +1851,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2066,13 +1862,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2081,13 +1873,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2096,13 +1884,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2111,13 +1895,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2126,13 +1906,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2141,13 +1917,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2156,13 +1928,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2171,13 +1939,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2186,13 +1950,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2201,13 +1961,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2216,13 +1972,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2231,13 +1983,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2246,13 +1994,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2772,14 +2516,14 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers] -length = "0x0000000000000000000000000000000000000000000000000000000000000001" +length = "0x0000000000000000000000000000000000000000000000000000000000000003" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] counter = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x023cfeab2c97a4c457a539c4b7c7c9d1fefa40027aacd687b5282ff01a46f27b" + value = "0x1d572b897a46622761043b29c51e639c89bda7b3a9f4111e8f1766a72bc194ec" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -2787,25 +2531,25 @@ inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000007" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x000000000000000000000000000000000000000000000000000000000000000c" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000002" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] @@ -3586,38 +3330,38 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs] -length = "0x0000000000000000000000000000000000000000000000000000000000000000" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x000000000000000000000000000000000000000000000000000000000000000d" [previous_kernel_public_inputs.end.private_logs.array.inner.inner] note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] fields = [ + "0x174c6b3d0fd14728e4fc5e53f7b262ab943546a7e125e2ed5e9fde3cf0b3e22f", + "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x1ca223fbc16e82cbb9bd22c108021ef47864791c258edbdd8eefa458c62ba8d2", + "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", + "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", + "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", + "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", + "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x000000000000000000000000000000000000000000000000000000000000000d" [previous_kernel_public_inputs.end.private_logs.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000002" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] @@ -5573,34 +5317,34 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.contract_class_logs_hashes] -length = "0x0000000000000000000000000000000000000000000000000000000000000000" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.contract_class_logs_hashes.array]] [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000008" [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner.inner] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" - length = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x242b9549d1e2c420a764a5aa2ba58d98b77e35fef8ffa5aa787f9b325f2b5005" + length = "0x0000000000000000000000000000000000000000000000000000000000000068" [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" [previous_kernel_public_inputs.end.public_call_requests] -length = "0x0000000000000000000000000000000000000000000000000000000000000001" +length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.public_call_requests.array]] - counter = "0x0000000000000000000000000000000000000000000000000000000000000006" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.public_call_requests.array.inner] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.public_call_requests.array]] counter = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6307,7 +6051,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [padded_side_effects] note_hashes = [ @@ -8311,9 +8055,9 @@ read_request_index = "0x00000000000000000000000000000000000000000000000000000000 "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", - "0x0951be8128e49814029387ac6bfbe43a1e43dadd05a6e50f78ef8265cd09b5a1", + "0x011493b3dc6ff7233e375206a6abca69781caccfbce08c0507c7ba581aa94b0b", "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", - "0x15f254a15d2db357812a7044082d84639b7c8adc2a909034fb01d4a6879296ab", + "0x2ed29e329b77e3cddc51479e8f2dd13802a7e1aa2ff1b447d6007fedf382717f", "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", @@ -8350,7 +8094,7 @@ read_request_index = "0x00000000000000000000000000000000000000000000000000000000 ] [hints.note_hash_read_request_hints.settled_read_hints.leaf_preimage] - value = "0x29ecb485abf1e4a9963bb4dada6e8b67bda9c6bb09527ecb8d0c64a0d119e0fd" + value = "0x302a86bd5883e95684cbcd46af941e62a60b0416ee605f00eae4a0189b8af2ee" [[hints.note_hash_read_request_hints.settled_read_hints]] read_request_index = "0x0000000000000000000000000000000000000000000000000000000000000040" @@ -11692,7 +11436,7 @@ read_request_index = "0x00000000000000000000000000000000000000000000000000000000 value = "0x0000000000000000000000000000000000000000000000000000000000000000" [[hints.nullifier_read_request_hints.read_request_actions]] -action = "0x0000000000000000000000000000000000000000000000000000000000000000" +action = "0x0000000000000000000000000000000000000000000000000000000000000001" hint_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[hints.nullifier_read_request_hints.read_request_actions]] @@ -11948,8 +11692,8 @@ action = "0x0000000000000000000000000000000000000000000000000000000000000000" hint_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[hints.nullifier_read_request_hints.pending_read_hints]] -read_request_index = "0x0000000000000000000000000000000000000000000000000000000000000040" -pending_value_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +read_request_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +pending_value_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [[hints.nullifier_read_request_hints.pending_read_hints]] read_request_index = "0x0000000000000000000000000000000000000000000000000000000000000040" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Prover.toml index 4a9ed54ae711..2875610b0af5 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Prover.toml @@ -1,130 +1,130 @@ -expiration_timestamp_upper_bound = "0x0000000000000000000000000000000000000000000000000000000069ff1b30" +expiration_timestamp_upper_bound = "0x000000000000000000000000000000000000000000000000000000006a0c712f" [previous_kernel.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000003d" sibling_path = [ - "0x1836f64afd38c3a05416bbcee658f4acce2576bbe554a445b33b8936297034e1", - "0x2c05a8ec2045319ea62b81134a53d4e0c1b021fed7877a3a8acc676cf26794f7", - "0x280ae800476659efd90f7ae6a3a2ae3958c1261ca9ae8ba3b2b8320fc9ef662d", - "0x1afa13b72352bab63bfdb391bbadee67783679a9b5ce7fbbcde44387ba5b0eae", - "0x2a99cb07c31aa5ee3a8af2c6db61485892e126a5eac56720fcbbbb002b19d015", - "0x0384c341c7892982bb9f5581098584a00bc572787bf4153d0a52532652ace783", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x0e5e5b81c76efb898b163faa6ee7d6855b64a79e56ac17ff7cf95a60a1125d58", + "0x1ed1f6ae3c2aba56858bdbb3c261d8f7700092a1a1f890d6a0a107e3712446e2", + "0x0ea9a4b61d0915de0514bdc6af213e5f1b338ed1afbef7f1e9fdcb042a751935", + "0x1998bd282e674d397ff88e6b98ed4c795f92263867aa8a0a0b73b1b5643128b5", + "0x084174c19225d48e9b905b49bd461775b745efe40c7f706e5df7e05b4d952d41", + "0x0ae4f3dc533a85154efaa40fbe95415d0544950a47ed66a57418e991f0f134a4", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [previous_kernel.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000011", "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000cad", - "0x0000000000000000000000000000002b2468b5f8f13bd482d710d25b291a02d4", - "0x000000000000000000000000000000000028799bf367c0778599b2b948882163", - "0x000000000000000000000000000000fe9b706fe16bc87d35001fd66356a746bc", - "0x000000000000000000000000000000000001ca485164bddf169d3fe6c29f62e7", - "0x00000000000000000000000000000075e09707371f536b6282e95e95cb185f37", - "0x000000000000000000000000000000000024009d9583c43b01bfe49bd946bf15", - "0x000000000000000000000000000000881a9c651f0a2aae2de99f5557fa22023f", - "0x00000000000000000000000000000000000068e5a5ca58bc35138b3847beeed4", - "0x000000000000000000000000000000f223a8c39d330da2a41cef98b4e091c9b7", - "0x0000000000000000000000000000000000211f7059c97618280acecd75745235", - "0x000000000000000000000000000000044e4a5f8a66993f61ec86dfb978efde9c", - "0x0000000000000000000000000000000000090682734b33c06cd65ba8824167f6", - "0x0000000000000000000000000000007add80ab4d0d02238831551a2844a9f730", - "0x00000000000000000000000000000000000bb45a300640a05ece5fe1ad9b9ee5", - "0x0000000000000000000000000000007da2be4190c8f0f38b37f33d411b427a1b", - "0x000000000000000000000000000000000026098dd8b73e82d335f5e784cbf652", - "0x0000000000000000000000000000007ab032555b3b13f26ed0788c300e54c30a", - "0x00000000000000000000000000000000002a8c9e9e15de7b8b11220f4055bf04", - "0x000000000000000000000000000000f4ce25385f14112552f1512e2f4e99d0e8", - "0x000000000000000000000000000000000015873846a6e7648a844f037a03f737", - "0x00000000000000000000000000000076dbac5187affde31d2adfb3b5064f5a77", - "0x000000000000000000000000000000000020ef23c172d94df80288571d7e3ca3", - "0x000000000000000000000000000000e69eb7802e5d99aa20bc39dee1f6b84b8f", - "0x00000000000000000000000000000000002b2c9af00759a128112ed819b8b1b0", - "0x000000000000000000000000000000f74bd0fb26a604548c9068fef410612fb9", - "0x00000000000000000000000000000000002ca283b09804c9b7d8ca32dc3a2c75", - "0x000000000000000000000000000000c90052c50c0497cddef7e3a71872d14596", - "0x0000000000000000000000000000000000231d65742b933d5aef1ad67db52143", - "0x000000000000000000000000000000b86b4223f0ebb39a8741b6ebba3a313095", - "0x00000000000000000000000000000000001f853f71eaa7368db93d05eefb5256", - "0x000000000000000000000000000000467ff45666661562c57d52de8c4f8f193c", - "0x00000000000000000000000000000000001fdb031a99c29b571b0a66a4140e8e", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000089d2777774ad5c33906740b3656fda53a0", - "0x0000000000000000000000000000000000133bedccd128dc4587817ae09af71b", - "0x000000000000000000000000000000641918e54723a119562889c1ff6239d13d", - "0x00000000000000000000000000000000002c14c2e4f17070e269f9903a383793", - "0x00000000000000000000000000000026c43cff4875a95471fe2c2008292fff78", - "0x00000000000000000000000000000000001224540abfac9c15d64e21d816b9dd", - "0x000000000000000000000000000000beb481b4d5d4eef75c1b133ca9b7efa690", - "0x000000000000000000000000000000000019b490637210bf2280a86ae0a1d7f7", - "0x000000000000000000000000000000e0b4e0795a8b1375e34eab2397b735ef03", - "0x00000000000000000000000000000000000effe6364fc31714fde11efcbe733c", - "0x0000000000000000000000000000005a1907824e164fc0fdd0f0e7c61f4d7398", - "0x00000000000000000000000000000000001cd6403b37da0361f243a3606ac383", - "0x0000000000000000000000000000006a48458b17770a4ad91f725dd01a8c486b", - "0x00000000000000000000000000000000000c395fd0e57de7d52c706e13918651", - "0x000000000000000000000000000000cde7b67f0a01ba051f06746ff7b56f59de", - "0x000000000000000000000000000000000020e0ab3fa354e260e0ac1855e128ca", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000654fe84b50aced8eb7212098af0880ed53", - "0x00000000000000000000000000000000002b2fcb6b0ee568a71f92d2a9bbfad3", - "0x0000000000000000000000000000005d9f4f1e59fac32314c435fb51e2a25ff0", - "0x000000000000000000000000000000000009734092d4e035b968ae8ee337464c", - "0x000000000000000000000000000000a28867ea56c5fbf4aca51fdbbf965e5dae", - "0x00000000000000000000000000000000002feaf04057ed002c072833048ce9e0", - "0x000000000000000000000000000000f9b70bdcd41a1c0bade216b9d5284af115", - "0x00000000000000000000000000000000001ece78d726aaf44e37d9053ebd1534", - "0x000000000000000000000000000000c4e55b000805b017402a109a6b29805245", - "0x00000000000000000000000000000000001d999b7c6ca8df0cca3c57ee4c8be8", - "0x0000000000000000000000000000008820aa820991933af75b5d02d44d0bf685", - "0x0000000000000000000000000000000000039880d1fbfc627ab3421788858e66", - "0x000000000000000000000000000000514dfa671906947f5f640255bfc583eedc", - "0x00000000000000000000000000000000000b0e0c990016a1fdf37d3d6daea7ae", - "0x00000000000000000000000000000040dbbc0f6d52ba0ce246acf816373fbbc1", - "0x0000000000000000000000000000000000035ba8d570a6b7efa251b206e85c82", - "0x0000000000000000000000000000003ebdd6ba8db24c72ad85e8d10fb1346027", - "0x0000000000000000000000000000000000035c795b4ad27e20c934ac5ae517b8", - "0x0000000000000000000000000000005369721308b3dda5dbbab39f83bffcf79a", - "0x0000000000000000000000000000000000241a6ba1547bf3c8eb2ded3454d897", - "0x0000000000000000000000000000009f97bcbba8db2f8bda79a78c0eaefacc5a", - "0x00000000000000000000000000000000002c960a56441f3a00b2f8b48f3b3563", - "0x000000000000000000000000000000ffe2ad855d3522d6b3f8b544681949c713", - "0x00000000000000000000000000000000000002f9753e605a6cbf6dbc604046a6", - "0x0000000000000000000000000000008cfee82227443d00335c9ef376137f6217", - "0x00000000000000000000000000000000001708d8cb04ad71f327107dd3e73cfb", - "0x0000000000000000000000000000007872392082ec4533c6b70f690660ee498f", - "0x0000000000000000000000000000000000122a83a98d1d526cb57355616bb850", - "0x0000000000000000000000000000000a95a3eeae99b98360d61166e89954845a", - "0x0000000000000000000000000000000000202c82d7bd85e9243e7ed0801ebe64", - "0x00000000000000000000000000000027acbc73301fe1b0c21888c2722dd75b7a", - "0x00000000000000000000000000000000002ae7d3ca125bd531826422c7d1acf7", - "0x000000000000000000000000000000d761bb670a9ff734cc38f0d30238a2b28c", - "0x000000000000000000000000000000000005aa3fab8a429258028c4a4287a0e6", - "0x0000000000000000000000000000007a80c32a515f441ce80a5d6cdb53d50866", - "0x000000000000000000000000000000000017f409fea3a1680e6df2a07e9eb3af", - "0x0000000000000000000000000000001a93444f40b0bc09418c7894fe797e2736", - "0x0000000000000000000000000000000000171474b32205fc141e14cfb847a8d3", - "0x000000000000000000000000000000081188cb41c2b23f91bef3a8237fb5fa5d", - "0x00000000000000000000000000000000001ed9b478e77d9f60e9614dfd6014ba", - "0x00000000000000000000000000000042f9a2c111e62ef204c3851affea6af0ef", - "0x0000000000000000000000000000000000108601bd973a835e50fc521d6ec1d9", - "0x000000000000000000000000000000f92be9d44c6688723f37065c3af9521bd6", - "0x000000000000000000000000000000000022ed90948b7d0f29ee1ed4349cab5a", - "0x000000000000000000000000000000bf6e68585d4cb32aeb39412d4a3e6cd968", - "0x00000000000000000000000000000000000c8df79002571c9aef12bb6d7f3bca", - "0x000000000000000000000000000000046577d9d6782e8214d846d3a16aa8ceb7", - "0x0000000000000000000000000000000000249e158a2e56acae4de64894bb2366", - "0x0000000000000000000000000000004b4ecd7a5a335425433b11e098157c3557", - "0x0000000000000000000000000000000000152c2ebca43c64a74ea10b830e9f62", - "0x0000000000000000000000000000006e65e30a946db2c5e16462e3a487d614eb", - "0x0000000000000000000000000000000000294d7279cdf2f3a5a0f47d5d830d40", + "0x0000000000000000000000000000000000000000000000000000000000000c2d", + "0x0000000000000000000000000000009746a298cc238fa9fc88119d64824cecd3", + "0x00000000000000000000000000000000000a622e89485dcc5a40545852372230", + "0x0000000000000000000000000000006809e41276c7672741eaf50c615e7aaf5f", + "0x000000000000000000000000000000000023ef3262cfcbaa1a38aa48f42b80a4", + "0x00000000000000000000000000000029b4a0a73660db847087b0ec0ff8ae7cc0", + "0x00000000000000000000000000000000000bbf015119fab668caabd4aac59b4a", + "0x0000000000000000000000000000003aceeaa5125630611ff88a1638c74b8bf8", + "0x00000000000000000000000000000000002954b4a5df3301bd05b4b33f4b1281", + "0x0000000000000000000000000000007d75fd1698bf937cad957054b4d802deac", + "0x00000000000000000000000000000000001eae87f9894a26c8d8685edcaa11f7", + "0x000000000000000000000000000000bec44c06c527d2c90cd142d22a575b64ad", + "0x00000000000000000000000000000000001ce6fd416b339978042baa3b29160b", + "0x000000000000000000000000000000601d1a36cbf2648b7a35e094aab2f78625", + "0x000000000000000000000000000000000013d19f319a00fc7417c1ad631d3286", + "0x000000000000000000000000000000cebe2c4b8938871fcd990b93f474835e2b", + "0x0000000000000000000000000000000000253ff4164f3a2cdd7a2118f953a472", + "0x000000000000000000000000000000633bff41528ff6e9648cabab45618cd3f8", + "0x00000000000000000000000000000000000a128ad23b420b11945de2c94bc8db", + "0x000000000000000000000000000000c2bdeaad6e1bb38c01807cbeb39eb01474", + "0x00000000000000000000000000000000001a87197d7cbb357c71e7475853a89a", + "0x000000000000000000000000000000d60d42e56b09250d5406827e9f63c5c507", + "0x00000000000000000000000000000000001c429c10ec7865314a9bb768fc77cb", + "0x000000000000000000000000000000874ae527782ea78b526a4069d5a5fffad6", + "0x00000000000000000000000000000000000cf6dd26f50b908aedf25ca7beb983", + "0x0000000000000000000000000000007dfb532ce535603daa17b40d4f20268fa6", + "0x00000000000000000000000000000000001aa8da80801279d91cd4386764d5b7", + "0x00000000000000000000000000000051498e1f98a404cce7b25f7487732af055", + "0x00000000000000000000000000000000002d5ce3870ecba8710b98522a635a24", + "0x0000000000000000000000000000003f1d7da491f2a68c39458177333aa62b8f", + "0x00000000000000000000000000000000001d1af6c81adf6a906f55b20aa99aa7", + "0x0000000000000000000000000000004398c4f4ff3f65cba6337e0a48437289b7", + "0x00000000000000000000000000000000002c90b326149002904e30310eed12dd", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ce520672cc9f4fba3288b2d696d69b60", + "0x0000000000000000000000000000000000240074838ef9434d6524883c8af328", + "0x000000000000000000000000000000cc5409001d9a1b6e499a55194c5cee623b", + "0x0000000000000000000000000000000000272e8cb04c7e831a06e0eff44b1633", + "0x00000000000000000000000000000029faeb6bccfe395b36c4dde26a9281cd51", + "0x0000000000000000000000000000000000079cd2f8b7f8d0ba574f06c074487c", + "0x000000000000000000000000000000467663df6ffc3082510ef243829669f9b2", + "0x0000000000000000000000000000000000154ba884593558e4fa1d35a08901c2", + "0x0000000000000000000000000000003b9367cb2541b5cae36cacba4a0e9565f2", + "0x00000000000000000000000000000000000e9c894d1634c38a1da7a18ff2a4d1", + "0x000000000000000000000000000000a44d578cb20654807e5da0fae4fb462540", + "0x00000000000000000000000000000000001583bdfc0f1f208b72177fd73a4e0e", + "0x0000000000000000000000000000005101bd383908b7e9563f9943ed5b6b9d5d", + "0x00000000000000000000000000000000001894ae59fb37a39ee483d90674a601", + "0x0000000000000000000000000000008eaa98f808cc4df6011d0467d94748bfef", + "0x000000000000000000000000000000000018728540c99b37787e0ec614d5d2c2", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000095b02b4b915ea97d2863c7de9364faf7c1", + "0x000000000000000000000000000000000024bf0c36515c471894eca07c722a6f", + "0x00000000000000000000000000000021b9c8dd0f3068ab110290ce8dde8ca475", + "0x0000000000000000000000000000000000033a64820c52027d57fb58ebb6c381", + "0x000000000000000000000000000000de86fb0a5a50dd02848572163142b8640e", + "0x000000000000000000000000000000000006104618e23a8bd65ba6678675ef30", + "0x0000000000000000000000000000007ecf243d0261b865862c9aa1c0fa854c03", + "0x00000000000000000000000000000000002b49777a506a0876586804d7265c91", + "0x000000000000000000000000000000b03490f3e92e51591fa83188e45ff33c1d", + "0x000000000000000000000000000000000020ca792b4db8d34742259c49a69680", + "0x000000000000000000000000000000bba53bf211eba5cfdc0655d659b54e5154", + "0x000000000000000000000000000000000025743fca2cf229c9e74f0b94b2a60c", + "0x00000000000000000000000000000039fa7ba046a2aa4d1e1b2e7caf7a8468b2", + "0x0000000000000000000000000000000000114565ee8a1a9f6c0765554f828b55", + "0x00000000000000000000000000000039f6f4a9450081d17e80431d7673b4e831", + "0x00000000000000000000000000000000001aeacf01182adb275721404acf94ec", + "0x000000000000000000000000000000b61eb26643a3330cf20693ce2863cd8df9", + "0x000000000000000000000000000000000001287624004468d7fdb961891f7657", + "0x0000000000000000000000000000008e93f0560ff5d7fc733764b1eb22480fef", + "0x0000000000000000000000000000000000122ec6ad7d326d49eb1ec1b6058f11", + "0x00000000000000000000000000000095ed3058c8b0990d267a70546ff583ee0f", + "0x000000000000000000000000000000000014b8a07a5bb9e756fca0fa2b309603", + "0x00000000000000000000000000000011c41e34d997fc68ea4bf83e558d0cc63c", + "0x00000000000000000000000000000000002d5aa2b07b478858f898b181d0ba8b", + "0x0000000000000000000000000000002181f534d66eac7d336c5a0615483614de", + "0x00000000000000000000000000000000001ddfc420c74fb84de1fc06e15cb736", + "0x000000000000000000000000000000221911551b028d679741b7201b0ecbec4c", + "0x00000000000000000000000000000000000dda073b8d6dff1f7820fd10608eac", + "0x000000000000000000000000000000f83c26a030132139738278422f03bf922a", + "0x0000000000000000000000000000000000090293167442d6241ef786787ad54a", + "0x00000000000000000000000000000081472fe64f8676d2c6ba66632be788181a", + "0x00000000000000000000000000000000002686bba5965dbeeace183975458ab6", + "0x000000000000000000000000000000afefc9d6f3b48945adcbfcfd1c96c9d317", + "0x000000000000000000000000000000000004230c01cef5000fc66eed900511c7", + "0x000000000000000000000000000000461b8ddba4875f5c0ee209e969c8cab5b5", + "0x000000000000000000000000000000000004f3c201bbca13be28a391550e3e15", + "0x0000000000000000000000000000008559177c932a1653672c242e7617b96ed7", + "0x0000000000000000000000000000000000171be06bb1a5c5e15ae25ea139e42a", + "0x000000000000000000000000000000ee99ac22da62f96c90ac540968ff4e0df5", + "0x00000000000000000000000000000000002a4b4f6cecfa52aeacb7c88e2ba547", + "0x00000000000000000000000000000075b8d277e2f2d2578c463156acd5f1475d", + "0x000000000000000000000000000000000013ad863e13e6edf10c859862b09f73", + "0x0000000000000000000000000000009f93998170f02cdbb3d8ab65ffc18aa878", + "0x000000000000000000000000000000000000b2bad4d1a7598557b09810779622", + "0x00000000000000000000000000000000d5a82f535d9f53a56ad2c90d651a6f07", + "0x000000000000000000000000000000000000e77d138f0fe1fb3334079b7a17b8", + "0x000000000000000000000000000000375d67be44557b3a7109eb34e19abe23bd", + "0x0000000000000000000000000000000000004374e342cf902621d2f067ee0dde", + "0x000000000000000000000000000000618d7aa8936861e2dfed7786fe06e14cbe", + "0x0000000000000000000000000000000000028eef3b42459371670ed47195575c", + "0x0000000000000000000000000000004185b847b001cc084cb5d9fc3c413c9447", + "0x00000000000000000000000000000000000f0cdae2ffe529626d71ad12c69406", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -145,76 +145,76 @@ sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000034620fc4f5dc2f120b5673912cf04226e9", - "0x000000000000000000000000000000000025a6078d74c0fd7d4dd9e328ad4c94", - "0x00000000000000000000000000000019d834f9bb59a8e973ed867f0477fc8121", - "0x00000000000000000000000000000000001fdeb0dc3db761477a1a9feb00c906", + "0x000000000000000000000000000000ae09bb7f78acfe7c9d9a2b944b789f8363", + "0x0000000000000000000000000000000000011fa902d1394869cea67da68c1718", + "0x000000000000000000000000000000655a4cb5f0e139646b6fe88fd680ee9c5d", + "0x0000000000000000000000000000000000019f3c976b53013b5041616ea60768", "0x00000000000000000000000000000076959cf0870e0ae93bb69edc64b0cacdac", "0x0000000000000000000000000000000000269679f8c1a1ad2aadccaf8ba3100e", "0x000000000000000000000000000000bb028a742987d54246ffc933f8240d70ef", "0x0000000000000000000000000000000000295f79977c6ae0d15cc2b68b7f0837", - "0x00000000000000000000000000000064dd7da7637cf2116a18531edc7fea829a", - "0x0000000000000000000000000000000000162e867465b02e01bbabb15c59b84d", - "0x00000000000000000000000000000071f09c1d3d2c8f9499c838fc966b04ada9", - "0x00000000000000000000000000000000000f4504ac6f302739e9f2c7aa824d12" + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" ] - hash = "0x297f9ac45dd6c9f333314227aacca93023e72710232e7120328d7e7c209ebc8f" + hash = "0x141adcbeacb22e8db98482647ab8bddc8bafc8d2c45ba62cefe4fabe03067018" [previous_kernel_public_inputs] min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff293f" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7f3e" is_private_only = false -claimed_first_nullifier = "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef" +claimed_first_nullifier = "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb" claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" [previous_kernel_public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" [previous_kernel_public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [previous_kernel_public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -233,22 +233,22 @@ fee_per_da_gas = "0x000000000000000000000000000000000000000000000000000000000000 fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1303,13 +1303,9 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1318,13 +1314,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1333,13 +1325,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1348,13 +1336,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1363,13 +1347,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1378,13 +1358,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1393,13 +1369,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1408,13 +1380,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1423,13 +1391,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1438,13 +1402,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1453,13 +1413,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1468,13 +1424,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1483,13 +1435,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1498,13 +1446,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1513,13 +1457,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1528,13 +1468,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1543,13 +1479,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1558,13 +1490,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1573,13 +1501,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1588,13 +1512,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1603,13 +1523,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1618,13 +1534,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1633,13 +1545,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1648,13 +1556,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1663,13 +1567,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1678,13 +1578,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1693,13 +1589,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1708,13 +1600,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1723,13 +1611,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1738,13 +1622,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1753,13 +1633,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1768,13 +1644,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1783,13 +1655,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1798,13 +1666,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1813,13 +1677,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1828,13 +1688,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1843,13 +1699,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1858,13 +1710,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1873,13 +1721,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1888,13 +1732,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1903,13 +1743,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1918,13 +1754,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1933,13 +1765,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1948,13 +1776,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1963,13 +1787,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1978,13 +1798,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1993,13 +1809,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2008,13 +1820,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2023,13 +1831,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2038,13 +1842,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2053,13 +1853,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2068,13 +1864,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2083,13 +1875,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2098,13 +1886,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2113,13 +1897,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2128,13 +1908,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2143,13 +1919,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2158,13 +1930,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2173,13 +1941,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2188,13 +1952,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2203,13 +1963,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2218,13 +1974,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2233,13 +1985,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2248,13 +1996,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2781,7 +2525,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" counter = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef" + value = "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -5596,13 +5340,13 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.public_call_requests.array.inner] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x00a5e40cab902df3efe088094577e83eb92103581c990f351edf1dfba3778905" [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x1be490a4b344f41827e94113f628fb311efc1abac19bc1e84b08fd578708964a" [[previous_kernel_public_inputs.end.public_call_requests.array]] counter = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6309,7 +6053,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [padded_side_effect_amounts] non_revertible_note_hashes = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/Prover.toml index e85826cf5411..908909bdd8d1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/Prover.toml @@ -1,130 +1,130 @@ -expiration_timestamp_upper_bound = "0x0000000000000000000000000000000000000000000000000000000069ff1b30" +expiration_timestamp_upper_bound = "0x000000000000000000000000000000000000000000000000000000006a0c6907" [previous_kernel.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000003d" sibling_path = [ - "0x1836f64afd38c3a05416bbcee658f4acce2576bbe554a445b33b8936297034e1", - "0x2c05a8ec2045319ea62b81134a53d4e0c1b021fed7877a3a8acc676cf26794f7", - "0x280ae800476659efd90f7ae6a3a2ae3958c1261ca9ae8ba3b2b8320fc9ef662d", - "0x1afa13b72352bab63bfdb391bbadee67783679a9b5ce7fbbcde44387ba5b0eae", - "0x2a99cb07c31aa5ee3a8af2c6db61485892e126a5eac56720fcbbbb002b19d015", - "0x0384c341c7892982bb9f5581098584a00bc572787bf4153d0a52532652ace783", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x0e5e5b81c76efb898b163faa6ee7d6855b64a79e56ac17ff7cf95a60a1125d58", + "0x1ed1f6ae3c2aba56858bdbb3c261d8f7700092a1a1f890d6a0a107e3712446e2", + "0x0ea9a4b61d0915de0514bdc6af213e5f1b338ed1afbef7f1e9fdcb042a751935", + "0x1998bd282e674d397ff88e6b98ed4c795f92263867aa8a0a0b73b1b5643128b5", + "0x084174c19225d48e9b905b49bd461775b745efe40c7f706e5df7e05b4d952d41", + "0x0ae4f3dc533a85154efaa40fbe95415d0544950a47ed66a57418e991f0f134a4", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [previous_kernel.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000011", "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000cad", - "0x0000000000000000000000000000002b2468b5f8f13bd482d710d25b291a02d4", - "0x000000000000000000000000000000000028799bf367c0778599b2b948882163", - "0x000000000000000000000000000000fe9b706fe16bc87d35001fd66356a746bc", - "0x000000000000000000000000000000000001ca485164bddf169d3fe6c29f62e7", - "0x00000000000000000000000000000075e09707371f536b6282e95e95cb185f37", - "0x000000000000000000000000000000000024009d9583c43b01bfe49bd946bf15", - "0x000000000000000000000000000000881a9c651f0a2aae2de99f5557fa22023f", - "0x00000000000000000000000000000000000068e5a5ca58bc35138b3847beeed4", - "0x000000000000000000000000000000f223a8c39d330da2a41cef98b4e091c9b7", - "0x0000000000000000000000000000000000211f7059c97618280acecd75745235", - "0x000000000000000000000000000000044e4a5f8a66993f61ec86dfb978efde9c", - "0x0000000000000000000000000000000000090682734b33c06cd65ba8824167f6", - "0x0000000000000000000000000000007add80ab4d0d02238831551a2844a9f730", - "0x00000000000000000000000000000000000bb45a300640a05ece5fe1ad9b9ee5", - "0x0000000000000000000000000000007da2be4190c8f0f38b37f33d411b427a1b", - "0x000000000000000000000000000000000026098dd8b73e82d335f5e784cbf652", - "0x0000000000000000000000000000007ab032555b3b13f26ed0788c300e54c30a", - "0x00000000000000000000000000000000002a8c9e9e15de7b8b11220f4055bf04", - "0x000000000000000000000000000000f4ce25385f14112552f1512e2f4e99d0e8", - "0x000000000000000000000000000000000015873846a6e7648a844f037a03f737", - "0x00000000000000000000000000000076dbac5187affde31d2adfb3b5064f5a77", - "0x000000000000000000000000000000000020ef23c172d94df80288571d7e3ca3", - "0x000000000000000000000000000000e69eb7802e5d99aa20bc39dee1f6b84b8f", - "0x00000000000000000000000000000000002b2c9af00759a128112ed819b8b1b0", - "0x000000000000000000000000000000f74bd0fb26a604548c9068fef410612fb9", - "0x00000000000000000000000000000000002ca283b09804c9b7d8ca32dc3a2c75", - "0x000000000000000000000000000000c90052c50c0497cddef7e3a71872d14596", - "0x0000000000000000000000000000000000231d65742b933d5aef1ad67db52143", - "0x000000000000000000000000000000b86b4223f0ebb39a8741b6ebba3a313095", - "0x00000000000000000000000000000000001f853f71eaa7368db93d05eefb5256", - "0x000000000000000000000000000000467ff45666661562c57d52de8c4f8f193c", - "0x00000000000000000000000000000000001fdb031a99c29b571b0a66a4140e8e", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000089d2777774ad5c33906740b3656fda53a0", - "0x0000000000000000000000000000000000133bedccd128dc4587817ae09af71b", - "0x000000000000000000000000000000641918e54723a119562889c1ff6239d13d", - "0x00000000000000000000000000000000002c14c2e4f17070e269f9903a383793", - "0x00000000000000000000000000000026c43cff4875a95471fe2c2008292fff78", - "0x00000000000000000000000000000000001224540abfac9c15d64e21d816b9dd", - "0x000000000000000000000000000000beb481b4d5d4eef75c1b133ca9b7efa690", - "0x000000000000000000000000000000000019b490637210bf2280a86ae0a1d7f7", - "0x000000000000000000000000000000e0b4e0795a8b1375e34eab2397b735ef03", - "0x00000000000000000000000000000000000effe6364fc31714fde11efcbe733c", - "0x0000000000000000000000000000005a1907824e164fc0fdd0f0e7c61f4d7398", - "0x00000000000000000000000000000000001cd6403b37da0361f243a3606ac383", - "0x0000000000000000000000000000006a48458b17770a4ad91f725dd01a8c486b", - "0x00000000000000000000000000000000000c395fd0e57de7d52c706e13918651", - "0x000000000000000000000000000000cde7b67f0a01ba051f06746ff7b56f59de", - "0x000000000000000000000000000000000020e0ab3fa354e260e0ac1855e128ca", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000654fe84b50aced8eb7212098af0880ed53", - "0x00000000000000000000000000000000002b2fcb6b0ee568a71f92d2a9bbfad3", - "0x0000000000000000000000000000005d9f4f1e59fac32314c435fb51e2a25ff0", - "0x000000000000000000000000000000000009734092d4e035b968ae8ee337464c", - "0x000000000000000000000000000000a28867ea56c5fbf4aca51fdbbf965e5dae", - "0x00000000000000000000000000000000002feaf04057ed002c072833048ce9e0", - "0x000000000000000000000000000000f9b70bdcd41a1c0bade216b9d5284af115", - "0x00000000000000000000000000000000001ece78d726aaf44e37d9053ebd1534", - "0x000000000000000000000000000000c4e55b000805b017402a109a6b29805245", - "0x00000000000000000000000000000000001d999b7c6ca8df0cca3c57ee4c8be8", - "0x0000000000000000000000000000008820aa820991933af75b5d02d44d0bf685", - "0x0000000000000000000000000000000000039880d1fbfc627ab3421788858e66", - "0x000000000000000000000000000000514dfa671906947f5f640255bfc583eedc", - "0x00000000000000000000000000000000000b0e0c990016a1fdf37d3d6daea7ae", - "0x00000000000000000000000000000040dbbc0f6d52ba0ce246acf816373fbbc1", - "0x0000000000000000000000000000000000035ba8d570a6b7efa251b206e85c82", - "0x0000000000000000000000000000003ebdd6ba8db24c72ad85e8d10fb1346027", - "0x0000000000000000000000000000000000035c795b4ad27e20c934ac5ae517b8", - "0x0000000000000000000000000000005369721308b3dda5dbbab39f83bffcf79a", - "0x0000000000000000000000000000000000241a6ba1547bf3c8eb2ded3454d897", - "0x0000000000000000000000000000009f97bcbba8db2f8bda79a78c0eaefacc5a", - "0x00000000000000000000000000000000002c960a56441f3a00b2f8b48f3b3563", - "0x000000000000000000000000000000ffe2ad855d3522d6b3f8b544681949c713", - "0x00000000000000000000000000000000000002f9753e605a6cbf6dbc604046a6", - "0x0000000000000000000000000000008cfee82227443d00335c9ef376137f6217", - "0x00000000000000000000000000000000001708d8cb04ad71f327107dd3e73cfb", - "0x0000000000000000000000000000007872392082ec4533c6b70f690660ee498f", - "0x0000000000000000000000000000000000122a83a98d1d526cb57355616bb850", - "0x0000000000000000000000000000000a95a3eeae99b98360d61166e89954845a", - "0x0000000000000000000000000000000000202c82d7bd85e9243e7ed0801ebe64", - "0x00000000000000000000000000000027acbc73301fe1b0c21888c2722dd75b7a", - "0x00000000000000000000000000000000002ae7d3ca125bd531826422c7d1acf7", - "0x000000000000000000000000000000d761bb670a9ff734cc38f0d30238a2b28c", - "0x000000000000000000000000000000000005aa3fab8a429258028c4a4287a0e6", - "0x0000000000000000000000000000007a80c32a515f441ce80a5d6cdb53d50866", - "0x000000000000000000000000000000000017f409fea3a1680e6df2a07e9eb3af", - "0x0000000000000000000000000000001a93444f40b0bc09418c7894fe797e2736", - "0x0000000000000000000000000000000000171474b32205fc141e14cfb847a8d3", - "0x000000000000000000000000000000081188cb41c2b23f91bef3a8237fb5fa5d", - "0x00000000000000000000000000000000001ed9b478e77d9f60e9614dfd6014ba", - "0x00000000000000000000000000000042f9a2c111e62ef204c3851affea6af0ef", - "0x0000000000000000000000000000000000108601bd973a835e50fc521d6ec1d9", - "0x000000000000000000000000000000f92be9d44c6688723f37065c3af9521bd6", - "0x000000000000000000000000000000000022ed90948b7d0f29ee1ed4349cab5a", - "0x000000000000000000000000000000bf6e68585d4cb32aeb39412d4a3e6cd968", - "0x00000000000000000000000000000000000c8df79002571c9aef12bb6d7f3bca", - "0x000000000000000000000000000000046577d9d6782e8214d846d3a16aa8ceb7", - "0x0000000000000000000000000000000000249e158a2e56acae4de64894bb2366", - "0x0000000000000000000000000000004b4ecd7a5a335425433b11e098157c3557", - "0x0000000000000000000000000000000000152c2ebca43c64a74ea10b830e9f62", - "0x0000000000000000000000000000006e65e30a946db2c5e16462e3a487d614eb", - "0x0000000000000000000000000000000000294d7279cdf2f3a5a0f47d5d830d40", + "0x0000000000000000000000000000000000000000000000000000000000000c2d", + "0x0000000000000000000000000000009746a298cc238fa9fc88119d64824cecd3", + "0x00000000000000000000000000000000000a622e89485dcc5a40545852372230", + "0x0000000000000000000000000000006809e41276c7672741eaf50c615e7aaf5f", + "0x000000000000000000000000000000000023ef3262cfcbaa1a38aa48f42b80a4", + "0x00000000000000000000000000000029b4a0a73660db847087b0ec0ff8ae7cc0", + "0x00000000000000000000000000000000000bbf015119fab668caabd4aac59b4a", + "0x0000000000000000000000000000003aceeaa5125630611ff88a1638c74b8bf8", + "0x00000000000000000000000000000000002954b4a5df3301bd05b4b33f4b1281", + "0x0000000000000000000000000000007d75fd1698bf937cad957054b4d802deac", + "0x00000000000000000000000000000000001eae87f9894a26c8d8685edcaa11f7", + "0x000000000000000000000000000000bec44c06c527d2c90cd142d22a575b64ad", + "0x00000000000000000000000000000000001ce6fd416b339978042baa3b29160b", + "0x000000000000000000000000000000601d1a36cbf2648b7a35e094aab2f78625", + "0x000000000000000000000000000000000013d19f319a00fc7417c1ad631d3286", + "0x000000000000000000000000000000cebe2c4b8938871fcd990b93f474835e2b", + "0x0000000000000000000000000000000000253ff4164f3a2cdd7a2118f953a472", + "0x000000000000000000000000000000633bff41528ff6e9648cabab45618cd3f8", + "0x00000000000000000000000000000000000a128ad23b420b11945de2c94bc8db", + "0x000000000000000000000000000000c2bdeaad6e1bb38c01807cbeb39eb01474", + "0x00000000000000000000000000000000001a87197d7cbb357c71e7475853a89a", + "0x000000000000000000000000000000d60d42e56b09250d5406827e9f63c5c507", + "0x00000000000000000000000000000000001c429c10ec7865314a9bb768fc77cb", + "0x000000000000000000000000000000874ae527782ea78b526a4069d5a5fffad6", + "0x00000000000000000000000000000000000cf6dd26f50b908aedf25ca7beb983", + "0x0000000000000000000000000000007dfb532ce535603daa17b40d4f20268fa6", + "0x00000000000000000000000000000000001aa8da80801279d91cd4386764d5b7", + "0x00000000000000000000000000000051498e1f98a404cce7b25f7487732af055", + "0x00000000000000000000000000000000002d5ce3870ecba8710b98522a635a24", + "0x0000000000000000000000000000003f1d7da491f2a68c39458177333aa62b8f", + "0x00000000000000000000000000000000001d1af6c81adf6a906f55b20aa99aa7", + "0x0000000000000000000000000000004398c4f4ff3f65cba6337e0a48437289b7", + "0x00000000000000000000000000000000002c90b326149002904e30310eed12dd", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ce520672cc9f4fba3288b2d696d69b60", + "0x0000000000000000000000000000000000240074838ef9434d6524883c8af328", + "0x000000000000000000000000000000cc5409001d9a1b6e499a55194c5cee623b", + "0x0000000000000000000000000000000000272e8cb04c7e831a06e0eff44b1633", + "0x00000000000000000000000000000029faeb6bccfe395b36c4dde26a9281cd51", + "0x0000000000000000000000000000000000079cd2f8b7f8d0ba574f06c074487c", + "0x000000000000000000000000000000467663df6ffc3082510ef243829669f9b2", + "0x0000000000000000000000000000000000154ba884593558e4fa1d35a08901c2", + "0x0000000000000000000000000000003b9367cb2541b5cae36cacba4a0e9565f2", + "0x00000000000000000000000000000000000e9c894d1634c38a1da7a18ff2a4d1", + "0x000000000000000000000000000000a44d578cb20654807e5da0fae4fb462540", + "0x00000000000000000000000000000000001583bdfc0f1f208b72177fd73a4e0e", + "0x0000000000000000000000000000005101bd383908b7e9563f9943ed5b6b9d5d", + "0x00000000000000000000000000000000001894ae59fb37a39ee483d90674a601", + "0x0000000000000000000000000000008eaa98f808cc4df6011d0467d94748bfef", + "0x000000000000000000000000000000000018728540c99b37787e0ec614d5d2c2", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000095b02b4b915ea97d2863c7de9364faf7c1", + "0x000000000000000000000000000000000024bf0c36515c471894eca07c722a6f", + "0x00000000000000000000000000000021b9c8dd0f3068ab110290ce8dde8ca475", + "0x0000000000000000000000000000000000033a64820c52027d57fb58ebb6c381", + "0x000000000000000000000000000000de86fb0a5a50dd02848572163142b8640e", + "0x000000000000000000000000000000000006104618e23a8bd65ba6678675ef30", + "0x0000000000000000000000000000007ecf243d0261b865862c9aa1c0fa854c03", + "0x00000000000000000000000000000000002b49777a506a0876586804d7265c91", + "0x000000000000000000000000000000b03490f3e92e51591fa83188e45ff33c1d", + "0x000000000000000000000000000000000020ca792b4db8d34742259c49a69680", + "0x000000000000000000000000000000bba53bf211eba5cfdc0655d659b54e5154", + "0x000000000000000000000000000000000025743fca2cf229c9e74f0b94b2a60c", + "0x00000000000000000000000000000039fa7ba046a2aa4d1e1b2e7caf7a8468b2", + "0x0000000000000000000000000000000000114565ee8a1a9f6c0765554f828b55", + "0x00000000000000000000000000000039f6f4a9450081d17e80431d7673b4e831", + "0x00000000000000000000000000000000001aeacf01182adb275721404acf94ec", + "0x000000000000000000000000000000b61eb26643a3330cf20693ce2863cd8df9", + "0x000000000000000000000000000000000001287624004468d7fdb961891f7657", + "0x0000000000000000000000000000008e93f0560ff5d7fc733764b1eb22480fef", + "0x0000000000000000000000000000000000122ec6ad7d326d49eb1ec1b6058f11", + "0x00000000000000000000000000000095ed3058c8b0990d267a70546ff583ee0f", + "0x000000000000000000000000000000000014b8a07a5bb9e756fca0fa2b309603", + "0x00000000000000000000000000000011c41e34d997fc68ea4bf83e558d0cc63c", + "0x00000000000000000000000000000000002d5aa2b07b478858f898b181d0ba8b", + "0x0000000000000000000000000000002181f534d66eac7d336c5a0615483614de", + "0x00000000000000000000000000000000001ddfc420c74fb84de1fc06e15cb736", + "0x000000000000000000000000000000221911551b028d679741b7201b0ecbec4c", + "0x00000000000000000000000000000000000dda073b8d6dff1f7820fd10608eac", + "0x000000000000000000000000000000f83c26a030132139738278422f03bf922a", + "0x0000000000000000000000000000000000090293167442d6241ef786787ad54a", + "0x00000000000000000000000000000081472fe64f8676d2c6ba66632be788181a", + "0x00000000000000000000000000000000002686bba5965dbeeace183975458ab6", + "0x000000000000000000000000000000afefc9d6f3b48945adcbfcfd1c96c9d317", + "0x000000000000000000000000000000000004230c01cef5000fc66eed900511c7", + "0x000000000000000000000000000000461b8ddba4875f5c0ee209e969c8cab5b5", + "0x000000000000000000000000000000000004f3c201bbca13be28a391550e3e15", + "0x0000000000000000000000000000008559177c932a1653672c242e7617b96ed7", + "0x0000000000000000000000000000000000171be06bb1a5c5e15ae25ea139e42a", + "0x000000000000000000000000000000ee99ac22da62f96c90ac540968ff4e0df5", + "0x00000000000000000000000000000000002a4b4f6cecfa52aeacb7c88e2ba547", + "0x00000000000000000000000000000075b8d277e2f2d2578c463156acd5f1475d", + "0x000000000000000000000000000000000013ad863e13e6edf10c859862b09f73", + "0x0000000000000000000000000000009f93998170f02cdbb3d8ab65ffc18aa878", + "0x000000000000000000000000000000000000b2bad4d1a7598557b09810779622", + "0x00000000000000000000000000000000d5a82f535d9f53a56ad2c90d651a6f07", + "0x000000000000000000000000000000000000e77d138f0fe1fb3334079b7a17b8", + "0x000000000000000000000000000000375d67be44557b3a7109eb34e19abe23bd", + "0x0000000000000000000000000000000000004374e342cf902621d2f067ee0dde", + "0x000000000000000000000000000000618d7aa8936861e2dfed7786fe06e14cbe", + "0x0000000000000000000000000000000000028eef3b42459371670ed47195575c", + "0x0000000000000000000000000000004185b847b001cc084cb5d9fc3c413c9447", + "0x00000000000000000000000000000000000f0cdae2ffe529626d71ad12c69406", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -145,65 +145,65 @@ sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000034620fc4f5dc2f120b5673912cf04226e9", - "0x000000000000000000000000000000000025a6078d74c0fd7d4dd9e328ad4c94", - "0x00000000000000000000000000000019d834f9bb59a8e973ed867f0477fc8121", - "0x00000000000000000000000000000000001fdeb0dc3db761477a1a9feb00c906", + "0x000000000000000000000000000000ae09bb7f78acfe7c9d9a2b944b789f8363", + "0x0000000000000000000000000000000000011fa902d1394869cea67da68c1718", + "0x000000000000000000000000000000655a4cb5f0e139646b6fe88fd680ee9c5d", + "0x0000000000000000000000000000000000019f3c976b53013b5041616ea60768", "0x00000000000000000000000000000076959cf0870e0ae93bb69edc64b0cacdac", "0x0000000000000000000000000000000000269679f8c1a1ad2aadccaf8ba3100e", "0x000000000000000000000000000000bb028a742987d54246ffc933f8240d70ef", "0x0000000000000000000000000000000000295f79977c6ae0d15cc2b68b7f0837", - "0x00000000000000000000000000000064dd7da7637cf2116a18531edc7fea829a", - "0x0000000000000000000000000000000000162e867465b02e01bbabb15c59b84d", - "0x00000000000000000000000000000071f09c1d3d2c8f9499c838fc966b04ada9", - "0x00000000000000000000000000000000000f4504ac6f302739e9f2c7aa824d12" + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" ] - hash = "0x297f9ac45dd6c9f333314227aacca93023e72710232e7120328d7e7c209ebc8f" + hash = "0x141adcbeacb22e8db98482647ab8bddc8bafc8d2c45ba62cefe4fabe03067018" [previous_kernel_public_inputs] min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff293f" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7716" is_private_only = true -claimed_first_nullifier = "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c" +claimed_first_nullifier = "0x1268b93c2a6a4d3780d6cb2b948cc3884e65336ef39eb7202b4de102b9cb3748" claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" [previous_kernel_public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" [previous_kernel_public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x1f8e9213a0888fe29bbbc5c39db80f4b9f1575e375c6a0932a13ca2b8e2fced2" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x1d706e11585e9d3ecfd4d2ead7a52c2a783a92adfbe3419e8671011fe5016491" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" [previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x0835e9ab1ea355f270408857dfd5647ca56d588ab4a7d573e67566f6324821d1" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1f860209ee462b9c30510a063670044f005084362ce71f528205a17ee048fc7d" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2597" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -214,7 +214,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [previous_kernel_public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -226,29 +226,29 @@ l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" [previous_kernel_public_inputs.constants.tx_context.gas_settings.max_fees_per_gas] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" -fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" [previous_kernel_public_inputs.constants.tx_context.gas_settings.max_priority_fees_per_gas] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1303,13 +1303,9 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1318,13 +1314,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1333,13 +1325,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1348,13 +1336,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1363,13 +1347,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1378,13 +1358,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1393,13 +1369,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1408,13 +1380,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1423,13 +1391,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1438,13 +1402,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1453,13 +1413,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1468,13 +1424,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1483,13 +1435,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1498,13 +1446,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1513,13 +1457,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1528,13 +1468,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1543,13 +1479,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1558,13 +1490,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1573,13 +1501,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1588,13 +1512,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1603,13 +1523,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1618,13 +1534,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1633,13 +1545,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1648,13 +1556,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1663,13 +1567,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1678,13 +1578,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1693,13 +1589,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1708,13 +1600,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1723,13 +1611,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1738,13 +1622,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1753,13 +1633,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1768,13 +1644,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1783,13 +1655,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1798,13 +1666,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1813,13 +1677,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1828,13 +1688,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1843,13 +1699,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1858,13 +1710,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1873,13 +1721,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1888,13 +1732,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1903,13 +1743,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1918,13 +1754,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1933,13 +1765,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1948,13 +1776,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1963,13 +1787,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1978,13 +1798,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1993,13 +1809,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2008,13 +1820,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2023,13 +1831,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2038,13 +1842,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2053,13 +1853,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2068,13 +1864,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2083,13 +1875,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2098,13 +1886,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2113,13 +1897,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2128,13 +1908,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2143,13 +1919,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2158,13 +1930,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2173,13 +1941,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2188,13 +1952,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2203,13 +1963,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2218,13 +1974,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2233,13 +1985,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2248,31 +1996,27 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.note_hashes] -length = "0x0000000000000000000000000000000000000000000000000000000000000002" +length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.note_hashes.array]] [previous_kernel_public_inputs.end.note_hashes.array.inner] -inner = "0x2295fa9f079bf362a4f01c3b07d9f912f9b484e5ee527ad7a528025a165b9352" -counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.note_hashes.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.note_hashes.array]] [previous_kernel_public_inputs.end.note_hashes.array.inner] -inner = "0x27f0738f58cf7f88e6845175913245e6f82475f464578de70619eceaff66402e" -counter = "0x000000000000000000000000000000000000000000000000000000000000000c" +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.note_hashes.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2781,7 +2525,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000003" counter = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c" + value = "0x1268b93c2a6a4d3780d6cb2b948cc3884e65336ef39eb7202b4de102b9cb3748" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -2789,10 +2533,10 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +counter = "0x0000000000000000000000000000000000000000000000000000000000000007" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x1567c8c1ff81dda9727361df23c92849c46772567aa0bf3723db03c3751e9d2e" + value = "0x091de02133d9012fa28a3a5e8e913d5587b6baff1f4dc765b3bf31aa60c8924f" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -2800,10 +2544,10 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] -counter = "0x000000000000000000000000000000000000000000000000000000000000000e" +counter = "0x000000000000000000000000000000000000000000000000000000000000000c" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x1cb96ed0bfe97ed05e23f013062425e5ce6599fb6430b162e69edfc317d5bf82" + value = "0x23b82c3f4fd6976adb96ec88b22c4c5d876bd55be4810759e4e9ed9ec26d3eb0" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -3588,97 +3332,97 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs] -length = "0x0000000000000000000000000000000000000000000000000000000000000003" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] -counter = "0x000000000000000000000000000000000000000000000000000000000000000b" +counter = "0x000000000000000000000000000000000000000000000000000000000000000d" [previous_kernel_public_inputs.end.private_logs.array.inner.inner] - note_hash_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] fields = [ - "0x2c3715409dc4762ec9a9a602d199ea9932d61edd3fd32c9891fe5ea5a722acde", - "0x10433733db106ed8336b9b799ec2debee9fe2da75f114f567eefde5abf9f74d3", - "0x17440c522b009a136c2207db86790b05464774690523c7fbf949ad381664d0ea", - "0x0a5e8928a4d74ad3256e8a697cfdf84b7baae32abad67b2de7c36ffd67acb665", - "0x0b1200621e156c6d79f463e17e81b96f11d18d716ca5222e7276e07d45845a26", - "0x04b2b64d09e487d10d557106046a94a97f2c40f4316e6667a2c2d9a99db05385", - "0x193da3d713c24b85e1c8f22dd8ef575e88d19c6732f8fd17e370cf64e65b3e04", - "0x08569203e8f3d028234ed200df77bca848c9b4b015ad8797c37669a5e5d1ee0c", - "0x13a9b2003409ad3d4f38caba797acc77092ddd431af25a955a83dc6f5b92cc93", - "0x16fece01bc0b0205bcbaca2904d5674d10573bfef038f94d3e5d526596da2ae9", - "0x0a438177a05071eaeb1862f154b187315de4dc804e275b0f2258baf4700c6d64", - "0x0959244a76e5e861ce5b8833101b91e19d758109d68cc174a6f9eec9c7afa008", - "0x03533d18a1c3ebcf22f820a243be161c9798ea59a506572e32e125c53b7aee7e", - "0x1e2b22ea302597bfcbcfdefcda48b60e35fce9c70f46c6cb90fa6db6e8d4dc6d", - "0x28fab93b8cd28d8d2a993badc3d1a080902feecfab019dc7c00af0ea9f6f403d", - "0x104c4c81c135af94af35a1eeb49b1262e5c53e25ee513731ddeb9f6496eea2ab" + "0x1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a8", + "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x1ca223fbc16e82cbb9bd22c108021ef47864791c258edbdd8eefa458c62ba8d2", + "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", + "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", + "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", + "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", + "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x000000000000000000000000000000000000000000000000000000000000000d" [previous_kernel_public_inputs.end.private_logs.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] -counter = "0x000000000000000000000000000000000000000000000000000000000000000d" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner] - note_hash_counter = "0x000000000000000000000000000000000000000000000000000000000000000c" + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] fields = [ - "0x1b7f52b7a346b47077bab6835a0810e5d75e977fc3f3fbb0436055bcdaa167ee", - "0x2320e89fb76918e7dc48b13861302dbf78af5ba8d5a20da77d19781ac32b9bc2", - "0x2a99619c0d4d380dbc3d53d03ed35011aa9c296a507fabcf712f43a0e5a10850", - "0x02e5d98e7dfbe7653dafb14afddd7e00f403b5a60816d7ab961823bd3cc4b628", - "0x223b37d6caffe87e91cddafdf65c4f641a609ff13350d02654b0fed1443088ab", - "0x2846b9aa4544f8f8851554f5d0c189c188756d734112e1eedd6840c8aeb0e66f", - "0x21cda3f228d55fb1b37f2b7c7a5d42066007143db17645669521ff58956fa7bf", - "0x1d8d79951d7389e5f9dfa963f93e399aebaa346e9ce3b3a5da1b45e4600a1553", - "0x15eabc8ed921f60621fa4fa35214748a7593f1c06a1e66b76092f789b4960bc5", - "0x16babb28d68725cb64d6d7558d49fb921c480359488fcdfb5292019239a50563", - "0x015e561b49da425d081b87bac01336defa1e29ee50d01b7be798ac28e05b24d6", - "0x04bf1a23807cb0711511a6140caf195df55fcf029842652243034ae2ca740648", - "0x2789cc422a86395739004c513cf6a15024e3adf5f2e238b18e1b4f1211a9383a", - "0x00c4e950cfe804e8a3623fe768c82b7340b0216f93c00351c53e2144364cfb51", - "0x2fd9827b4118b7ef401dff1727785e46fdd31947d2e733f4b39076f43652c18a", - "0x158ca7fba6e7fa7b3eb7c062751182d93b4e36b5c77d2e609e246b810650e59e" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] -counter = "0x000000000000000000000000000000000000000000000000000000000000000f" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner] note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] fields = [ - "0x07d20bd951900d3094f2894e3c76c117114e3150dc3197e9e325e42b4487c6e2", - "0x127157561e774918ba656738fb61ad37f92086431bd4f1e4842ab11928b0f8d2", - "0x2e5cf59c8f2eee7a06d14cdedb8fe58945357cb16f4c792094325909a12924b2", - "0x0e29376c31f2aa7a156c6ce6d1fc9529998251d8500604658f173ff86adffa98", - "0x20761b8be9a186cf6a1730b8a1e99049a07e45c005e66d27b6e0ef15a2833e2f", - "0x1adf679b2441cf3535241924a35164cf8309256721e3f9fcb860bc2acc462b46", - "0x06a613741497b7b7ee978a495bfed7d19bbf76c462d268cee17a3920b1b1abe0", - "0x10ade06e253c1cfd65f24246211fb703c157fd9b563ffaf6ab01b6fba4635155", - "0x2311c6b104555d4d9afc7d66be6b47a41f8aa96eb77f613a75fc952da5975ccf", - "0x08431c3838d7ad6198c1d33ff138953ace3520551bd95b69692609ee11ded216", - "0x1822c33cf8097138c896bb9f7aad7def909a6859d5e640919fd16ebcf153a0db", - "0x11203b31ef49d39fb85a5ea474116c334c156091ab468493a480f13ad1ec1849", - "0x207a4712bacadd2f631fe253cb62932a7acb586dd6dd1b10e0fbe733f61a8f11", - "0x2c862b0eb14b1325a0ca63dda4570f718541d998fb4aba96339b7913b80757c9", - "0x1bf17ee7d3cf2487dcf1eb7a3647b0920c9e68aacc0a33c9a424d4ee6601ded3", - "0x2c70c9b7da7d7df78fcae182d124d7041209070f76d920e5d5c2d7590c385ea1" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -5575,18 +5319,18 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.contract_class_logs_hashes] -length = "0x0000000000000000000000000000000000000000000000000000000000000000" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.contract_class_logs_hashes.array]] [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000008" [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner.inner] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" - length = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x242b9549d1e2c420a764a5aa2ba58d98b77e35fef8ffa5aa787f9b325f2b5005" + length = "0x0000000000000000000000000000000000000000000000000000000000000068" [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" [previous_kernel_public_inputs.end.public_call_requests] length = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6309,4 +6053,4 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" diff --git a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixture_builder.nr index 9721be95d429..83ec51b19263 100644 --- a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixture_builder.nr @@ -80,7 +80,6 @@ use types::{ }, merkle_tree::membership::MembershipWitness, messaging::l2_to_l1_message::L2ToL1Message, - point::Point, proof::{verification_key::{MegaVerificationKey, VerificationKey}, vk_data::VkData}, public_keys::PublicKeys, side_effect::{Counted, Ordered, Scoped}, @@ -965,11 +964,11 @@ impl FixtureBuilder { pub fn add_request_for_key_validation( &mut self, - pk_m: Point, + pk_m_hash: Field, sk_app: Field, key_type_domain_separator: Field, ) { - let request = KeyValidationRequest { pk_m, sk_app }; + let request = KeyValidationRequest { pk_m_hash, sk_app }; let request_and_separator = KeyValidationRequestAndSeparator { request, key_type_domain_separator }; let scoped_key_validation_request_and_generator = @@ -1258,10 +1257,7 @@ impl FixtureBuilder { fn mock_key_validation_request(self, index: u32) -> KeyValidationRequestAndSeparator { let value_offset = 3030 + self.value_offset + index as Field; - let request = KeyValidationRequest { - pk_m: Point { x: value_offset, y: 1 + value_offset, is_infinite: false }, - sk_app: 2 + value_offset, - }; + let request = KeyValidationRequest { pk_m_hash: value_offset, sk_app: 2 + value_offset }; KeyValidationRequestAndSeparator { request, key_type_domain_separator: 3 + value_offset } } diff --git a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/contracts.nr b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/contracts.nr index de6692fde7f3..41e15d836783 100644 --- a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/contracts.nr +++ b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/contracts.nr @@ -27,17 +27,17 @@ pub global default_contract: ContractData = ContractData { public_bytecode_commitment: 0x256abef672381d551191d5bbecf2dec6ac9cc2a81189f886ac22e29e5c58c49c, private_functions_root: 0x2653ec1bf2be3a13fa9b645cec2557f2b543286fc39168ec42b705835a301bb6, address: AztecAddress { - inner: 0x136422d2d758eb9181240eee44720fa9bc433d3a16bc13163699dc4f47540b0d, + inner: 0x1599beafce80b22c56446667e1627d865bb87ea94b8f1bdc757979f78a596042, }, partial_address: PartialAddress { - inner: 0x1676695fc9a4f3bc8816e4dc82a8856b2ae565d4872691a6e944cc3ce8897e72, + inner: 0x13bf689e2b04d5a75694270c1872e74b0c998c3f7f2f3a0a95648f9f41600808, }, contract_class_id: ContractClassId { inner: 0x2888d24c26f34b139f0f1d30278df8f9007d06da3b63cfe6eeb9a710d51f4f4a, }, public_keys: PublicKeys::default(), salted_initialization_hash: SaltedInitializationHash { - inner: 0x1d83f43991ef3c393247a1796b194020c559aaf129e515adc6eace265f726452, + inner: 0x20b8accdca7010cfebfcc932f55e3acf5136dfe57ba51d386dac8e9d110d9567, }, deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000, @@ -52,17 +52,17 @@ pub global parent_contract: ContractData = ContractData { public_bytecode_commitment: 0x1cfb8e870870be1d102249b47923b63c2d54f33ca81e3028d74a06d8dd5944ca, private_functions_root: 0x03cca4d59a01776df283eb2c8915cb144ad3f40a0b0ba06e9c24c532c59e3c43, address: AztecAddress { - inner: 0x2e90a78904fdb353ddf6eda97aedcfc2b8bf5a942f10f57a1e85373b740e7eca, + inner: 0x1ea25c8d3d0223005170fc2cc0a0e8e3593e322bfcdebc817cc2a02cc95fca9c, }, partial_address: PartialAddress { - inner: 0x2cfac19f0c29a86d17b4c60b205376bbd4c8e45d1dfd02dcd33820638d1d6d1e, + inner: 0x09dba9fffbfd68d6828334a178433b7bfae9d07c3c6f424ee4afa0304655c5d3, }, contract_class_id: ContractClassId { inner: 0x2998b9cf4a582f068a01b43c141dbcc5fd8f5cd17a797484b5a5db2386cf7574, }, public_keys: PublicKeys::default(), salted_initialization_hash: SaltedInitializationHash { - inner: 0x2bfefc4cfdd56352f0d6cf62ae70abe702d7d948f5ccff4eeb51f9aefaece295, + inner: 0x1384ae0b0212cbeb6cd53d6c8d9dfc6334318553dd6f33fdaa97b5dae4ab9dbb, }, deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000, @@ -77,17 +77,17 @@ pub global updated_contract: ContractData = ContractData { public_bytecode_commitment: 0x225d884cfeaddc5292dadbf921e7699632336876c65a33459d3b2ad9b5ec0da3, private_functions_root: 0x2b26caef823c6be4c41ef1980dace9b61825f8e6a16792c765a2cd8cb2121e75, address: AztecAddress { - inner: 0x1a56e3cef400d47addbbf65a95ea505b8f628a2d65a096d0e4d46a8cc9bd72c3, + inner: 0x144f3aaae816b99f40fbea5b9f80fe4683bf68a14876e7379c4171c871a1ef09, }, partial_address: PartialAddress { - inner: 0x04a4ed87aa4cff86962b974fe3f79d76e4bf3f034d4e2bde2bb50765927fad40, + inner: 0x12b89345d5d63f8bf9f73f5890d5caa0c5f023c61d313b1abeea40e300a83755, }, contract_class_id: ContractClassId { inner: 0x07a63b1343bb8515d1115202c71cdc95f9bcda9c2237bdfc25435b89ffa06b46, }, public_keys: PublicKeys::default(), salted_initialization_hash: SaltedInitializationHash { - inner: 0x0bbf968b28a0a1fa3a90ceb4c7104d63e7a8dc845a9c885781d74018d1579e59, + inner: 0x1f121db378dbceaf871eed1b9f0b20efcdca988e76f8abeaa11b2cdc80474189, }, deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml index f9937c534a5b..98750fce6576 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml @@ -484,7 +484,7 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x22e5411ababf49ccdacb44202da8507dcac351bce3fab350c18dd0655abcf9c0" + block_headers_hash = "0x07d6c206790cf70b15b8243736ee089cda60cf2c3e85d131fa3ec16d1f5bdd36" in_hash = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" out_hash = "0x0018febbd74d861e38064a4ff9d3b5ed7a39b398576ef75e104848700819a700" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -493,8 +493,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -513,7 +513,7 @@ proof = [ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x0edef98680cbea2855c4f0f152a0ecd69358e68b10da7b7e301f35ce709c13fa" + root = "0x27b365d73aa1b8ac1eb39c75262e2b87a238d041cc98fcb795f4c597c620ce64" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -576,10 +576,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" ] state = [ - "0x08cdf544ec44d694936ed6a5aa580afb2a3b1a4b087ba80870d4d01c79cb5772", - "0x192972b72a1776fa9d30c1202807fca4f9272b156c9e1eafa5f93e94a13c439b", - "0x23ace986d5ee172559ce2153d8a166075599a4403288cbe1a150bda49415fae6", - "0x0f3ccb179877769f2d268206c1b45ab9af36d5e7e005de27ede90c1a29450039" + "0x13ec9d9b37f0599c5765a81513125e07305454198fecae73a69e7d41dfb27215", + "0x24fe963f8f4139d84f904228cfe1e10256e9106331e614b72ed86be8903e4259", + "0x114cba9fee3fa49ffd5f440aa162c6ce6e8410138a592e587337646bb8b04ca7", + "0x10325219e420881603ba4ea16613cf66fa1c43ff98bceb97acaaab599e3326b5" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -587,134 +587,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" sibling_path = [ - "0x23d78e0b464510ddf15e00aafb3d9a34c4300cb431a0343efa8acc7ac7174e1f", - "0x24ebbcfd36a0a9ea7467ed78450dd4914d8c54a1434a5dfd9757f4f88c51b867", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x1276688c1c8f1024c963d35957328b73153c55580532254f0676c26e2ad55993", + "0x177b04fc814d3ca71e4c26c7a32c0c913574feaf5567348e99c5cc65f0f9ddfe", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000015", "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x000000000000000000000000000000e4ecee2341c2499228c4d2c83a9520cae8", - "0x000000000000000000000000000000000028d32ba99192667c15e398069c3240", - "0x0000000000000000000000000000006fb00058cacfb1b276d32fa36447360c8c", - "0x000000000000000000000000000000000001a8699458060a98552c6907a085e7", - "0x00000000000000000000000000000035e6b6b068c96f12086377d88703f3e07e", - "0x000000000000000000000000000000000015477ce75a652da3c7317382f97441", - "0x0000000000000000000000000000006b648f1adda6e61b44e9867b5f8e3b4f79", - "0x0000000000000000000000000000000000284a9d333412f98641932adc241a55", - "0x000000000000000000000000000000e4a1e119917387b63453afe2152f923081", - "0x000000000000000000000000000000000016f3a12e54e2b76aa8a0c2350c5b03", - "0x000000000000000000000000000000e6a6952f1b80d571443fb3a9782f7ba03a", - "0x0000000000000000000000000000000000115314dec35ce22a37e5e08838dd90", - "0x000000000000000000000000000000608fa42518b2ed1d41d26a56c4e7fd1cd0", - "0x00000000000000000000000000000000000e864b9635bc3ab6a2e8a63311af9a", - "0x000000000000000000000000000000089e6633599c12307e5d2315b0559fa3ff", - "0x0000000000000000000000000000000000188c6476388f9b0875dea7de1bc491", - "0x000000000000000000000000000000abca067961d5609684ecd2136ba688b8d5", - "0x000000000000000000000000000000000003650b02580ae03fa6c488d150619a", - "0x000000000000000000000000000000a7a66d3882208ec15d795f73ff135448cb", - "0x00000000000000000000000000000000000eda3b802a8c57b6007532ac4d3c73", - "0x0000000000000000000000000000001a0f5ebabaa07f627ed7025287560ef87d", - "0x0000000000000000000000000000000000081f627ebc9b282e50d5101f2fdc0b", - "0x000000000000000000000000000000af44c7ddc6ed98861741ef7d79b45171ab", - "0x0000000000000000000000000000000000189091a7b840d8a84827cc8270560e", - "0x000000000000000000000000000000c10049e49d4cd16c33bbc1e8eb3238ea26", - "0x00000000000000000000000000000000002578443465dd684c74b9c635f2c33e", - "0x000000000000000000000000000000770092209b5122c863dacecd7406bb2d48", - "0x00000000000000000000000000000000000f3fee6266059403a65308d4c5d7eb", - "0x000000000000000000000000000000533f8b9f4c4a0d43ef35dab7d27c1ea8da", - "0x00000000000000000000000000000000001adf8c6f547a4381844323d92940ac", - "0x0000000000000000000000000000003c366da2e86813e08788a4a283cff05948", - "0x000000000000000000000000000000000009d343f03cc09faee9ca1d918d51aa", - "0x0000000000000000000000000000004eff2a8415f5ebcbbb774b024c7cca829a", - "0x00000000000000000000000000000000001bdd73863935251e91860c886a55b1", - "0x0000000000000000000000000000003df888a4b79151f5f34eed566c6d247e55", - "0x00000000000000000000000000000000002d996ddc7dcf55af0fecfbe916441d", - "0x00000000000000000000000000000035a1c8de7d282962a240a6704a18d9aa9d", - "0x000000000000000000000000000000000022c5a65fc79d84f800459e76bd6ddc", - "0x000000000000000000000000000000f694c211bf5e8247c2ed4c9772d66b5320", - "0x00000000000000000000000000000000002254e08116deb9d889a0143317b65f", - "0x00000000000000000000000000000048358b74356aff020c99bcfffc97f02b91", - "0x00000000000000000000000000000000001d9bb0f7098bb21c970677fb97a3de", - "0x0000000000000000000000000000003fd980235a24687982d5bc1e10572d41bc", - "0x00000000000000000000000000000000002ad88fe0270c96dbf63278dd32b0eb", - "0x0000000000000000000000000000002aa721427068275b015588487a6dd9da77", - "0x000000000000000000000000000000000010ed5178cf97b67466833bb3e294fc", - "0x000000000000000000000000000000fc9b469311b99d851b65fb621b17172be3", - "0x0000000000000000000000000000000000058b714d3d803f8cea308e60246a25", - "0x000000000000000000000000000000ab189fd5ba15e2bc3843c70e4b6ccc5874", - "0x00000000000000000000000000000000001f0042de0aeed97be6e8b8e93e5484", - "0x000000000000000000000000000000990cfdb6f4a3699f168f757c1a663e2792", - "0x000000000000000000000000000000000029d9940fe4dfdae5c2cc1ebfdba6d8", - "0x00000000000000000000000000000006147c05564229442b8f35ada3f0f58754", - "0x00000000000000000000000000000000001ea24fc9d78495240f0fc072c3d6e9", - "0x0000000000000000000000000000008333bf707667d3ac3960826883a0d26107", - "0x00000000000000000000000000000000000e7f2da7e4a8b4ee0bca717b98686d", - "0x000000000000000000000000000000f80529b50987783f12df2e1ee9f91fdccc", - "0x00000000000000000000000000000000002fbee99a2fa069d2da029ad5a86c40", - "0x000000000000000000000000000000ea3704a764aeda63475f07b984b2297f60", - "0x00000000000000000000000000000000002cf75af466282247648425172dd45b", - "0x00000000000000000000000000000068754ac413cc462e8a87396033bafe80fc", - "0x0000000000000000000000000000000000138b5a95236c3755c228128437cb81", - "0x0000000000000000000000000000007c551a7f9f585f152f2899cd5c73cdf658", - "0x00000000000000000000000000000000001601277332a9e90e2af9bb57340356", - "0x0000000000000000000000000000007543dc89bcca355d7e34573dff53f933e2", - "0x0000000000000000000000000000000000170cb4ff2fe573d8a4f20d7e7b64ef", - "0x000000000000000000000000000000a32270e25bda22ff0b953eb2ccdd937551", - "0x00000000000000000000000000000000000b5603a198907b41d522094f42cad2", - "0x000000000000000000000000000000d0ff37f21975e21ddcaafdd3dd783ad7d6", - "0x00000000000000000000000000000000002d0a2f4c7e56c0c56b889f47c622c6", - "0x0000000000000000000000000000009472ecb153285dccdc60cf91dde517845e", - "0x000000000000000000000000000000000015e573aca14b7c5fd370bcfc540b27", - "0x000000000000000000000000000000c303cfdc251b35fff418176773aa2776e4", - "0x000000000000000000000000000000000026e160cb0be92aa253d24a3ef4762e", - "0x000000000000000000000000000000caa9c67bcb76b860aeb9f0f4b012671fbb", - "0x00000000000000000000000000000000001386aeb173c2f13bc20ed2b78147c1", - "0x0000000000000000000000000000002b385a5dfd8c9a7ffc125cfd6fa7f8fd45", - "0x00000000000000000000000000000000001597a3dd423660dbd9daa02d14e187", - "0x000000000000000000000000000000d563bdfaa101f554e342f7fe227dc29f16", - "0x0000000000000000000000000000000000090a2f765e614082aa702ded80dffe", - "0x0000000000000000000000000000002c13af1d7029f509b59a9d7902023a0783", - "0x000000000000000000000000000000000015f5fbf1568f18d113c76d8125b4c9", - "0x000000000000000000000000000000832350cc0d3066c6a9d8d4e59c38966d94", - "0x00000000000000000000000000000000002c0a8c5e6b3ad7b65677d02e3af4ca", - "0x0000000000000000000000000000004581bf4848fb500439bee9e9db80d8dce2", - "0x00000000000000000000000000000000001a7ae19bf5ba02728391e18925e760", - "0x000000000000000000000000000000d9b2acde6149cf8e6f308444a49c333a30", - "0x0000000000000000000000000000000000192e53bff5334c0fd6d7f110fc3552", - "0x00000000000000000000000000000095b5d8b7b4a63b05df652b0d10ef146d26", - "0x0000000000000000000000000000000000099e3bd5a0a00ab7fe18040105b9b3", - "0x0000000000000000000000000000002129af3a637f5a622a32440f860d1e2a7f", - "0x00000000000000000000000000000000000015b8d2515d76e2ccec99dcd19459", - "0x000000000000000000000000000000222b888108dc25d1aa450e0b4bc212c37e", - "0x00000000000000000000000000000000001b917517920bad3d8bc01c9595092a", - "0x000000000000000000000000000000482141c7ebe42000a1d58ccb74381f6d19", - "0x0000000000000000000000000000000000305e8992b148eedb22e6e992077a84", - "0x0000000000000000000000000000007c86847618681dc29d8a9363ab7c40e1c3", - "0x000000000000000000000000000000000016465a5ccbb550cd2c63bd58116fe4", - "0x000000000000000000000000000000439973ac12d7ca796d6fe98ca40e6ca6b7", - "0x00000000000000000000000000000000002e24d420fbf9508ed31de692db477b", - "0x00000000000000000000000000000028edd1a7e46c840d9c943fdf45521c64ce", - "0x0000000000000000000000000000000000043d063b130adfb37342af45d0155a", - "0x0000000000000000000000000000009330952ae74c573d1686d9cb4a00733854", - "0x0000000000000000000000000000000000261522c4089330646aff9673619494", - "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000ea6e74a6fa43b4810edc310e2d2b66dab4", + "0x000000000000000000000000000000000015c12f6f69bff32654e403b8e9a2b8", + "0x00000000000000000000000000000010f1d77dfb1e9178bab79124490d92915a", + "0x00000000000000000000000000000000000a9b89b1676b31989664a34260314d", + "0x000000000000000000000000000000a2d8941fda778834590a006f995557ff4c", + "0x00000000000000000000000000000000002dadd9e8063bfbee06194004949394", + "0x0000000000000000000000000000002036fe67ff22643d06461e1c8edcbc2dc9", + "0x000000000000000000000000000000000021c85b69f65f83d6cf1854a9563213", + "0x000000000000000000000000000000b19756d6156d0300b3ecb9be77605be1a8", + "0x0000000000000000000000000000000000014a4064a3b551e9b75fa13659629b", + "0x0000000000000000000000000000003491c66acf5693a16ec1f7241609c18f45", + "0x000000000000000000000000000000000023b0ed5030538c865d72cb8908352a", + "0x000000000000000000000000000000efedf593c1cfc28146ff68d9dcb1070ca7", + "0x00000000000000000000000000000000002a8174a5153b946abe57e2ed06d454", + "0x0000000000000000000000000000009c3212d084550b683558797af1477ceb8f", + "0x00000000000000000000000000000000002c32c65b02e59d9aae5b8a57ec27e4", + "0x0000000000000000000000000000007b88e113308893f906561837b9edc3baa5", + "0x00000000000000000000000000000000001a45b642b5e649f033eca82a810b8b", + "0x00000000000000000000000000000068591e612a0127878f63e7923f17854d2a", + "0x00000000000000000000000000000000001d50690ef0dd775e7f4fc0f17281bf", + "0x000000000000000000000000000000eece658386d09783fcc2d61a622eb6b121", + "0x00000000000000000000000000000000001d5b3af11c73d93414e18accc31071", + "0x0000000000000000000000000000007b1ee7fea7dfabee7dad1a5e3e816c2a2e", + "0x00000000000000000000000000000000000a5f02160bfa014a46b329f3618dc8", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043bda12a99877a984942e29d821cd37870", + "0x000000000000000000000000000000000020b1906b429f07ca51070221399472", + "0x000000000000000000000000000000c185af02499653794e9d4c7fa1a6c5751c", + "0x00000000000000000000000000000000002927f8b050e657021afb2f572e0f84", + "0x000000000000000000000000000000ceda688bdd2aea1e5253ea0d86743abebd", + "0x00000000000000000000000000000000000072f93e3607e4ac8c369fb92fe33a", + "0x000000000000000000000000000000eaff91f9cc05f03c6d8546358d580ef17a", + "0x0000000000000000000000000000000000225d5df5771e53084f6e364ad8e3da", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000002218617f23e467fecd2e3c938179a2b578", + "0x00000000000000000000000000000000002497b7dd7eec4e260f8ca521f1109e", + "0x000000000000000000000000000000914e208f9621734ce56985cdd29d01a78b", + "0x00000000000000000000000000000000001092e497a21b124b279b86e029a993", + "0x0000000000000000000000000000002ef4ddf310bee1f74f655cbb0ceb9315d0", + "0x0000000000000000000000000000000000270b81bec5e6b0f455065b02f68a0f", + "0x000000000000000000000000000000ef21188ec62b59040e4f1b89dfa23be48e", + "0x000000000000000000000000000000000009ced6e0108e8e67b299d9e3bad9a9", + "0x000000000000000000000000000000f61d5b8425740d0df669b875491e615449", + "0x0000000000000000000000000000000000064a6a9bbcefc6ad4b2d4e1e03985f", + "0x000000000000000000000000000000d004ad7846785bcb0db2672f6e5292f7c2", + "0x00000000000000000000000000000000002114c1fc4a3c39cbc96baf3ba693af", + "0x0000000000000000000000000000005cc5465cd9391ce8e7799e91bf9aac8039", + "0x00000000000000000000000000000000001c59b40d18b5d06d88617f2ed5c568", + "0x0000000000000000000000000000008134581657d125ca542477d684313ad999", + "0x0000000000000000000000000000000000259435f2950ead4bad62f0635944d8", + "0x0000000000000000000000000000008e3beb4333afb6a1db12c0889130b8f7f7", + "0x00000000000000000000000000000000002d022d695e566dd0ddfd15b59ad6f6", + "0x00000000000000000000000000000019ac6e38521a0144c3d1abe706030d643e", + "0x00000000000000000000000000000000000961e2643f9317a4d6144abb77cae4", + "0x000000000000000000000000000000827e5482f658cec2661f8cf88c4558800d", + "0x00000000000000000000000000000000002bcc1992b1410cdd05f32c2148a800", + "0x000000000000000000000000000000049c1604c9e61fe1eb1a4e6c0044a88607", + "0x00000000000000000000000000000000001a50aafae1419fae00770a64d75a52", + "0x0000000000000000000000000000003a404091304c1a4935267fb66a90af706f", + "0x0000000000000000000000000000000000175f69e34efe02635c0450ff14d814", + "0x00000000000000000000000000000056a7488e33d23f5a7e31e8c24c4d32feb9", + "0x0000000000000000000000000000000000152b125831f20c0046084a92a3a01d", + "0x0000000000000000000000000000001bd75185387ebcf04a2d1541b418c93962", + "0x000000000000000000000000000000000007d44e382095a4ddb6c84d676f975b", + "0x000000000000000000000000000000e37e00ccdd16f0cfb118365311a964e475", + "0x00000000000000000000000000000000001c3ba17a670cdeca7019e1d2c17e93", + "0x000000000000000000000000000000ef2f893fc357863e53675b8dfdace77275", + "0x000000000000000000000000000000000013a4df076b371985ff93656b8e4483", + "0x0000000000000000000000000000007adddc444f0c602af7efaa9c977e9ab80f", + "0x0000000000000000000000000000000000138e76ae51938924778a06f02de461", + "0x000000000000000000000000000000f63ec082d951768fe05e6d3bc9d50bc72d", + "0x00000000000000000000000000000000002ac3a11527579ccbe6c1966976f6ad", + "0x00000000000000000000000000000066d0ea63d8dd4511ec55e666f7bf6d6c3d", + "0x00000000000000000000000000000000001fe7a9cb68d795240eaec0b6efe451", + "0x0000000000000000000000000000005309c6e2db27d4be273a758a178e1af682", + "0x00000000000000000000000000000000000962316a08cadc097d50603d1606c4", + "0x000000000000000000000000000000ab5c17e93d31a1c79c62d8597447920f36", + "0x000000000000000000000000000000000019ede1992f131cdd105f8afcde56a5", + "0x000000000000000000000000000000b03aa7f0563671be6a98678d8dac3ed963", + "0x00000000000000000000000000000000002c9acda51c7b3e6e04e82aaf0bbe35", + "0x000000000000000000000000000000b7eceb60b962a8108199e7506d967bf042", + "0x00000000000000000000000000000000000ab8ec69e3b26d13207351e2be7d7d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000019988ebb1316d375d71e97a8545a3c71a1", - "0x0000000000000000000000000000000000223ffc44e0e98747d5be232098b76c", - "0x00000000000000000000000000000039f06fcc03eb0ffcc95a6e4ffb19181791", - "0x00000000000000000000000000000000000d49dfcd43c5d2f7fd6edd6a818e5c" + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x000000000000000000000000000000ab626198b0ffe754ee7a00134867d6524b", + "0x0000000000000000000000000000000000016d89d36083b0f55dba4523be0aff", + "0x00000000000000000000000000000081d7c7a641b523d79569cb352fd7652081", + "0x000000000000000000000000000000000023fdf5ec3df2b078ebe39feac15b55" ] - hash = "0x05ce98498d8e3590661695e0243b58df2e19f9b0e7229b9ef88ee6fb20c40442" + hash = "0x1cd81d6249bfece0299cdfaff8344081684997c787276db4fb5cdb25a0d6822d" [[inputs.previous_rollups]] proof = [ @@ -1202,7 +1202,7 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x026f28b344918f22933d91a736c98c3d8f45258367baa5703621c045f634f02b" + block_headers_hash = "0x1953e1bdf126cbbbf44f73a3952cfe3ac37b665859467480ae6846d2539b6f7b" in_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" out_hash = "0x00abb50b8989a7f19fd4526d43e15a1ab5d2a43af413cc8ca91e82a3c8828625" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1211,8 +1211,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -1227,11 +1227,11 @@ proof = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x0edef98680cbea2855c4f0f152a0ecd69358e68b10da7b7e301f35ce709c13fa" + root = "0x27b365d73aa1b8ac1eb39c75262e2b87a238d041cc98fcb795f4c597c620ce64" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x0d5581ddb590b1f2e972ae3399ac1639129b04a4b4282a219285a5dba6553cdf" + root = "0x10abfc1e58ab5ed471d9c7fedcf2b291ad533ac85d136968ea047db10d73d599" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -1276,10 +1276,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" ] state = [ - "0x08cdf544ec44d694936ed6a5aa580afb2a3b1a4b087ba80870d4d01c79cb5772", - "0x192972b72a1776fa9d30c1202807fca4f9272b156c9e1eafa5f93e94a13c439b", - "0x23ace986d5ee172559ce2153d8a166075599a4403288cbe1a150bda49415fae6", - "0x0f3ccb179877769f2d268206c1b45ab9af36d5e7e005de27ede90c1a29450039" + "0x13ec9d9b37f0599c5765a81513125e07305454198fecae73a69e7d41dfb27215", + "0x24fe963f8f4139d84f904228cfe1e10256e9106331e614b72ed86be8903e4259", + "0x114cba9fee3fa49ffd5f440aa162c6ce6e8410138a592e587337646bb8b04ca7", + "0x10325219e420881603ba4ea16613cf66fa1c43ff98bceb97acaaab599e3326b5" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -1294,10 +1294,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" ] state = [ - "0x186114d0d063d6e6ddee6515e508484b364b20eeca9ca340f8566e398b71b198", - "0x114fbdb8bc7b843c83778ba1c8780534af4f59451f33adcb6a437c245d4bed64", - "0x2808ea7e05edca8293485bb1dfde34257ab644659366d516601dd5beba26639c", - "0x0ba75ded1f1125dbe2d4e7a5b18a7b2e2c238a70c72ed529163eb34be09a36d2" + "0x06b7a09d376432aa2b0a7411a06aaad2d07f77fe65a5401eea06ab9d30b77ceb", + "0x06b7ab96aca0b2e842d7692f25a662728d09309529ca41b0e61eb20e19a7f38a", + "0x0b211453e69b20a81d2247120eae55ca5f80139276d8d9a7bb790996624e335d", + "0x1af797fb95b1713b94475070546774ffc67e4d61c261abb49048a7834cc7e665" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1305,131 +1305,131 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000e" sibling_path = [ - "0x0d000c0ce80da2c814b0f1508b74728e2eb05f4fdfb0396e1e6939106be41f29", - "0x02e6f22eee7e3e5aa6291ccac5ee76b8a2f1e338a74bf57530740f36d19c9b2b", - "0x14c22836312c6ac50d8aae1289b45c06410355406e5af5ecf43bf59432dcdd17", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x2781192850bee4946aa72958703bc69fec3ab04ecffc00c34abcb81befd3c88f", + "0x2a4b8973bfb7d252bd970f41d74702d12b8bc7f63b15188bc79d78bda4a9413d", + "0x07a849e820943807a1c5531526528e89be50a06725dee96179285d8108e565c9", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000002fb0b1381b4486fbd49fa9fdb4d74afed8", - "0x00000000000000000000000000000000001b03700ad9942abf5144e1bd7393d2", - "0x0000000000000000000000000000007f3e184921857992c24753b966424214c6", - "0x0000000000000000000000000000000000283119b961cda64e529c68e135fa17", - "0x000000000000000000000000000000c251b282c34c8a6d712e6c12903362497c", - "0x00000000000000000000000000000000002c89e5571ae0b09fa870346cbd5cee", - "0x0000000000000000000000000000008eb0fcf7af2d945fd3266cd7b0b449e8d3", - "0x000000000000000000000000000000000021d78ef089716338837787911d13b0", - "0x0000000000000000000000000000007f691d58aee9d65248c5eecbbaddc13a98", - "0x0000000000000000000000000000000000098627646fa61b9928d6dc11c96e13", - "0x0000000000000000000000000000002c58cf39b7f2b04d82c4338ef8958a7473", - "0x00000000000000000000000000000000001aef806cf0aba5af2f1f8978cd56d8", - "0x00000000000000000000000000000082bb268c0e10a8bf5c0ef242f9906e4892", - "0x00000000000000000000000000000000000c90d93936cc598061c4d29f0b25a4", - "0x0000000000000000000000000000004d114fbbc4055f5761b7f8840f0da32908", - "0x00000000000000000000000000000000002957bebd162ed2169df723dde18c97", - "0x000000000000000000000000000000e9eea3e81c31b1aa9400fa13197b7393fb", - "0x0000000000000000000000000000000000218c3140bfb6edddbcb2d4cbc126bb", - "0x000000000000000000000000000000c0ff9e22fab79999e9ed7d78e138d2987d", - "0x000000000000000000000000000000000028bcfd13128cabc46955265a1e05dd", - "0x00000000000000000000000000000023a74d6f1a3fabe39ff7f0f6150be9ec00", - "0x00000000000000000000000000000000002e2507d7bf2a01aec6fd026fa0a409", - "0x0000000000000000000000000000000a0acda35b6f3d1a438d5fcf5783a50797", - "0x000000000000000000000000000000000021e1c9a570c3d0417707daa478fa20", - "0x000000000000000000000000000000c10049e49d4cd16c33bbc1e8eb3238ea26", - "0x00000000000000000000000000000000002578443465dd684c74b9c635f2c33e", - "0x000000000000000000000000000000770092209b5122c863dacecd7406bb2d48", - "0x00000000000000000000000000000000000f3fee6266059403a65308d4c5d7eb", - "0x00000000000000000000000000000093ed6cb8d6a2d5363b2c995ec9f930a714", - "0x0000000000000000000000000000000000276fea1e0f63f52d1e7564b9a81494", - "0x0000000000000000000000000000000389f3a2b3a8f8cc2f5f5d1cd72a8d196d", - "0x000000000000000000000000000000000013bcbd1229609722bcecd1798d4a4b", - "0x000000000000000000000000000000fe9ce7b1fd6536624c2fa96787f74d7bb0", - "0x00000000000000000000000000000000000c3c6d07104e24ea5acc68c3423208", - "0x000000000000000000000000000000b8da6eb9140a2d5588a8710a2d6d6318a2", - "0x00000000000000000000000000000000001b1f1fa538a3b66f72c15c53cca715", - "0x0000000000000000000000000000004730a9529ef0eb509d55e1379829c016c4", - "0x00000000000000000000000000000000001ce37c2c228f312b7c1e64bcca1dfd", - "0x000000000000000000000000000000a378c68d165ba8929cf5e20f479ed90e1d", - "0x000000000000000000000000000000000023024fd5c636e9ead7d63e4eac96d9", - "0x00000000000000000000000000000082a25f4e5374c7548fa507be32b596f423", - "0x000000000000000000000000000000000018ca6faa15b5b52e1ae8b15cb8b83f", - "0x000000000000000000000000000000091c75d9a46e8a66235f387c882bb14df2", - "0x000000000000000000000000000000000018f3db0dcead736435b7467239e00b", - "0x000000000000000000000000000000b87fb21960e7763dfd42205c459fdc41fa", - "0x00000000000000000000000000000000000267a4a344f85d00b6b0040d1c2150", - "0x0000000000000000000000000000000bd1017af78a6260c7d0f6eccb3a8d3890", - "0x000000000000000000000000000000000002641016e4e2bf5752b1e9472dde95", - "0x0000000000000000000000000000004697a8a794f990510a018a5b2c50f35b76", - "0x00000000000000000000000000000000000de0ab75e8b485639fe023a368024c", - "0x000000000000000000000000000000be33c35449966234d9bdf48ba396a57c4f", - "0x00000000000000000000000000000000000df556c20deb7a8ab0ee850f970c51", - "0x0000000000000000000000000000007e5366f459b2b033ca3664ff8f4a641d18", - "0x0000000000000000000000000000000000192f68a938c5a9ea9a5cc9f2181675", - "0x0000000000000000000000000000003a6f876985d4d54592c5b5c16ab8b16750", - "0x00000000000000000000000000000000002da0d2ee45300969c52f5ae43c7402", - "0x000000000000000000000000000000c0f7aa427b2ea5fe4f0e45dcb2eec42f83", - "0x000000000000000000000000000000000009739dbd1003e81acae3f329654c42", - "0x0000000000000000000000000000009191ff080e493eb7d3eb33ec9823178f09", - "0x00000000000000000000000000000000002c951c03d7dadfa04fdc92a298ea8f", - "0x000000000000000000000000000000245cbb1c8e9f243b94d55edca314c340d7", - "0x00000000000000000000000000000000000de0f174fce3433422830fdb869c6e", - "0x0000000000000000000000000000005348fbfc2bff27c23db0f849baac752835", - "0x00000000000000000000000000000000000fa0fe8cbbf06318ad99adc23d2e0c", - "0x000000000000000000000000000000b37df3b0cfe3793620f5315db38c0dcd29", - "0x0000000000000000000000000000000000011ef80549887e786cea0d08c13608", - "0x000000000000000000000000000000e085aac6fe78f6a3574c61f888eb0ace80", - "0x000000000000000000000000000000000015ea74a6e14e77ffea0611ecc18015", - "0x000000000000000000000000000000635cc32ee452dd83211c337fd3423850ff", - "0x000000000000000000000000000000000030399e012ea636c746005ba35a4536", - "0x000000000000000000000000000000c6c09fdb5d8cbc0266b956e5539ad94b8f", - "0x00000000000000000000000000000000000728658d282bb922ecff1634645aff", - "0x0000000000000000000000000000008fc753267c4b4393209eabc80d1c4fcac8", - "0x00000000000000000000000000000000001add24bab07f36d9d6e11beabf5bb8", - "0x0000000000000000000000000000001a38a11d04a6dc1d788b1cc4da1d171341", - "0x000000000000000000000000000000000004eadc7d1bcf2320272a6d96972ae7", - "0x0000000000000000000000000000004749834da45ee7f8ffc427cf41f3b715e3", - "0x000000000000000000000000000000000005e4285178878dbecdfd0c6eba227a", - "0x000000000000000000000000000000182e1a0661bfd39a43bcbbb18e3691b327", - "0x0000000000000000000000000000000000262b3f8b46fac1d385cc0f3bc24ee0", - "0x000000000000000000000000000000434d5dbebbf6fbc03531f25d963f155b9a", - "0x0000000000000000000000000000000000082a0f4d55eb1206313a4955f41f03", - "0x000000000000000000000000000000034001bbce1dcce343e80ff7a821fc3444", - "0x000000000000000000000000000000000013176cdf2f7fb58e75a4954f0bfd28", - "0x000000000000000000000000000000acb6987d4aafb95942bc208f40df86f426", - "0x00000000000000000000000000000000000e52fac6880e3f51e7641ab893e82a", - "0x0000000000000000000000000000002377224018803fe8e8922c797432d2d985", - "0x00000000000000000000000000000000000b3d671707c2cdc4842e4e8ffefc09", - "0x00000000000000000000000000000095b5d8b7b4a63b05df652b0d10ef146d26", - "0x0000000000000000000000000000000000099e3bd5a0a00ab7fe18040105b9b3", - "0x0000000000000000000000000000002129af3a637f5a622a32440f860d1e2a7f", - "0x00000000000000000000000000000000000015b8d2515d76e2ccec99dcd19459", - "0x000000000000000000000000000000222b888108dc25d1aa450e0b4bc212c37e", - "0x00000000000000000000000000000000001b917517920bad3d8bc01c9595092a", - "0x000000000000000000000000000000482141c7ebe42000a1d58ccb74381f6d19", - "0x0000000000000000000000000000000000305e8992b148eedb22e6e992077a84", - "0x0000000000000000000000000000007c86847618681dc29d8a9363ab7c40e1c3", - "0x000000000000000000000000000000000016465a5ccbb550cd2c63bd58116fe4", - "0x000000000000000000000000000000439973ac12d7ca796d6fe98ca40e6ca6b7", - "0x00000000000000000000000000000000002e24d420fbf9508ed31de692db477b", - "0x00000000000000000000000000000028edd1a7e46c840d9c943fdf45521c64ce", - "0x0000000000000000000000000000000000043d063b130adfb37342af45d0155a", - "0x0000000000000000000000000000009330952ae74c573d1686d9cb4a00733854", - "0x0000000000000000000000000000000000261522c4089330646aff9673619494", - "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000161e5bb10fa2b7c7380009239b649b4734", + "0x00000000000000000000000000000000000badbf533a087faffe865010dc5b37", + "0x000000000000000000000000000000381bfa95df551e67c494b29f07bfc5149c", + "0x00000000000000000000000000000000001bf4738c48442b6d952222d821547f", + "0x000000000000000000000000000000cdf67a2562ab96b4917ea73217efafd3b3", + "0x00000000000000000000000000000000001b0666d4bc44552a2ffc0223345a23", + "0x00000000000000000000000000000052e280645ffe873ef1e2cce244d3b23265", + "0x000000000000000000000000000000000029365e95dc11f595f23b37d9c475db", + "0x000000000000000000000000000000e0546cf49094bcd8d9e4a0e2f0b0d21d73", + "0x00000000000000000000000000000000001dd314bca6a6ded1a4a64266a516ce", + "0x000000000000000000000000000000c529043942840056e63f2fcffad4221afd", + "0x000000000000000000000000000000000011c2731f6fe0cb9f3c7d88d710950d", + "0x0000000000000000000000000000000dccca0374b5478a2414205ee24ca83668", + "0x000000000000000000000000000000000007e95f7cd90c21519b280c7c007fcc", + "0x00000000000000000000000000000004de3a9f180f0a4f01dab186eba8530269", + "0x00000000000000000000000000000000001372faf74b763ba502d7cc0845a54c", + "0x0000000000000000000000000000008aa4681b00633c2a5a63702641a6d36041", + "0x00000000000000000000000000000000002dc7f4ccd6922fc4b6654e175f2a80", + "0x000000000000000000000000000000d0d4f6ecbd8ee863fa3160211931061e33", + "0x0000000000000000000000000000000000263cb61cd13a131bdb313fa1159c3c", + "0x000000000000000000000000000000739ca3af1ec76a87a037f25bca5447ee69", + "0x0000000000000000000000000000000000065132cc73a764a9958eaf16937aac", + "0x0000000000000000000000000000004f397550e79074d0c4d3108fe675be5a4e", + "0x000000000000000000000000000000000012a58f58ab7bd421ca8f0fdf7990ed", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000dbe8bffec86d9a9c4e194450aafe44569a", + "0x00000000000000000000000000000000001ad711549791cb4bfb26753da71976", + "0x000000000000000000000000000000eef413cdd499365c5aff81234c29a8e9c8", + "0x00000000000000000000000000000000001c1a2f7052492deb0bf3831f1d659f", + "0x000000000000000000000000000000a430987c325c792662db95707eeb73bcda", + "0x00000000000000000000000000000000001fc6620d5b4b91a2bb7e967e4ca0a0", + "0x000000000000000000000000000000d3010833f9a0a6df8b842d2e94c7443271", + "0x00000000000000000000000000000000002b34c8b03764d6438d76005e33f136", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000090eb905a6ce8fdcfb3ad69b20f37b471a0", + "0x000000000000000000000000000000000015411f1068f3c41c0f03f763abc15a", + "0x000000000000000000000000000000afca164bedcee548eecb0590ec5abf1127", + "0x0000000000000000000000000000000000145ea9d00e643079977aa78cd2c109", + "0x000000000000000000000000000000854f1c53b1fafeaae64bc08161c77048b7", + "0x00000000000000000000000000000000001e235518c5c034960eec5fc45a716e", + "0x00000000000000000000000000000035145365e610d44ef42fa8ea613a9df4aa", + "0x00000000000000000000000000000000000f949d81fe0404cba9da3dbe012bd7", + "0x000000000000000000000000000000c5f55c78208dcda151683ee8cf95e8bc47", + "0x000000000000000000000000000000000012b17b8f64a8606a7817da004b71c1", + "0x0000000000000000000000000000007359e5ac4a48e1c4cf0e5665c6c059d99b", + "0x00000000000000000000000000000000001d7a0474a2bb254bf932f10146b961", + "0x00000000000000000000000000000024e0b7c596516bb0b5a2e8d6cb248b56a2", + "0x000000000000000000000000000000000012e9c9b3e8143abd574124134a05c8", + "0x000000000000000000000000000000dbc92535cff5ca03ba09ca111642d39fda", + "0x00000000000000000000000000000000002043571f43cad61de3a5e4328a4aee", + "0x00000000000000000000000000000079d599186f46e769fcc207b0cd6cbdc01e", + "0x00000000000000000000000000000000000c5c2f9466df09ea80f0ec14870034", + "0x0000000000000000000000000000005f94f587b12643ff51063a28353833f770", + "0x00000000000000000000000000000000000cf56aa28ed4b4beb7ff157d7da3ef", + "0x000000000000000000000000000000de4b43f87ff9317c8e9d9c4588fc2eef2d", + "0x000000000000000000000000000000000012d0aa842859d2ee838f5510f9bc22", + "0x0000000000000000000000000000006f2fdb4213da0129f8365bc86a01f6164d", + "0x00000000000000000000000000000000000bdc73bc5280a4afc7e65947531e51", + "0x000000000000000000000000000000f14874ba0df22c460d8352ca030bd9a861", + "0x00000000000000000000000000000000000885382903e5ffbd837b5e0e4bbf06", + "0x00000000000000000000000000000066e80b7e34ebe3899a4d07dea4f62cc7df", + "0x000000000000000000000000000000000013f829d0878ad53de418679f370067", + "0x0000000000000000000000000000002980ae9f85fad098e5a76ca9e6bdac5779", + "0x00000000000000000000000000000000001a774ae589e96cfbefb418dddcdaa2", + "0x000000000000000000000000000000327c44b0ed90d01976c32c94f04ef2cea8", + "0x0000000000000000000000000000000000225d757cb4f2bfbf6d13b8114d7b16", + "0x000000000000000000000000000000bdc629840f4a9d071f9fb1384008254135", + "0x000000000000000000000000000000000004e75cee70f3e11a2402faef92a73b", + "0x000000000000000000000000000000f40c508a906897027558980610fc4df4f2", + "0x00000000000000000000000000000000001f959d41e40d111d021ab23b4ef843", + "0x000000000000000000000000000000587fcafd86184e71ec3d650b3ba85f03fa", + "0x00000000000000000000000000000000000610c97af06081281e7404f44aee4b", + "0x0000000000000000000000000000007b029cc296434696323f9c37b5e4c9cf55", + "0x00000000000000000000000000000000000614733fbf8d375012614cce5e4aa0", + "0x000000000000000000000000000000bc102f5fba012ade36bbf671474a9afae2", + "0x00000000000000000000000000000000000d2b78d31298fc946624e482d61850", + "0x000000000000000000000000000000c1c26c3fbdd4fb7de13c6af78b90063442", + "0x00000000000000000000000000000000002da9dd34c453f3d5a99691ba052769", + "0x000000000000000000000000000000a788520d601038b7bcb1ef241547ddc5e1", + "0x00000000000000000000000000000000002a280445997573df993f3eaa9cc9bd", + "0x000000000000000000000000000000ec4d9274437dc457e7da9ee9f5d57b0825", + "0x000000000000000000000000000000000029454eff7f180c04c3dccd1d762531", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000005d656b6df65180c7833e41dc3231ba543d", - "0x000000000000000000000000000000000011345e9011207695e22c16713acdb8", - "0x0000000000000000000000000000007d63cb71b503d4b9abe5d31e76ac70ff93", - "0x000000000000000000000000000000000026b61287fe7afce1e989dc0d30a961" + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000007cf4b5713ad71efb2e02fe45bb7fc9507f", + "0x000000000000000000000000000000000026cf1fe248bb52d3e86b9f64b3c2d3", + "0x0000000000000000000000000000000e590349a07b67f041c3c615e4f436aeab", + "0x000000000000000000000000000000000015a097ca4d6bfa82e4dd755b3ebb59" ] - hash = "0x15602bffd51fabacf870d678a216f360ee85085e4b283f99086a716d2be141c1" + hash = "0x0b292d3b888b2793be2b844d85cf1ee4c10e4646758de66819a7d9483c294c05" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml index b55f7bf5c86f..c82902e1d32e 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml @@ -478,140 +478,140 @@ new_archive_sibling_path = [ [inputs.parity_root.public_inputs] sha_root = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" converted_root = "0x2f7247450c6d856804ef9fade0d5af92e4b87b1576f07ec88359012bf4c21abf" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.parity_root.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" sibling_path = [ - "0x259832d81ade32c589e6ab56f6c2bc4acf0b711b10e539b4ee38d8bacefbdcc3", - "0x00a28019e6ca588777548cd5e154dbf4f567f886cc8a01a812b4d3122f308cb7", - "0x03762ae9136a49df4624f45517c27d99c8b81a305e36011a211dda34608a3daa", - "0x2740690820f0df46bcbf149ccb51f228fb81a46173ad1793687319f77d32d49f", - "0x026fbe21cffb22c458f7e07b206bdaf767d39af34024eefe88e3d8b56eb9f695", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x26cc9e64527e3b22ec4559bc77cf5a17da79641f2be800e6ecdcd1956333e85f", + "0x2ba2de2d2cb820a66a273f2ba930d43a4469119ad58fe01eaed0e0d615ffb426", + "0x18f1abfe1a07005f35a20c06b468f7a4d3b68ecc2c025c88271b6550a827d41b", + "0x2370b2e567b79fe42809d72237ad8694479d864b90033ecbded55e041404191e", + "0x2c420960f09a97665929b2c1b4c167142f9e188be47609019306d64a45249c19", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.parity_root.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000016", - "0x000000000000000000000000000000000000000000000000000000000000000b", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x00000000000000000000000000000078b17daee7ce0a5fb9f5a84a2842c3b468", - "0x00000000000000000000000000000000001e4a85b98d71b0d69292687e2c5e94", - "0x00000000000000000000000000000000c3c7c53f8d6f387d02cbd30b373f624a", - "0x0000000000000000000000000000000000027492d891507b7fb721f827ec2125", - "0x000000000000000000000000000000448da0795e65c2acddb6a180b618ca4500", - "0x000000000000000000000000000000000026376b31e8ce3bb070bfed46801c3c", - "0x000000000000000000000000000000a8b4423143eb061d06dcf70a9b88d96cc0", - "0x0000000000000000000000000000000000140986c98f877b30ce48cb90461312", - "0x000000000000000000000000000000dc3228da5397acec91842e0564247a3281", - "0x00000000000000000000000000000000002c26f116c4120584e7c05868b9e034", - "0x000000000000000000000000000000f5ebf083289c311ee2d289dc034b0031b5", - "0x000000000000000000000000000000000027e5ca168fcf7984917277bd63aeb3", - "0x000000000000000000000000000000087667ff676cfafa2db57dd50364cfe79c", - "0x00000000000000000000000000000000002bb973ea83e8487c41459600a6ef16", - "0x00000000000000000000000000000000a38ca13acac1410f3d7ca6db34fa63f0", - "0x00000000000000000000000000000000002068ffd126a125d99af872b91155ff", - "0x000000000000000000000000000000fdc1eeb335429c34b4488e1ce565edd0be", - "0x00000000000000000000000000000000001279bb6460b4bdefc838d4cb235155", - "0x0000000000000000000000000000005ef93e2a85a22e47a3b3eabb4e229dfb95", - "0x000000000000000000000000000000000002085147ee68b313f39acde522a5b1", - "0x0000000000000000000000000000003601a6e8eaee36ae589e4f3efd39aacdd0", - "0x000000000000000000000000000000000015b26c9be4890cbf333c9d18e023f8", - "0x0000000000000000000000000000002597739e1725777058acf8c41ece5bc230", - "0x0000000000000000000000000000000000127f2d8950de2d351261de15ad3692", - "0x000000000000000000000000000000f0707fa498b915bb84481f22c68f82f852", - "0x0000000000000000000000000000000000026e1e4979e0d760c48aba45674641", - "0x000000000000000000000000000000ea45d31bd10dd18ccc02388e6f8b291dcc", - "0x000000000000000000000000000000000023e937480766000ba36ae295ec1e48", - "0x00000000000000000000000000000031baaf67d48e00f988f210e567ddd2b45d", - "0x00000000000000000000000000000000002715a3d431eafcba537d10c3033057", - "0x000000000000000000000000000000bbb3120089d0de7b11c4a1f29199f88181", - "0x00000000000000000000000000000000000367ef60efb55665d6d840fa949717", - "0x000000000000000000000000000000ed04c2879b84b210376953f58ce48eba0e", - "0x00000000000000000000000000000000000b092c857d4a2e5520dfaafb203c03", - "0x0000000000000000000000000000005da6cf732c008d8d037ca34a818312a024", - "0x000000000000000000000000000000000029f868f7234099b8361cb3510e7d8a", - "0x000000000000000000000000000000a0843902e624f3adccde6cf44e08311d4b", - "0x00000000000000000000000000000000000373ffc7fce598489f487b9c8c0ebd", - "0x000000000000000000000000000000a7314c6ed61312feaff048ba4b49842b7e", - "0x000000000000000000000000000000000028ef66d9ba57db55d9037eee6292af", - "0x000000000000000000000000000000d6a3a1c9a17835658d11e6a5d0fe9cf907", - "0x00000000000000000000000000000000001716bd0d35f792b5b5d1b3d57bceeb", - "0x0000000000000000000000000000008997c4ec5fabfd7e709a9e39a9ade4f7bf", - "0x00000000000000000000000000000000000f0a6f177b950ddd7b7eb33d04db21", - "0x00000000000000000000000000000039501b07dae9c6fb88b4c42448be3cb384", - "0x00000000000000000000000000000000001eaf14768ccbf9c57b217dec1e31d8", - "0x000000000000000000000000000000dc531c7d21f7b45ffbca2717ec44b041e8", - "0x0000000000000000000000000000000000279bdd1d3a8e15802c608c6b4708e1", - "0x000000000000000000000000000000b37783542b31dce0d8c31c0852e1d763c3", - "0x00000000000000000000000000000000002f467244c882fabc33838b10b7eb2a", - "0x000000000000000000000000000000ca408d8763a614b172e9b946a7dbb2e74b", - "0x0000000000000000000000000000000000262b64694fd389afba33f2989accea", - "0x000000000000000000000000000000b61193261fec588db146c2170e4d2b0a0e", - "0x00000000000000000000000000000000002f32c65a1fe400d17787690e55d2c8", - "0x00000000000000000000000000000007fbc70d900496b6366e965b79a2113b36", - "0x00000000000000000000000000000000002be977d4f13c3e45b8aa682458f534", - "0x00000000000000000000000000000019ec1befb0c5f1cddfebc885efc6265f95", - "0x000000000000000000000000000000000005d3ab687eed8f108bc3a75ec3b8e1", - "0x00000000000000000000000000000051bb7f4b08721f57f545ebc0e07d3eebf6", - "0x00000000000000000000000000000000000d9503879b9bd744448b6eb9fb2f7a", - "0x0000000000000000000000000000005a02ba394e9d2d3e77bcccd895c10694fc", - "0x000000000000000000000000000000000027e25fdc49dc55b63ef3d1ca90b5b2", - "0x00000000000000000000000000000091db8035e2aaa8610742df1503300087f9", - "0x0000000000000000000000000000000000021dc3eaf7990b12e4468c2e28bab0", - "0x000000000000000000000000000000e846d69b700fdd8b078052da8b91c352d7", - "0x00000000000000000000000000000000000c951fe8e7eb4a6298b14be6382f93", - "0x000000000000000000000000000000ec89072912c27066e932cf77f821994c90", - "0x0000000000000000000000000000000000182e68039cceed32fdac710403b7da", - "0x0000000000000000000000000000008debe6230106974006084e7308b4b5feca", - "0x00000000000000000000000000000000001ebd658ddc30d75e5e721359395120", - "0x0000000000000000000000000000006d3b5839b70a5b60de45166b9c2a4be3f5", - "0x00000000000000000000000000000000002ecf96badf1253c40c1486fabbfcad", - "0x00000000000000000000000000000098213252fb5d3b6c5a9747469ebcf0dcd9", - "0x00000000000000000000000000000000002d869db2f87c96d3e31e66aa911dda", - "0x000000000000000000000000000000555c7af1975654730348730a11775c9759", - "0x00000000000000000000000000000000002b8d102334de6b8cbc22090f9dda68", - "0x000000000000000000000000000000d34433dab85ff5064014d6b58f60d67c25", - "0x0000000000000000000000000000000000139da62905bcf796f7101bbc76122c", - "0x0000000000000000000000000000003840706e6d07460c44d74cba5c2b34358d", - "0x00000000000000000000000000000000000aa2f8b6291279bea275b7c9913258", - "0x000000000000000000000000000000019eaa3b842224650e76c5cb0e94484c6d", - "0x000000000000000000000000000000000006c9f637fbb6502a38f91b85ace5f5", - "0x000000000000000000000000000000efc01f95fe550a9a9f1476758824a74301", - "0x000000000000000000000000000000000003eaa2fbce3122916d12c78b219b9b", - "0x000000000000000000000000000000a6eda6357e83ebf12fcf13845427e4a057", - "0x0000000000000000000000000000000000255208b91373b2dede462b7e8b0b52", - "0x0000000000000000000000000000006d2aecad4cd09ada8fea8abb2ebbf070f5", - "0x000000000000000000000000000000000012bfb11d7a805c6e591f874ae3637a", - "0x000000000000000000000000000000f4a6c6ffdf80a72db78762e237d58cd5f6", - "0x000000000000000000000000000000000026814a59803555635a3b6dfd056d19", - "0x000000000000000000000000000000f45b8d96069231f48e0d0c34d57593a6a6", - "0x00000000000000000000000000000000000b9dc32399025796005b2f68c15991", - "0x000000000000000000000000000000750e1b5cb997a3adf8540bf55bb9264ec4", - "0x00000000000000000000000000000000001f6cd5b6d43f67798ae4655c016f37", - "0x000000000000000000000000000000596cc6183848f32c60ec74fe2bcd76b20f", - "0x00000000000000000000000000000000000ed62d10b019355f008b46412d0e2d", - "0x0000000000000000000000000000002020dfdab8c9db8335bca3c8284b1585b2", - "0x000000000000000000000000000000000023a2906d03204aa4f79b5b80b92eaa", - "0x0000000000000000000000000000009116c4d15f7c9a51f17c3830fe7c1e3b42", - "0x000000000000000000000000000000000024aecae332db48e03b97fc645a7f05", - "0x000000000000000000000000000000834c5e938cf9e8bd4bd5847e2408407276", - "0x000000000000000000000000000000000008524b40cf87b668119022f691cfac", - "0x000000000000000000000000000000e699df860731437ec57f9890fe4b3a4205", - "0x00000000000000000000000000000000000e1e9d4327e635f547da67aef57e86", - "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x000000000000000000000000000000000000000000000000000000000000000c", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x0000000000000000000000000000004f85c893bf8b1e843f2dffc48dc074f196", + "0x0000000000000000000000000000000000215339c99786f23abf06aa628e2bb5", + "0x00000000000000000000000000000021f56f1fd166b444f6945fef45a4260c98", + "0x000000000000000000000000000000000029832f088b0a8c0ed5fb1876da60ee", + "0x000000000000000000000000000000683bd852b0d5317d3104e00d57a7ff12fe", + "0x00000000000000000000000000000000000d2eb234e163af0321005edbadf074", + "0x00000000000000000000000000000043d1d78f4556dca95ed3ae27b1bb967956", + "0x00000000000000000000000000000000002406ce5529e27d341a34d8c9a819d2", + "0x000000000000000000000000000000d2bb936edd0bcb9cf33e24855aa3095d1e", + "0x000000000000000000000000000000000016629d2674b560633c3db0a21598ea", + "0x00000000000000000000000000000092c8bd15ab345a54468aba584a6f16e2b5", + "0x00000000000000000000000000000000001fbbe74a5bb8bad495a22f4a0384dd", + "0x000000000000000000000000000000d7dbc1eca647580a4a952821d02d282259", + "0x00000000000000000000000000000000002d68b4713f14d3be50ddb099e2b736", + "0x000000000000000000000000000000d4dfc475729d110ffc01eac27a1bb07187", + "0x000000000000000000000000000000000015026e1e1768366175d180725092cd", + "0x000000000000000000000000000000d799d0753526bf23193f9ab8f73c1c7307", + "0x0000000000000000000000000000000000052dcf1d1d89071ecfbfe34de96dff", + "0x0000000000000000000000000000008a7f1c8955fef499a04d57fa057c30e66a", + "0x00000000000000000000000000000000001fedcb5a5fb32238adaca91e2be32f", + "0x00000000000000000000000000000047c5bb126a6e6c788dec340b858f577f7d", + "0x000000000000000000000000000000000013e3b742ca471a245262fb2ecee07a", + "0x000000000000000000000000000000b6284febc7d58cc5491fee7334064865ef", + "0x00000000000000000000000000000000000038ae53da7215a286ebd0649136a1", + "0x0000000000000000000000000000006eed465622852dce8a0702c5327cff0583", + "0x000000000000000000000000000000000022b0941f412859d1cc37a757ca4375", + "0x0000000000000000000000000000008bef872c634b8c03bfe7ff37c00a727192", + "0x000000000000000000000000000000000004906c8767a040a562b166a360c43b", + "0x0000000000000000000000000000001770bcd5e95d6ed8c6299af5208e594351", + "0x00000000000000000000000000000000001170f991d5a8c2cece25a2eec45ac2", + "0x000000000000000000000000000000dd2567c65087f4413c4a68442f7838d361", + "0x00000000000000000000000000000000002b2e2b9fa7017ed5b534b950976cfb", + "0x00000000000000000000000000000060445810cd95870d181367a860937116e0", + "0x00000000000000000000000000000000000171fcd0debd9f9966aa439dafa69c", + "0x00000000000000000000000000000036d276aef0f30fea87630c34381ff63a36", + "0x000000000000000000000000000000000029a01a7f04aa1c5fc36c458ab5f806", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000e402279945a076c945901fca356628c525", - "0x000000000000000000000000000000000012fedcb7313f77c3006a35e9fb9f8d", - "0x00000000000000000000000000000084a3a7ab7d80d65ae1cf14ed89c99c143a", - "0x00000000000000000000000000000000002ece2d07ef9c9b1afa02b75b16e861" + "0x000000000000000000000000000000441c338c655b7e22f91724c986ec2a7d0a", + "0x00000000000000000000000000000000000988f7c276931907f533dfa99ae0ad", + "0x000000000000000000000000000000555d1bf8e49259a2b77c8e0caae5b13feb", + "0x00000000000000000000000000000000000716aa5a6148a8455d44f8759f22f5", + "0x0000000000000000000000000000006400f037f61c707f2729c70c5d912ce9d3", + "0x0000000000000000000000000000000000116682196031717f5d1cc4d903aafe", + "0x0000000000000000000000000000006459e7ac42c142260295108e744e33a0c1", + "0x000000000000000000000000000000000009228de1a4fbd3de4d757390f162da", + "0x00000000000000000000000000000067656846b7e2309e7c18c1cce38675bb00", + "0x000000000000000000000000000000000029e7406191ce46a9babc6ac5ff12cf", + "0x00000000000000000000000000000032e79eca379410f7ec358f9da21bac9fa9", + "0x00000000000000000000000000000000002c817548c195702d46fafe6ccd4faf", + "0x0000000000000000000000000000004fbb48b68f274f27d30cdcb82ee7cac9b2", + "0x0000000000000000000000000000000000068f9a71089873a24f8351d1e70d97", + "0x000000000000000000000000000000795c4af1416754d9625f084be947a93c64", + "0x000000000000000000000000000000000024e4ffd72d451203c5bc7d04a27116", + "0x0000000000000000000000000000008ca18e089457f9cceb58c823a944b03f26", + "0x00000000000000000000000000000000000422b4f22af36e628698a6865ddecd", + "0x000000000000000000000000000000fb52c4f612125db4012ed8a2e84e1d2c6c", + "0x000000000000000000000000000000000019dc534f8dd81d19f72590c6e1fb8e", + "0x000000000000000000000000000000fa01f84fdc11a5d03b14bee3a99a680c37", + "0x000000000000000000000000000000000022dad727328995272891d530216d61", + "0x000000000000000000000000000000b5f4bf23591d8b2447d60d61737c2c36bf", + "0x000000000000000000000000000000000002e2a075eaa9f4dd89c257af6cbab0", + "0x0000000000000000000000000000003561668a93cb72e95a340771ddc66e9c1a", + "0x00000000000000000000000000000000000026940a62997474ab260b2841eafb", + "0x00000000000000000000000000000075c66b2eeb9c27b8611335bafd53ed5e6b", + "0x000000000000000000000000000000000020720351df147e866486a5db6e8bf9", + "0x000000000000000000000000000000fa65c2574867f702f76ee91bf9721891f4", + "0x00000000000000000000000000000000000550d2b73072fe8ebb458db32bc272", + "0x0000000000000000000000000000005e45bf32b04d43d7d9e082552a7c6e3aab", + "0x0000000000000000000000000000000000156b9320b1c02a5ae4d5245079ef93", + "0x0000000000000000000000000000007dd31f38bd2d2529ea3d3537bddc4c2d8d", + "0x00000000000000000000000000000000001460b51e2428e23b3d5f0e0623a2a5", + "0x0000000000000000000000000000009973429339ccb353bf51ed2d258ab0c734", + "0x00000000000000000000000000000000002675f20f2783781dae8b8ceee4b947", + "0x000000000000000000000000000000f19f97ae0fa6b47d95ce8c99deff02825f", + "0x000000000000000000000000000000000008ac106283f7faa2a9523d6d3b6a65", + "0x000000000000000000000000000000ece35a6af0338418a01080dc9e20d76e8c", + "0x0000000000000000000000000000000000223186953dd9de4ffdf175c62fe17b", + "0x0000000000000000000000000000002cdb64ca6e6e3ae04f48e894d029463405", + "0x00000000000000000000000000000000002934e04d3c42257882836e1cd3c909", + "0x00000000000000000000000000000010928865f0c2b283d43e700debac484ce4", + "0x00000000000000000000000000000000001267fc086b1485e85ea3a8d0cd75de", + "0x000000000000000000000000000000f9cdf1ac824371f6761a75f1208a9ddfad", + "0x00000000000000000000000000000000000e0fdaaebe67864d0d5e9eadb9efc5", + "0x00000000000000000000000000000017a6567e4f95497a889a7d72f19789b322", + "0x0000000000000000000000000000000000288f112dfaacee642430e19b6959db", + "0x000000000000000000000000000000a16e293e7727181d85a1c007ac038f36fb", + "0x00000000000000000000000000000000000dd700294b3714e9f7b0e14b5d532b", + "0x0000000000000000000000000000008ac20e1e987aa4c40027fd4f9efd59fa05", + "0x0000000000000000000000000000000000154ef731c875ef2164785e8ff31c30", + "0x0000000000000000000000000000001911ff084795513c823a4fda7a38335e8c", + "0x0000000000000000000000000000000000302c54e62b85bc435230433f081725", + "0x000000000000000000000000000000c4779e7986fcf2ef065416576329f1c47c", + "0x00000000000000000000000000000000001ebeffb4dbaac41852670eeb9ede9d", + "0x000000000000000000000000000000f030e0b5c911d86aef1ef86fff6c540d91", + "0x00000000000000000000000000000000000bae7a5c23fa083c7231387cf8d78a", + "0x0000000000000000000000000000001942fc1702b7a2afec85c9a8473d44c487", + "0x000000000000000000000000000000000000210966c79a864b7f987cf31ab127", + "0x000000000000000000000000000000f77fcafc38ec30e711c06c5755d04144d6", + "0x00000000000000000000000000000000002db7460ea7c5e17383e5d1b8affeb4", + "0x0000000000000000000000000000007f430ccebae1fa38c07b989cb9ac4ccb2d", + "0x00000000000000000000000000000000001d815d190889cb37cacc2ccf4cfc96", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003ef880305f8c4beb28f1f80f7cc0e7d3f2", + "0x00000000000000000000000000000000000483fb33808b70b4a034dca390e659", + "0x0000000000000000000000000000003d66a145da1b03e8dc9914efd105dac5e6", + "0x00000000000000000000000000000000002a25301cc6f9e024e87f0b58047b1e" ] - hash = "0x260bc49f0702223b7f21b3aa27a20c75348991d78be9041f06bde5d2b51a3fc3" + hash = "0x17df297aed2208dd702c20c31bd85e54e0984ff5f2e4c2032f507c647b261849" [inputs.previous_archive] root = "0x21d6f855045a944864d3132e6d985947abedb3c639bcfb1b67a0fd240dff64b1" @@ -636,8 +636,8 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml index b60a27ba98d5..91d7ad39a447 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml @@ -28,10 +28,10 @@ new_l1_to_l2_message_subtree_root_sibling_path = [ "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" ] new_archive_sibling_path = [ - "0x08c303b52910eab1e07d04de401bcbe8d8f36ca377c5168e795f7f5f4156bcd5", - "0x1cfdc3f191fd4278971f73de8ee4302bd29051bb0c93c1ba7a8a7feaa4e59846", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x08ead7d93a6e0ab74b47c029605a16640557a4c3e830a2f6294aea4559e5325d", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -477,19 +477,19 @@ new_archive_sibling_path = [ [inputs.parity_root.public_inputs] sha_root = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" converted_root = "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.parity_root.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" sibling_path = [ - "0x03c2794698e7be6401d02011dc2296136a6aeb5a9ea3e6d244ece148cf45e1d0", + "0x1fd3c3c6e02265cacc9ce121274750908e476487f11894bf5fecd63e8782786e", "0x2ba2de2d2cb820a66a273f2ba930d43a4469119ad58fe01eaed0e0d615ffb426", "0x18f1abfe1a07005f35a20c06b468f7a4d3b68ecc2c025c88271b6550a827d41b", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.parity_root.vk_data.vk] @@ -1099,62 +1099,62 @@ new_archive_sibling_path = [ [inputs.previous_rollup.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x0000000000000000000000000000000000000000000000000022e452ad469ea0" - accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + accumulated_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" [inputs.previous_rollup.public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollup.public_inputs.constants.last_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" + root = "0x2d7278322ae3f2f02196f7b5eb323c037067b5a8bb27bb36e5936e01618b922e" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" [inputs.previous_rollup.public_inputs.constants.l1_to_l2_tree_snapshot] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" [inputs.previous_rollup.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000b" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000043" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde108" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2d77" [inputs.previous_rollup.public_inputs.constants.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.previous_rollup.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000003699e8ba0" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" [inputs.previous_rollup.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" [inputs.previous_rollup.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x0c877a1bf89b9eae6a04511e6f74bfaa71157ae9e20aa265ec7fb092914f6726" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [inputs.previous_rollup.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x21c0735ecdd66391ddb7fff9448a7973f1b8b4399648b1a150afb92d3a0d0ff5" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [inputs.previous_rollup.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" +root = "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.previous_rollup.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1175,128 +1175,128 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollup.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x000000000000000000000000000000000000000000000000000000000000000a" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000083" [inputs.previous_rollup.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000021e00afaeb15ed67ca0", - "0x0000000000000000000000000000000000000000000000000000000000000af0", - "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3" + "0x000a00000b020b0c000a090c2400000c00000c1027010504012300000c3d2d00", + "0x0003052600000000000000000000000000000000000000000000000000000000", + "0x000100000304092d00030a2d00050b2300000c222d010a082d04080b00000a02" ] state = [ - "0x11cc4dd8716179a3121aa6820cf8805b0e65d61d2b958fe317a1ec807c461a21", - "0x0027ae2792755b030071ea296ff933c1fbc939538b5565420ed3e94832815961", - "0x20fa0000aefa41fd803dab187b732d999bc74c8fbd1093faea082ec34b9a2976", - "0x15a69510721f899245edece9d54fb2ab846e01ef0c7480c8a80c649d69839cbd" + "0x1136161b0a665262c6670f13fc5040fb92cb9e9d8788a3e9007001bdc43cee76", + "0x18aa9fc3a56d70689da90c5f45ccd7f24947674af768221cd37158e6464e7ea6", + "0x1a30cbb374bc6cbdf6fb5b69ab449abd42245f063d346c7e6ebf9a110a83325f", + "0x056dec8ddd7e8e484e5fc378ab54c3ef2c1b70c644fa27f94fe44506d0feec0e" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false [inputs.previous_rollup.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" sibling_path = [ - "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", - "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", - "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", - "0x099ef6a9a40aaf85e056bda90684adf858addbb90af303d82f8157b86b705b92", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x1ef80142d10a45fb61f3a4192d352f1d813530777b10ca6db9613ccf5d025640", + "0x0a2d5d1c88992fa153310bc96af4c750c81353526f8c7dfe2b069ed57136e696", + "0x1c3b50ab3c647b6d36f1830308d4542ce50afddf32694ad04eb0cd74c3745ac8", + "0x09ef85eaa102507d30f8dd98ca7ac4118e672d857aa409ddcbfcd5ead95566f9", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollup.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x0000000000000000000000000000000000000000000000000000000000000016", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000008a8843c678d444ced3a35d87626e56ed9f", - "0x0000000000000000000000000000000000060403e4feb303ebae0081cbad4e96", - "0x000000000000000000000000000000f0fe138760bd40aadc43c77ad160555212", - "0x0000000000000000000000000000000000154e802ee66f7a511a469adb8153e5", - "0x00000000000000000000000000000012b75e2667d243bc4bb7b0cde3bdc5eefc", - "0x000000000000000000000000000000000013e94fa83017e580a2e280e4f8c376", - "0x000000000000000000000000000000fb8b3161040e7a5502bf277aec7b82cb6b", - "0x000000000000000000000000000000000014e7113349a6d4f2b0d3c9bde42075", - "0x0000000000000000000000000000006bc15064df220ad5d2fea722296bf72c99", - "0x00000000000000000000000000000000002039216ff43d16e0a63e542794decf", - "0x000000000000000000000000000000f0d3e00b510ae4272fbba83d787c7e6b6e", - "0x000000000000000000000000000000000022f73b00c62c39fc49fbffa96081da", - "0x0000000000000000000000000000000ff9f67bc7c9b90987dbed3fadf40bacc4", - "0x00000000000000000000000000000000001dc87bb292ea49bdb5bb87509c9781", - "0x00000000000000000000000000000025239c23a65572724acdd6663984afc224", - "0x000000000000000000000000000000000005e345da6870bd306f04558f601b45", - "0x000000000000000000000000000000cb380ac3dc3f8788bab24fcb5d9eedc949", - "0x000000000000000000000000000000000017714c1fab296b76d2f78ed675c1ce", - "0x00000000000000000000000000000095bca1a9f9a186f7ec34e43c479e5d1b2f", - "0x000000000000000000000000000000000018d292be64529b7e9ec24c76e561d9", - "0x0000000000000000000000000000006f1bd711730ae2aaf83227b9d9f46daa43", - "0x00000000000000000000000000000000002df0b894f5971084c0a65839178a66", - "0x000000000000000000000000000000909f2efe0bffa95e984d456089f568f59b", - "0x00000000000000000000000000000000002908f2c7ddf9573df347d6c9f22fde", + "0x0000000000000000000000000000003f557273f3723ac427671e7e0241709f42", + "0x00000000000000000000000000000000001a4c7c79f45cd9c3b2730b1014fb2c", + "0x000000000000000000000000000000a0758982a879da262fb5d4a283eb0b2fbd", + "0x00000000000000000000000000000000001cd980c7d658817fc07f56422786c8", + "0x0000000000000000000000000000001116c0ef394a159d7d04035e2d2b1df210", + "0x00000000000000000000000000000000001fc719cba8f7ef0eec1facb64807b8", + "0x00000000000000000000000000000030ae5b7a71f6a3350eb91e843430327027", + "0x000000000000000000000000000000000010623eeba8739fad768943b6a32cd7", + "0x00000000000000000000000000000075f511068970271dc3805b753a601ff6bf", + "0x0000000000000000000000000000000000087d083bd0a030d3e8d20a44cac510", + "0x0000000000000000000000000000008a1d365a7e9c0cdce156eefc77f82c324b", + "0x00000000000000000000000000000000000caa3c2fe3eec6d3abba790f3fdb0f", + "0x000000000000000000000000000000226b13400df89aa52dc04c9ba11ec76d0b", + "0x00000000000000000000000000000000000f98a2766e0e9bfae8946b711ef013", + "0x0000000000000000000000000000003795e58e429596f55168217c1397f38a8a", + "0x00000000000000000000000000000000002e1f8ca27b32c2497816dd49c983e2", + "0x00000000000000000000000000000024169a17177b075798734095f9cc8daf09", + "0x0000000000000000000000000000000000221931eec1149ebc68293392b42121", + "0x000000000000000000000000000000ba47588390fa3d72b699d8b0917b7e3406", + "0x00000000000000000000000000000000000e598a4916409aaf3745b4c6185f93", + "0x000000000000000000000000000000b749616c0462fced8081f284a03518d1a8", + "0x0000000000000000000000000000000000241ceb3abe3289083ce8c8c8bc28d0", + "0x0000000000000000000000000000001d9bd025c3e2e26266d41ff2e384400b47", + "0x00000000000000000000000000000000001e259846a94808bed66227cf262eff", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", - "0x000000000000000000000000000000d2c67f3c526e05aa6d25558ae65cf0e3ac", - "0x000000000000000000000000000000000006cc97b785475ed3429d939fa00e96", - "0x000000000000000000000000000000c5240a725c016a35037b37f73c37b68de9", - "0x000000000000000000000000000000000015e6206f121de2aafe259c32889a4b", - "0x0000000000000000000000000000004cba3ce39736c272ff963bdbdfcb67c2ef", - "0x0000000000000000000000000000000000243b3786310485c3234295957c5222", - "0x0000000000000000000000000000002c3672eaf01e849995fc3f6dc99dcd1d60", - "0x00000000000000000000000000000000001449e8673b109f980a1542f1ddd670", - "0x000000000000000000000000000000f077af86375782052dfc713a0c67f9a08b", - "0x0000000000000000000000000000000000124108d868884e76f5ceeb60b2bdae", - "0x00000000000000000000000000000029c3fd985c5dd5867bd8fed36ad940e02d", - "0x0000000000000000000000000000000000146fedc34ca9246ab0df070f31ee14", - "0x000000000000000000000000000000706a32f5a8f5fa44205bb08662e0ef1396", - "0x000000000000000000000000000000000016ded7f7f0b72d3ecf256f5c2ee613", - "0x0000000000000000000000000000002eaf856304cdbbb4d0b926d9c9211028c0", - "0x000000000000000000000000000000000004696250db37878179b548105ff54e", - "0x000000000000000000000000000000047767298e4177562ddcbcae03c7ec6ccc", - "0x00000000000000000000000000000000001f29f52f5f45f28e462390b0f914f9", - "0x00000000000000000000000000000004e950f9459bf160429275bc6a733319ea", - "0x0000000000000000000000000000000000175f23657f8f899b10b84c1ffe432c", - "0x0000000000000000000000000000006e522620788963bd42d9ab48810f89afe4", - "0x00000000000000000000000000000000002243c76dbde36a37e42b92bae3eb16", - "0x0000000000000000000000000000005641fbcbddd5abb62d653fd7f1ed10ed7e", - "0x000000000000000000000000000000000007d25e6a46da918fdb902e1a78efb4", - "0x00000000000000000000000000000065f7509bb551cb061c5fd1e92bc85a4974", - "0x00000000000000000000000000000000002efbc0dd9b88baa9675d95ae595e68", - "0x00000000000000000000000000000046bdd1d7603fdb2ee53f8966b3069082a5", - "0x0000000000000000000000000000000000161d3346daa3f83e4416d59e8135b6", - "0x000000000000000000000000000000ec124a53466d06b5e0df3e77f9f6a6ae15", - "0x0000000000000000000000000000000000128b36a77e814ffa503da6fd061fc3", - "0x0000000000000000000000000000002cfa5f8d00fe2bbdd85db6b0179a4c7346", - "0x00000000000000000000000000000000002b7ce5f45710c4b113f7ca6b3291b0", - "0x00000000000000000000000000000054409cb824bb2028eb6a501f9585b13eda", - "0x000000000000000000000000000000000026412333aa334f56e0761374f0c38b", - "0x0000000000000000000000000000002a23ae58cbd13760028a699488d5a4300f", - "0x0000000000000000000000000000000000225067a42bdcd7d9eec23d250acc92", - "0x0000000000000000000000000000006e28e63b7d6bc65c15c009f5dd9304f8fd", - "0x00000000000000000000000000000000002648ab0c9cfefbb147853e364bef8d", - "0x000000000000000000000000000000f00a9e6c1594965b7c14b2310b489b52f9", - "0x00000000000000000000000000000000000a03f4283d5d64b7245827349741ee", - "0x00000000000000000000000000000073f3c5531dc194b7332ef4e765192e3962", - "0x0000000000000000000000000000000000088b01c6cab84d827c1d8eae1ebbbd", - "0x000000000000000000000000000000e197f3a024045bec491c28fc4b7594347b", - "0x000000000000000000000000000000000025bf29aee6c0dd8976574600dfacea", - "0x00000000000000000000000000000023cebfa19e1e206b1d71359821037c31b7", - "0x00000000000000000000000000000000000c2354b63a0bcd72350e606c3fa0e7", - "0x000000000000000000000000000000fcf564b220543fd0aea7b28c05df85fe3a", - "0x00000000000000000000000000000000000c2f035d78985f2c0e4ab138790e69", - "0x0000000000000000000000000000005129d16313e897118223bd963067e22700", - "0x000000000000000000000000000000000004c87b337be4b82e809af637daef82", - "0x000000000000000000000000000000279941b3633c9a8e9fc6e68ef4be5633f4", - "0x00000000000000000000000000000000002a9334f2cfa791a9bbc88cc234a5d2", - "0x000000000000000000000000000000ab1a8db808cb2b1b90ba26085c23154102", - "0x00000000000000000000000000000000002c04e8fdbd1f2154a1b42961e3b6b5", - "0x0000000000000000000000000000005729f9b6dcfc45fa934c44ad8800e2b7c6", - "0x00000000000000000000000000000000002c584d4df5aaa602e46e5033408d64", - "0x0000000000000000000000000000004daf206a533411e7b39ab99acaf3287ca2", - "0x000000000000000000000000000000000020d85db8daa0dd9c83ceda296cbe73", - "0x000000000000000000000000000000ab6d868729c089d55819b59b1df10e26ce", - "0x000000000000000000000000000000000004b5421430befd61f014813d315ade", + "0x0000000000000000000000000000005eab99fc5c34cd0a9cf32bc53d04beea68", + "0x00000000000000000000000000000000002eea4190ba69ef934f8be916a217a9", + "0x0000000000000000000000000000005429ed84e5768b172fc483197bcfb786df", + "0x00000000000000000000000000000000000387e378a43d625a53900bde3ff4ad", + "0x0000000000000000000000000000006073a1bf82ba61c51ce96d6cb7030a22b4", + "0x00000000000000000000000000000000001ebaecf236ff2932e24e68d8e1be3b", + "0x00000000000000000000000000000006abf6369ec441190fb054e33c764fb032", + "0x00000000000000000000000000000000001bdbd38b557395b30427017524ba12", + "0x0000000000000000000000000000001d7bb00201b0efb3035f5048c3df84c772", + "0x000000000000000000000000000000000024548bcd56a9ef16c14feae610f806", + "0x000000000000000000000000000000e5655012ed18fcd1d8e339226dd0ba4078", + "0x0000000000000000000000000000000000227c2110109edbbc3955d0465bbc22", + "0x0000000000000000000000000000007bf8464ca9aa703f1e8a25d6e20221d3e9", + "0x000000000000000000000000000000000024963361ceb6d7756c3c2c42a845fe", + "0x00000000000000000000000000000048c96ec4485788f3ccdc37c4ae2a71f1a4", + "0x0000000000000000000000000000000000262b455b6cd2796327e461304e18f7", + "0x000000000000000000000000000000f750d5b7b2337529d40ced8d774f0283e6", + "0x0000000000000000000000000000000000120ef244fda086bafa6f4eccaf97fd", + "0x000000000000000000000000000000fc90ae3789baa78d1d13220b4f34c98f4e", + "0x00000000000000000000000000000000000d60e7b02c8af3cfd72fe199d6a8f6", + "0x0000000000000000000000000000000b9c9b15d9b55b4a49d449b2cd9dbf2dc2", + "0x0000000000000000000000000000000000129d1259178a85eee0f4d95edf2756", + "0x000000000000000000000000000000e8f0abccd4a45c69a68832f6ef8851f04a", + "0x00000000000000000000000000000000000b977396722d8361fecf325e0e32bc", + "0x000000000000000000000000000000645575d035dbf0dc7a5012097524a972d3", + "0x00000000000000000000000000000000001b4b534173d70982fcd6c9544d725d", + "0x0000000000000000000000000000000410cceb82ec7354128465ac80a1ffa862", + "0x00000000000000000000000000000000002acddfed4a484b2d862b4ca275b4d7", + "0x00000000000000000000000000000022d1618e485430a15465e219a117d3edfe", + "0x000000000000000000000000000000000007b06e6eb92e0b7a34acf20a1369f8", + "0x000000000000000000000000000000e856ca1b174973f3af5310a7e38cb305e6", + "0x000000000000000000000000000000000010be0fec1c7598a1c63ec216db4681", + "0x000000000000000000000000000000f0639c87f66ace434ddb4fe65ab243bfde", + "0x00000000000000000000000000000000000c3c99921dee4f0506f5127627f327", + "0x000000000000000000000000000000aa1c283b5ed1b8b43addafd2bb63ecf30d", + "0x00000000000000000000000000000000002b9dc475b4a10275550d8b8d8fbe3b", + "0x00000000000000000000000000000032af5ee654ac1bb41937bb3add8e38ba3e", + "0x00000000000000000000000000000000001491fed9838cf1fe30a73db7421ab1", + "0x0000000000000000000000000000007c9bcd4ba41aac07ea382a61e7b79bc6dd", + "0x0000000000000000000000000000000000064fbc9678a0191e9974927405e063", + "0x000000000000000000000000000000cf990fc7f643af435bd552d6c21f4f12d9", + "0x0000000000000000000000000000000000170bb10fc59004dae5b55d43a9f478", + "0x00000000000000000000000000000019a1d0ed8d637f1c2afba5fdd385d5fcd2", + "0x00000000000000000000000000000000001aeb885acef6da1ab84b4be20c558c", + "0x000000000000000000000000000000a11da3a0f3c7903c1b8119a3727c1d92a6", + "0x0000000000000000000000000000000000054448cc8cc704196f0ee4b52a9d63", + "0x0000000000000000000000000000000e44ab863c917d81428b86f84af8cd1a25", + "0x000000000000000000000000000000000024d7a2087fcd46a69fd94e824dfff2", + "0x0000000000000000000000000000009f11cf3ef8d440c8e83a8eacfe48155eaf", + "0x0000000000000000000000000000000000255afe02ffbc3178db86e228039ff5", + "0x0000000000000000000000000000004a9ad3947e4b5066ad0b4a731d994fa3a4", + "0x0000000000000000000000000000000000092b00146ab98c77c752c32098468c", + "0x000000000000000000000000000000165a72693efa48c7ecebf3f1fea42db4a6", + "0x00000000000000000000000000000000002e108deabceced2338790d19ba16b2", + "0x0000000000000000000000000000001722f48e7ed1f6f73faaf4007e165811f2", + "0x00000000000000000000000000000000002d43d6af66193fced48fd6f89e74f8", + "0x000000000000000000000000000000ac5108d90de1d0e6ce3d6186c769e8b2aa", + "0x00000000000000000000000000000000000de8c8ad0bfcca457220d03c5eb698", + "0x000000000000000000000000000000ab4c7dff5c06e3ad269e8e48dcb13f0a20", + "0x0000000000000000000000000000000000139a57f59fdf3ec29554b9179adc03", "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", @@ -1317,13 +1317,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000bd9c096acdaa162e6c7ee9b718f7fbf759", - "0x00000000000000000000000000000000002c70947eefbeb3fcbc1953b2ccb88f", - "0x00000000000000000000000000000045e09e50b539ce6228369e4b4cb8530ce0", - "0x0000000000000000000000000000000000062cf2c7d023a38df32e6c8c04a8c1" + "0x00000000000000000000000000000027dd7a7146d1c4ff9332e930ec54b6ea2e", + "0x0000000000000000000000000000000000251eb2367a907e55626a07bbea7e2b", + "0x000000000000000000000000000000ed074fc7f9cd09872a83d8c368c93a0725", + "0x00000000000000000000000000000000002621701db780a70b161ef185f06af9" ] - hash = "0x208d8b1ad2d688325416c8a23881e8b14753352851d7740b339ea2ebd455cdcc" + hash = "0x0a7fb889325f39bec13ee8f853c529ad8458c39c703cf4277c5b066d8d2eee15" [inputs.previous_l1_to_l2] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001c00" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml index 969d8532627b..c6438c29451a 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml @@ -28,10 +28,10 @@ new_l1_to_l2_message_subtree_root_sibling_path = [ "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" ] new_archive_sibling_path = [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x1cfdc3f191fd4278971f73de8ee4302bd29051bb0c93c1ba7a8a7feaa4e59846", + "0x02963c966fa7ce35d09c6efedc0319a95890e2e43d65e589e1554b9297826ced", + "0x171c3c9d071c144fac4784c5f2ccea6e9164bf047088712fc7b8e4d5a68cf235", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x08ead7d93a6e0ab74b47c029605a16640557a4c3e830a2f6294aea4559e5325d", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -477,19 +477,19 @@ new_archive_sibling_path = [ [inputs.parity_root.public_inputs] sha_root = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" converted_root = "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.parity_root.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" sibling_path = [ - "0x03c2794698e7be6401d02011dc2296136a6aeb5a9ea3e6d244ece148cf45e1d0", + "0x1fd3c3c6e02265cacc9ce121274750908e476487f11894bf5fecd63e8782786e", "0x2ba2de2d2cb820a66a273f2ba930d43a4469119ad58fe01eaed0e0d615ffb426", "0x18f1abfe1a07005f35a20c06b468f7a4d3b68ecc2c025c88271b6550a827d41b", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.parity_root.vk_data.vk] @@ -1099,31 +1099,31 @@ new_archive_sibling_path = [ [inputs.previous_rollups.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000002" out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x00000000000000000000000000000000000000000000000000885bb87af2ece0" - accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000001210e5" + accumulated_fees = "0x0000000000000000000000000000000000000000000000000083c454635e0920" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000011752b" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" + next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" [inputs.previous_rollups.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000a" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000042" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde0c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x000000000000000000000000000000000000000000000000000000000000000b" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000025" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2e4f" [inputs.previous_rollups.public_inputs.constants.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.previous_rollups.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1133,28 +1133,28 @@ new_archive_sibling_path = [ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x11ea69a14ea9c12bed3f481dd61addfb2d90d96aa40b626c4d2e47b3466e7b88" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" +root = "0x2d172b57477efffd52c4725031d5f351fe4b85137ca4a7121c486b7a6354f637" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x10e14d1e03084d8016d8018077d4e629cb58cbf3139897cdd78db40c002a04d7" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x0a8a1e4bcc4ca37ba1c0e2fcb5e41bc311a5e6b619df6801f0c66240b9614b22" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x1410b6658243b878037c23a953c69c3a138fdf38373efa0662a549111364b310" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x2d36c4289f1a8a4595fd6c28fc83a76c3ebe1112a192448aa6b8400c8d1bc260" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x26fd6ffebb711b7b1d916a895bb8bf3c6b5fc915b1e5a22db0fb801072027d80" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x082091a51b72ed76964eecd0505df5c335ce81a43e8f39055f31498364687c7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x2cef7e5e25fb54c99feb0d6fbc5bb44eb98d00d3022f4baf5e3f6025a7320293" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x2ee93e7bf272c4871c6ea3459ba1e3cfb0a00ee0432439a6095280b78ed82244" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollups.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1175,33 +1175,33 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000047" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000045" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x2a44787960631c708a6c54319236e2733f5bf18956a780d4f076e06d46e8c52f", - "0x21c2f9acd4cfd49d3570c4429b45c6dcf5658ac7592091682403c9468c8fbfc5", - "0x089c49b97c1e121fc3d9c0d7f3793cdd886de1fb26e735edbdae3790abaedd66" + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", + "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969", + "0x00000000000000000000000000000000000000000000021e012495ef5cfd1660" ] state = [ - "0x0b196378726e6d2cbd4d793963bdda8cc494c766409365f6a0f3b9f8e2e2c277", - "0x29906675cd547621ba2ccf000d609acec4b304b7b4d929f9e586687d92c311a9", - "0x17ecd8ac459a19c262c431de5d01f6726a3b03485399398d69165cc195454006", - "0x254280886c6baee6bfedb4dae9055f680574d4b1bb6a4245fb1f24c70eedaa76" + "0x22ea2f893e011e4e7eee01b158986dc9992f64040159170bcb324eae3e034b97", + "0x06a52127441effdec8d468b67c99f1845277ff28156fa7e2abc426c475b77e5a", + "0x27ce40389262fdebb78d0324fb312c0cbf88401e5c7b144c75ba81aaced2ec9c", + "0x0e692e75fdd9a570ffb576fd43504909483cbe4ee5d110f8d2d63bb4478a30dd" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" sibling_path = [ - "0x208d8b1ad2d688325416c8a23881e8b14753352851d7740b339ea2ebd455cdcc", + "0x25f3ed562872c5e18abd2b9c6d87543b21886af47c7a714c99e78776bae18397", "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", - "0x099ef6a9a40aaf85e056bda90684adf858addbb90af303d82f8157b86b705b92", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x24cead94db344ae1716301e94784822099e114c4deaddb78f16e8724ee376aaa", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] @@ -1811,31 +1811,31 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x000000000000000000000000000000000000000000000000004894bc72b69ca0" - accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000099dbf" + accumulated_fees = "0x000000000000000000000000000000000000000000000000004d2c208a4b8060" + accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" + next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" [inputs.previous_rollups.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000a" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000042" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde0c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x000000000000000000000000000000000000000000000000000000000000000b" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000025" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2e4f" [inputs.previous_rollups.public_inputs.constants.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.previous_rollups.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1845,45 +1845,45 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x26fd6ffebb711b7b1d916a895bb8bf3c6b5fc915b1e5a22db0fb801072027d80" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x082091a51b72ed76964eecd0505df5c335ce81a43e8f39055f31498364687c7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x2cef7e5e25fb54c99feb0d6fbc5bb44eb98d00d3022f4baf5e3f6025a7320293" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x2ee93e7bf272c4871c6ea3459ba1e3cfb0a00ee0432439a6095280b78ed82244" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x1cfed5fd7ef032befae488393236dfabcdca928fd71b5775b02eeeca5952b149" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" +root = "0x17809078aea757181529cc251693b3402311164785b07da22da983ca02d24ffa" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000047" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000045" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x2a44787960631c708a6c54319236e2733f5bf18956a780d4f076e06d46e8c52f", - "0x21c2f9acd4cfd49d3570c4429b45c6dcf5658ac7592091682403c9468c8fbfc5", - "0x089c49b97c1e121fc3d9c0d7f3793cdd886de1fb26e735edbdae3790abaedd66" + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", + "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969", + "0x00000000000000000000000000000000000000000000021e012495ef5cfd1660" ] state = [ - "0x0b196378726e6d2cbd4d793963bdda8cc494c766409365f6a0f3b9f8e2e2c277", - "0x29906675cd547621ba2ccf000d609acec4b304b7b4d929f9e586687d92c311a9", - "0x17ecd8ac459a19c262c431de5d01f6726a3b03485399398d69165cc195454006", - "0x254280886c6baee6bfedb4dae9055f680574d4b1bb6a4245fb1f24c70eedaa76" + "0x22ea2f893e011e4e7eee01b158986dc9992f64040159170bcb324eae3e034b97", + "0x06a52127441effdec8d468b67c99f1845277ff28156fa7e2abc426c475b77e5a", + "0x27ce40389262fdebb78d0324fb312c0cbf88401e5c7b144c75ba81aaced2ec9c", + "0x0e692e75fdd9a570ffb576fd43504909483cbe4ee5d110f8d2d63bb4478a30dd" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] @@ -1891,15 +1891,15 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000021e00d293040c1d1b40", - "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec", - "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3" + "0x00000000000000000000000000000000000000000000021e00d769ced2b19600", + "0x00000000000000000000000000000000000000000000000000000000000003e8", + "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969" ] state = [ - "0x046ca01947e306f5aad217a20c357e8720e466bf48af683e5dc034abe73721f0", - "0x14686ac6e82fd9bd26ab09d349ce45506d9c0d1dee28a4967817015ea73b887b", - "0x0b7d5bc95988dfda6650240e060e449c0ec3d312f8da80bd59a897a3ce57c1ee", - "0x1ea8a35effe09689490c7037df5f38ebfc4f6641047f2e4bcab5542979b4667c" + "0x1bc609f7dcef364685bb5064b63088b4b176e64477bcb8a59d1c5d75ecf2daa8", + "0x034e84257006a2e620593aa7b0d53b07c9241554a3c0758e9e8d3dd4dbb7fb69", + "0x0ea57cf50569254eb0b5e0a6bc854a45fd90dc63bbfc989ac9aab7b658b90219", + "0x09602775b5f377f951b58721d32a2e6596705625a417c0dbf308d84edb29d9df" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false @@ -1910,10 +1910,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", - "0x099ef6a9a40aaf85e056bda90684adf858addbb90af303d82f8157b86b705b92", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x24cead94db344ae1716301e94784822099e114c4deaddb78f16e8724ee376aaa", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] @@ -1921,94 +1921,94 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000008a8843c678d444ced3a35d87626e56ed9f", - "0x0000000000000000000000000000000000060403e4feb303ebae0081cbad4e96", - "0x000000000000000000000000000000f0fe138760bd40aadc43c77ad160555212", - "0x0000000000000000000000000000000000154e802ee66f7a511a469adb8153e5", - "0x00000000000000000000000000000012b75e2667d243bc4bb7b0cde3bdc5eefc", - "0x000000000000000000000000000000000013e94fa83017e580a2e280e4f8c376", - "0x000000000000000000000000000000fb8b3161040e7a5502bf277aec7b82cb6b", - "0x000000000000000000000000000000000014e7113349a6d4f2b0d3c9bde42075", - "0x0000000000000000000000000000006bc15064df220ad5d2fea722296bf72c99", - "0x00000000000000000000000000000000002039216ff43d16e0a63e542794decf", - "0x000000000000000000000000000000f0d3e00b510ae4272fbba83d787c7e6b6e", - "0x000000000000000000000000000000000022f73b00c62c39fc49fbffa96081da", - "0x0000000000000000000000000000000ff9f67bc7c9b90987dbed3fadf40bacc4", - "0x00000000000000000000000000000000001dc87bb292ea49bdb5bb87509c9781", - "0x00000000000000000000000000000025239c23a65572724acdd6663984afc224", - "0x000000000000000000000000000000000005e345da6870bd306f04558f601b45", - "0x000000000000000000000000000000cb380ac3dc3f8788bab24fcb5d9eedc949", - "0x000000000000000000000000000000000017714c1fab296b76d2f78ed675c1ce", - "0x00000000000000000000000000000095bca1a9f9a186f7ec34e43c479e5d1b2f", - "0x000000000000000000000000000000000018d292be64529b7e9ec24c76e561d9", - "0x0000000000000000000000000000006f1bd711730ae2aaf83227b9d9f46daa43", - "0x00000000000000000000000000000000002df0b894f5971084c0a65839178a66", - "0x000000000000000000000000000000909f2efe0bffa95e984d456089f568f59b", - "0x00000000000000000000000000000000002908f2c7ddf9573df347d6c9f22fde", + "0x000000000000000000000000000000b545d833a3cc9654dc3778c8fc7ba02260", + "0x00000000000000000000000000000000001b66ea392ccb7834c732bf86004463", + "0x00000000000000000000000000000085d1593162873215b0b41c64cb7cb0f3dd", + "0x0000000000000000000000000000000000137f2cf2c8141ddf32dc7895df5a91", + "0x00000000000000000000000000000015bd11a0a68a9fa3cb97d7b377340600a0", + "0x00000000000000000000000000000000001c98939c525c07b9dc35242a7c7552", + "0x000000000000000000000000000000cc31fdbc0ca878839693b87eee464d9f98", + "0x00000000000000000000000000000000002ba8d519b16b09c6af76887171a8bf", + "0x0000000000000000000000000000009a381e1beac98b23aeaee28a9046ac5ad9", + "0x00000000000000000000000000000000000aef8131f15aa3d0ba42d130678428", + "0x0000000000000000000000000000005f188d32071b43a3bd819e75c138f643e0", + "0x00000000000000000000000000000000002f02065d3e3a5ef4fdd72b9e71a6db", + "0x0000000000000000000000000000000562756bd3ba24529dde902ebf387674a2", + "0x00000000000000000000000000000000000d69752978cb2604a8f5976fa5b2aa", + "0x0000000000000000000000000000002d4785d1c39f767ca2489e57956e264037", + "0x00000000000000000000000000000000000eb3abc7015aef51cad0792c015bfb", + "0x000000000000000000000000000000feb4eee7085cf9c45105254a02f9265e10", + "0x00000000000000000000000000000000000beb9239680b506079e5cda03a9cdf", + "0x000000000000000000000000000000f6d0ed07f67728bfc43ac279ee33b4f6a5", + "0x0000000000000000000000000000000000130de3209e04190412baf56475a662", + "0x0000000000000000000000000000005ba14f0dd0b7766fb3855b36587341a777", + "0x000000000000000000000000000000000008d2a5bc2cebd4e7b9696c3aaee35d", + "0x0000000000000000000000000000000d8ca8b57e8aefe0252ffd103e1d3a2b94", + "0x0000000000000000000000000000000000084daf23a4d3af94ab98db652895c2", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", - "0x000000000000000000000000000000d2c67f3c526e05aa6d25558ae65cf0e3ac", - "0x000000000000000000000000000000000006cc97b785475ed3429d939fa00e96", - "0x000000000000000000000000000000c5240a725c016a35037b37f73c37b68de9", - "0x000000000000000000000000000000000015e6206f121de2aafe259c32889a4b", - "0x0000000000000000000000000000004cba3ce39736c272ff963bdbdfcb67c2ef", - "0x0000000000000000000000000000000000243b3786310485c3234295957c5222", - "0x0000000000000000000000000000002c3672eaf01e849995fc3f6dc99dcd1d60", - "0x00000000000000000000000000000000001449e8673b109f980a1542f1ddd670", - "0x000000000000000000000000000000f077af86375782052dfc713a0c67f9a08b", - "0x0000000000000000000000000000000000124108d868884e76f5ceeb60b2bdae", - "0x00000000000000000000000000000029c3fd985c5dd5867bd8fed36ad940e02d", - "0x0000000000000000000000000000000000146fedc34ca9246ab0df070f31ee14", - "0x000000000000000000000000000000706a32f5a8f5fa44205bb08662e0ef1396", - "0x000000000000000000000000000000000016ded7f7f0b72d3ecf256f5c2ee613", - "0x0000000000000000000000000000002eaf856304cdbbb4d0b926d9c9211028c0", - "0x000000000000000000000000000000000004696250db37878179b548105ff54e", - "0x000000000000000000000000000000047767298e4177562ddcbcae03c7ec6ccc", - "0x00000000000000000000000000000000001f29f52f5f45f28e462390b0f914f9", - "0x00000000000000000000000000000004e950f9459bf160429275bc6a733319ea", - "0x0000000000000000000000000000000000175f23657f8f899b10b84c1ffe432c", - "0x0000000000000000000000000000006e522620788963bd42d9ab48810f89afe4", - "0x00000000000000000000000000000000002243c76dbde36a37e42b92bae3eb16", - "0x0000000000000000000000000000005641fbcbddd5abb62d653fd7f1ed10ed7e", - "0x000000000000000000000000000000000007d25e6a46da918fdb902e1a78efb4", - "0x00000000000000000000000000000065f7509bb551cb061c5fd1e92bc85a4974", - "0x00000000000000000000000000000000002efbc0dd9b88baa9675d95ae595e68", - "0x00000000000000000000000000000046bdd1d7603fdb2ee53f8966b3069082a5", - "0x0000000000000000000000000000000000161d3346daa3f83e4416d59e8135b6", - "0x000000000000000000000000000000ec124a53466d06b5e0df3e77f9f6a6ae15", - "0x0000000000000000000000000000000000128b36a77e814ffa503da6fd061fc3", - "0x0000000000000000000000000000002cfa5f8d00fe2bbdd85db6b0179a4c7346", - "0x00000000000000000000000000000000002b7ce5f45710c4b113f7ca6b3291b0", - "0x00000000000000000000000000000054409cb824bb2028eb6a501f9585b13eda", - "0x000000000000000000000000000000000026412333aa334f56e0761374f0c38b", - "0x0000000000000000000000000000002a23ae58cbd13760028a699488d5a4300f", - "0x0000000000000000000000000000000000225067a42bdcd7d9eec23d250acc92", - "0x0000000000000000000000000000006e28e63b7d6bc65c15c009f5dd9304f8fd", - "0x00000000000000000000000000000000002648ab0c9cfefbb147853e364bef8d", - "0x000000000000000000000000000000f00a9e6c1594965b7c14b2310b489b52f9", - "0x00000000000000000000000000000000000a03f4283d5d64b7245827349741ee", - "0x00000000000000000000000000000073f3c5531dc194b7332ef4e765192e3962", - "0x0000000000000000000000000000000000088b01c6cab84d827c1d8eae1ebbbd", - "0x000000000000000000000000000000e197f3a024045bec491c28fc4b7594347b", - "0x000000000000000000000000000000000025bf29aee6c0dd8976574600dfacea", - "0x00000000000000000000000000000023cebfa19e1e206b1d71359821037c31b7", - "0x00000000000000000000000000000000000c2354b63a0bcd72350e606c3fa0e7", - "0x000000000000000000000000000000fcf564b220543fd0aea7b28c05df85fe3a", - "0x00000000000000000000000000000000000c2f035d78985f2c0e4ab138790e69", - "0x0000000000000000000000000000005129d16313e897118223bd963067e22700", - "0x000000000000000000000000000000000004c87b337be4b82e809af637daef82", - "0x000000000000000000000000000000279941b3633c9a8e9fc6e68ef4be5633f4", - "0x00000000000000000000000000000000002a9334f2cfa791a9bbc88cc234a5d2", - "0x000000000000000000000000000000ab1a8db808cb2b1b90ba26085c23154102", - "0x00000000000000000000000000000000002c04e8fdbd1f2154a1b42961e3b6b5", - "0x0000000000000000000000000000005729f9b6dcfc45fa934c44ad8800e2b7c6", - "0x00000000000000000000000000000000002c584d4df5aaa602e46e5033408d64", - "0x0000000000000000000000000000004daf206a533411e7b39ab99acaf3287ca2", - "0x000000000000000000000000000000000020d85db8daa0dd9c83ceda296cbe73", - "0x000000000000000000000000000000ab6d868729c089d55819b59b1df10e26ce", - "0x000000000000000000000000000000000004b5421430befd61f014813d315ade", + "0x0000000000000000000000000000000c6fdc12f114b3dff18c32b6639206626d", + "0x000000000000000000000000000000000029ea8e59560238dd94abed35cb70c8", + "0x000000000000000000000000000000798b53b0eca893b352181071c60c1697a3", + "0x0000000000000000000000000000000000143bc71afee8cde0cf0923214ba969", + "0x00000000000000000000000000000085734dbd3f00d833c7f16d28c7c161a6e6", + "0x00000000000000000000000000000000001dc1695bb379cc1fe09ce6224bbd76", + "0x00000000000000000000000000000076510156d9bbb6e8916f5df3484dbe501a", + "0x000000000000000000000000000000000002f88711cc50540166aaf0ed7563ce", + "0x0000000000000000000000000000004e92767827fb29389f5eecfe92604eab79", + "0x000000000000000000000000000000000015e003572014e30792cc42dd76f703", + "0x000000000000000000000000000000e9101815687b2b199e9813ab45410c58a0", + "0x00000000000000000000000000000000000bdf464606fd075764ebd13de85d18", + "0x000000000000000000000000000000a4765d6f5df947831e3f85a1bd0bc7628a", + "0x00000000000000000000000000000000000c553b386599253dcca9bcad704ca3", + "0x000000000000000000000000000000832463786e94b008b4014e652a0a06d7a8", + "0x000000000000000000000000000000000011ff61570f0bf2e97760512082e6f3", + "0x00000000000000000000000000000044e15aaa95424af2ca33a24f73d87a9fed", + "0x0000000000000000000000000000000000265a6e89432e27fe25605d534fefff", + "0x000000000000000000000000000000e50b139f7dcefba4c36067e75084866789", + "0x00000000000000000000000000000000001f7c7a9bcf4d3731b120fdb685be9a", + "0x000000000000000000000000000000c61155084507edfd2780b6595d0383e3d3", + "0x000000000000000000000000000000000024732fdee72acfeb9fcd7ecd03f17b", + "0x000000000000000000000000000000e3eba5ed351243e1b88baf42d6e3c3497f", + "0x00000000000000000000000000000000001ac8ebfb4b65882179207743191dab", + "0x000000000000000000000000000000d5ab1236a0b5298b47f9d147a330a0d1a6", + "0x000000000000000000000000000000000004bf74c81b93344ee6eb639f9b27f5", + "0x000000000000000000000000000000f54856ecc2104aaa4a8b1412198b8f19a0", + "0x000000000000000000000000000000000009657c61abf1cefe29851881f04171", + "0x0000000000000000000000000000000671c904145c28b987a2097d7e0a44bed7", + "0x000000000000000000000000000000000014a3beb99844cce00bf4bf29835019", + "0x000000000000000000000000000000bb586be39659e96f6200416f882ea6791a", + "0x00000000000000000000000000000000000ec0d3c4d4d09bf02f60b610ca417c", + "0x000000000000000000000000000000a27b8cc202048319ee3216614fe0b2bc78", + "0x0000000000000000000000000000000000259f13400b5ca91f037e522892f1d0", + "0x0000000000000000000000000000005afa7274e86f2e4544d9bc2995a4b59eb6", + "0x000000000000000000000000000000000013d4650df900f0413b1d29aa9ba528", + "0x000000000000000000000000000000a0230f28d66f5d56c9ff831a471d3c5f9b", + "0x00000000000000000000000000000000002b59c41dfcccc1692e67253054b1e5", + "0x000000000000000000000000000000cb139be520f9594c3b3265adf3c829a0be", + "0x00000000000000000000000000000000001a03e4be32cf715c13caa3b09031f2", + "0x000000000000000000000000000000acd2e4f92b6605e95986f1cffa82304b50", + "0x0000000000000000000000000000000000259fb01c767e7769e772eb56ce8193", + "0x000000000000000000000000000000282782aa36fde06ed1c6dd811c75864c98", + "0x00000000000000000000000000000000001369a47591ca24aab36f32a1f92922", + "0x0000000000000000000000000000001c17cb9d98dae6214548afa20c9f1c4f7c", + "0x000000000000000000000000000000000008b8f3d446e6f4e097bd6841e421b5", + "0x00000000000000000000000000000039e4c093b585f6a6fcb22f99bd8c342b7e", + "0x00000000000000000000000000000000003041bf4ef4eb97be85a8fdc7c9479e", + "0x000000000000000000000000000000da48e82a3d5d7897cb678ff5610a5cf1ff", + "0x000000000000000000000000000000000003acb814504ffac1f2ed4a14fc9bd3", + "0x0000000000000000000000000000009dca7075e3e05e41559f28912a82971ea0", + "0x0000000000000000000000000000000000235b08870fcb646e907b4d3d736174", + "0x00000000000000000000000000000088b105b378f5f68086a26e45ce7db625c5", + "0x00000000000000000000000000000000001d5e5ec54b2dc9f683c10f467d96ac", + "0x00000000000000000000000000000077d8cfd48ba52a9cdd346b1cf45f0d718e", + "0x00000000000000000000000000000000001d96ca59605ed27e2028cb8af363e0", + "0x0000000000000000000000000000006b206e2ff7e814240e93358f1c3ca92a89", + "0x00000000000000000000000000000000000f68e0a1401d250cc41f4478d6e0c3", + "0x0000000000000000000000000000003563a2722147fff76720456302877e3e2c", + "0x0000000000000000000000000000000000000ccf9ca6c5707774553f9e9a96f5", "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", @@ -2029,13 +2029,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000bd9c096acdaa162e6c7ee9b718f7fbf759", - "0x00000000000000000000000000000000002c70947eefbeb3fcbc1953b2ccb88f", - "0x00000000000000000000000000000045e09e50b539ce6228369e4b4cb8530ce0", - "0x0000000000000000000000000000000000062cf2c7d023a38df32e6c8c04a8c1" + "0x000000000000000000000000000000b0d85375aa0d40d56afab87a4500a0ee93", + "0x00000000000000000000000000000000002ff36f19431aa225aa3f1788d0c736", + "0x0000000000000000000000000000008395fb5b5962fc53092baed85b90f142e4", + "0x0000000000000000000000000000000000236be094b70d84fe3007f69d527f24" ] - hash = "0x208d8b1ad2d688325416c8a23881e8b14753352851d7740b339ea2ebd455cdcc" + hash = "0x25f3ed562872c5e18abd2b9c6d87543b21886af47c7a714c99e78776bae18397" [inputs.previous_l1_to_l2] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml index 9e681460ac92..4041bc024fee 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml @@ -1,7 +1,7 @@ [inputs] new_archive_sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x300378810ae25edf6021ba94b4ba9ad6eafaf9caec8c6504ba8ef81f3240f780", + "0x21decddb0e57243b3ec2d7320d3979efb6efebd4352375c223cf4f8efd1dbef3", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", @@ -523,12 +523,12 @@ new_archive_sibling_path = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.last_archive] - root = "0x0edef98680cbea2855c4f0f152a0ecd69358e68b10da7b7e301f35ce709c13fa" + root = "0x27b365d73aa1b8ac1eb39c75262e2b87a238d041cc98fcb795f4c597c620ce64" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollup.public_inputs.constants.l1_to_l2_tree_snapshot] @@ -586,10 +586,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" ] state = [ - "0x08cdf544ec44d694936ed6a5aa580afb2a3b1a4b087ba80870d4d01c79cb5772", - "0x192972b72a1776fa9d30c1202807fca4f9272b156c9e1eafa5f93e94a13c439b", - "0x23ace986d5ee172559ce2153d8a166075599a4403288cbe1a150bda49415fae6", - "0x0f3ccb179877769f2d268206c1b45ab9af36d5e7e005de27ede90c1a29450039" + "0x13ec9d9b37f0599c5765a81513125e07305454198fecae73a69e7d41dfb27215", + "0x24fe963f8f4139d84f904228cfe1e10256e9106331e614b72ed86be8903e4259", + "0x114cba9fee3fa49ffd5f440aa162c6ce6e8410138a592e587337646bb8b04ca7", + "0x10325219e420881603ba4ea16613cf66fa1c43ff98bceb97acaaab599e3326b5" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -604,10 +604,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x1b111ef987a8412d74666407b504b312064231fbf5c26a46f410fa863d95c877", - "0x1be482b447910939727d105aa8f4722d4300002a9481483a5a47b5be0d458a69", - "0x0918650d25d3222c18bf60663bf62753764ad8b75fc3ce5e74c3fa9c9470b1b8", - "0x1eba072dced35bc1bb87f4b50410109a790c58dd87ad9eebd46f50a25112d9b4" + "0x02a5b53c7efb068bc743feca8874f269cfe88163e97fef0ae200aa662ada3895", + "0x17a9dc2d3bc5a2ba2f0435e36c8441f5a18e087f04a9812a1261c97a3988bed6", + "0x1848e27196daf1ad40d8564e8b84be69d789d47c42ba2035af49d5c522d4cd43", + "0x29c59fa7664efcf9d55dd4bfdecbc4a442e78f6a405b6b5846d6c0ba49f78ca7" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -615,131 +615,131 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollup.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollup.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000008580b9a8c85e4a3c1e7b1089bd79f3bc28", - "0x000000000000000000000000000000000022dc01e3ed0e1b10bdcff9d093431a", - "0x00000000000000000000000000000054f9950035e8ffae852707e9d1a9032e59", - "0x0000000000000000000000000000000000276c56cb94e0545b3bfd85919a8ce8", - "0x0000000000000000000000000000009352ff9d82645804416a2b338260fa235d", - "0x000000000000000000000000000000000010a253776d2bdcb7129acfa2e91ac5", - "0x00000000000000000000000000000095babbbc4a6d5a9b68707c3a8e1e9508e2", - "0x000000000000000000000000000000000030157ca77e90f7ee9155c1009b06a1", - "0x000000000000000000000000000000068047e82e283284235befaa9cc7a1838d", - "0x00000000000000000000000000000000000bcd70cc5042e81e440b1ea5ef3c3f", - "0x0000000000000000000000000000007702a95c1bf5e2923ca69f26cc2d7efe0f", - "0x00000000000000000000000000000000000adeb0e8b1074c68de2b2172f21c5e", - "0x000000000000000000000000000000520354133ccbbccfc69be0c01b92abdf0f", - "0x00000000000000000000000000000000002dea248e3c2fe054c698a861bf4c27", - "0x000000000000000000000000000000f93b6112b7de5c27298a81c68d502b7beb", - "0x00000000000000000000000000000000002be3a33fc9502b0cc8b9427fcfe50f", - "0x000000000000000000000000000000168f01ff83f4a014a90db19e5d882a0a0a", - "0x000000000000000000000000000000000008876edc3cc7e3825dc194e21cb011", - "0x0000000000000000000000000000006d1df389f06e514e1829af3744dc64294a", - "0x000000000000000000000000000000000022e86ef68622bd107e5080cc062a4f", - "0x000000000000000000000000000000d137fc89e86049cb1b141b67b3361b6298", - "0x00000000000000000000000000000000001d7ad7d0634dc08d7d9816b5b6814c", - "0x000000000000000000000000000000defd2454e2c3a75ec8e0730bd3640b9408", - "0x00000000000000000000000000000000000b189f6ee9395b1ca5771c361501d7", - "0x00000000000000000000000000000001fccf755f5b30a7d544b2f78ce075cb5d", - "0x000000000000000000000000000000000026f5423942948047e155a519b195e8", - "0x000000000000000000000000000000a9efc76daffb8dfe2a39570b2d5d046767", - "0x000000000000000000000000000000000026e7dd89fe96952a4603c2b5555538", - "0x00000000000000000000000000000008262b430328dcaab242dd8acc504e8ac9", - "0x000000000000000000000000000000000015f3ab1410f0e5dd3e00f03b9f563b", - "0x0000000000000000000000000000008fca5ff8ed9a5d41fe9b451f02502dd1c9", - "0x0000000000000000000000000000000000266aa6e4947434ef18adeba3700713", - "0x000000000000000000000000000000d93cecd04341f5da304f3c92f0670afc43", - "0x000000000000000000000000000000000020165b3fd2bfb72a4de3dc68f66eed", - "0x000000000000000000000000000000094a6d376eb3cc1ba94b4da00dea583eac", - "0x00000000000000000000000000000000001caf7742d251b04f3517f0f1e5a625", - "0x0000000000000000000000000000003be5647cd472ad0b06a48f632997e3eea2", - "0x000000000000000000000000000000000015fb4d9ecb8125b3243cee37698c48", - "0x0000000000000000000000000000000854a3ab5bcbca1e86d4949b1b7c5f4b0e", - "0x000000000000000000000000000000000015450314fbf315448dc3379dc82214", - "0x0000000000000000000000000000009c2c55d2ea5bdf5fc5e28f1a78b1d29625", - "0x000000000000000000000000000000000020b36a8406ec64352600587cf04194", - "0x000000000000000000000000000000f14d08d9dab6a54412d741166146188ae6", - "0x00000000000000000000000000000000001b5a34ccd7eaf5cd09ab920011552f", - "0x00000000000000000000000000000074b7827a59faf701f7f41df26e5476c40c", - "0x00000000000000000000000000000000002decbab1c87b933da1625951860793", - "0x000000000000000000000000000000751aab48a0e01094128242ea0aaab63ff7", - "0x00000000000000000000000000000000001a2a334289adf8d23d4d52caf4cfe6", - "0x000000000000000000000000000000f6a41261290460b25e1e7d7bf69b564ae6", - "0x00000000000000000000000000000000000296925feaed4585bb03319f126d96", - "0x00000000000000000000000000000055b70d653ebd7df04f720951e76a27369b", - "0x000000000000000000000000000000000019744937a687edc9f46fb8323a46d9", - "0x00000000000000000000000000000047978fda5b64d8fc4571f09da3e8ccc7de", - "0x0000000000000000000000000000000000139de6a387109f47ecbacc74e03742", - "0x0000000000000000000000000000007f5afdfcb7bcd85aa293676e18e899a03e", - "0x000000000000000000000000000000000006a2971c1c947f4cadb07ebc9bc980", - "0x0000000000000000000000000000006cdb69a57b7f7a25b99e18fc0f83c1bc70", - "0x000000000000000000000000000000000028f2a76a01dc3cc927cdba29383e9b", - "0x0000000000000000000000000000001bbc4d6033de44907975ce473bc0f4f148", - "0x00000000000000000000000000000000002642f26fc1850c4b9b7fc4cd860ab9", - "0x000000000000000000000000000000ac996074e35eb268f6ebbe99e9c7d26c47", - "0x00000000000000000000000000000000002262620617978a01f75646f1909969", - "0x000000000000000000000000000000e63aa32bcc098428f407b5e07d9cb26118", - "0x000000000000000000000000000000000022b294b6a7dc4c17319f9a91a1b443", - "0x000000000000000000000000000000649d9ce9147431632893f55d3c6bbc158e", - "0x000000000000000000000000000000000020698c9b0787f14aa66a57bc232ec1", - "0x000000000000000000000000000000b4fde29f9bde909609d70bf9862dd65cf1", - "0x000000000000000000000000000000000005fcac9b75cac50d87ca827678c070", - "0x00000000000000000000000000000071e27b0a0dd0e2180985072f4a949f0c1d", - "0x000000000000000000000000000000000025d2d1388eddcf016213f1cadc763f", - "0x000000000000000000000000000000b216bad715cdfa7c382d30d7a368cc1346", - "0x0000000000000000000000000000000000302dbbf78b13a6d71d1978b5607145", - "0x00000000000000000000000000000002ebdec49969d2ff9220240bbcb8730617", - "0x000000000000000000000000000000000027f41cad8540e47008c1da90340ef6", - "0x000000000000000000000000000000e8259148321315cc34166a206fe910c6cb", - "0x000000000000000000000000000000000013444efc30c7688d961f36de252af6", - "0x0000000000000000000000000000005b7c7ad432291e9dff1dfad51159e50dbf", - "0x0000000000000000000000000000000000205ec973a0d1c898c1def7852353b3", - "0x0000000000000000000000000000007940a7e88fe5ce47af688975c92be1b62a", - "0x000000000000000000000000000000000015bdab44fe41eec6ee62ed58f55ff5", - "0x0000000000000000000000000000003693b90aedcd664eede665df6f376cf526", - "0x0000000000000000000000000000000000207c38fd6851d1568fe18a83585f31", - "0x000000000000000000000000000000f1a8a60975b9b092aab1421166be08c2f5", - "0x000000000000000000000000000000000015450d2e8ea17db209302582b886f1", - "0x000000000000000000000000000000526e857040a344bd434bfdbf94d3a49196", - "0x00000000000000000000000000000000000d0112b922a852c4754ab3929d6d02", - "0x000000000000000000000000000000d88041fa28c8118a58ceacbcc8780844b5", - "0x00000000000000000000000000000000002584170ebef150b71c5e6aa93e2fbb", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a2c4fbcbebac01e208127093cbf44780d4", - "0x00000000000000000000000000000000001ca34545a074b1cb689aa0b343402d", - "0x000000000000000000000000000000a58c28598055d8818a6dbadd0018904386", - "0x0000000000000000000000000000000000152154cbc213630f5c7ec1ee37751b" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000f944590031f1d3b251c3dc90ea2821c71d", + "0x00000000000000000000000000000000000d31fd1a4942efade625e012c77df1", + "0x0000000000000000000000000000001e9acd89b92c18e3d89b881b26312bb12b", + "0x000000000000000000000000000000000000736f00a23cbea07da614d8b767e4", + "0x00000000000000000000000000000012167fb1f0d3b9afea7d534404e3b36b53", + "0x0000000000000000000000000000000000021e6d056d0d40c720927abd39c872", + "0x0000000000000000000000000000004ea3f0c21ee1056b3e2ad9c082242e5a2e", + "0x00000000000000000000000000000000000c574204fd079871ae599e192d72c8", + "0x0000000000000000000000000000002654c5b2b175f95fdb2ab405dcc4220545", + "0x00000000000000000000000000000000001fd13a35df71290c2354c6c5f610de", + "0x000000000000000000000000000000d5e3b3464d67c82f035b33016912264b04", + "0x000000000000000000000000000000000009fcdab45c12d2f313f95b94a1dcb8", + "0x000000000000000000000000000000768c5a9d8ca0081f67ff3171a7ffe3ba49", + "0x00000000000000000000000000000000001cd676b8d32bb0bb898d83a9f49a2b", + "0x00000000000000000000000000000028650bc3473de217fbfec1e9fb10e4e999", + "0x0000000000000000000000000000000000260c000ea0ebc3db3ba672328007a5", + "0x000000000000000000000000000000f1948fbf68599bf0628f118156de61f57f", + "0x00000000000000000000000000000000000033e796d200425f6a499de18dbfeb", + "0x00000000000000000000000000000016a35cf8fc5f017037adf860723e6346e5", + "0x0000000000000000000000000000000000088cf6d72197800bb1300677f734a7", + "0x00000000000000000000000000000047169c153b6cc24bbac1e4126410779ccb", + "0x000000000000000000000000000000000022b70bfb92e8c7944ae65a49b7effa", + "0x000000000000000000000000000000425c661c37104ad33c2054f3cfde9954d0", + "0x000000000000000000000000000000000000c36b8ecc5963bef022dea4dfadcc", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", + "0x000000000000000000000000000000862e0c485b99696417d296ecc2b2bac316", + "0x00000000000000000000000000000000000ae46fcce211297d2d7fcab27fc041", + "0x000000000000000000000000000000551700c158e12cb40d8ea4ef2563b6fb43", + "0x00000000000000000000000000000000000b515d88939b250a4a4758e4e2ea53", + "0x000000000000000000000000000000f4bae0ad0baeb9d42c7fe2ae3d18c98fad", + "0x00000000000000000000000000000000002a20d66bd435a17fdf1eaf345d5933", + "0x000000000000000000000000000000ed8a8ba528c7088b1ae4730572e1ec32c8", + "0x000000000000000000000000000000000009506de430d6b9f9863e6f10cd35fb", + "0x000000000000000000000000000000682b627744ce0319f4d9191675057282fb", + "0x000000000000000000000000000000000017de059961f8c12752abd299396f86", + "0x000000000000000000000000000000b975958ec262178729e94350c0e7543fb0", + "0x0000000000000000000000000000000000220ce50e394560e53f025e094d17aa", + "0x0000000000000000000000000000001fca3a68a28d438e85e9dc955856752779", + "0x000000000000000000000000000000000028f8f3400bb3b9d19b02ec709e2ee4", + "0x0000000000000000000000000000004e35d073460b0634ebe216d49a3dca9b36", + "0x00000000000000000000000000000000000cb0f5827b08075c405353f10ba632", + "0x0000000000000000000000000000001ece860550ce14fae74eda0123ded56a74", + "0x00000000000000000000000000000000000a34b258bd3daaf8f9edd201c25ed3", + "0x0000000000000000000000000000008cb28ae85d58a75302229585a9ad114c2b", + "0x000000000000000000000000000000000014aac1da344ad32659c3036510fcc1", + "0x000000000000000000000000000000822b45036d5c2befa8a20df910513570c4", + "0x000000000000000000000000000000000011244b388e709fbcb7f54658cfac43", + "0x000000000000000000000000000000389de9951eb8fad7e25e4ad0a9229d2275", + "0x0000000000000000000000000000000000136e6eb0ee251f9b12336cb7bb46ee", + "0x00000000000000000000000000000088f21d9f6c7c54ce4e9a4c103a91b54a58", + "0x0000000000000000000000000000000000187f2beab9a05ca29d2137ee7cbc19", + "0x0000000000000000000000000000009c703a5eb43dcef0686e08fa57ef452f68", + "0x000000000000000000000000000000000012caebb183f1490d3e4f2a2c583ab6", + "0x0000000000000000000000000000009dab4a0aa8d4954a8e1761db3da148a746", + "0x0000000000000000000000000000000000230a08da3b62fd6479b4230760b686", + "0x00000000000000000000000000000081a00a1e38bbd5212603f18ef982a5189d", + "0x000000000000000000000000000000000021ae0f9df38f1e70fa3c26867f4ee8", + "0x0000000000000000000000000000001a722dbd34f841b4823cd055149fce642f", + "0x000000000000000000000000000000000002df2693a9b134670cfe72bf29b363", + "0x00000000000000000000000000000007c906c328630b844b0797e34cedccd1ec", + "0x00000000000000000000000000000000002ab2ae39dd9c0259f7dfb1dda47e81", + "0x000000000000000000000000000000ac6642a4923aa2df07a00a9d3e462b0ed1", + "0x000000000000000000000000000000000015afb7af6c0fc23a24457aa887df9c", + "0x0000000000000000000000000000004d916ec23ef29c0b6134f208e3535671d4", + "0x00000000000000000000000000000000000d37c6c25852903d79475133d414e8", + "0x00000000000000000000000000000029ad212431ba1972de7ee0ba9f12113be3", + "0x000000000000000000000000000000000005c2393db23155844d4f71bead84d0", + "0x000000000000000000000000000000c69074efa82a4910eaf8ab8689d7aafcad", + "0x000000000000000000000000000000000029f3d77437006a0eacf1a149c4b8a0", + "0x00000000000000000000000000000030926853da69d4016eca2f1f0df5e5316f", + "0x000000000000000000000000000000000014841d3291aecd45ea0e05657dbed2", + "0x00000000000000000000000000000052fdb060fe666a3f686088f1f6996a1cf9", + "0x00000000000000000000000000000000002be878eb09939603b391aa9ee0393a", + "0x000000000000000000000000000000d99de3b49476e64c0138037838cfc63803", + "0x0000000000000000000000000000000000260874b43f32c373783efe7ef200a2", + "0x0000000000000000000000000000004951edbb25e9c6b65d446e3418b2b3f16e", + "0x00000000000000000000000000000000002300fac13ab48d40a91114d1ff9627", + "0x00000000000000000000000000000090b8d216da73861ee276dddb17428d8c09", + "0x000000000000000000000000000000000028f906106984e5fa78812869cc1aee", + "0x000000000000000000000000000000ce2aff6eda49d5b8be6ee42104d2aa21e0", + "0x000000000000000000000000000000000002833f671993d2b772b5dec0e12056", + "0x0000000000000000000000000000008be4e7cfb1fdf317a33b7bc3530625e6b8", + "0x000000000000000000000000000000000023404bed8e224a350755410e5c96b2", + "0x000000000000000000000000000000cd9a812fad3fe3a89983e416b70529445b", + "0x00000000000000000000000000000000000b66296ff191a2cf6dbe6ca03dcd0c", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003e895e3756deb16393c59a6a9d3669ce0f", + "0x0000000000000000000000000000000000262d7f27b9058ca9bd2e0620f9a3d3", + "0x000000000000000000000000000000b98c4ce00d755cb57daf4bc1b860536fc3", + "0x0000000000000000000000000000000000017137ecc6753555f49859a34eeb62" ] - hash = "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6" + hash = "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml index 4536a33189ef..110c6d4f6505 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml @@ -523,8 +523,8 @@ new_archive_sibling_path = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] @@ -604,10 +604,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x095ff6c475ee1af84257c77b73b727e6ebf0cc7015e0318ea5ceb14044e637a8", - "0x28810b36811d26c3700f0c7867fc191986df3ef57ea3a195b396ae8e1516b1a7", - "0x0d0d075374c48ade348ced65280060db0bfe6c16752688a5d65a07afc55cf16c", - "0x0b29f6eee3031f85d7f5ce02982c80e8fc06b552319a441c5b0fc3521d9c801c" + "0x019c8b37514a1a54433fb4ee411ccaf6da8c99234b4e5d11cc5f6b95c3989bb5", + "0x026875d420939d38c5495ee684f0a31efd5cab908193ae929d1c426d68bb9409", + "0x1a8c7e8add3b6e5ee547b84164a1d59756426ff82c71128c0627a7c01c830220", + "0x081d1fadf8d9a49f296a172486009b0c5f64d52de31142cfc01bc2b08387210a" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -615,134 +615,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" sibling_path = [ - "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000015", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x000000000000000000000000000000cd83c7ffbb8a401156e168f37116ffb187", - "0x000000000000000000000000000000000004c9803d25f3aa3d87971ec69e9a09", - "0x0000000000000000000000000000002b8e3b59ff58ee5825f04add8396938ab7", - "0x00000000000000000000000000000000000ca92b3e71dca284819687b09058a5", - "0x000000000000000000000000000000f13a4c94014267f0fb20df8d4745321157", - "0x0000000000000000000000000000000000228ccf8e5e66edf617fe9cdffaa9f3", - "0x0000000000000000000000000000008bedbc082dc889634e668f035d885cb110", - "0x000000000000000000000000000000000000d1506f1dee82696f1132266cd876", - "0x000000000000000000000000000000eed1511734ae738d49eddd8c477030de23", - "0x0000000000000000000000000000000000185f94db8b977ecb674f578da3d454", - "0x00000000000000000000000000000052efb8157e56280d78c004328b104e22ee", - "0x00000000000000000000000000000000001e61e2eda64fdcef0aa3f7086d25ae", - "0x000000000000000000000000000000a7ba8e154b7cb9b052f03b722d1fada3ab", - "0x00000000000000000000000000000000001b74f30f877fcb688c4d7942a512ea", - "0x000000000000000000000000000000a64cc9925a82d55b5c8ed69024e76a1002", - "0x0000000000000000000000000000000000051a307beab7624f895eac2d7b107e", - "0x000000000000000000000000000000b71a10e4cb199c53f8ab26f4b5750e6ff1", - "0x000000000000000000000000000000000026ae3964368b4d1a78b494281305a6", - "0x00000000000000000000000000000070e6d26eeb2ae247b554ade309575fc966", - "0x00000000000000000000000000000000001b72f55e4403556e86319b26bac156", - "0x0000000000000000000000000000008d27b4ec306af3043276b465679e8bd42f", - "0x0000000000000000000000000000000000235c5f58ac9d6dca390a516970b4b2", - "0x000000000000000000000000000000f9cc90e3b5b8897ba1b69b74148d74cfc5", - "0x00000000000000000000000000000000002b2e95de9addf042a25f2539a53d1e", - "0x0000000000000000000000000000004288fb745aa3b78da694bc2f3c28178b53", - "0x0000000000000000000000000000000000029292ff399aa7b20eb1f743696c46", - "0x0000000000000000000000000000003582186b8e684671a476f80b8d0e114d5d", - "0x00000000000000000000000000000000001b3109c18b36e49b5ef30578b4bc60", - "0x00000000000000000000000000000083d976f2c2c90d81da35771e3f1822b38f", - "0x000000000000000000000000000000000004e8a3defd811d412647bd93ce9086", - "0x000000000000000000000000000000c2c94de698986ec3786d6f5b13b0a476b4", - "0x000000000000000000000000000000000004d6d12b482b85c51eb055c92d5560", - "0x000000000000000000000000000000d9fb425aa4b440ae16c1b17731a6529ec7", - "0x0000000000000000000000000000000000009388e6b80710c3afdbff80db6e84", - "0x0000000000000000000000000000002775ccd14fc93fee7d75f048054b1cbcd7", - "0x000000000000000000000000000000000000142a9e45b6b4b0b28a54737e0901", - "0x000000000000000000000000000000d88146894fb0088baf74ad347a6fa92dde", - "0x0000000000000000000000000000000000019df6a3b49d4de18dbe387aac8372", - "0x0000000000000000000000000000001775a3327c99e192a79ee17db4e2c514e2", - "0x0000000000000000000000000000000000062b76de133a235165e878faa5619f", - "0x000000000000000000000000000000c8383897bcdda98939560cf15dfefd9c0b", - "0x00000000000000000000000000000000001b84d621bc2ee73d81ad2bd595f2a8", - "0x00000000000000000000000000000093ec3803f444457ef388287856eaccad0b", - "0x0000000000000000000000000000000000103b731d15612e1b8ac234c501b92d", - "0x000000000000000000000000000000d83455ed5536ab998435ffd929486967f5", - "0x00000000000000000000000000000000000870e19f1fc3e0921179828f3dd48b", - "0x0000000000000000000000000000008a0b19fe136076435faa22c077837f88bb", - "0x00000000000000000000000000000000000039184f52378de1cbba4a757335f4", - "0x00000000000000000000000000000019bba41ff000f1c9a2800dff26a0ba56ce", - "0x000000000000000000000000000000000012a445925f8b47a193556076199e49", - "0x0000000000000000000000000000005ba24d7fb287fc15134264f129609a2bd8", - "0x000000000000000000000000000000000007076816a94acb232f9ce3c1ae86f4", - "0x000000000000000000000000000000f85d9c960786d5542ee7fb2b2413a6d377", - "0x00000000000000000000000000000000001501ca79d9e60002f03f2b2b7b650a", - "0x000000000000000000000000000000af9fa7ef32ca1cb5f5abfbcc106009b7d9", - "0x00000000000000000000000000000000000a3631ac245c1bcbc41500fbe90c39", - "0x000000000000000000000000000000c20fa79072822cd75c97c5b81e20ca8378", - "0x00000000000000000000000000000000001c6e3d83b0c29f88cf55cb349764c7", - "0x00000000000000000000000000000094269c5b70a400d545ff6927eb4ff34d94", - "0x0000000000000000000000000000000000179a075c118abe5e19ec509b92c329", - "0x000000000000000000000000000000f7bf1c1f7d4dd3e707966c05f1d2cf0efa", - "0x00000000000000000000000000000000002dfb152b58a74c48565f0dba30108d", - "0x000000000000000000000000000000cc8f8c54c07a2909a5e4dd79a7fee3e9f9", - "0x0000000000000000000000000000000000111875cd09b6d83b8c85d81902de1d", - "0x00000000000000000000000000000067879f62b49d4ec18a05fc15c67e61c1f0", - "0x000000000000000000000000000000000007d113480afafd29d13ea18ad95bc2", - "0x000000000000000000000000000000ff6cd4cc6b0f04ecadac8b0370831197bc", - "0x00000000000000000000000000000000002cf71926c179ee1544ddcdef962d3b", - "0x00000000000000000000000000000011dac3e4f0a624a359d0577b6ad0c6a9ea", - "0x0000000000000000000000000000000000021c6d473c1f38d00361a916aa5c57", - "0x00000000000000000000000000000003b3480a0434d1d1f33e1c9f1a7d0cb25d", - "0x00000000000000000000000000000000002c5c8e4157e553f3188d193d1b9569", - "0x00000000000000000000000000000019b738d9ea76f9cb03a4bcdb7533944a36", - "0x00000000000000000000000000000000001c8f2968fe3967d675bdc3dd95ae45", - "0x00000000000000000000000000000081ead652a5562e48d2271eb63e0b53f517", - "0x00000000000000000000000000000000000252e44fb0d2cd6daafe79b8a7ce1f", - "0x0000000000000000000000000000008fa4d0b6af4adecb0c882b3550bf708e3a", - "0x0000000000000000000000000000000000026f63ebffc62201b820a594862e6c", - "0x000000000000000000000000000000a9e22eecb21492cfdd0820eddc2392ecad", - "0x0000000000000000000000000000000000100eff1372735728c7d857bbe751cd", - "0x00000000000000000000000000000098c24dca66ff39798ffef0819d63447c2b", - "0x0000000000000000000000000000000000117ee5d863045ed0f1f8a3268a44cd", - "0x000000000000000000000000000000c42efe335044bad810e4db5ca3a9a90b33", - "0x00000000000000000000000000000000001eea6c61e4ba0267d212d7d6a01fde", - "0x000000000000000000000000000000278bf3b77e15b280c8d91851ef86e22130", - "0x000000000000000000000000000000000007d1cb6e175db110b93183dc69610a", - "0x000000000000000000000000000000d7d26293651d377457c5f70fc897df4d02", - "0x00000000000000000000000000000000000ee609268fa9ca425545724809dec0", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000059f7a0ea97f63ad48cd0ace39569e0e2cf", - "0x0000000000000000000000000000000000104032af6f298e3ac85696d4973026", - "0x000000000000000000000000000000a4c46e1adb8515fa5ddcd4296d689f8e51", - "0x0000000000000000000000000000000000172a0575991ea836ef0e3040f33e6e" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x0000000000000000000000000000004a89413217aa26a02d1673611c718e3f40", + "0x00000000000000000000000000000000002a74011d7b1576ee63e514f36d2ca7", + "0x000000000000000000000000000000fc6ccc829e509138e5ecaf67c0a21ae3ea", + "0x000000000000000000000000000000000025ff9c29534f6fc12896ca920730a7", + "0x0000000000000000000000000000002709461b8a6badd93121132b357506ad42", + "0x000000000000000000000000000000000018979b97518955d80ea51e8795dd65", + "0x0000000000000000000000000000002086ceef11774f164dc1826039e29a08b2", + "0x000000000000000000000000000000000002706e4d78635695a83b8ee7fe2852", + "0x000000000000000000000000000000f48fa484144b68aabb48f3c67447f619c4", + "0x00000000000000000000000000000000002c00e7b78d2dbb440843c2b8bb9d5c", + "0x000000000000000000000000000000de8ddbcaefce22d2dd0f1a9cf8505ad74c", + "0x00000000000000000000000000000000001d75f1ae876350f117464d47581ea3", + "0x0000000000000000000000000000004bbb761087bee09db612cd1683c9991da0", + "0x00000000000000000000000000000000000a1f0b2bc8f3940a7767ca70f869dc", + "0x000000000000000000000000000000e4d6e66fe44086d4e95043082d7660511d", + "0x00000000000000000000000000000000002857e0d300379ee0a5657b0628ac68", + "0x000000000000000000000000000000377899dd24559db542bb2da421c7aa5b2e", + "0x00000000000000000000000000000000000f954842d0809f870031c014244349", + "0x0000000000000000000000000000004500fe7e27caadb3185ec74d1d8c9c23c6", + "0x000000000000000000000000000000000011e0156211bae38b72e70774aad837", + "0x000000000000000000000000000000d64abf570d80329272f3ac73e763a56074", + "0x00000000000000000000000000000000002221eb3028e13e02824a2cdbebb343", + "0x000000000000000000000000000000e6ac6ff13cde0a60ccaefe09ee9f6e4951", + "0x000000000000000000000000000000000000042f684a98fd028e51ed457fb6d2", + "0x000000000000000000000000000000b1795305b34f2f47e00fefef8e3ff03117", + "0x0000000000000000000000000000000000219d203b492d7debf5d8e7df9d2059", + "0x000000000000000000000000000000bfa96395c8478bacb512c36590c5b7b901", + "0x00000000000000000000000000000000001088537efb9ccd4bbaf4c519fb15ef", + "0x000000000000000000000000000000a63a7e103f77ddd62d4a2aca5a18595bc2", + "0x00000000000000000000000000000000000ffe27c096d9d37613d28524ee24bb", + "0x0000000000000000000000000000008b2aa8f75dabd90ee7f9d45da83109530f", + "0x000000000000000000000000000000000029197cfde9aa521758643b088ca6d9", + "0x0000000000000000000000000000000c60bc3c5493f56066aeaf379eff701730", + "0x0000000000000000000000000000000000045592a6815997cad253c4d4360857", + "0x000000000000000000000000000000fe9bb200d66804b00fe6af2cbd06b90be1", + "0x00000000000000000000000000000000002dfca6770dcd191d2cdcd25959b927", + "0x000000000000000000000000000000d638a6a9b28e4cda3be3200ca416f090a6", + "0x00000000000000000000000000000000002912073cf985c4e403f2e81c78f0c4", + "0x00000000000000000000000000000017b813b81461e0af074adb3ee3a06a2dbd", + "0x0000000000000000000000000000000000193d82b9851cb7b79be69631dbed9d", + "0x000000000000000000000000000000585192fdba2a34dfe3cf05bc74f14aa04b", + "0x000000000000000000000000000000000019c364971252aebd3f848754f68cc0", + "0x000000000000000000000000000000d6c225cba31833473b544e439b76525948", + "0x0000000000000000000000000000000000172a802a4ccf4f87a056c01096e603", + "0x0000000000000000000000000000008a86fac91395708a05f2bf567c42624355", + "0x00000000000000000000000000000000001c5122e5aa5acc0563a65f2fadb548", + "0x000000000000000000000000000000c7ba316af264f3d0c9ffdfa37abe8449af", + "0x00000000000000000000000000000000001e4e1e04112cc99e43eaa819700377", + "0x000000000000000000000000000000171f9151f102c97ebaf8155f92f2818ad4", + "0x00000000000000000000000000000000002b9c517d5a5ca458d9a42ae50a21e3", + "0x000000000000000000000000000000a9ab641f6b11aa7b449f9d162ee4b41c4a", + "0x0000000000000000000000000000000000083f917d6f05453ad4449a07cb2db9", + "0x0000000000000000000000000000000fd8ba5a6cbe569669fa504b146a11e1c2", + "0x00000000000000000000000000000000002d96c1b0fb6b92bbdf9028c918ab12", + "0x00000000000000000000000000000001b66bc49279fdcee016dc50f445385e2b", + "0x00000000000000000000000000000000002b27073221dc103e65d22ef60f7565", + "0x000000000000000000000000000000d9f07543a10843697cb26aeb1e0fa41864", + "0x00000000000000000000000000000000001af76ea4d294fd82e82426b2247091", + "0x000000000000000000000000000000c95c82ccbed1535404379be4d37b661a7b", + "0x000000000000000000000000000000000004c2eb0e09fa417808cf776e09d9bd", + "0x000000000000000000000000000000f7ecd4caac36af30f57c88f8aa8758994f", + "0x000000000000000000000000000000000007a8712e54abef6a5800fb6c9f797d", + "0x00000000000000000000000000000032261b0e19195842c9e13efbf6677d3e7b", + "0x00000000000000000000000000000000001a77dd002f088f48be1c495240a4f4", + "0x0000000000000000000000000000007a9784569003accf3b18631652c41efd9c", + "0x00000000000000000000000000000000001a3bc8c8561c039ee8dd33dcf97bfb", + "0x0000000000000000000000000000008a638165173e41c0baef2a580cca67198a", + "0x00000000000000000000000000000000000ecceac0ea7acc23801d0b99315ed8", + "0x0000000000000000000000000000009c864dd9c99b9871c3cfb939d4197834ef", + "0x0000000000000000000000000000000000131aac5ec5b228a425c6a1d954f41a", + "0x00000000000000000000000000000011cae94a9b789855cde56a72734268be61", + "0x000000000000000000000000000000000015c8120597f6b5302046b58b445198", + "0x00000000000000000000000000000058f4333384b72ecdfc0a66a3b34a9870b9", + "0x000000000000000000000000000000000013db543b79ebed9f63c95904240a6e", + "0x000000000000000000000000000000c71b7fdef4cdc241adcddb23c473ad222c", + "0x00000000000000000000000000000000001823079555cf386247dbe609c2fd06", + "0x000000000000000000000000000000e46930d371eafddab0c6053b1ae159c463", + "0x00000000000000000000000000000000000c0bc40e324750ba1c752c09daed25", + "0x000000000000000000000000000000137e3a04a63f70a2f6971ca99b7844dc67", + "0x000000000000000000000000000000000014c957a738079d071b3d181b99c0e7", + "0x000000000000000000000000000000815544c36c3b22a89d3a78b3553bec6f68", + "0x000000000000000000000000000000000009c2204fe3bd67f8872d6e75792d19", + "0x000000000000000000000000000000d3e085f947f7511f7d7f87a504e99f5546", + "0x00000000000000000000000000000000001d1e1a783d6fde70d844bc2c83c3ae", + "0x000000000000000000000000000000109b3d637fe0d1d5013b3710fc1cddf89f", + "0x000000000000000000000000000000000006101682027f56bffe9486a672801a", + "0x000000000000000000000000000000797993b995dba1e0e98de672a76a776c3f", + "0x00000000000000000000000000000000002765c3ceee9f9d0f11bd159621fa1e", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003ac18237da8d96caddaa1c49a178b8b47d", + "0x0000000000000000000000000000000000174dfd5c124039dc6e2a38f0f99775", + "0x0000000000000000000000000000005790969811e28ed4e16d2729036649f344", + "0x00000000000000000000000000000000000f9c6e462a5b03759c42538b9b7c36" ] - hash = "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56" + hash = "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa" [[inputs.previous_rollups]] proof = [ @@ -1235,8 +1235,8 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] @@ -1298,10 +1298,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x095ff6c475ee1af84257c77b73b727e6ebf0cc7015e0318ea5ceb14044e637a8", - "0x28810b36811d26c3700f0c7867fc191986df3ef57ea3a195b396ae8e1516b1a7", - "0x0d0d075374c48ade348ced65280060db0bfe6c16752688a5d65a07afc55cf16c", - "0x0b29f6eee3031f85d7f5ce02982c80e8fc06b552319a441c5b0fc3521d9c801c" + "0x019c8b37514a1a54433fb4ee411ccaf6da8c99234b4e5d11cc5f6b95c3989bb5", + "0x026875d420939d38c5495ee684f0a31efd5cab908193ae929d1c426d68bb9409", + "0x1a8c7e8add3b6e5ee547b84164a1d59756426ff82c71128c0627a7c01c830220", + "0x081d1fadf8d9a49f296a172486009b0c5f64d52de31142cfc01bc2b08387210a" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1316,10 +1316,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7f9d34d" ] state = [ - "0x23a9bf42f5fb21102f92950e5a129127b977ad0e0d8cc6f021b0fc620b733c63", - "0x04c04f44462b3c2c334fe3f7466d2202283eb1f9c7e8b4ee679f2942ef98b57a", - "0x1a1e433d1ede575233704d82d0e09b65957a4d70d9e9184fa3aee3879ef746f1", - "0x06f9428dc4495436f76a28564601d6e45f10a9db4334941163eeea845fdab3a8" + "0x05153cbf60a272f44025c5df22636b8efe554dad1522a47a40dd5b3441326171", + "0x23fd331bfec83c48528be67bfbea84585a5f6d5b5528c5f030c222fc26331f3f", + "0x04c2cf5ad5cc66f41b327d1a4cd4bb4bc6006cc48ccda31a9bb943c40cfe4137", + "0x05df9fe44f2dd2bc21e2883077c78aed05e35c3b27b4acaf603aa29e7e17ea82" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false @@ -1327,131 +1327,131 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000008580b9a8c85e4a3c1e7b1089bd79f3bc28", - "0x000000000000000000000000000000000022dc01e3ed0e1b10bdcff9d093431a", - "0x00000000000000000000000000000054f9950035e8ffae852707e9d1a9032e59", - "0x0000000000000000000000000000000000276c56cb94e0545b3bfd85919a8ce8", - "0x0000000000000000000000000000009352ff9d82645804416a2b338260fa235d", - "0x000000000000000000000000000000000010a253776d2bdcb7129acfa2e91ac5", - "0x00000000000000000000000000000095babbbc4a6d5a9b68707c3a8e1e9508e2", - "0x000000000000000000000000000000000030157ca77e90f7ee9155c1009b06a1", - "0x000000000000000000000000000000068047e82e283284235befaa9cc7a1838d", - "0x00000000000000000000000000000000000bcd70cc5042e81e440b1ea5ef3c3f", - "0x0000000000000000000000000000007702a95c1bf5e2923ca69f26cc2d7efe0f", - "0x00000000000000000000000000000000000adeb0e8b1074c68de2b2172f21c5e", - "0x000000000000000000000000000000520354133ccbbccfc69be0c01b92abdf0f", - "0x00000000000000000000000000000000002dea248e3c2fe054c698a861bf4c27", - "0x000000000000000000000000000000f93b6112b7de5c27298a81c68d502b7beb", - "0x00000000000000000000000000000000002be3a33fc9502b0cc8b9427fcfe50f", - "0x000000000000000000000000000000168f01ff83f4a014a90db19e5d882a0a0a", - "0x000000000000000000000000000000000008876edc3cc7e3825dc194e21cb011", - "0x0000000000000000000000000000006d1df389f06e514e1829af3744dc64294a", - "0x000000000000000000000000000000000022e86ef68622bd107e5080cc062a4f", - "0x000000000000000000000000000000d137fc89e86049cb1b141b67b3361b6298", - "0x00000000000000000000000000000000001d7ad7d0634dc08d7d9816b5b6814c", - "0x000000000000000000000000000000defd2454e2c3a75ec8e0730bd3640b9408", - "0x00000000000000000000000000000000000b189f6ee9395b1ca5771c361501d7", - "0x00000000000000000000000000000001fccf755f5b30a7d544b2f78ce075cb5d", - "0x000000000000000000000000000000000026f5423942948047e155a519b195e8", - "0x000000000000000000000000000000a9efc76daffb8dfe2a39570b2d5d046767", - "0x000000000000000000000000000000000026e7dd89fe96952a4603c2b5555538", - "0x00000000000000000000000000000008262b430328dcaab242dd8acc504e8ac9", - "0x000000000000000000000000000000000015f3ab1410f0e5dd3e00f03b9f563b", - "0x0000000000000000000000000000008fca5ff8ed9a5d41fe9b451f02502dd1c9", - "0x0000000000000000000000000000000000266aa6e4947434ef18adeba3700713", - "0x000000000000000000000000000000d93cecd04341f5da304f3c92f0670afc43", - "0x000000000000000000000000000000000020165b3fd2bfb72a4de3dc68f66eed", - "0x000000000000000000000000000000094a6d376eb3cc1ba94b4da00dea583eac", - "0x00000000000000000000000000000000001caf7742d251b04f3517f0f1e5a625", - "0x0000000000000000000000000000003be5647cd472ad0b06a48f632997e3eea2", - "0x000000000000000000000000000000000015fb4d9ecb8125b3243cee37698c48", - "0x0000000000000000000000000000000854a3ab5bcbca1e86d4949b1b7c5f4b0e", - "0x000000000000000000000000000000000015450314fbf315448dc3379dc82214", - "0x0000000000000000000000000000009c2c55d2ea5bdf5fc5e28f1a78b1d29625", - "0x000000000000000000000000000000000020b36a8406ec64352600587cf04194", - "0x000000000000000000000000000000f14d08d9dab6a54412d741166146188ae6", - "0x00000000000000000000000000000000001b5a34ccd7eaf5cd09ab920011552f", - "0x00000000000000000000000000000074b7827a59faf701f7f41df26e5476c40c", - "0x00000000000000000000000000000000002decbab1c87b933da1625951860793", - "0x000000000000000000000000000000751aab48a0e01094128242ea0aaab63ff7", - "0x00000000000000000000000000000000001a2a334289adf8d23d4d52caf4cfe6", - "0x000000000000000000000000000000f6a41261290460b25e1e7d7bf69b564ae6", - "0x00000000000000000000000000000000000296925feaed4585bb03319f126d96", - "0x00000000000000000000000000000055b70d653ebd7df04f720951e76a27369b", - "0x000000000000000000000000000000000019744937a687edc9f46fb8323a46d9", - "0x00000000000000000000000000000047978fda5b64d8fc4571f09da3e8ccc7de", - "0x0000000000000000000000000000000000139de6a387109f47ecbacc74e03742", - "0x0000000000000000000000000000007f5afdfcb7bcd85aa293676e18e899a03e", - "0x000000000000000000000000000000000006a2971c1c947f4cadb07ebc9bc980", - "0x0000000000000000000000000000006cdb69a57b7f7a25b99e18fc0f83c1bc70", - "0x000000000000000000000000000000000028f2a76a01dc3cc927cdba29383e9b", - "0x0000000000000000000000000000001bbc4d6033de44907975ce473bc0f4f148", - "0x00000000000000000000000000000000002642f26fc1850c4b9b7fc4cd860ab9", - "0x000000000000000000000000000000ac996074e35eb268f6ebbe99e9c7d26c47", - "0x00000000000000000000000000000000002262620617978a01f75646f1909969", - "0x000000000000000000000000000000e63aa32bcc098428f407b5e07d9cb26118", - "0x000000000000000000000000000000000022b294b6a7dc4c17319f9a91a1b443", - "0x000000000000000000000000000000649d9ce9147431632893f55d3c6bbc158e", - "0x000000000000000000000000000000000020698c9b0787f14aa66a57bc232ec1", - "0x000000000000000000000000000000b4fde29f9bde909609d70bf9862dd65cf1", - "0x000000000000000000000000000000000005fcac9b75cac50d87ca827678c070", - "0x00000000000000000000000000000071e27b0a0dd0e2180985072f4a949f0c1d", - "0x000000000000000000000000000000000025d2d1388eddcf016213f1cadc763f", - "0x000000000000000000000000000000b216bad715cdfa7c382d30d7a368cc1346", - "0x0000000000000000000000000000000000302dbbf78b13a6d71d1978b5607145", - "0x00000000000000000000000000000002ebdec49969d2ff9220240bbcb8730617", - "0x000000000000000000000000000000000027f41cad8540e47008c1da90340ef6", - "0x000000000000000000000000000000e8259148321315cc34166a206fe910c6cb", - "0x000000000000000000000000000000000013444efc30c7688d961f36de252af6", - "0x0000000000000000000000000000005b7c7ad432291e9dff1dfad51159e50dbf", - "0x0000000000000000000000000000000000205ec973a0d1c898c1def7852353b3", - "0x0000000000000000000000000000007940a7e88fe5ce47af688975c92be1b62a", - "0x000000000000000000000000000000000015bdab44fe41eec6ee62ed58f55ff5", - "0x0000000000000000000000000000003693b90aedcd664eede665df6f376cf526", - "0x0000000000000000000000000000000000207c38fd6851d1568fe18a83585f31", - "0x000000000000000000000000000000f1a8a60975b9b092aab1421166be08c2f5", - "0x000000000000000000000000000000000015450d2e8ea17db209302582b886f1", - "0x000000000000000000000000000000526e857040a344bd434bfdbf94d3a49196", - "0x00000000000000000000000000000000000d0112b922a852c4754ab3929d6d02", - "0x000000000000000000000000000000d88041fa28c8118a58ceacbcc8780844b5", - "0x00000000000000000000000000000000002584170ebef150b71c5e6aa93e2fbb", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a2c4fbcbebac01e208127093cbf44780d4", - "0x00000000000000000000000000000000001ca34545a074b1cb689aa0b343402d", - "0x000000000000000000000000000000a58c28598055d8818a6dbadd0018904386", - "0x0000000000000000000000000000000000152154cbc213630f5c7ec1ee37751b" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000f944590031f1d3b251c3dc90ea2821c71d", + "0x00000000000000000000000000000000000d31fd1a4942efade625e012c77df1", + "0x0000000000000000000000000000001e9acd89b92c18e3d89b881b26312bb12b", + "0x000000000000000000000000000000000000736f00a23cbea07da614d8b767e4", + "0x00000000000000000000000000000012167fb1f0d3b9afea7d534404e3b36b53", + "0x0000000000000000000000000000000000021e6d056d0d40c720927abd39c872", + "0x0000000000000000000000000000004ea3f0c21ee1056b3e2ad9c082242e5a2e", + "0x00000000000000000000000000000000000c574204fd079871ae599e192d72c8", + "0x0000000000000000000000000000002654c5b2b175f95fdb2ab405dcc4220545", + "0x00000000000000000000000000000000001fd13a35df71290c2354c6c5f610de", + "0x000000000000000000000000000000d5e3b3464d67c82f035b33016912264b04", + "0x000000000000000000000000000000000009fcdab45c12d2f313f95b94a1dcb8", + "0x000000000000000000000000000000768c5a9d8ca0081f67ff3171a7ffe3ba49", + "0x00000000000000000000000000000000001cd676b8d32bb0bb898d83a9f49a2b", + "0x00000000000000000000000000000028650bc3473de217fbfec1e9fb10e4e999", + "0x0000000000000000000000000000000000260c000ea0ebc3db3ba672328007a5", + "0x000000000000000000000000000000f1948fbf68599bf0628f118156de61f57f", + "0x00000000000000000000000000000000000033e796d200425f6a499de18dbfeb", + "0x00000000000000000000000000000016a35cf8fc5f017037adf860723e6346e5", + "0x0000000000000000000000000000000000088cf6d72197800bb1300677f734a7", + "0x00000000000000000000000000000047169c153b6cc24bbac1e4126410779ccb", + "0x000000000000000000000000000000000022b70bfb92e8c7944ae65a49b7effa", + "0x000000000000000000000000000000425c661c37104ad33c2054f3cfde9954d0", + "0x000000000000000000000000000000000000c36b8ecc5963bef022dea4dfadcc", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", + "0x000000000000000000000000000000862e0c485b99696417d296ecc2b2bac316", + "0x00000000000000000000000000000000000ae46fcce211297d2d7fcab27fc041", + "0x000000000000000000000000000000551700c158e12cb40d8ea4ef2563b6fb43", + "0x00000000000000000000000000000000000b515d88939b250a4a4758e4e2ea53", + "0x000000000000000000000000000000f4bae0ad0baeb9d42c7fe2ae3d18c98fad", + "0x00000000000000000000000000000000002a20d66bd435a17fdf1eaf345d5933", + "0x000000000000000000000000000000ed8a8ba528c7088b1ae4730572e1ec32c8", + "0x000000000000000000000000000000000009506de430d6b9f9863e6f10cd35fb", + "0x000000000000000000000000000000682b627744ce0319f4d9191675057282fb", + "0x000000000000000000000000000000000017de059961f8c12752abd299396f86", + "0x000000000000000000000000000000b975958ec262178729e94350c0e7543fb0", + "0x0000000000000000000000000000000000220ce50e394560e53f025e094d17aa", + "0x0000000000000000000000000000001fca3a68a28d438e85e9dc955856752779", + "0x000000000000000000000000000000000028f8f3400bb3b9d19b02ec709e2ee4", + "0x0000000000000000000000000000004e35d073460b0634ebe216d49a3dca9b36", + "0x00000000000000000000000000000000000cb0f5827b08075c405353f10ba632", + "0x0000000000000000000000000000001ece860550ce14fae74eda0123ded56a74", + "0x00000000000000000000000000000000000a34b258bd3daaf8f9edd201c25ed3", + "0x0000000000000000000000000000008cb28ae85d58a75302229585a9ad114c2b", + "0x000000000000000000000000000000000014aac1da344ad32659c3036510fcc1", + "0x000000000000000000000000000000822b45036d5c2befa8a20df910513570c4", + "0x000000000000000000000000000000000011244b388e709fbcb7f54658cfac43", + "0x000000000000000000000000000000389de9951eb8fad7e25e4ad0a9229d2275", + "0x0000000000000000000000000000000000136e6eb0ee251f9b12336cb7bb46ee", + "0x00000000000000000000000000000088f21d9f6c7c54ce4e9a4c103a91b54a58", + "0x0000000000000000000000000000000000187f2beab9a05ca29d2137ee7cbc19", + "0x0000000000000000000000000000009c703a5eb43dcef0686e08fa57ef452f68", + "0x000000000000000000000000000000000012caebb183f1490d3e4f2a2c583ab6", + "0x0000000000000000000000000000009dab4a0aa8d4954a8e1761db3da148a746", + "0x0000000000000000000000000000000000230a08da3b62fd6479b4230760b686", + "0x00000000000000000000000000000081a00a1e38bbd5212603f18ef982a5189d", + "0x000000000000000000000000000000000021ae0f9df38f1e70fa3c26867f4ee8", + "0x0000000000000000000000000000001a722dbd34f841b4823cd055149fce642f", + "0x000000000000000000000000000000000002df2693a9b134670cfe72bf29b363", + "0x00000000000000000000000000000007c906c328630b844b0797e34cedccd1ec", + "0x00000000000000000000000000000000002ab2ae39dd9c0259f7dfb1dda47e81", + "0x000000000000000000000000000000ac6642a4923aa2df07a00a9d3e462b0ed1", + "0x000000000000000000000000000000000015afb7af6c0fc23a24457aa887df9c", + "0x0000000000000000000000000000004d916ec23ef29c0b6134f208e3535671d4", + "0x00000000000000000000000000000000000d37c6c25852903d79475133d414e8", + "0x00000000000000000000000000000029ad212431ba1972de7ee0ba9f12113be3", + "0x000000000000000000000000000000000005c2393db23155844d4f71bead84d0", + "0x000000000000000000000000000000c69074efa82a4910eaf8ab8689d7aafcad", + "0x000000000000000000000000000000000029f3d77437006a0eacf1a149c4b8a0", + "0x00000000000000000000000000000030926853da69d4016eca2f1f0df5e5316f", + "0x000000000000000000000000000000000014841d3291aecd45ea0e05657dbed2", + "0x00000000000000000000000000000052fdb060fe666a3f686088f1f6996a1cf9", + "0x00000000000000000000000000000000002be878eb09939603b391aa9ee0393a", + "0x000000000000000000000000000000d99de3b49476e64c0138037838cfc63803", + "0x0000000000000000000000000000000000260874b43f32c373783efe7ef200a2", + "0x0000000000000000000000000000004951edbb25e9c6b65d446e3418b2b3f16e", + "0x00000000000000000000000000000000002300fac13ab48d40a91114d1ff9627", + "0x00000000000000000000000000000090b8d216da73861ee276dddb17428d8c09", + "0x000000000000000000000000000000000028f906106984e5fa78812869cc1aee", + "0x000000000000000000000000000000ce2aff6eda49d5b8be6ee42104d2aa21e0", + "0x000000000000000000000000000000000002833f671993d2b772b5dec0e12056", + "0x0000000000000000000000000000008be4e7cfb1fdf317a33b7bc3530625e6b8", + "0x000000000000000000000000000000000023404bed8e224a350755410e5c96b2", + "0x000000000000000000000000000000cd9a812fad3fe3a89983e416b70529445b", + "0x00000000000000000000000000000000000b66296ff191a2cf6dbe6ca03dcd0c", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003e895e3756deb16393c59a6a9d3669ce0f", + "0x0000000000000000000000000000000000262d7f27b9058ca9bd2e0620f9a3d3", + "0x000000000000000000000000000000b98c4ce00d755cb57daf4bc1b860536fc3", + "0x0000000000000000000000000000000000017137ecc6753555f49859a34eeb62" ] - hash = "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6" + hash = "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml index 28d9ad79f9c8..e1c95dc4ee1c 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml @@ -484,7 +484,7 @@ proof = [ [inputs.previous_rollups.public_inputs] checkpoint_header_hashes = [ - "0x004d16fb29611dba53004101a433c88fddade0ec60446fddec1589851839a774", + "0x00ba58769fa3e9ec12fd9ab7b264fe69545833f8e7d80571d73ab23a5fc0d4a1", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -520,32 +520,32 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x00f30d99838de8d9e0b40bb5f19c53ebd2cea2e4e324a6b48a4db2655906ad63" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" + root = "0x1bd8fa52c473ccd76cdfd70179aff3b4c59093d598a639557ae1b8798c7c9c4e" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" [inputs.previous_rollups.public_inputs.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.new_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x000000000000000000000000000000000000000000000000003b2f97f0a76c80" + value = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -734,53 +734,53 @@ proof = [ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator] - blob_commitments_hash_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" - z_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" - gamma_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" + blob_commitments_hash_acc = "0x00d6847a188b930077a3101f4aa9101df879af2f4ba3d98192671bdff91d365a" + z_acc = "0x09fadf698f44ed60ef99f4cf1f02a5e4bae20ab2c777ef2f262312e4179af8b2" + gamma_acc = "0x152ea6722a0d24ee928218d153639be747e005105bbf45f366483a8f794fccf3" [inputs.previous_rollups.public_inputs.start_blob_accumulator.y_acc] limbs = [ - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x0000" + "0xf062c57de642dd9de6651787c3e335", + "0x7abcb3fd85a05e708716a7399c23b4", + "0x5ff7" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc] - is_infinity = true + is_infinity = false [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.x] limbs = [ - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x000000" + "0xeee029bf7b2bda4e9568e610dc676f", + "0x4a5f26a53b04bf523a03022d2ba283", + "0x916569ab4bdfdfdd5e50b597c6e454", + "0x019f18" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.y] limbs = [ - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x000000" + "0x238f6e09e67017cc5605af0151d6a2", + "0x568c3f78402057433fea52201c6c49", + "0x1608271b45acc1124b7031b1521278", + "0x03e3f3" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x0000" + "0x7e03f0fd5d9259ec22f5a878b085a2", + "0x43f338bf8a80477fe9e51ec48ae296", + "0x624b" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00c6080f82da97cd32a6e6f96167937982d1b1d102f2670358d457217207a2a5" - z_acc = "0x1ff8cc937c58f2d72966f69b2e490b6dc7f6704680430ac91ea6c0e6207d4d96" - gamma_acc = "0x1684547681775fced98c96d09e82919f729d14549da6323b669a8512c9b3802e" + blob_commitments_hash_acc = "0x0033179ae5491de60cb7cb226671c0f9cea4921f3cacc19438be4d3faa3197c5" + z_acc = "0x293660ab12ef78b885259a67870ffda82b66285965582c47c2568e27fc16f0a4" + gamma_acc = "0x28353ccf291c3c96b0582bf7464325c8322a026d8cf818681b5adb4350148614" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0xd2054ab1639ea442bd23a5b1c57cf5", - "0x4b6135801975f6ab44b107b0a1e000", - "0x677b" + "0xb102ba7ec86991ae3ba7b2d12b0dc6", + "0xd76e5f1b5af021a20c74cbcd8aad8f", + "0x5d37" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -788,35 +788,35 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0xca945aeef9c954013ca54795553295", - "0x9c13e59f13d27ea1d0bbfde41965a9", - "0xf7f9f09f06a5e9f04fb45ab0edb363", - "0x18f7d5" + "0xc579f953d8a89a0c706ffb2abe948f", + "0xbaefc069fa51d7500378d3edc07995", + "0x0f70c87301439b44c18917db9913ab", + "0x087104" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xb04ef08577b05403570538b51898a0", - "0x2797dcc9fb92375446462d46b4ccbb", - "0x39156e19c6155c4ef0f97030dc5d90", - "0x0ad01d" + "0xd131744519d494f5e8f56689d4443c", + "0xbe7390d50563da363e58d775d860a7", + "0x17eff8005836b5a6ba962eedafff26", + "0x09fbda" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x6579a521845bb572269ce72673d0ad", + "0x8e766c234f30ecffc5afead1a0488c", + "0x308b" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.previous_rollups.vk_data] @@ -824,11 +824,11 @@ proof = [ sibling_path = [ "0x1edc2329182e13c58f5ced1e4ca120ba845e074e81d59ee64d0bbd583ecdd429", "0x1f502972a4bdd0353e082932afca85331d93e89c99ab3a78511939c18eb14641", - "0x1f0a3ab28f16510e4f9a5682a8b5f2826f55082cd639c6b76e6e970d8bb4224d", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x18e6586768e6bcc980c4756fb8e50dc355a096b22c3088284883e77065a2dfd0", + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] @@ -1437,7 +1437,7 @@ proof = [ [inputs.previous_rollups.public_inputs] checkpoint_header_hashes = [ - "0x00db58820ef17b4cb952c006ed78296097c3fcf7fd0fc3e3cec1f8260fc64045", + "0x008fb5a2af014eed924e6550a1a568a936137e0ae9596268bdd3a5e228642d41", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1473,32 +1473,32 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" + root = "0x1bd8fa52c473ccd76cdfd70179aff3b4c59093d598a639557ae1b8798c7c9c4e" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.new_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000d0f074eda98980" + value = "0x000000000000000000000000000000000000000000000000003b2f97f0a76c80" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1687,15 +1687,15 @@ proof = [ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator] - blob_commitments_hash_acc = "0x00c6080f82da97cd32a6e6f96167937982d1b1d102f2670358d457217207a2a5" - z_acc = "0x1ff8cc937c58f2d72966f69b2e490b6dc7f6704680430ac91ea6c0e6207d4d96" - gamma_acc = "0x1684547681775fced98c96d09e82919f729d14549da6323b669a8512c9b3802e" + blob_commitments_hash_acc = "0x0033179ae5491de60cb7cb226671c0f9cea4921f3cacc19438be4d3faa3197c5" + z_acc = "0x293660ab12ef78b885259a67870ffda82b66285965582c47c2568e27fc16f0a4" + gamma_acc = "0x28353ccf291c3c96b0582bf7464325c8322a026d8cf818681b5adb4350148614" [inputs.previous_rollups.public_inputs.start_blob_accumulator.y_acc] limbs = [ - "0xd2054ab1639ea442bd23a5b1c57cf5", - "0x4b6135801975f6ab44b107b0a1e000", - "0x677b" + "0xb102ba7ec86991ae3ba7b2d12b0dc6", + "0xd76e5f1b5af021a20c74cbcd8aad8f", + "0x5d37" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc] @@ -1703,37 +1703,37 @@ proof = [ [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.x] limbs = [ - "0xca945aeef9c954013ca54795553295", - "0x9c13e59f13d27ea1d0bbfde41965a9", - "0xf7f9f09f06a5e9f04fb45ab0edb363", - "0x18f7d5" + "0xc579f953d8a89a0c706ffb2abe948f", + "0xbaefc069fa51d7500378d3edc07995", + "0x0f70c87301439b44c18917db9913ab", + "0x087104" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.y] limbs = [ - "0xb04ef08577b05403570538b51898a0", - "0x2797dcc9fb92375446462d46b4ccbb", - "0x39156e19c6155c4ef0f97030dc5d90", - "0x0ad01d" + "0xd131744519d494f5e8f56689d4443c", + "0xbe7390d50563da363e58d775d860a7", + "0x17eff8005836b5a6ba962eedafff26", + "0x09fbda" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x6579a521845bb572269ce72673d0ad", + "0x8e766c234f30ecffc5afead1a0488c", + "0x308b" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00ff28bea8c07e7b060d248cb2071f813aa6e39e07e3a527c1739e6a7793c093" - z_acc = "0x11b2ee0dde26d315a246f5bdc01db8abe8200c6581201debd1cffc51ad26f95d" - gamma_acc = "0x152f389c138d41dde799d4f4fc748753332ddcd5bcd19fe35e4fbe60581534c2" + blob_commitments_hash_acc = "0x00996b577cb6f53aa9d5d22026fa7e7ed5a2a8976186df5414ed93231113a1b3" + z_acc = "0x04b51a58745a148f28f5c26a2d502c8001354179837d098e3af3955de34bf714" + gamma_acc = "0x1bfd4f0bfbabe502f62a2825f8fbc6b52df23371928e6422797997084279f299" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0x4183756e36181f92164c36776c2ba3", - "0xaff710205b13b83794ee63e35bb424", - "0x411e" + "0x0194e1d1e3be1d6f12d6eeb0e18311", + "0x447972f46deb3eff934723afb8d8de", + "0x2435" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -1741,35 +1741,35 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0x6e2f87b978f4bca529d7ad90a41cd8", - "0x734aa1582c8aee32f8334cfc594ab0", - "0x21aa57d7e1012415e25e37ee62bbcb", - "0x015e58" + "0x5e7c6caafcf94afa0766159ff528a4", + "0xecf78cbd1e0c5335e42da88a421390", + "0x39fa11170a3706ed93d37f65f0f7a4", + "0x169dc0" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xd8e530734ccb89f49a545e13ead68c", - "0x914523b3ef75387e032ac9fef36157", - "0x5342c94a6ba1df16b871173b323290", - "0x1604f8" + "0xb6ad8a240910f66dd9deea18fb02f5", + "0x7abb241ff936e62fe95dba9efaca7a", + "0x2a5bfb0a073fe526435c3e8bfedbae", + "0x125deb" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xc0250cc6b8725b2b00687dab94d327", - "0xd7f65a721538376d885811c9aafe6f", - "0x297f" + "0xc962ef153772fa92ab05d6d4de0b69", + "0xc842f223fc7445950dc69c40c23ee4", + "0x05a5" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.previous_rollups.vk_data] @@ -1777,11 +1777,11 @@ proof = [ sibling_path = [ "0x1edc2329182e13c58f5ced1e4ca120ba845e074e81d59ee64d0bbd583ecdd429", "0x1f502972a4bdd0353e082932afca85331d93e89c99ab3a78511939c18eb14641", - "0x1f0a3ab28f16510e4f9a5682a8b5f2826f55082cd639c6b76e6e970d8bb4224d", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x18e6586768e6bcc980c4756fb8e50dc355a096b22c3088284883e77065a2dfd0", + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml index d140961b168f..4082395687cc 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml @@ -483,70 +483,70 @@ proof = [ ] [inputs.previous_rollup.public_inputs] - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde108" - block_headers_hash = "0x04c025c44ceb642aa54659bf652c91b00ccb432f9837ec84c1c282e567c223fc" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2d77" + block_headers_hash = "0x09ae38c4bdd7cdbfee06b35cc61272ed229c502820948e040a4acf7081f149e0" in_hash = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x0000000000000000000000000000000000000000000000000022e452ad469ea0" - accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + accumulated_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" [inputs.previous_rollup.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000043" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" [inputs.previous_rollup.public_inputs.constants.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.previous_rollup.public_inputs.constants.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000003699e8ba0" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" [inputs.previous_rollup.public_inputs.previous_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" + root = "0x2d7278322ae3f2f02196f7b5eb323c037067b5a8bb27bb36e5936e01618b922e" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" [inputs.previous_rollup.public_inputs.new_archive] - root = "0x0f84849714aa969caef587fe17273c9fae12f846c68db0f1ab092faf93a29145" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000c" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [inputs.previous_rollup.public_inputs.start_state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001c00" [inputs.previous_rollup.public_inputs.start_state.partial.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" [inputs.previous_rollup.public_inputs.start_state.partial.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x0c877a1bf89b9eae6a04511e6f74bfaa71157ae9e20aa265ec7fb092914f6726" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [inputs.previous_rollup.public_inputs.start_state.partial.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x21c0735ecdd66391ddb7fff9448a7973f1b8b4399648b1a150afb92d3a0d0ff5" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.end_state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" [inputs.previous_rollup.public_inputs.end_state.partial.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [inputs.previous_rollup.public_inputs.end_state.partial.nullifier_tree] -root = "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" +root = "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.previous_rollup.public_inputs.end_state.partial.public_data_tree] -root = "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -567,33 +567,33 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollup.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000011" + num_absorbed_fields = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.end_sponge_blob.sponge] cache = [ - "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b", - "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a", - "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1" + "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe", + "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0", + "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" ] state = [ - "0x0e1dd9cced5f0826c6e4058004b9cb3a696b39c148c0354124d03d9ed9b4ef46", - "0x0e88efccb1b5effd0110855538123edbbdb2e94b791607a00b954bece2a9bfc9", - "0x1957ffd20204e64443fb09410f7b76cfb098ff3becc10b9e08208fad4d4b03cb", - "0x0c822003a2f7fd4b344c8b039a0d20ff579eed35b7d7e49c8d2fbda1d2e1560c" + "0x294da480f532f9cf8882572adfb599fcea5cf5e13bd97e903a0edbc71bc098e1", + "0x04a930a66e3a346e476c659793e6fee319f3cd0b2657de9fe293ceeb8e105ff6", + "0x203d216c6dd630eba962b8072458bedf7d9a44841805fd481883662fe854327a", + "0x095b497103f425dbb2d5d2fc815c146b922f8b615a25957df526930cea50a313" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollup.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" sibling_path = [ "0x1276688c1c8f1024c963d35957328b73153c55580532254f0676c26e2ad55993", - "0x1025a6a71839d2ab10e9652312547fd6944d80234a52379f6a944c2500ebc294", + "0x086165748e62548024cf40b2812afa99e17d1b248dc89861b56485995305a5ca", "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", - "0x099ef6a9a40aaf85e056bda90684adf858addbb90af303d82f8157b86b705b92", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x24cead94db344ae1716301e94784822099e114c4deaddb78f16e8724ee376aaa", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollup.vk_data.vk] @@ -718,10 +718,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints] previous_archive_sibling_path = [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x1cfdc3f191fd4278971f73de8ee4302bd29051bb0c93c1ba7a8a7feaa4e59846", - "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x021ec3586514f8c888aa40f75e3da945b1504d409908f520f3e65c85b552495b", + "0x304d599cf4ed52817a3206c05651477614f9456baa967427479e1f1c475e1e2d", + "0x150ab49c0bdc816db61f65db0c30c6c26aaf7ad56f042affb9fe006aa795a971", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -757,145 +757,145 @@ new_out_hash_sibling_path = [ "0x00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c" ] blobs_fields = [ - "0x00000000009c707518000000010000000300000000000000000000000000000a", - "0x2ca391890a7afa0a4098cceb64d9aa356e84a1055e6e2b3df10e2a5033f0b691", - "0x0000000000000000000000000000000000000000000000000022e452ad469ea0", - "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef", - "0x2935995b8343928a25acdb09654bdc27aeef345ec185caa48fb0048bd475fbcb", - "0x0000000000000000000000000000000000000000000000000000000000001c20", - "0x0dc02e099550676b3dcfd522010d4db9d2c47a4556dfa28aa20a4a0eb35c54a4", - "0x0000000000000000000000000000000000000000000000000000000000000af0", - "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3", - "0x00000000000000000000000000000000000000000000021e00afaeb15ed67ca0", - "0x0000000000000000000000000000eb8dcdbf0000000069fde1080000000b0001", - "0x000000000000000002c0000000000d0000000003c0000000008b0000000a3979", - "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1", - "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f", - "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1", - "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b", - "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a", - "0x0000000000000000000000000000000000000000000000008c63744300000012", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000009c70751800000003000000010001000d00000000006c0000000083", + "0x0590b52cd0b0945171050227160d7339dec3eb41a5be14a84d97c17d2bc80ff1", + "0x00000000000000000000000000000000000000000000000002449f1e83b9af00", + "0x13876606079602e1a9f3118b3d14ccd36b2b01915abc971c97eaaf1ad6032a7f", + "0x273617117fe26c8b346c634f743b8d215d0d188fa290d3e3283106fb06d380f1", + "0x1bdad00a23307084c2c182515aeda85e0139ca1eb438836ae93c331dd90e6e7d", + "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969", + "0x00000000000000000000000000000000000000000000021e0219674fdaa32380", + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a8", + "0x09d3e27b2b71e2140366b7b610129b819b841efe0dc06bf715e3eb5b68f65571", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0ced49df8bad805ad50a3b054eb121748b0c4343ea4451686bfeba125dc7e294", + "0x252ec1d53f8683ece6631cefb05fb44afc9ed830f13e8f8e68f7c94210f02eb9", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", + "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", + "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", + "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", + "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", + "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x20f5895a4e837356c2d551743df6bf642756dcd93cd31cbd37c556c90bf7f244", + "0x252ec1d53f8683ece6631cefb05fb44afc9ed830f13e8f8e68f7c94210f02eb9", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x2109f5b7c318644c97ea14f3207164f6704cdd3416bd91448360b63c45d7ec6c", + "0x01d0aee7b081283eb5d46eafb04dd16f380df7fba4803ac42ad7e92c61394ba5", + "0x0000000000000000000000000000000000000000000000000000000000000c3e", + "0x0027000204012800000104804a270000044a2500000041270203040127020404", + "0x00001f0a0003000400492d0849022500000064270202044a27020304003b0e00", + "0x000300022900004304ffffffff27004404032700450404270046040027004704", + "0x000127004804022629020003006efc2c540a2a02030427020501012402000400", + "0x00000084230000019d2d08010427020604040008010601270304040100220402", + "0x00061f3000440047000600220447062d0b060600220448072d0b07071c0a0709", + "0x00041c0a0908001c0a08070400220444082d0b08081e020004001e020004002d", + "0x0008010427020904020008010901270304040100220402092d0a090a2d0e080a", + "0x0027020a040b2d08000b2d0a060d2d0a070e2d0a040f0008000a002500000a61", + "0x002d0200002d0a0d082d0a0e090c2846080424020004000001352500000b7c00", + "0x00220944042d0b040427020704012702090403002a0709082d08010600080108", + "0x0001270306040100220602082d0e070800220802082d0e07082702080403002a", + "0x000608072d0a07082d0e040800220602072d0b07072702080403002a0608043b", + "0x000e00070004230000019d2902000400132874f50a2a02040624020006000001", + "0x00b823000003372d08010427020604040008010601270304040100220402061f", + "0x003000440047000600220447062d0b060600220448072d0b07071c0a0709041c", + "0x000a0908001c0a08070400220444082d0b08081e020004001e020004002d0801", + "0x000427020904020008010901270304040100220402092d0a090a2d0e080a2702", + "0x000a040b2d08000b2d0a060d2d0a070e2d0a040f0008000a002500000a612d02", + "0x0000002d0a0d082d0a0e090c2846080424020004000002692500000b7c002209", + "0x0044042d0b04042d08010827020904020008010901270308040100220802092d", + "0x000a090a2d0e040a27020a040b2d08000b2d0a060d2d0a070e2d0a080f000800", + "0x000a002500000a612d0200002d0a0d042d0a0e090c2846040624020006000002", + "0x00cf2500000b7c00220944042d0b040427020704012702090403002a0709082d", + "0x000801060008010801270306040100220602082d0e070800220802082d0e0708", + "0x002702080403002a0608072d0a07082d0e040800220602072d0b070727020804", + "0x0003002a0608043b0e0007000423000003372902000400bf0791460a2a020406", + "0x0024020006000003522300000445280200080406402d0801092802000a040641", + "0x000008010a012703090401002209020a1f3200080047000a27020a00002d0801", + "0x00062802000b0406410008010b012703060401002206020b2802000c04064000", + "0x002a0c0b0c2d0a0b0d23000003b82d0e0a0d00220d020d0c2a0d0c0e2402000e", + "0x00000003af2d0846042d08460723000003d20c2a04080a2402000a000009f223", + "0x00000003e41e020004001e0200040027020604002702080403002a0608072d08", + "0x0001040008010701270304040100220402072d0e060700220702072d0e060727", + "0x0002070403002a04070600220402072d0b07072702080403002a0408063b0e00", + "0x000700062300000445290200040025a995770a2a020406240200060000046023", + "0x000000062d2d08010427020604040008010601270304040100220402061f3000", + "0x00440047000600220447062d0b060600220448072d0b07071c0a0709041c0a09", + "0x00080000220444072d0b07071e020004001e020004002d080104270209040300", + "0x0008010901270304040100220402092d0a090a2d0e080a00220a020a2d0e070a", + "0x0000220402073a03200043004300060048000720020004210200062d08010827", + "0x0002070400002208020a2d0b0a0a27020b0403002a080b092232000600460009", + "0x002d0a060a2703080401002208020b2d0e0a0b00220b020b2d0e0a0b27020c04", + "0x0003002a0a0c0b0008010b0127020b04002d0a0a0c06220c020c0a2a070b0d2d", + "0x000a0c072402000d000005632d0a07072402000d0000057d0a2a070c0e240200", + "0x000e0000057d2500000b8e24020004000005b3230000058a2d0b080400220402", + "0x00042d0e040800220802062d0b06062702090403002a0809043c0e0604230000", + "0x0005b30c2846070424020004000005c52500000b7c00220844042d0b04042702", + "0x000704012702090403002a0709082d0801060008010801270306040100220602", + "0x00082d0e070800220802082d0e07082702080403002a0608072d0a07082d0e04", + "0x000800220602072d0b07072702080403002a0608043b0e00070004230000062d", + "0x00290200040035be18a00a2a020406240200060000064823000008272d080104", + "0x0027020604040008010601270304040100220402061f30004400470006002204", + "0x0047062d0b060600220448072d0b07071c0a0709041c0a09080000220444072d", + "0x000b07071e020004001e020004002d08010927020a04050008010a0127030904", + "0x0001002209020a2d0a0a0b2d0e030b00220b020b2d0e060b00220b020b2d0e08", + "0x000b00220b020b2d0e070b00220902033a032000430043000400450003200200", + "0x0003210200042d080107270206040000220702092d0b090927020a0403002a07", + "0x000a0822320004004600082d0a04092703070401002207020a2d0e090a00220a", + "0x00020a2d0e090a27020b0403002a090b0a0008010a0127020a04002d0a090b06", + "0x00220b020b0a2a060a0c2d0a0b062402000c0000075d2d0a06062402000c0000", + "0x0007770a2a060b0d2402000d000007772500000b8e24020003000007ad230000", + "0x0007842d0b070300220302032d0e030700220702042d0b04042702080403002a", + "0x000708033c0e040323000007ad0c2846060324020003000007bf2500000b7c00", + "0x00220744032d0b030327020604012702080403002a0608072d08010400080107", + "0x0001270304040100220402072d0e060700220702072d0e06072702070403002a", + "0x000407062d0a06072d0e030700220402062d0b06062702070403002a0407033b", + "0x000e0006000323000008272702030265270204026e2702060274270207027227", + "0x000208026f270209026c27020a025527020b026b27020c027727020d02202702", + "0x000e027327020f0263270210027b270211027d2d080112270213041c00080113", + "0x0001270312040100221202132d0a13142d0e0a1400221402142d0e0414002214", + "0x0002142d0e0b1400221402142d0e041400221402142d0e081400221402142d0e", + "0x000c1400221402142d0e041400221402142d0e0d1400221402142d0e0e140022", + "0x001402142d0e031400221402142d0e091400221402142d0e031400221402142d", + "0x000e0f1400221402142d0e061400221402142d0e081400221402142d0e071400", + "0x00221402142d0e0d1400221402142d0e101400221402142d0e0e140022140214", + "0x002d0e031400221402142d0e091400221402142d0e031400221402142d0e0f14", + "0x0000221402142d0e061400221402142d0e081400221402142d0e071400221402", + "0x00142d0e1114270203010027020400010a2a03050624020006000009f2270207", + "0x00041e2d080108270209041e00080109012d0a08092a030009059b5bbff74a5b", + "0x00ff190022090209002212020a27020b041b2d020a032d0209042d020b052500", + "0x00000ba027020a041b002a090a092d0e040900220902092d0e02090022090209", + "0x003c0e07080c2a07080a2402000a00000a042500000b7c002209020b002a0b07", + "0x000a2d0b0a0a002207470b0e2a070b0c2402000c00000a292500000bd22d0206", + "0x0003280000040406412500000be42d08050c00220c020d002a0d040e2d0e0a0e", + "0x00002204470a2d0a0a042d0a0c062d0a0b0723000003d21c0a03050000220447", + "0x00032d0b03032d08010427020604030008010601270304040100220402062d0a", + "0x0006072d0e050700220702072d0e030700220402033903200043004300020048", + "0x00000320020002210200032d080105270204040000220502072d0b0707270208", + "0x000403002a05080622320003004600062d0a0307270305040100220502082d0e", + "0x00070800220802082d0e07082702090403002a07090800080108012702080400", + "0x002d0a070906220902090a2a04080a2d0a09042402000a00000b232d0a040424", + "0x0002000a00000b3d0a2a04090b2402000b00000b3d2500000b8e240200020000", + "0x000b732300000b4a2d0b050200220202022d0e020500220502032d0b03032702", + "0x00060403002a0506023c0e03022300000b732d0a04022d0a0503262a01000105", + "0x00e408504502b58c1f3c040201262a0100010575fef108377c8a4f3c04020126", + "0x0000000305072d0003082d0004092300000bc42d0108062d0406090000080208", + "0x0000000902090c0008070a2400000a00000bb2262a01000105d007ebf4cbc667", + "0x00903c040201262d0103060a000602072400000700000c392d00010500000104", + "0x000100000304092d00030a2d00050b2300000c222d010a082d04080b00000a02", + "0x000a00000b020b0c000a090c2400000c00000c1027010504012300000c3d2d00", + "0x0003052600000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000eb8dcdbf000000006a0b2d77000000080001", + "0x000000000000000002000000000008000000000280000000008a00000008992c", + "0x2d7278322ae3f2f02196f7b5eb323c037067b5a8bb27bb36e5936e01618b922e", + "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b", + "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe", + "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0", + "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a", + "0x0000000000000000000000000000000000000000000000008c6374430000008b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -25334,64 +25334,64 @@ blobs_fields = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000" ] -blobs_hash = "0x0098dfcc50238facc959eceef09a4ed661501b8a94815f8d69ad5b265956d2f1" +blobs_hash = "0x00682a8ea5dd86c86fb5429635732ad886f0310197db03f05ba37d6cf07b72b3" [inputs.hints.previous_block_header] - sponge_blob_hash = "0x208b2bb1ace451b93e09ef0119c861c986fb26bb867456eb5c93661b83befc33" - total_fees = "0x00000000000000000000000000000000000000000000000000d0f074eda98980" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000001baea4" + sponge_blob_hash = "0x0be6bd8144feece3fe238707409045d13f60f729f75a291fc5a6e8a9d652fc2a" + total_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + total_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" [inputs.hints.previous_block_header.last_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x22143a53487336dae7b1e2d79f04e2d69537775312e313a6bd2ba1631581b2c3" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" [inputs.hints.previous_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001c00" [inputs.hints.previous_block_header.state.partial.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" [inputs.hints.previous_block_header.state.partial.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x0c877a1bf89b9eae6a04511e6f74bfaa71157ae9e20aa265ec7fb092914f6726" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [inputs.hints.previous_block_header.state.partial.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x21c0735ecdd66391ddb7fff9448a7973f1b8b4399648b1a150afb92d3a0d0ff5" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.hints.previous_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000a" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000042" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde0c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000007" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000021" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2d2f" [inputs.hints.previous_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.hints.previous_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" [inputs.hints.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.hints.start_blob_accumulator] - blob_commitments_hash_acc = "0x00ff28bea8c07e7b060d248cb2071f813aa6e39e07e3a527c1739e6a7793c093" - z_acc = "0x11b2ee0dde26d315a246f5bdc01db8abe8200c6581201debd1cffc51ad26f95d" - gamma_acc = "0x152f389c138d41dde799d4f4fc748753332ddcd5bcd19fe35e4fbe60581534c2" + blob_commitments_hash_acc = "0x009da512df7feb01c37d5bcb7e907e17d51fd84ad4460d4c642413504a87bfdc" + z_acc = "0x1a9e1d4cc81124337b17a9c662071843771d6a41f3cf53ee36568c2349b3647b" + gamma_acc = "0x070699060ce578bd02837627c0a9fa9cfb31bdb9f2a27c0dcb057bcd76292927" [inputs.hints.start_blob_accumulator.y_acc] limbs = [ - "0x4183756e36181f92164c36776c2ba3", - "0xaff710205b13b83794ee63e35bb424", - "0x411e" + "0x677c77feb299419897580647b86f12", + "0x1d6d20f741d9fa453db4cbf0848ef2", + "0x45f2" ] [inputs.hints.start_blob_accumulator.c_acc] @@ -25399,35 +25399,35 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints.start_blob_accumulator.c_acc.x] limbs = [ - "0x6e2f87b978f4bca529d7ad90a41cd8", - "0x734aa1582c8aee32f8334cfc594ab0", - "0x21aa57d7e1012415e25e37ee62bbcb", - "0x015e58" + "0xee591e91d1df051f9b267a38554db6", + "0x6494af33697703d42086d0bac214b2", + "0x42bfd42f76abb7a4329c55bb6ccce5", + "0x10b49f" ] [inputs.hints.start_blob_accumulator.c_acc.y] limbs = [ - "0xd8e530734ccb89f49a545e13ead68c", - "0x914523b3ef75387e032ac9fef36157", - "0x5342c94a6ba1df16b871173b323290", - "0x1604f8" + "0x8dd9d1424edc6766a3ea218b160e52", + "0xe3ee3c4c4e4e143f4caa4d794524a9", + "0xe208c7435d9f16c77e2d4bfc5a9ae7", + "0x0619ab" ] [inputs.hints.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0xc0250cc6b8725b2b00687dab94d327", - "0xd7f65a721538376d885811c9aafe6f", - "0x297f" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.hints.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.hints.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [[inputs.hints.blob_commitments]] @@ -25435,18 +25435,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints.blob_commitments.x] limbs = [ - "0x1f41ee1ce165ab1325a3d58dcce4b0", - "0x8cc2d9c146e110aecfd6e1d0a88478", - "0x5f035ed6b113a1d400984d75519e9c", - "0x0c2ecb" + "0xf54d4bafcdeb415daf044bfbc4959a", + "0x4ba7a36a0219a6a364c57913dd510b", + "0xa755c27bc765ce4d23bcabe820b2db", + "0x053fbb" ] [inputs.hints.blob_commitments.y] limbs = [ - "0x6e4b336ccd13490195783945cd06c4", - "0x87ab466617f89f75e1b4e5cc2de3cf", - "0x5c00c3065f22ed5a6511f4ef9144d8", - "0x0290b1" + "0x2937637584e15ed0d59e47f0f3fe13", + "0xbda1b755e5a650bff2324b1f83e52b", + "0x107c15e866e8b12ba7cb457e23ea8c", + "0x0ecd31" ] [[inputs.hints.blob_commitments]] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml index 98a0feb10878..e2377934e954 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml @@ -484,7 +484,7 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x09f6fe2394de36a32f372c238a502348b0b79debb779fecfd9de7388dc2df8d3" + block_headers_hash = "0x092d9c9b723f4a91d24cb333dd118c5f17feddbcec1eb988d00b2dcca8a12aa4" in_hash = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" out_hash = "0x00bd3da907cbb210cd100bd369f8dd7eb04b938c69dce277dc1efea8403ed88e" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -493,8 +493,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -513,7 +513,7 @@ proof = [ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x0d5581ddb590b1f2e972ae3399ac1639129b04a4b4282a219285a5dba6553cdf" + root = "0x10abfc1e58ab5ed471d9c7fedcf2b291ad533ac85d136968ea047db10d73d599" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -576,10 +576,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" ] state = [ - "0x186114d0d063d6e6ddee6515e508484b364b20eeca9ca340f8566e398b71b198", - "0x114fbdb8bc7b843c83778ba1c8780534af4f59451f33adcb6a437c245d4bed64", - "0x2808ea7e05edca8293485bb1dfde34257ab644659366d516601dd5beba26639c", - "0x0ba75ded1f1125dbe2d4e7a5b18a7b2e2c238a70c72ed529163eb34be09a36d2" + "0x06b7a09d376432aa2b0a7411a06aaad2d07f77fe65a5401eea06ab9d30b77ceb", + "0x06b7ab96aca0b2e842d7692f25a662728d09309529ca41b0e61eb20e19a7f38a", + "0x0b211453e69b20a81d2247120eae55ca5f80139276d8d9a7bb790996624e335d", + "0x1af797fb95b1713b94475070546774ffc67e4d61c261abb49048a7834cc7e665" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -587,134 +587,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000f" sibling_path = [ - "0x15602bffd51fabacf870d678a216f360ee85085e4b283f99086a716d2be141c1", - "0x02e6f22eee7e3e5aa6291ccac5ee76b8a2f1e338a74bf57530740f36d19c9b2b", - "0x14c22836312c6ac50d8aae1289b45c06410355406e5af5ecf43bf59432dcdd17", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x0b292d3b888b2793be2b844d85cf1ee4c10e4646758de66819a7d9483c294c05", + "0x2a4b8973bfb7d252bd970f41d74702d12b8bc7f63b15188bc79d78bda4a9413d", + "0x07a849e820943807a1c5531526528e89be50a06725dee96179285d8108e565c9", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000015", "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x000000000000000000000000000000bc40d1d77d5f27602c7a5c9dcfdd10a577", - "0x0000000000000000000000000000000000290d95127ce2d246f860afc4417008", - "0x0000000000000000000000000000005cbd5faf5f59e15c010fc58d3fe9e540b1", - "0x00000000000000000000000000000000001c1664bcd931f8720205c14774d342", - "0x000000000000000000000000000000e387aea29d37cb480af72d484d55b6db6c", - "0x000000000000000000000000000000000009819e8a531a4e83e8b585a5144e20", - "0x000000000000000000000000000000a1608d0aac1cba0b1a9be724adb7bad88c", - "0x00000000000000000000000000000000001dd226cbaf4d26d6530c6515111999", - "0x0000000000000000000000000000009cd23598a766328147bb89f172954d7b29", - "0x00000000000000000000000000000000000d423e810f78ea0c2de42822af19e7", - "0x000000000000000000000000000000a55922fba9387fb37978bbd6af4459e04a", - "0x00000000000000000000000000000000000006ecc1eebeaa91b95f82ddf0e88f", - "0x00000000000000000000000000000043557bb0d6f710fca0eb9026bf8a98125a", - "0x000000000000000000000000000000000009ff26fbd0bad0ae72c988daff6c0c", - "0x00000000000000000000000000000006859f9f51510814ee09ad960084d53608", - "0x00000000000000000000000000000000001acfe8b3a2dd74d8013a77c604ada6", - "0x000000000000000000000000000000584d59b5e078a46e2662eba84435d2e4bd", - "0x000000000000000000000000000000000006482f6bf0fb0b343d0f97ef69c6b2", - "0x0000000000000000000000000000009d06b99a519e14ae6c8cea34c266f500c7", - "0x000000000000000000000000000000000025948c8dade30c58b5de9219f2ca95", - "0x00000000000000000000000000000093d02ec5125183c643276a59b448fed664", - "0x00000000000000000000000000000000000e27bbd8a3f92cf1dd4964e4973b73", - "0x0000000000000000000000000000005f8e948b5bb98b37d2cfa364c13bf016c1", - "0x0000000000000000000000000000000000111bc97b3a794e05e394f12e060ce6", - "0x000000000000000000000000000000de739fa0af1b1abc39f66b36bf6babfc93", - "0x00000000000000000000000000000000002ec2db775d5362c26b1211d0c67b33", - "0x00000000000000000000000000000092bff11ad703ff9e37f33e0254b1cae0b3", - "0x00000000000000000000000000000000001f2e9c9949c5722f9c0f27d4c01426", - "0x0000000000000000000000000000003627cef107994ae39ad4e69391443a0997", - "0x00000000000000000000000000000000001fb58a2ef67ec15c272e5d7d9fdd12", - "0x000000000000000000000000000000f49addd07ba78c471bfce78c0e211de5e0", - "0x00000000000000000000000000000000000f8a586c69ee00ea0e41154296c359", - "0x00000000000000000000000000000064ef2ac931af2758da6f7f50962ac3aee8", - "0x000000000000000000000000000000000025844bfa45c1614111a515cc924942", - "0x000000000000000000000000000000030d10358e7c9ac3f42b647f523d169a58", - "0x000000000000000000000000000000000018749a4984c4b5f9f4776ee6119102", - "0x00000000000000000000000000000034847db5296ad05fc68d47d76af31b3fbe", - "0x00000000000000000000000000000000000b15d1ae95f4b0db468e55ac0124d8", - "0x000000000000000000000000000000ed9af9fc0f97291c7f59f97bbe779da8be", - "0x0000000000000000000000000000000000188ff968dd82e23e5fdbbbd17a1d9f", - "0x0000000000000000000000000000009484b03063127bfe6d86b88c8ae47c01bb", - "0x0000000000000000000000000000000000108ae749d0d2eeb1996779852c330a", - "0x000000000000000000000000000000c6ebd746a8b5176e70a61f91162a6d4e2d", - "0x00000000000000000000000000000000000b89bcdd866b9cd89975b5ad0e6d89", - "0x0000000000000000000000000000003a110dd7b65b005ebf4c552b3c67ef1555", - "0x000000000000000000000000000000000029162ed048f542c4f7b03cb25b49e6", - "0x00000000000000000000000000000068316453bc8319f06cedcfd6c32608cd1f", - "0x00000000000000000000000000000000000e251b62bf239581fb597eed6740e0", - "0x00000000000000000000000000000025b00fdba3615375ed7d3976b356e495ab", - "0x000000000000000000000000000000000019f6c87da0b230ac04532351fe4b1d", - "0x0000000000000000000000000000001e23899052e207e75d15ce3d53d5e32847", - "0x0000000000000000000000000000000000019b9ff1c73b02d0f4517a97cee440", - "0x00000000000000000000000000000098bdab2108ae94ca4f485f5d02848d78d4", - "0x000000000000000000000000000000000004286964c20572873b6cf4da257471", - "0x0000000000000000000000000000000f611fb20ca3f9a6e05b17a755e0d55789", - "0x00000000000000000000000000000000000bd64babea596e197f373eb7aa8a43", - "0x0000000000000000000000000000008b37d49bd8ea21edbcaed541649fa8bdf5", - "0x0000000000000000000000000000000000267b1d48ccf67020ae08c7626a6c1c", - "0x000000000000000000000000000000cc687415f8c3305515f13d525e24085188", - "0x00000000000000000000000000000000002ca0b4b1f880019458bb2cd76f1f6e", - "0x00000000000000000000000000000030225fa6aa96e3972e46e3696527aae07d", - "0x00000000000000000000000000000000002b4de086c87a07bba4c423443feeab", - "0x0000000000000000000000000000000185f97c684593ba3560c433759c004853", - "0x000000000000000000000000000000000023cb3980074547c96e69cf1b54a618", - "0x0000000000000000000000000000009f864e1df408fd077100e0708be9692950", - "0x00000000000000000000000000000000002d465fd67c5262361e605c6e12915e", - "0x000000000000000000000000000000d4d9d690e0e19ef0a850cc44aeb72d291d", - "0x00000000000000000000000000000000001a1575ccf82dc1999e30c8bc1cd879", - "0x0000000000000000000000000000007b9c3ed13d551bfbc79f7216b917bdd693", - "0x00000000000000000000000000000000001c7905dbeeeafe6a96e0005768c3ad", - "0x000000000000000000000000000000abeca755a49df461a20ac6f0d8aa21bc90", - "0x00000000000000000000000000000000002ea0bedd06b133984bc27df51d6cb1", - "0x000000000000000000000000000000b07d6e88b09f97805879886a4f6f2d38ea", - "0x00000000000000000000000000000000001d0d1ffb001c9b3899d7be3d350184", - "0x00000000000000000000000000000007edda6116badb825639e5ac0bc35bcc72", - "0x000000000000000000000000000000000000c8ef5f1d8a85d3f564339779a623", - "0x000000000000000000000000000000e98b4e97afce7c1eda4af175ea75a95ff5", - "0x00000000000000000000000000000000001fc215448b3315991812153c3ff4c6", - "0x000000000000000000000000000000a05a9ffcb63515d19bd5c987c9d9c8e29f", - "0x00000000000000000000000000000000003018d45fe1f2d7b5ad3f1be15c2f2a", - "0x000000000000000000000000000000f7b12583d31b279777eff4b5cdcb77fdb8", - "0x00000000000000000000000000000000002d8ba043960803f8bdecd1765200ca", - "0x000000000000000000000000000000904912e20bb0691aaf85e36dce6b473d7f", - "0x00000000000000000000000000000000001c69cd654d955bce8b4edb9c7f1fe1", - "0x000000000000000000000000000000bf797dee8dfb0567fb3985708d7e353387", - "0x00000000000000000000000000000000002743e0b1f32f249b5ae16902fb391c", - "0x000000000000000000000000000000d82e431c626c79dbf17adb5fe768f904b2", - "0x00000000000000000000000000000000001bc72b2ac20d87b289025c21613b39", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000dc4a993f7acd99b494105345a2fdaa0a2", - "0x0000000000000000000000000000000000250b675604342cefa92c43e49384e4", - "0x000000000000000000000000000000b042a664238ae53b3e5a3c1c332c3c26d7", - "0x00000000000000000000000000000000000bb7745eec39ba256f4e95e5c1b96f" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x00000000000000000000000000000089079e540b719b4976bc29d819da265672", + "0x00000000000000000000000000000000000169511d89b1b0e96da32e525c72fc", + "0x000000000000000000000000000000e06e062182e6dfad1e73262298e47b4942", + "0x000000000000000000000000000000000022b5e38bf07cca64a821cb6a1c50be", + "0x000000000000000000000000000000844e6f07bcbb405a7eccb53cbe0dcdac25", + "0x000000000000000000000000000000000019ccf675743a22e6910df635b6c02d", + "0x000000000000000000000000000000b3f7c9c54170a598243436c12b5e714430", + "0x00000000000000000000000000000000002565cbc85f940dbde932bfc4eb2b46", + "0x000000000000000000000000000000df6dd669dda6e917c2ac2ef5dee2599599", + "0x00000000000000000000000000000000000871514dca64f33dcef23979db5be6", + "0x000000000000000000000000000000a6a76f61c436e1325c59d9ca45156088cf", + "0x0000000000000000000000000000000000253be2ad6c1112a4293bfd778dcac0", + "0x00000000000000000000000000000061b34f5bbdfec177f721dc5f52ce5dfce8", + "0x00000000000000000000000000000000000c45d1ecf903c7083b085bd11e7a18", + "0x00000000000000000000000000000092b8c18509dc81b2af5c0dd4eab9e950c6", + "0x00000000000000000000000000000000000285d5abda6e0c8cc477b2b6d5a7c8", + "0x000000000000000000000000000000c31ba9fc26a1b329bf3a87101fe6e021ee", + "0x00000000000000000000000000000000001906c827ab4161488be3c186420748", + "0x0000000000000000000000000000003705e273cf24eef2d204884b0490063d93", + "0x00000000000000000000000000000000002a897d4386a8d79d754334ed1f277e", + "0x000000000000000000000000000000ef186aa03a1ea746fdfff4df4032261232", + "0x0000000000000000000000000000000000039bf4b51ed17830647b92c603871a", + "0x000000000000000000000000000000bd63d8fb924d2dcb07408e87c266c7b98e", + "0x00000000000000000000000000000000000824ca926bc6de275907dba25bdd31", + "0x0000000000000000000000000000004724cde9ce06e5411caabd7dd4fe2dcf89", + "0x0000000000000000000000000000000000267e7e5f0e6e2991964e87475f961b", + "0x0000000000000000000000000000001f11b31d10d889999d1f1349f99703a55f", + "0x00000000000000000000000000000000001ca2da1bd75c23c6533fc450360e0a", + "0x00000000000000000000000000000027909050e7b7eb67e7c9a4d6345f0eb69e", + "0x000000000000000000000000000000000011db3d79dd9d93947d2b7dc1c10672", + "0x000000000000000000000000000000353c06fb739bccbdcc744f38fcd0508a03", + "0x0000000000000000000000000000000000182f67bb76281c69170de22262dc6a", + "0x000000000000000000000000000000aee4088b33f36d708509b67a51df161c1b", + "0x00000000000000000000000000000000001f0af39954e92ebe02d2d09a9c019a", + "0x000000000000000000000000000000bbabc0cbdb5576ed44ba86792c4f0f3778", + "0x000000000000000000000000000000000001f9dcf9530d2449c557570860964f", + "0x000000000000000000000000000000e712b7c295c2913bc21ecd1c4fd978aeae", + "0x000000000000000000000000000000000020e9f99d67ea5e7fc51a2e22bfee4a", + "0x000000000000000000000000000000cfeace77443d79774754135c7968bf9d09", + "0x0000000000000000000000000000000000200ef4e004b1a6adf1c77145207df9", + "0x00000000000000000000000000000041d5b70488ce0785e27d77408b6085664a", + "0x0000000000000000000000000000000000206ee6f2103341c45c9b7671f392dd", + "0x0000000000000000000000000000008835d9dc525cd7f5221558932b0c0b79dd", + "0x00000000000000000000000000000000000547db4cde23842669a45900d460fe", + "0x000000000000000000000000000000aa8e1629d9ad0470808401bde58b032ad1", + "0x0000000000000000000000000000000000268f1b5be84cb1098c37af45c316e0", + "0x00000000000000000000000000000093192140c3ddeecebf383c332418a14eeb", + "0x00000000000000000000000000000000000129bf9dd7ef08589bd72fb388080f", + "0x000000000000000000000000000000ba08e502a40fe2d53953e74922703c4dd1", + "0x00000000000000000000000000000000001832a1f9489f19b4cabaeefd71ee29", + "0x00000000000000000000000000000007c6d0327de911d59b21bdaa35b13c198c", + "0x000000000000000000000000000000000021711257b12d37f6cc6bf0563cb71b", + "0x00000000000000000000000000000078540776e3fd93faf9c54d5168a662f856", + "0x0000000000000000000000000000000000002d078a43ad1d6c7f5b3d402a6611", + "0x000000000000000000000000000000ae81eb3cc1ae191ee4aa4214664d38a1d6", + "0x000000000000000000000000000000000015bddad4ba217f293029f383450df8", + "0x0000000000000000000000000000008b6c95adb242724e37da69f7a7ea68a5bd", + "0x000000000000000000000000000000000003b5e4a74d1e95b020f39d30eeca27", + "0x0000000000000000000000000000003102092e740ebecabc67864cd9cb36bc7a", + "0x000000000000000000000000000000000025ecef72137002818caafefff75640", + "0x000000000000000000000000000000a1a6659848b5210b9dcb9cbb0ea37359af", + "0x00000000000000000000000000000000001fd1df39bd8e442aa9ed4ec9818bca", + "0x0000000000000000000000000000005bdf45263c9710d45361e5a2a3f368d632", + "0x00000000000000000000000000000000002f00901bb28669af54074c0319ea4c", + "0x00000000000000000000000000000052d2ac68ce89bbd7c109c1ee22951430dd", + "0x0000000000000000000000000000000000291b0c8ec2d5a8ffabec390a97a0af", + "0x0000000000000000000000000000007332fb2757456b72c08ba53f2a6cbfdb99", + "0x00000000000000000000000000000000001c0e1cecfbdc2bce36f4446718039d", + "0x000000000000000000000000000000df0a10f65a3b192b15683732a7af4d35fb", + "0x00000000000000000000000000000000002d21b2fdc09d5c66d9cd3cdf1155d2", + "0x000000000000000000000000000000a419c6200eeceddf7c2310c1d55843fe57", + "0x0000000000000000000000000000000000164d6ede4c1c9cfad8019f4fef5607", + "0x000000000000000000000000000000155a288f925fc795dd91d8ffb9607e7588", + "0x00000000000000000000000000000000001d1a7044ac92e07e3f7a4d1adb808c", + "0x0000000000000000000000000000005006485f5f919139ac4cf8f2b48806c330", + "0x00000000000000000000000000000000002f38995bad2db25ab25059fdf2b6f7", + "0x0000000000000000000000000000000fa857db14df227f02ccb383869d141032", + "0x0000000000000000000000000000000000035df66ed51a2c5ebe05f09679be0e", + "0x000000000000000000000000000000ccd13789864d814c1c8e1d1896cf6d0d77", + "0x0000000000000000000000000000000000138d6ef3e6963f4fe192b274487006", + "0x0000000000000000000000000000001ef73e731e5c4ce7164d5fdb07175ea87d", + "0x0000000000000000000000000000000000178a3808d159a83c5c9966694f8ab0", + "0x0000000000000000000000000000008bca1f7f73e29b028b131da2a003bcc042", + "0x0000000000000000000000000000000000252d50a4729066a33228a590d3eca1", + "0x000000000000000000000000000000b027810138d0953c2b6ea7e149e4565004", + "0x0000000000000000000000000000000000303c0f2b5d507eb93d0ac0ebd043c2", + "0x00000000000000000000000000000002743dd7f3f2b76f827352e8e6b866e3ef", + "0x00000000000000000000000000000000000876c0bf77208a49e0cdd002dc3d55", + "0x000000000000000000000000000000720c42b7569cc2f3149f891bea025eb3e1", + "0x00000000000000000000000000000000000a4a472694ec96876785ee52db9117", + "0x000000000000000000000000000000899f74d8c6cb5d6913934ce86bf7a8fd2f", + "0x00000000000000000000000000000000002351d8cf62e447a6ad623d1576c70e", + "0x000000000000000000000000000000eff011caee40885a1228037bacd671c917", + "0x000000000000000000000000000000000028a9e4afdebabed8c9db5043f651d9", + "0x000000000000000000000000000000df5feae8869502a1c8b84f2bfa88460397", + "0x00000000000000000000000000000000002a4aea8df3da995b6993d106db01d7", + "0x0000000000000000000000000000007865f93da8894da5579d078bc52c865a23", + "0x000000000000000000000000000000000008ff54796b152dd8613c8b78175f0f", + "0x000000000000000000000000000000a6451fa917a48400fa444deb67a7ae56c5", + "0x00000000000000000000000000000000000ae3e2509278517f5cde67366a90c5", + "0x0000000000000000000000000000005e1f735a0fcf0b9170f0fb96b149aa6bfa", + "0x0000000000000000000000000000000000121155b0e2aa30081d1cd787338972", + "0x000000000000000000000000000000507a37d65b4307ff81bc9bb1dda679defa", + "0x00000000000000000000000000000000000eb66dc9635ca0b929275cbaccb034", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x000000000000000000000000000000cec3be02d424d395a16063578c12504acb", + "0x00000000000000000000000000000000001a583a66b4ace72db0600f3285f6d4", + "0x000000000000000000000000000000ef5f8bd3e2da9628dfa8917ab2f40afb41", + "0x000000000000000000000000000000000025c530a8f279e6cc4fb10e10984f2a" ] - hash = "0x0d000c0ce80da2c814b0f1508b74728e2eb05f4fdfb0396e1e6939106be41f29" + hash = "0x2781192850bee4946aa72958703bc69fec3ab04ecffc00c34abcb81befd3c88f" [[inputs.previous_rollups]] proof = [ @@ -1202,7 +1202,7 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x26882f9b919de7921bc48927adca4121d39e03766a0f70e268c967ac959fdda1" + block_headers_hash = "0x1349b8af6fa1399d3367ec1646ea31a8eb527fa0a93f7df141a99b8087c242a5" in_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" out_hash = "0x009be21298b4428b38b9b314446eef3243121c400edd3780e34da475ea5f17c3" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1211,8 +1211,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -1227,11 +1227,11 @@ proof = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x0d5581ddb590b1f2e972ae3399ac1639129b04a4b4282a219285a5dba6553cdf" + root = "0x10abfc1e58ab5ed471d9c7fedcf2b291ad533ac85d136968ea047db10d73d599" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x215f1b994274f12963668b1b1e69654c637c40187eb26d2f7bdf49fa7d1960de" + root = "0x2f6a583f6610c5573c95d4b79eafb659b67b4428dbf13990edf928f599a03ef9" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -1276,10 +1276,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" ] state = [ - "0x186114d0d063d6e6ddee6515e508484b364b20eeca9ca340f8566e398b71b198", - "0x114fbdb8bc7b843c83778ba1c8780534af4f59451f33adcb6a437c245d4bed64", - "0x2808ea7e05edca8293485bb1dfde34257ab644659366d516601dd5beba26639c", - "0x0ba75ded1f1125dbe2d4e7a5b18a7b2e2c238a70c72ed529163eb34be09a36d2" + "0x06b7a09d376432aa2b0a7411a06aaad2d07f77fe65a5401eea06ab9d30b77ceb", + "0x06b7ab96aca0b2e842d7692f25a662728d09309529ca41b0e61eb20e19a7f38a", + "0x0b211453e69b20a81d2247120eae55ca5f80139276d8d9a7bb790996624e335d", + "0x1af797fb95b1713b94475070546774ffc67e4d61c261abb49048a7834cc7e665" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1294,10 +1294,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x06d941e09284387689272aef891ff6ec71993e808f3a832c4d1fd74955b1901e" ] state = [ - "0x17da65d95854743f81498e2d569a4d11fe47a652ce11c27768e392475e503771", - "0x0fdf668913527d70795bd6225710f94e802493ca2ded968c29e45816b9366662", - "0x0de554ab6116e8d6245bfb791eb15006e14be4f10497002ec9a426a760a73974", - "0x28dc4bfd4e171c7418cda7f902dfd3e22433e1341085ae4d528f8b7082131ae7" + "0x1525d886fd143dc1893161cc7bc9a7a29cebdd09a955543f883ea4d2823b10e0", + "0x19060008e02e5f734643d2a087bae8c913fb8e79e47b50c5718e729cdedacade", + "0x21ebef3c51c070c1f17b925d3d30851b9afaa56d85745d6b8c0ab8586a014c29", + "0x124caee5596391b2756e5c3339afc57827b191b7e89529ef096b427cd6c19f89" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false @@ -1305,134 +1305,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000e" sibling_path = [ - "0x0d000c0ce80da2c814b0f1508b74728e2eb05f4fdfb0396e1e6939106be41f29", - "0x02e6f22eee7e3e5aa6291ccac5ee76b8a2f1e338a74bf57530740f36d19c9b2b", - "0x14c22836312c6ac50d8aae1289b45c06410355406e5af5ecf43bf59432dcdd17", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x2781192850bee4946aa72958703bc69fec3ab04ecffc00c34abcb81befd3c88f", + "0x2a4b8973bfb7d252bd970f41d74702d12b8bc7f63b15188bc79d78bda4a9413d", + "0x07a849e820943807a1c5531526528e89be50a06725dee96179285d8108e565c9", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000002fb0b1381b4486fbd49fa9fdb4d74afed8", - "0x00000000000000000000000000000000001b03700ad9942abf5144e1bd7393d2", - "0x0000000000000000000000000000007f3e184921857992c24753b966424214c6", - "0x0000000000000000000000000000000000283119b961cda64e529c68e135fa17", - "0x000000000000000000000000000000c251b282c34c8a6d712e6c12903362497c", - "0x00000000000000000000000000000000002c89e5571ae0b09fa870346cbd5cee", - "0x0000000000000000000000000000008eb0fcf7af2d945fd3266cd7b0b449e8d3", - "0x000000000000000000000000000000000021d78ef089716338837787911d13b0", - "0x0000000000000000000000000000007f691d58aee9d65248c5eecbbaddc13a98", - "0x0000000000000000000000000000000000098627646fa61b9928d6dc11c96e13", - "0x0000000000000000000000000000002c58cf39b7f2b04d82c4338ef8958a7473", - "0x00000000000000000000000000000000001aef806cf0aba5af2f1f8978cd56d8", - "0x00000000000000000000000000000082bb268c0e10a8bf5c0ef242f9906e4892", - "0x00000000000000000000000000000000000c90d93936cc598061c4d29f0b25a4", - "0x0000000000000000000000000000004d114fbbc4055f5761b7f8840f0da32908", - "0x00000000000000000000000000000000002957bebd162ed2169df723dde18c97", - "0x000000000000000000000000000000e9eea3e81c31b1aa9400fa13197b7393fb", - "0x0000000000000000000000000000000000218c3140bfb6edddbcb2d4cbc126bb", - "0x000000000000000000000000000000c0ff9e22fab79999e9ed7d78e138d2987d", - "0x000000000000000000000000000000000028bcfd13128cabc46955265a1e05dd", - "0x00000000000000000000000000000023a74d6f1a3fabe39ff7f0f6150be9ec00", - "0x00000000000000000000000000000000002e2507d7bf2a01aec6fd026fa0a409", - "0x0000000000000000000000000000000a0acda35b6f3d1a438d5fcf5783a50797", - "0x000000000000000000000000000000000021e1c9a570c3d0417707daa478fa20", - "0x000000000000000000000000000000c10049e49d4cd16c33bbc1e8eb3238ea26", - "0x00000000000000000000000000000000002578443465dd684c74b9c635f2c33e", - "0x000000000000000000000000000000770092209b5122c863dacecd7406bb2d48", - "0x00000000000000000000000000000000000f3fee6266059403a65308d4c5d7eb", - "0x00000000000000000000000000000093ed6cb8d6a2d5363b2c995ec9f930a714", - "0x0000000000000000000000000000000000276fea1e0f63f52d1e7564b9a81494", - "0x0000000000000000000000000000000389f3a2b3a8f8cc2f5f5d1cd72a8d196d", - "0x000000000000000000000000000000000013bcbd1229609722bcecd1798d4a4b", - "0x000000000000000000000000000000fe9ce7b1fd6536624c2fa96787f74d7bb0", - "0x00000000000000000000000000000000000c3c6d07104e24ea5acc68c3423208", - "0x000000000000000000000000000000b8da6eb9140a2d5588a8710a2d6d6318a2", - "0x00000000000000000000000000000000001b1f1fa538a3b66f72c15c53cca715", - "0x0000000000000000000000000000004730a9529ef0eb509d55e1379829c016c4", - "0x00000000000000000000000000000000001ce37c2c228f312b7c1e64bcca1dfd", - "0x000000000000000000000000000000a378c68d165ba8929cf5e20f479ed90e1d", - "0x000000000000000000000000000000000023024fd5c636e9ead7d63e4eac96d9", - "0x00000000000000000000000000000082a25f4e5374c7548fa507be32b596f423", - "0x000000000000000000000000000000000018ca6faa15b5b52e1ae8b15cb8b83f", - "0x000000000000000000000000000000091c75d9a46e8a66235f387c882bb14df2", - "0x000000000000000000000000000000000018f3db0dcead736435b7467239e00b", - "0x000000000000000000000000000000b87fb21960e7763dfd42205c459fdc41fa", - "0x00000000000000000000000000000000000267a4a344f85d00b6b0040d1c2150", - "0x0000000000000000000000000000000bd1017af78a6260c7d0f6eccb3a8d3890", - "0x000000000000000000000000000000000002641016e4e2bf5752b1e9472dde95", - "0x0000000000000000000000000000004697a8a794f990510a018a5b2c50f35b76", - "0x00000000000000000000000000000000000de0ab75e8b485639fe023a368024c", - "0x000000000000000000000000000000be33c35449966234d9bdf48ba396a57c4f", - "0x00000000000000000000000000000000000df556c20deb7a8ab0ee850f970c51", - "0x0000000000000000000000000000007e5366f459b2b033ca3664ff8f4a641d18", - "0x0000000000000000000000000000000000192f68a938c5a9ea9a5cc9f2181675", - "0x0000000000000000000000000000003a6f876985d4d54592c5b5c16ab8b16750", - "0x00000000000000000000000000000000002da0d2ee45300969c52f5ae43c7402", - "0x000000000000000000000000000000c0f7aa427b2ea5fe4f0e45dcb2eec42f83", - "0x000000000000000000000000000000000009739dbd1003e81acae3f329654c42", - "0x0000000000000000000000000000009191ff080e493eb7d3eb33ec9823178f09", - "0x00000000000000000000000000000000002c951c03d7dadfa04fdc92a298ea8f", - "0x000000000000000000000000000000245cbb1c8e9f243b94d55edca314c340d7", - "0x00000000000000000000000000000000000de0f174fce3433422830fdb869c6e", - "0x0000000000000000000000000000005348fbfc2bff27c23db0f849baac752835", - "0x00000000000000000000000000000000000fa0fe8cbbf06318ad99adc23d2e0c", - "0x000000000000000000000000000000b37df3b0cfe3793620f5315db38c0dcd29", - "0x0000000000000000000000000000000000011ef80549887e786cea0d08c13608", - "0x000000000000000000000000000000e085aac6fe78f6a3574c61f888eb0ace80", - "0x000000000000000000000000000000000015ea74a6e14e77ffea0611ecc18015", - "0x000000000000000000000000000000635cc32ee452dd83211c337fd3423850ff", - "0x000000000000000000000000000000000030399e012ea636c746005ba35a4536", - "0x000000000000000000000000000000c6c09fdb5d8cbc0266b956e5539ad94b8f", - "0x00000000000000000000000000000000000728658d282bb922ecff1634645aff", - "0x0000000000000000000000000000008fc753267c4b4393209eabc80d1c4fcac8", - "0x00000000000000000000000000000000001add24bab07f36d9d6e11beabf5bb8", - "0x0000000000000000000000000000001a38a11d04a6dc1d788b1cc4da1d171341", - "0x000000000000000000000000000000000004eadc7d1bcf2320272a6d96972ae7", - "0x0000000000000000000000000000004749834da45ee7f8ffc427cf41f3b715e3", - "0x000000000000000000000000000000000005e4285178878dbecdfd0c6eba227a", - "0x000000000000000000000000000000182e1a0661bfd39a43bcbbb18e3691b327", - "0x0000000000000000000000000000000000262b3f8b46fac1d385cc0f3bc24ee0", - "0x000000000000000000000000000000434d5dbebbf6fbc03531f25d963f155b9a", - "0x0000000000000000000000000000000000082a0f4d55eb1206313a4955f41f03", - "0x000000000000000000000000000000034001bbce1dcce343e80ff7a821fc3444", - "0x000000000000000000000000000000000013176cdf2f7fb58e75a4954f0bfd28", - "0x000000000000000000000000000000acb6987d4aafb95942bc208f40df86f426", - "0x00000000000000000000000000000000000e52fac6880e3f51e7641ab893e82a", - "0x0000000000000000000000000000002377224018803fe8e8922c797432d2d985", - "0x00000000000000000000000000000000000b3d671707c2cdc4842e4e8ffefc09", - "0x00000000000000000000000000000095b5d8b7b4a63b05df652b0d10ef146d26", - "0x0000000000000000000000000000000000099e3bd5a0a00ab7fe18040105b9b3", - "0x0000000000000000000000000000002129af3a637f5a622a32440f860d1e2a7f", - "0x00000000000000000000000000000000000015b8d2515d76e2ccec99dcd19459", - "0x000000000000000000000000000000222b888108dc25d1aa450e0b4bc212c37e", - "0x00000000000000000000000000000000001b917517920bad3d8bc01c9595092a", - "0x000000000000000000000000000000482141c7ebe42000a1d58ccb74381f6d19", - "0x0000000000000000000000000000000000305e8992b148eedb22e6e992077a84", - "0x0000000000000000000000000000007c86847618681dc29d8a9363ab7c40e1c3", - "0x000000000000000000000000000000000016465a5ccbb550cd2c63bd58116fe4", - "0x000000000000000000000000000000439973ac12d7ca796d6fe98ca40e6ca6b7", - "0x00000000000000000000000000000000002e24d420fbf9508ed31de692db477b", - "0x00000000000000000000000000000028edd1a7e46c840d9c943fdf45521c64ce", - "0x0000000000000000000000000000000000043d063b130adfb37342af45d0155a", - "0x0000000000000000000000000000009330952ae74c573d1686d9cb4a00733854", - "0x0000000000000000000000000000000000261522c4089330646aff9673619494", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000005d656b6df65180c7833e41dc3231ba543d", - "0x000000000000000000000000000000000011345e9011207695e22c16713acdb8", - "0x0000000000000000000000000000007d63cb71b503d4b9abe5d31e76ac70ff93", - "0x000000000000000000000000000000000026b61287fe7afce1e989dc0d30a961" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000161e5bb10fa2b7c7380009239b649b4734", + "0x00000000000000000000000000000000000badbf533a087faffe865010dc5b37", + "0x000000000000000000000000000000381bfa95df551e67c494b29f07bfc5149c", + "0x00000000000000000000000000000000001bf4738c48442b6d952222d821547f", + "0x000000000000000000000000000000cdf67a2562ab96b4917ea73217efafd3b3", + "0x00000000000000000000000000000000001b0666d4bc44552a2ffc0223345a23", + "0x00000000000000000000000000000052e280645ffe873ef1e2cce244d3b23265", + "0x000000000000000000000000000000000029365e95dc11f595f23b37d9c475db", + "0x000000000000000000000000000000e0546cf49094bcd8d9e4a0e2f0b0d21d73", + "0x00000000000000000000000000000000001dd314bca6a6ded1a4a64266a516ce", + "0x000000000000000000000000000000c529043942840056e63f2fcffad4221afd", + "0x000000000000000000000000000000000011c2731f6fe0cb9f3c7d88d710950d", + "0x0000000000000000000000000000000dccca0374b5478a2414205ee24ca83668", + "0x000000000000000000000000000000000007e95f7cd90c21519b280c7c007fcc", + "0x00000000000000000000000000000004de3a9f180f0a4f01dab186eba8530269", + "0x00000000000000000000000000000000001372faf74b763ba502d7cc0845a54c", + "0x0000000000000000000000000000008aa4681b00633c2a5a63702641a6d36041", + "0x00000000000000000000000000000000002dc7f4ccd6922fc4b6654e175f2a80", + "0x000000000000000000000000000000d0d4f6ecbd8ee863fa3160211931061e33", + "0x0000000000000000000000000000000000263cb61cd13a131bdb313fa1159c3c", + "0x000000000000000000000000000000739ca3af1ec76a87a037f25bca5447ee69", + "0x0000000000000000000000000000000000065132cc73a764a9958eaf16937aac", + "0x0000000000000000000000000000004f397550e79074d0c4d3108fe675be5a4e", + "0x000000000000000000000000000000000012a58f58ab7bd421ca8f0fdf7990ed", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000dbe8bffec86d9a9c4e194450aafe44569a", + "0x00000000000000000000000000000000001ad711549791cb4bfb26753da71976", + "0x000000000000000000000000000000eef413cdd499365c5aff81234c29a8e9c8", + "0x00000000000000000000000000000000001c1a2f7052492deb0bf3831f1d659f", + "0x000000000000000000000000000000a430987c325c792662db95707eeb73bcda", + "0x00000000000000000000000000000000001fc6620d5b4b91a2bb7e967e4ca0a0", + "0x000000000000000000000000000000d3010833f9a0a6df8b842d2e94c7443271", + "0x00000000000000000000000000000000002b34c8b03764d6438d76005e33f136", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000090eb905a6ce8fdcfb3ad69b20f37b471a0", + "0x000000000000000000000000000000000015411f1068f3c41c0f03f763abc15a", + "0x000000000000000000000000000000afca164bedcee548eecb0590ec5abf1127", + "0x0000000000000000000000000000000000145ea9d00e643079977aa78cd2c109", + "0x000000000000000000000000000000854f1c53b1fafeaae64bc08161c77048b7", + "0x00000000000000000000000000000000001e235518c5c034960eec5fc45a716e", + "0x00000000000000000000000000000035145365e610d44ef42fa8ea613a9df4aa", + "0x00000000000000000000000000000000000f949d81fe0404cba9da3dbe012bd7", + "0x000000000000000000000000000000c5f55c78208dcda151683ee8cf95e8bc47", + "0x000000000000000000000000000000000012b17b8f64a8606a7817da004b71c1", + "0x0000000000000000000000000000007359e5ac4a48e1c4cf0e5665c6c059d99b", + "0x00000000000000000000000000000000001d7a0474a2bb254bf932f10146b961", + "0x00000000000000000000000000000024e0b7c596516bb0b5a2e8d6cb248b56a2", + "0x000000000000000000000000000000000012e9c9b3e8143abd574124134a05c8", + "0x000000000000000000000000000000dbc92535cff5ca03ba09ca111642d39fda", + "0x00000000000000000000000000000000002043571f43cad61de3a5e4328a4aee", + "0x00000000000000000000000000000079d599186f46e769fcc207b0cd6cbdc01e", + "0x00000000000000000000000000000000000c5c2f9466df09ea80f0ec14870034", + "0x0000000000000000000000000000005f94f587b12643ff51063a28353833f770", + "0x00000000000000000000000000000000000cf56aa28ed4b4beb7ff157d7da3ef", + "0x000000000000000000000000000000de4b43f87ff9317c8e9d9c4588fc2eef2d", + "0x000000000000000000000000000000000012d0aa842859d2ee838f5510f9bc22", + "0x0000000000000000000000000000006f2fdb4213da0129f8365bc86a01f6164d", + "0x00000000000000000000000000000000000bdc73bc5280a4afc7e65947531e51", + "0x000000000000000000000000000000f14874ba0df22c460d8352ca030bd9a861", + "0x00000000000000000000000000000000000885382903e5ffbd837b5e0e4bbf06", + "0x00000000000000000000000000000066e80b7e34ebe3899a4d07dea4f62cc7df", + "0x000000000000000000000000000000000013f829d0878ad53de418679f370067", + "0x0000000000000000000000000000002980ae9f85fad098e5a76ca9e6bdac5779", + "0x00000000000000000000000000000000001a774ae589e96cfbefb418dddcdaa2", + "0x000000000000000000000000000000327c44b0ed90d01976c32c94f04ef2cea8", + "0x0000000000000000000000000000000000225d757cb4f2bfbf6d13b8114d7b16", + "0x000000000000000000000000000000bdc629840f4a9d071f9fb1384008254135", + "0x000000000000000000000000000000000004e75cee70f3e11a2402faef92a73b", + "0x000000000000000000000000000000f40c508a906897027558980610fc4df4f2", + "0x00000000000000000000000000000000001f959d41e40d111d021ab23b4ef843", + "0x000000000000000000000000000000587fcafd86184e71ec3d650b3ba85f03fa", + "0x00000000000000000000000000000000000610c97af06081281e7404f44aee4b", + "0x0000000000000000000000000000007b029cc296434696323f9c37b5e4c9cf55", + "0x00000000000000000000000000000000000614733fbf8d375012614cce5e4aa0", + "0x000000000000000000000000000000bc102f5fba012ade36bbf671474a9afae2", + "0x00000000000000000000000000000000000d2b78d31298fc946624e482d61850", + "0x000000000000000000000000000000c1c26c3fbdd4fb7de13c6af78b90063442", + "0x00000000000000000000000000000000002da9dd34c453f3d5a99691ba052769", + "0x000000000000000000000000000000a788520d601038b7bcb1ef241547ddc5e1", + "0x00000000000000000000000000000000002a280445997573df993f3eaa9cc9bd", + "0x000000000000000000000000000000ec4d9274437dc457e7da9ee9f5d57b0825", + "0x000000000000000000000000000000000029454eff7f180c04c3dccd1d762531", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000007cf4b5713ad71efb2e02fe45bb7fc9507f", + "0x000000000000000000000000000000000026cf1fe248bb52d3e86b9f64b3c2d3", + "0x0000000000000000000000000000000e590349a07b67f041c3c615e4f436aeab", + "0x000000000000000000000000000000000015a097ca4d6bfa82e4dd755b3ebb59" ] - hash = "0x15602bffd51fabacf870d678a216f360ee85085e4b283f99086a716d2be141c1" + hash = "0x0b292d3b888b2793be2b844d85cf1ee4c10e4646758de66819a7d9483c294c05" [inputs.hints] previous_archive_sibling_path = [ @@ -1476,7 +1476,7 @@ new_out_hash_sibling_path = [ ] blobs_fields = [ "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x149ec99267de2c967f076659b1ce7c2ef1e39b2de7a3c8fca6144e419a0274c0", + "0x1fa8c9e190ef51acc5e052f31c13e3b45f6a971ff92a5b3a128ab4debc2980a4", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7d1b000", "0x00000000000000000000000000000000000000000000000000000000b7d1b001", @@ -2838,7 +2838,7 @@ blobs_fields = [ "0x1fe2338f2916a0bd017ff73606723336792d97d6c91a387862c4d5ab893a6f29", "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922", "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x12ca038fdc7a689a9ef836b5edc09fc0ebba53d29405ede497d098f12b33c642", + "0x10b5b722c0807e2bbfb09230febb255d9c0fff9c50469e2389e88d9ee38a3189", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7e5c000", "0x00000000000000000000000000000000000000000000000000000000b7e5c001", @@ -4194,12 +4194,12 @@ blobs_fields = [ "0x00000000000000000000000000000000000000000000000000000000b7e5c34e", "0x0000000000000000000000000000eb8dcdbf0000000000000186000000020001", "0x00000000000000000040000000000200000000010000000000fe000000000000", - "0x0edef98680cbea2855c4f0f152a0ecd69358e68b10da7b7e301f35ce709c13fa", + "0x27b365d73aa1b8ac1eb39c75262e2b87a238d041cc98fcb795f4c597c620ce64", "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449", "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8", "0x0bb359d329306f1fc12b8b3a551903d4732e3e8814b2de27816ea59c24f1a2f8", "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x26fd006fd312bdf184fc64451856f788e40cf4aeb9d9a50da4c4be19d40adb31", + "0x1be1bf28dec1713b8bf50f30d29338963f2661a98cc83b0d7edf2010ac8b6e26", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7f9d000", "0x00000000000000000000000000000000000000000000000000000000b7f9d001", @@ -5555,7 +5555,7 @@ blobs_fields = [ "0x00000000000000000000000000000000000000000000000000000000b7f9d34e", "0x0000000000000000000000000000eb8dcdbf0000000000000186000000030001", "0x000000000000000000400000000003000000000140000000013d000000000000", - "0x0d5581ddb590b1f2e972ae3399ac1639129b04a4b4282a219285a5dba6553cdf", + "0x10abfc1e58ab5ed471d9c7fedcf2b291ad533ac85d136968ea047db10d73d599", "0x0058e56291a20ba5208dec6c4e6f93513a7e475709e9292d09b7ca1c7147703e", "0x06d941e09284387689272aef891ff6ec71993e808f3a832c4d1fd74955b1901e", "0x0ed4dc2f0161f133a04ebd27d3f9b7ab3d7046c1443c15bc9530cb3f5d9e9e08", @@ -26052,7 +26052,7 @@ blobs_fields = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000" ] -blobs_hash = "0x004081e2169fa22b2772ab0bde677d1c43254458e4af0c5884cf49ba3f4b72ea" +blobs_hash = "0x00031d7de335de20811f08b722d4fba78989fa94027ff1a8eec54aaea67fe5b0" [inputs.hints.previous_block_header] sponge_blob_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -26139,13 +26139,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [inputs.hints.final_blob_challenges] - z = "0x0d9e4f48a791aec62f6b7d1fc9035386da8a75d4a5eb234257b0e38a4cc7b9ae" + z = "0x0b4ef7a0f91b1c53bd4db4aec602254a28846ae5a42f2d8980d1912799c4b733" [inputs.hints.final_blob_challenges.gamma] limbs = [ - "0x810f80bc31d4ee4b1bc2e3cb4c28f5", - "0xcbb430183357d87fc1f80f3d1d31da", - "0x0b30" + "0x3fdb267131d938840645510fbcb081", + "0x65bb921ac3dc8dd116a3f59bb3183b", + "0x121b" ] [[inputs.hints.blob_commitments]] @@ -26153,18 +26153,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints.blob_commitments.x] limbs = [ - "0xcce5778469f0cecc548341f35f9ebb", - "0x8280546f7e9cb753aedf0a06fa034c", - "0xaf119193234c6f715aac4220979f16", - "0x130f08" + "0x665c40a423c8604a17e3da76ccc812", + "0xfe81e0faede6060a8108ca85ba9088", + "0x82c2811283002382832fef00453c0b", + "0x12b897" ] [inputs.hints.blob_commitments.y] limbs = [ - "0x5d218e9fd26f0a1c61e85eefe76e5b", - "0x571b53682bb7dd0ffcc88ba0f592a8", - "0x3058c697809e40f6e414aecb1c9a0a", - "0x078a44" + "0xcf949ef8ac7b342c359434c38b287d", + "0x129b3a7a403691b2c1b2b8ec052995", + "0xf4dbd895942ad8f1d6ab389ccfa412", + "0x070c7b" ] [[inputs.hints.blob_commitments]] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml index 64ff802314a0..5e87e095cfff 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml @@ -484,10 +484,10 @@ proof = [ [inputs.previous_rollups.public_inputs] checkpoint_header_hashes = [ - "0x004d16fb29611dba53004101a433c88fddade0ec60446fddec1589851839a774", - "0x00db58820ef17b4cb952c006ed78296097c3fcf7fd0fc3e3cec1f8260fc64045", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00a8a666b95bb2db4e3f95e5bcb8f5f962fa6ff42a2539a3c486aa868d15446a", + "0x0003467aeaebe55a1faed0cde7a7ebecc0b4168ff83de06f64342187de9b266e", + "0x00ba58769fa3e9ec12fd9ab7b264fe69545833f8e7d80571d73ab23a5fc0d4a1", + "0x008fb5a2af014eed924e6550a1a568a936137e0ae9596268bdd3a5e228642d41", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -520,17 +520,17 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x00f30d99838de8d9e0b40bb5f19c53ebd2cea2e4e324a6b48a4db2655906ad63" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + root = "0x22143a53487336dae7b1e2d79f04e2d69537775312e313a6bd2ba1631581b2c3" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.previous_out_hash] @@ -539,31 +539,31 @@ proof = [ [inputs.previous_rollups.public_inputs.new_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x000000000000000000000000000000000000000000000000003b2f97f0a76c80" + value = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000d0f074eda98980" + value = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x000000000000000000000000000000000000000000000000003b2f97f0a76c80" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -772,15 +772,15 @@ proof = [ ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00ff28bea8c07e7b060d248cb2071f813aa6e39e07e3a527c1739e6a7793c093" - z_acc = "0x11b2ee0dde26d315a246f5bdc01db8abe8200c6581201debd1cffc51ad26f95d" - gamma_acc = "0x152f389c138d41dde799d4f4fc748753332ddcd5bcd19fe35e4fbe60581534c2" + blob_commitments_hash_acc = "0x00996b577cb6f53aa9d5d22026fa7e7ed5a2a8976186df5414ed93231113a1b3" + z_acc = "0x04b51a58745a148f28f5c26a2d502c8001354179837d098e3af3955de34bf714" + gamma_acc = "0x1bfd4f0bfbabe502f62a2825f8fbc6b52df23371928e6422797997084279f299" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0x4183756e36181f92164c36776c2ba3", - "0xaff710205b13b83794ee63e35bb424", - "0x411e" + "0x0194e1d1e3be1d6f12d6eeb0e18311", + "0x447972f46deb3eff934723afb8d8de", + "0x2435" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -788,35 +788,35 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0x6e2f87b978f4bca529d7ad90a41cd8", - "0x734aa1582c8aee32f8334cfc594ab0", - "0x21aa57d7e1012415e25e37ee62bbcb", - "0x015e58" + "0x5e7c6caafcf94afa0766159ff528a4", + "0xecf78cbd1e0c5335e42da88a421390", + "0x39fa11170a3706ed93d37f65f0f7a4", + "0x169dc0" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xd8e530734ccb89f49a545e13ead68c", - "0x914523b3ef75387e032ac9fef36157", - "0x5342c94a6ba1df16b871173b323290", - "0x1604f8" + "0xb6ad8a240910f66dd9deea18fb02f5", + "0x7abb241ff936e62fe95dba9efaca7a", + "0x2a5bfb0a073fe526435c3e8bfedbae", + "0x125deb" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xc0250cc6b8725b2b00687dab94d327", - "0xd7f65a721538376d885811c9aafe6f", - "0x297f" + "0xc962ef153772fa92ab05d6d4de0b69", + "0xc842f223fc7445950dc69c40c23ee4", + "0x05a5" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.previous_rollups.vk_data] @@ -824,11 +824,11 @@ proof = [ sibling_path = [ "0x1be72f1f471a29db247f7c4f19c03e11631575edec0695c29deba92770cce437", "0x0c0e71d61b37e5093a79987574f6a04cf58c7a6b47f650ec04b30cb9c9b3ccec", - "0x1f0a3ab28f16510e4f9a5682a8b5f2826f55082cd639c6b76e6e970d8bb4224d", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x18e6586768e6bcc980c4756fb8e50dc355a096b22c3088284883e77065a2dfd0", + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] @@ -1437,8 +1437,8 @@ proof = [ [inputs.previous_rollups.public_inputs] checkpoint_header_hashes = [ - "0x009751d5fc5ec4f92e16f7b70c3b084aced0c7e9416fae20ebc6fcbca6b9501c", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x004638ad10c7cbda76930cc7f1472de2ccc8920da89114128202779de93410ff", + "0x00afd2bd40cee0982472b0b99c78d510bd9001cbb785bdc1a1b68db9a0a3175a", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1473,38 +1473,38 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x0f84849714aa969caef587fe17273c9fae12f846c68db0f1ab092faf93a29145" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000c" + root = "0x06da63b13a4fad622178ece351f2198feaf74e70c18ba14fe5fa6e4834c0ff51" + next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000d" [inputs.previous_rollups.public_inputs.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [inputs.previous_rollups.public_inputs.new_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000022e452ad469ea0" + value = "0x00000000000000000000000000000000000000000000000000d0f074eda98980" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x000000000000000000000000000000000000000000000000004d2c208a4b8060" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1687,15 +1687,15 @@ proof = [ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator] - blob_commitments_hash_acc = "0x00ff28bea8c07e7b060d248cb2071f813aa6e39e07e3a527c1739e6a7793c093" - z_acc = "0x11b2ee0dde26d315a246f5bdc01db8abe8200c6581201debd1cffc51ad26f95d" - gamma_acc = "0x152f389c138d41dde799d4f4fc748753332ddcd5bcd19fe35e4fbe60581534c2" + blob_commitments_hash_acc = "0x00996b577cb6f53aa9d5d22026fa7e7ed5a2a8976186df5414ed93231113a1b3" + z_acc = "0x04b51a58745a148f28f5c26a2d502c8001354179837d098e3af3955de34bf714" + gamma_acc = "0x1bfd4f0bfbabe502f62a2825f8fbc6b52df23371928e6422797997084279f299" [inputs.previous_rollups.public_inputs.start_blob_accumulator.y_acc] limbs = [ - "0x4183756e36181f92164c36776c2ba3", - "0xaff710205b13b83794ee63e35bb424", - "0x411e" + "0x0194e1d1e3be1d6f12d6eeb0e18311", + "0x447972f46deb3eff934723afb8d8de", + "0x2435" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc] @@ -1703,37 +1703,37 @@ proof = [ [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.x] limbs = [ - "0x6e2f87b978f4bca529d7ad90a41cd8", - "0x734aa1582c8aee32f8334cfc594ab0", - "0x21aa57d7e1012415e25e37ee62bbcb", - "0x015e58" + "0x5e7c6caafcf94afa0766159ff528a4", + "0xecf78cbd1e0c5335e42da88a421390", + "0x39fa11170a3706ed93d37f65f0f7a4", + "0x169dc0" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.y] limbs = [ - "0xd8e530734ccb89f49a545e13ead68c", - "0x914523b3ef75387e032ac9fef36157", - "0x5342c94a6ba1df16b871173b323290", - "0x1604f8" + "0xb6ad8a240910f66dd9deea18fb02f5", + "0x7abb241ff936e62fe95dba9efaca7a", + "0x2a5bfb0a073fe526435c3e8bfedbae", + "0x125deb" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0xc0250cc6b8725b2b00687dab94d327", - "0xd7f65a721538376d885811c9aafe6f", - "0x297f" + "0xc962ef153772fa92ab05d6d4de0b69", + "0xc842f223fc7445950dc69c40c23ee4", + "0x05a5" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00e314212187820bcccc75acc041531f0e6f2139db72f9962951480b5eb309b4" - z_acc = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" - gamma_acc = "0x28a8c47b24266cbe95e6e5df4d8f583081a6e7d873a03dfabcf3fad3204acc2f" + blob_commitments_hash_acc = "0x00dafdb7b3b799bb084d877da599210547153bfa1d95e15454e5ef8828ee2a97" + z_acc = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" + gamma_acc = "0x0249abb0caa46e44620756bbe031549d27fd3993d9dff07bcf79463630d05de0" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0xca8704c4fce27431f9bc6cf6bc5ee8", - "0x2e59181e0640e995e15724147eea98", - "0x5a08" + "0xca5f370e7aab4dad06c01870c19fbc", + "0xd1fb9335d20269ffbc84bda2f21514", + "0x566e" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -1741,165 +1741,165 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0x1fc2db53f95236761d435a3d7a82eb", - "0x4f0266217c841c706ff759bcd9619a", - "0x6b2dfe9b2403f250a44b3a4a85c7a7", - "0x09f649" + "0x6d0f563da7ead85edb604d6454b7b5", + "0xeb7000efa3ffe5e92db92568794b8a", + "0x1189810c2c041ab7e783b85fbb3468", + "0x0afd1e" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xdf0f6a879571ea5e99241f6a774cc6", - "0x962be4a71909fb2b0c13c6d8aa4780", - "0xd7e987a1f4d2937f67abc39e2ce5d4", - "0x042b58" + "0xa6ae6e509b73011d557a87995f4632", + "0xfee59d3ca5668d346a68e82ace828f", + "0x5699038166c3c7de96889ef819f997", + "0x168603" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xed650727d9732d1fc427beb2dcf581", - "0xdcd9e8dc02a33765f813f467a095de", - "0x0e9c" + "0xeb5d3ce954df93f05b2310b2c784f9", + "0xbe6bc80053e1871b4cb41540dc987f", + "0x3255" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.previous_rollups.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000011" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000013" sibling_path = [ - "0x1edc2329182e13c58f5ced1e4ca120ba845e074e81d59ee64d0bbd583ecdd429", - "0x1f502972a4bdd0353e082932afca85331d93e89c99ab3a78511939c18eb14641", - "0x1f0a3ab28f16510e4f9a5682a8b5f2826f55082cd639c6b76e6e970d8bb4224d", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x1be72f1f471a29db247f7c4f19c03e11631575edec0695c29deba92770cce437", + "0x0c0e71d61b37e5093a79987574f6a04cf58c7a6b47f650ec04b30cb9c9b3ccec", + "0x18e6586768e6bcc980c4756fb8e50dc355a096b22c3088284883e77065a2dfd0", + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x0000000000000000000000000000000000000000000000000000000000000015", "0x00000000000000000000000000000000000000000000000000000000000000a3", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000302787373675614b5065e413ff7cb47635", - "0x000000000000000000000000000000000030223bf53e330987976984cbc8b777", - "0x0000000000000000000000000000005d7e3c622753bc9765188b58278de58e2b", - "0x0000000000000000000000000000000000155d33c8914989120390dd1f1b565a", - "0x000000000000000000000000000000ee6a96b509792fe4cb08ba5b690a829260", - "0x00000000000000000000000000000000002334a82c7c45a013fd6565043b3e34", - "0x000000000000000000000000000000b64df10cafd4414f4ca1cfcc9df1104b83", - "0x0000000000000000000000000000000000146a7f5eacb3170bc6517966b91c32", - "0x0000000000000000000000000000009d478f8685010a03b0c7e082a0bc36f004", - "0x000000000000000000000000000000000000ba76040d675cb33d320e90572c0b", - "0x0000000000000000000000000000003be6828a9dfcbeaf8f85587eb0e140f22c", - "0x00000000000000000000000000000000002be8cad756fc14e20e65bcdac55d84", - "0x00000000000000000000000000000060d5a42641ead1f373092743119aa3af8c", - "0x0000000000000000000000000000000000164fde87f47eecf92ee4516ec82322", - "0x000000000000000000000000000000a8a3b797a6fe3470f8e4f7869dd43c2bc7", - "0x000000000000000000000000000000000017ec5446085f31ee161d9b3aeb1dc4", - "0x00000000000000000000000000000058cb2aac262dfffdaf058bcc776cd9a491", - "0x00000000000000000000000000000000000c3392013d42001efe4b51a9f9839d", - "0x000000000000000000000000000000eccc64c49eb40425e8fe5224ccdc43c1e4", - "0x00000000000000000000000000000000001f6506bedb6d949f1f86098e65a72d", - "0x0000000000000000000000000000002dd78f1fd00370a8383fbc3ba9753685ec", - "0x00000000000000000000000000000000002162b403b60b934527df3cdf67eaeb", - "0x000000000000000000000000000000d68ea8aebfb824365dabd01f6423c18a43", - "0x00000000000000000000000000000000000e1416c2f366756eb6713a61c29e0e", - "0x000000000000000000000000000000577c33d5c10b485d8c213d16ac4664dd62", - "0x00000000000000000000000000000000001dbb32af825db919015b2f62ac527a", - "0x0000000000000000000000000000004089798ec9503f6d851e3f36c8134fffca", - "0x0000000000000000000000000000000000258c2a8625473699411a82c908b205", - "0x000000000000000000000000000000900e70ab0eb295b2339744f30290816695", - "0x00000000000000000000000000000000002b8710de153dbcb980c871c8641455", - "0x00000000000000000000000000000064c8a69e30c314b2c9f307b9859388b725", - "0x00000000000000000000000000000000000274811b6c58c4854427d143980169", - "0x000000000000000000000000000000bd95ab45995e60444bcbcf2f650df95bfb", - "0x00000000000000000000000000000000001f24b2f347e01bcdbd025ac0559c85", - "0x000000000000000000000000000000ee494e93426c721d97ae5aa62c90310e73", - "0x000000000000000000000000000000000015237248ed9e657735f540e8c7756d", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000013c3bccc5388da92f5d871dfc5798c6f7d", - "0x00000000000000000000000000000000001ed1d4ff8584dd1dd72fa169b590d1", - "0x0000000000000000000000000000003de967fe48c15d8973f84a210a95dd64de", - "0x0000000000000000000000000000000000127264f024fdb1905c1b9311a69989", - "0x00000000000000000000000000000067ab29550dc70b79125476307dde9d4eb1", - "0x00000000000000000000000000000000002dc480e42e6eea643f7ceb8de96baf", - "0x000000000000000000000000000000b78c2d92f2d7d849bac283fd66764341fb", - "0x0000000000000000000000000000000000230044dfbb796950437c31b1813440", - "0x0000000000000000000000000000002864afee535c3f2025e8d4270039646e66", - "0x00000000000000000000000000000000000dc28f5cecb40979171218dd29e4fe", - "0x0000000000000000000000000000009a0ffd05fb01bef000cc4c463054f3c151", - "0x000000000000000000000000000000000021d43883eb57a05047400f4a96ef19", - "0x000000000000000000000000000000acf8cee1de7f48c4f06266c8cfbad2151e", - "0x000000000000000000000000000000000006cd8fd38f0b7cd6f9151b5ac5337e", - "0x0000000000000000000000000000005654df5102eb796e74c9de073e107a39ac", - "0x0000000000000000000000000000000000028174128b65de0f5263c0e175b23b", - "0x0000000000000000000000000000008ca702a32d860f9280e625c387f3521f13", - "0x000000000000000000000000000000000019d792292ea80445492b5514e0dddc", - "0x00000000000000000000000000000050bbf69e0ae3345cd601a80f62379ab9b2", - "0x000000000000000000000000000000000023cc9e9fb3e9cb8b7c8e06200a279b", - "0x000000000000000000000000000000c3b8f00f6e9bd29ac661c44ce1a18528a2", - "0x000000000000000000000000000000000014a93c6f48de42b23c9ac1f7dbe811", - "0x000000000000000000000000000000f5328aed500abdc6320165cddcaca4fffa", - "0x0000000000000000000000000000000000232b23c95bd3a3df804c4a93de6472", - "0x0000000000000000000000000000006676bec8a1892b306e941dcc5d4011100c", - "0x00000000000000000000000000000000001df5186ae0a33ea8836ed671a892b4", - "0x0000000000000000000000000000004bad445ac665f80bc6acf512e07e85bc38", - "0x00000000000000000000000000000000001d2cdff266585d4078e18118fa9092", - "0x0000000000000000000000000000002c610edad308e27919b035922986bc8bff", - "0x0000000000000000000000000000000000088752e898b6a27f557963cf76e0c0", - "0x0000000000000000000000000000004f28478251fd7e453b7baa9f3020a953c6", - "0x0000000000000000000000000000000000169c31849094fa7939daae18f3c5bb", - "0x0000000000000000000000000000005dc0a499195b7457c28e8736067f4aded8", - "0x000000000000000000000000000000000025d7847b139148f3fc3f063fb052f1", - "0x000000000000000000000000000000789ab89aaf1ab942d695d28b895ed5b26a", - "0x000000000000000000000000000000000001b405d8ca6f44a8937d1becbe4681", - "0x0000000000000000000000000000005d3e2c6adda13104da28bd3d0d40726903", - "0x000000000000000000000000000000000006657556bced744fca4baebc7a7a08", - "0x0000000000000000000000000000001f1e42fe306d2ed7e063bc7dcaae2d30b3", - "0x000000000000000000000000000000000029f36b235f098995d51d6825cea708", - "0x00000000000000000000000000000011de9fe4ab7736b1c511efcb2eef509918", - "0x00000000000000000000000000000000002b60e192da925f3d135e6641d4ea6e", - "0x000000000000000000000000000000f088858045a80449ef186d814d04b39f9d", - "0x0000000000000000000000000000000000153d832bdd7a9f6463622c3507f239", - "0x000000000000000000000000000000d8a9eebdce988c3fd2f0999930a15138b2", - "0x0000000000000000000000000000000000075f1ac6bf2a6b487ae46aa505d3fa", - "0x00000000000000000000000000000087ee2dbbf2a048bad137c4db1b8ebff300", - "0x000000000000000000000000000000000011cbf2a4f1f11c63d8eb9513ee53e5", - "0x000000000000000000000000000000f5e4c418c7383a63f7237510cbcbb73c14", - "0x000000000000000000000000000000000028199b65e442cc03e751b5deb448e4", - "0x000000000000000000000000000000a702cc20da20448c18d688e550e57c745c", - "0x00000000000000000000000000000000001f309a205e7f82854e940ece89372c", - "0x0000000000000000000000000000007aac52d4113e4e71f28eb47905e925a389", - "0x000000000000000000000000000000000020e9e49e102536e6956c9bae558653", - "0x00000000000000000000000000000001ba2d9676f12016903f2696eba0098b47", - "0x00000000000000000000000000000000002f61c08a9c545fd795f8433ca00c12", - "0x0000000000000000000000000000001edfe50b3721a067770f9499a6083d4c77", - "0x0000000000000000000000000000000000248065a6e53c3f8b8d3db47272f7b0", - "0x000000000000000000000000000000ae34cb14f3eb595d76a2dd9402b1b23d64", - "0x000000000000000000000000000000000017ec2c75eec02d3be50d530b2b11fa", - "0x000000000000000000000000000000b0c14b05eabc7a7ad842ef1166b9fbdd8b", - "0x00000000000000000000000000000000002e2832206b3d1167b6287b5eb53374", - "0x0000000000000000000000000000002bf99439219158d7f65fa75dea73dc9a15", - "0x00000000000000000000000000000000002149e5cd921f23b5d7de4650b9daa0", + "0x0000000000000000000000000000009a433e100615459dfb183f916b2062d61d", + "0x00000000000000000000000000000000002442616e2b0dbfa98b7ecbf193290e", + "0x000000000000000000000000000000c01f6dba139585c4cad33c1af1fc441f89", + "0x0000000000000000000000000000000000171aa053d4084079a830588b22ba81", + "0x0000000000000000000000000000003f6b7aea43a81106f616f3e575cee60863", + "0x000000000000000000000000000000000023f454864d42eb2c5024c72da2c08c", + "0x00000000000000000000000000000005987b401231fb970567be0badf86d7514", + "0x00000000000000000000000000000000002fdd84af6261fa6ee0f99f6bc1c881", + "0x0000000000000000000000000000001a6fbc62493ef0dc2c39bd5488af0fda32", + "0x000000000000000000000000000000000019f368e2c0dd3ae06755c7d83e1381", + "0x0000000000000000000000000000003800b8f4c83ccda2d5cff8bc18913d60e5", + "0x000000000000000000000000000000000014f1a75a1c0ce95480335398dbf82e", + "0x000000000000000000000000000000061722135564a0c33a56affa3ee1eb0c3c", + "0x000000000000000000000000000000000028fc5b4ae27c4be3b68af426e5cc25", + "0x000000000000000000000000000000094a72c62cd7f643f998a774a3c1692a9c", + "0x000000000000000000000000000000000002e23f17ec6396bd3bf8497546c82b", + "0x000000000000000000000000000000d7775db81e7c0c37e6940e97c3026fc49b", + "0x00000000000000000000000000000000001a76225c5d8d4a24eac9b6060483a5", + "0x000000000000000000000000000000d1322466b768603245adbfbe707afc9aee", + "0x00000000000000000000000000000000000c423cffb03800ad0f6f0b5bcb0a1e", + "0x0000000000000000000000000000001ade4e785ba270672b708c1cb93ca2fdd5", + "0x00000000000000000000000000000000000b468b6e311689fa6ec4503d2d1b5d", + "0x0000000000000000000000000000003a8473fa13716d7c47fb0a41d10f538fa6", + "0x000000000000000000000000000000000013151dfa49a54d259a8c4fec4736bc", + "0x000000000000000000000000000000f09823147b5a2f1315af76f84626faacc5", + "0x00000000000000000000000000000000002cfa957d32526624e97ec08d0763b4", + "0x00000000000000000000000000000095f75874399828c93364b7d272bdd91ad8", + "0x0000000000000000000000000000000000169d8b404b534c0a246767dc1b6cc2", + "0x000000000000000000000000000000579241f2e3236abb3e318f1a4266ba0431", + "0x000000000000000000000000000000000015c834520f6ae2df99028826545250", + "0x000000000000000000000000000000f31db19daed1017929ae88f4f3f8521a77", + "0x00000000000000000000000000000000002e3e6fa8fc5c271d95c32504342c96", + "0x000000000000000000000000000000156ccc48324606bba2a81e44d3033965f3", + "0x00000000000000000000000000000000001bbd1a661b55e4cf8c0bde338d994b", + "0x0000000000000000000000000000002e67e823cf8228948ae5c34f71a8347851", + "0x000000000000000000000000000000000006afe3e3e1b881c6df566f4532e8f0", + "0x000000000000000000000000000000b2f235dc16b84add85650d924582ec7dce", + "0x000000000000000000000000000000000013ec9ae6dbfc2a7310ee57e4cf96fb", + "0x00000000000000000000000000000043c924cd03d3652d1c7a1fa38eee85b013", + "0x00000000000000000000000000000000000b9e9493e39b71b0126548ef5f3890", + "0x000000000000000000000000000000fb37e6795aba9baa1a7c554c6614ab1276", + "0x00000000000000000000000000000000002bfa7eb130ab19d31141f4bd1a790d", + "0x000000000000000000000000000000aa4fa8ab5e1111f572bc0be8c5648dda2a", + "0x00000000000000000000000000000000000d1a47317b27c288eadb2a2fcec2e9", + "0x000000000000000000000000000000148d3def2091cffc18e7a99af26b32c426", + "0x00000000000000000000000000000000002978869bbda368adea3c9c670bfebe", + "0x000000000000000000000000000000f29b693ede78010c05b1ea2f98e6287d5c", + "0x0000000000000000000000000000000000285f6de42d2f63b6e09f638916be31", + "0x000000000000000000000000000000c529156a781367b9b39ccdb6f714cac912", + "0x000000000000000000000000000000000012afdcb744cd9b85dcf16b7e4794fa", + "0x0000000000000000000000000000003f0ee19f812e23c3e0c17d24cecf19ea9c", + "0x00000000000000000000000000000000002f68f3fb589c01cd8aa6215c944590", + "0x000000000000000000000000000000035e524c6948e5b34c206582bf43bf55ed", + "0x000000000000000000000000000000000024755c3619d8c89bb48b9d266ac87c", + "0x0000000000000000000000000000009a82ca92daff9b5992759a94953b8f8628", + "0x00000000000000000000000000000000003038a4b10faec561f34c2ea32bc713", + "0x000000000000000000000000000000633018b6c00a2169cef96b4073117721c0", + "0x00000000000000000000000000000000002f17430771a2fc7344dd1c104fd00b", + "0x00000000000000000000000000000069085f0ce834cf4d649d802da99138a95b", + "0x000000000000000000000000000000000006947eb82654ee05b374bb416cf04b", + "0x000000000000000000000000000000bbe898ab38ac7a24524eef7b79d2639f76", + "0x000000000000000000000000000000000002c40b232a07d9d11f3dac35b85dd3", + "0x000000000000000000000000000000047258f098b82fad4617620d0189f879e0", + "0x000000000000000000000000000000000026c6c071c1d3ad9e14eb001be27125", + "0x0000000000000000000000000000000c49a35af28b7e551244d77b56d59b5512", + "0x0000000000000000000000000000000000189085667c613410461cbd17b30c56", + "0x000000000000000000000000000000ca38ed6144991e99907f522e28860f0de8", + "0x000000000000000000000000000000000007c40e2ecae3ebea24bd3ec55ac484", + "0x000000000000000000000000000000bfffcabb70a790bc545c4ee3bfce18a260", + "0x000000000000000000000000000000000010e55bdeb1092f2a6444bc396cb56f", + "0x0000000000000000000000000000009c4e20b003ed4f70b4a62cfc57204f24c6", + "0x00000000000000000000000000000000001e00b7ff0421bfe32f28205fd0df4e", + "0x000000000000000000000000000000cf5869f07bfb05fa6a7b3482f3331f9d8e", + "0x000000000000000000000000000000000022c6e62a5e3445a01fbe8fb277eae1", + "0x000000000000000000000000000000b5dced535f594636ae43aa82db9c0a562a", + "0x000000000000000000000000000000000015b098ffbfd590c9db9622f8456377", + "0x00000000000000000000000000000069eea6cb45c453c7458f7a14981f8a4639", + "0x00000000000000000000000000000000001e577951336e913442cfa05d0e9a0d", + "0x0000000000000000000000000000009ef7b985877ffb4041cea6f6912eb32a8c", + "0x000000000000000000000000000000000020521a7cfd616db7e549b3c64d777e", + "0x000000000000000000000000000000e9f0722fce51e4bf5e31b757228e9ccbf1", + "0x00000000000000000000000000000000000fa84f6bb49d001a7506c96419e7ce", + "0x000000000000000000000000000000a761f66f198a2c14c07c32f6604cf578d2", + "0x000000000000000000000000000000000019635c073e9a560147b7295882e765", + "0x00000000000000000000000000000033deb909e8f26ca9aa0417a0172f02690f", + "0x00000000000000000000000000000000000880fc020fc451935fb66e22daa7c1", + "0x0000000000000000000000000000006367288f16161fa5df3f49cedd8a8e34b2", + "0x0000000000000000000000000000000000304e31fe6eba575d1b3f3ebef0066e", + "0x000000000000000000000000000000c5cafa7e75b7c69af15b1a1e1bc905d603", + "0x00000000000000000000000000000000000056634d879eaebb861aab7f6f754f", + "0x00000000000000000000000000000075b6c4cb8ee2d596e52fe1b3d9405cb208", + "0x00000000000000000000000000000000002bf855c3a58ee0e60041a921be728b", + "0x000000000000000000000000000000a4e608225e21e96a15388fd855afcb8bd9", + "0x000000000000000000000000000000000001eb45674390c99d0df7b66959f3a6", + "0x000000000000000000000000000000da7a7c3519858b8c78980a95a3c0ace91c", + "0x000000000000000000000000000000000004b30cecdd534cbfb3c9ffdf2ef2c3", + "0x0000000000000000000000000000003a35ed1dc0d1ff7aae4209529a34930921", + "0x0000000000000000000000000000000000210c99ed727129a1d40e9f9a7adcaf", + "0x000000000000000000000000000000fd35d6cbde8ca6b8e64652a47a495d4eac", + "0x000000000000000000000000000000000019c18ce002d04e602c1607ffe9a256", + "0x000000000000000000000000000000a3a317653f93cb7e27ab835d087169be62", + "0x00000000000000000000000000000000002f16044c7d21455e2e0af21446869d", + "0x00000000000000000000000000000052868428cacab9195b92aaa5470ecc2279", + "0x0000000000000000000000000000000000008866d791a72df4357df8031c5f7b", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000f6e131d6ce506eb0d3892b0c27cfe0f4a8", - "0x00000000000000000000000000000000001668301c6c961e364526eb8abf9792", - "0x0000000000000000000000000000001ace35f485f93f441c7e0a6df02303688a", - "0x000000000000000000000000000000000010adb5f7e278a58893faf2b4b3ed80" + "0x000000000000000000000000000000009fc2164d514381cbd046643639eb0897", + "0x00000000000000000000000000000000002f78c031ec3c08a5ab5a89a1d10683", + "0x0000000000000000000000000000007152fc85b72cc8621b05374d34058fd1dc", + "0x0000000000000000000000000000000000045f49a06cc7dca8937f78ab17e851" ] - hash = "0x16e2d4dba2d1561651bffffca7396ffbb146c6eea7b127f67a4b056c70bc7da3" + hash = "0x1dfa2952af644c59aa9d8ddec361d72059e139e64ce4790c4d3599963ba40244" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-private/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-private/Prover.toml index 0daea78c3d23..7494b3844f3f 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-private/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-private/Prover.toml @@ -3,7 +3,7 @@ anchor_block_archive_sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x08ead7d93a6e0ab74b47c029605a16640557a4c3e830a2f6294aea4559e5325d", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -3061,1017 +3061,1017 @@ contract_class_log_fields = [ [inputs.hiding_kernel_proof_data] proof = [ - "0x00ffd75efda6e34b65121fde81a69ba5f2a45acc69b143f1e333d23658e80f55", - "0x0094776a12fb89f4b79a211bfa3a123207f9ad5633b79be105497666fb335bf5", - "0x00d17297ba98cbb8657cb604ec67599c7a85328c46b50b54b0cbc52943fd2264", - "0x009dff5d1b2b67b894899ebcc54bca90dd7480e42a685a692c75d0f8055bec2c", - "0x00c0d25d3d357e684dbb3e1b28e7aabf97967a5ff28a67c38886575be5b6babd", - "0x0022cb2794ffb670f60a8dff4602cf5e93ca43bf651c52fc0919a8fb973374e9", - "0x00adf3b1bad196cacf4bbced5c5901d3efebf39d6b89e517f94d45ccfb1efbd3", - "0x0028c69ebe9961c53434f6c4d4f3e9921ff5b652674b535f132a1fc7c8228de3", - "0x00fe3ad1f7d405ad161fe64ba928307a2fbdb9ac1157dbe82e2d6d72f5044edf", - "0x002dc6b27c1b5fbabceb49c8ed5d3c2dec4fb00afe60324b03cca49974726d60", - "0x000f1525f80fe686760ef1f3b292c309ab7452b0c3678b4c0654b5ae25a3f32d", - "0x00dbcbc18aef1cd4c03e4335ecd088883fd93e6a2ba98c10d2ac34cda77dfc48", - "0x00f4e56686b75cd63c78b800bc9a5fe549ca6bcd9d6eca61c1fa5a104fce5546", - "0x0054e54c83d00911ef88f8f1ed287779c630a34045420201d0669f14c1b4de66", - "0x0018c65a26ab7e3b8ebac5221afa73da55ae5c36c08d9a0018da7d5d17e29872", - "0x00711647e952591a6ca41f5620fa9a03bb75790f8f81db6dfa82c31548480456", - "0x0013925676e49ac65094b4d49d52e1a170e5039602fcf864b0ac6f7e9da2e562", - "0x00d91b375ddef300c30fbb8aeab90cf398034b025f3a80928e5648caa4305977", - "0x005482eb58c00660408674a52b2dbcf144f6cd81e8eae46f8472f23e676656a2", - "0x00eaca2a637d4108f9d875a6894f7b6d422c7866620003ae177a6e3d0f8144f4", - "0x00e94a79f13f9ac53694a4f4a7937305f9ee22511b40f32cdc5295f811329b1d", - "0x0092a64411b0146c87875de91204ed5887e86adc0e1420b95095a40c3bebe4e4", - "0x000b8ee89f7b2e5b15306b27947219fa81b6ed217c7e2f062405610b17a3eac3", - "0x00cb681d138ffcd55f855e933bb676a70e00ee0cfe6b052c3ad9bd98b0f2830a", - "0x004ad7e724966e80273dd1cbc4438c33753f51003cfa7a9539e655b5500b916e", - "0x00da0e801b70978301c27e0932a556f858dae29306da56a5e9fc4d12ae81d4bc", - "0x003c88b248de4edcb308ffabca61a81d0badf09ab8c0db324115cac211a33315", - "0x00fa54e31397b715b3b4f78d101a92f46182627272e4bcaa9661c18423b7aad2", - "0x004bf3e6103dbc0f11e88e4a96ae979650b453fb23293d6042f422ecee105c8e", - "0x00aa32266a8e4a7794d11c5cdc0b3a94828fdec171940886f71c481595573c45", - "0x004d234cff37718289fedc718cbc31527aedea95dc6dbfda696e03b7eabf9023", - "0x0072505be5605360c6974f2456aa1ef0a20a9d080af340cf4ca3a9a605398257", - "0x0027fb05374784e684c91cc9d14237550a7c4f394cd83dc375629c0992093892", - "0x005a78001cf50b1003c738fb1d5bafa348bd87a995a627ea058d269df6467538", - "0x00f5a712d8697c55a2d079a425ea01b2d5f1835a6024452a4dee96d8d84ce12e", - "0x0049b1ac87b46fb780996fea081b31f7fc3a48e93b44c74b961086fac1dec208", - "0x00fad978518359b69586fd3898da97a077f2c7cef71f5092a187a0c514c3af05", - "0x00c59283427a17f123d663975bd19939ee89775b8e7c94fcd9bd5b3241ccaab4", - "0x00923ee87ab5358cec0dbd2a80b8692b4bf7f4dad1f8d844f4a7f9ab4d8bac8c", - "0x006b4cfa0700b36c4eba18ff146692a3280bbfd3ca77afff2ed4f28b77279806", - "0x00b3df44b2ede48afd7f8623cc1effc2ba735a26f84c7bab2fbefcec7811f5e8", - "0x001c2661dc49f216ea9d0a8aa92b42bd3b47d33fd14489514cb7f8bc27904e48", - "0x002dd11f2ea077b2dae65a51527862c022df36c0307acd228dcfeaaad24c348f", - "0x00cce3192f03077621ac9dfa9d3c74578df9fc4cd92279c5424a5005bd96d494", - "0x0019b5385a04d7a04bc5e959cf3c7ab40161643e708d0e7fb4ed3e041ea05b27", - "0x00c69e7eee0f2d74ab6f09f20334f09d71c70aa1debc9ea6982a4466a1b0d940", - "0x000470dac797cee8c98eff759b080f250f4741af184c23ce815aea4cfc4e8c48", - "0x0077db2fa409a80393e0e0a2c11e9d70c2e5a8638c1c9437699dec6294712973", - "0x00dbe9cc8ea14f3af035459adf3a81e8907f6825ecff3d23339995592e3ef0ab", - "0x0005cd8fa6df56ff6bea8aca5174379bc05b1be3005208151bc6ff12127acfed", - "0x00fe3a1af45ef5e3ad0e4600434f0d35e2f2497d0f2b8af16731563ca0e61964", - "0x009e0611af494263d72231e5bd024838ee9d685df45054adc5605287dd911383", - "0x00cb244e2dc1b125f1b63565440a6b12d7fadd2f224dd9398eef59dec2c519f2", - "0x00ab953633f658117abda1c94812bf746724499504dab6d9f73ca4b1e5b479ad", - "0x00a5e839bb44dff0b346d4785e34274d2efbfc96466adbb951531aa23745fdec", - "0x004081ac19c5d624029d58663f1a2d81fb43559ee9f4a0ada6939ee3cbcb59d0", - "0x00fc77c7714e75ddd629369407eacc37d4f06ebb6408e1a674c2e6f7458486d4", - "0x00200f4567c708d8bf6305e1596756bf740c1565b6685bed4acbec81c21e334d", - "0x005190221e0ed1fadb52805279274d6070b4e66e8f99d6d677c5ac7698c5585d", - "0x00c060759e742ac60dee8624e7bef11d95c25a75752ba54a9756cd8a3ad29b49", - "0x0088bfdbc2d149a96860d92213b3efffe302b8047b685f2f070f92ffd11f126b", - "0x00a9709e3d7c990f3e9df6aa1158b267befce727676a06470440a3d439493fa5", - "0x00481b00e3ea9fed099f355ff7d93f845461ff60187d1a93048e185fb3fa17b0", - "0x00b0ad26295afe5052a8a146fcdd7256616c8502f52c581d39939284c10b88e7", - "0x00f37729095752021c4c756ec5f82a1665dccac4838106225af649aba0719466", - "0x00896364974c0f4ab9ddf0ff8efc0ea0291196a724c38c9f0bfaa824669e735d", - "0x00ca06d90a05cfa04f1f12c01b554b77ed4a1803ef900d1739e5b7e0fcc4298f", - "0x005cf219fa11cdaaeecc9111a3c6d5d9f6b6ac48d73cf2ca8459f0001a7252aa", - "0x00a0dcacf4d8909895fa74ac2fb19dac071f3eebaa87a9b288569545d3d4a459", - "0x00560885c50c9b3330f2883185fb9fb889d8274b7aad7c09287602cb34b57736", - "0x0014091ac9016c73f76c16da9ee2d7c0fcb1923dff44069f3e0c48516a489dff", - "0x0011f6cc01f0c634990c827ed8ce622106bca44d800dfceab72eaca7b97aaf26", - "0x00062a8bdd4c181da3c0d8db39fd5e3fb4a2c73502e74d1582545241cee24f6d", - "0x0002dcdf3ef72c76dc4f2db72b71f0c38092e7336e4819ab3071674f1e213948", - "0x00d300b5e4bc03e1786182b5e2acb06b9bcecf220dcfedf8282cb66daa14b336", - "0x0098bd593aba34edd8c5ab0196ef9decf21b554fdefd3d65e20e0bd10615f893", - "0x00bdae3b00f52e096681762b639eadc26f8d5ae0152e435103664816630998ab", - "0x000d4377eb4b67c45637153ce4e9d91ed9cfb974ecc78b839f6accdacb71dd92", - "0x0074b62778d941a2539ff5f3c5612df968c04a5edc39722fa9c58fc6d79531b9", - "0x00d4ebaa8947bf046bf3d9c56661d4974fcd2c59db6b00534c338a65567759eb", - "0x00a53e0d5d5a57bc2b20f0a6212d3dee63816e0ac3adbfd7c3c688a6477d306f", - "0x003dd28b3becf359f1038832484168f47ccfb88daf62379251f125c14c75000d", - "0x00049973f1c05f070fe62138443073bbe3f28dbe2e0389ba7350220dbf127c8e", - "0x00450aa2c34fbfcbfa2ff9c037426f06c3fb1686ee6f4f12f5b4f5afc073272c", - "0x004f8dc9c25c46adf54e838982fcc9ab2396a13a8810d4cf32cde4168ca64f56", - "0x006e8e03f85bc18191b58538adccb21ad65246f59e591f97f48733f7d6bea23b", - "0x006cd3fb83405999e677cf5d7487887acc7b1cc496aa44e297166bc89ce65024", - "0x00960212536689cdbba2bb302a06be296fafa80c8188d0f63e081c7c8024e9c5", - "0x00544a83d08c93b1389d7725528861b5026c2c3e85cbd85ecb68f3082908a73e", - "0x000e7a9088d83afd167463f0837390214f4000db121bae34a90bca1f159b7e8a", - "0x00f98fc88ea73c8f6942d155ef39829684cb33dc0a9b408309fc4c1bfe22b894", - "0x008e676979c9c2c35c2e53e771cd34706c337f220952e07aec75be0d51145027", - "0x00f3f80db41e4d5b34a48bcfbcc7f82f3b878d81da4ee41d739eca84037b9e2f", - "0x0054af458a4daff7aaa295af26733ea8d49749b759bccef54de69638fc93799a", - "0x009d699fadc87947ea6d2c12445c1a5265ff01ad0c91582fa4bfac62d95cd3ad", - "0x00a2a16b2d92288b9f954d012ae4db21e50d538a94c38558cba0899d7e73e2ad", - "0x0067b4a5355b3b0087041a43f2ab03ee7745df904fef5ea244d039c903ceb091", - "0x00d7a48abc04a190ba3912271166e8dc93fc86be702a6411d7d66d6ecb9b293e", - "0x00d38a3a570b4d0e3bd2a304c34898351936db4e8e9278f331247f77c736b210", - "0x00872ddb3e904029c680fb188e5475e855fece2fedd07f2a4ae1bad46ede51d3", - "0x009075efaeaa2b761ac8520a05f8d633d5018f63fd4b27bb140fda33483b33a2", - "0x0074283d7872f1ea5f1b97b8f9921faea86c1cdbd66164eb39dffc6bede8558d", - "0x00c56fc456899d3e6ce3f1affbb9b7b070b7606a4378c1878555c38dda18ccd8", - "0x0077628608d0615b89905aecfc878a2e56ece2359ef12a196f200d094862a2b9", - "0x0028bf28f847b0f28ea3bcf441390d6688d6f388d6c14d056bf810c0a2e36012", - "0x0094b752463346e22191e752f55e58adca12af840b7491b8630e12e5bd53d87d", - "0x001f60ab6e2bfdac64e66e9d67553501cf841d8ae37fe2aa8f469ee7680760c7", - "0x00dfb73cb441dab864f6ca5fdbf5cc6278ba1905b663970340175eeefcbf90bb", - "0x005c57d2a80127b9902f9799f172fe384852ba94a84e8454b823bea37b6c6bc6", - "0x008350a4f1a5bbca102bafd6aa0fdb0d547cefef0f251f0fac0bfdbf45f6f535", - "0x007e1655610eca51be0a6518710cd90ff44cdd78a60ad37bca7a6a99e784c81b", - "0x00c896fd7f29c3be28f83c987ed24a96883034b4e2c86afca477b70ce3bb48a5", - "0x00ac938106af7be51e768d9f6c0b31b2e8a5aae4f948fcb965e8b512b1b115c1", - "0x00821ca77be45ecab881a47a312782959c9910da5c92ec3b465363bb9318eaea", - "0x000379a5292696b0c00395f7a88f399d57d1e82553fbf2b00edbbdfc4b1cd670", - "0x006a4a43463fb2797c2a64e82f5ba9cd0aada8500947b370a2b6c1509eeb96ef", - "0x002320aebd6d209852a8b20bc96027da97ffe47230146f331c3b2fe3ef5fd166", - "0x00084900fa32b26e930cf45f312d3c951b715d8c0d92b6d7b15ddc6cd2dda6f6", - "0x00094fe8e88d007793fbbd41812b45ef1bb92bce16f1759c030f0f30e5a78b35", - "0x001c4ae4a057fce62c55a015018840fbce0155f39dcd90f1c85bf0d3cd478320", - "0x000df43e5f53ebcf4dd664c94eb5cd93afb3abe811d9dc9da7b1679ece9bcbbe", - "0x00c373b8a8e96f6c15f165aa1f44677c65ffb3cf2586d235017d2ec7202a83af", - "0x005ac0d0316e9e5b58c9cda198618bf934350ca446e1d89b9678d8febfa7097f", - "0x00db546a5ffc90afe616014af94fba468e0bf9294a9fdc9cc018fce0bd187f79", - "0x006f0f795c70daa026780016ab81ae08f980dcbb16f5b66a48bdc8c1d8ed78ac", - "0x0053112e3ef6b8bff7d3c974890bd8f21f73fcd29104743047857d1b28cd5272", - "0x0012dfe8535397ca222b82fd8d1f81049b6b329fc8e8c04b9df4b6b7a31d8d5a", - "0x004c579a0cabef2ba7b850c224d97eafe93ed023c801ce34d404542dc699ef11", - "0x006438d149b3d5c954b5c2c6bd432ba51f72db66407335f43b20487cbcc1526f", - "0x00e710daf787f00e5b597f9bdc0d9a4386ef718fd709986b1a8d0b28a5eb81b4", - "0x00729aa5d89c00f22753a7b1e4a2cd1266de1d310b8f7d3bad6082bd857b7bd5", - "0x00403c0b7e953a13c5256b9462c07ea69472714235189cd7734e0d538b8db887", - "0x00fd4ef4be186ba095017acc419a1a8d7ebcc5d3973c4cc77cc164beaba73754", - "0x0099e12b2609e52f328f354774bd596258bdb35f33480df2474ea08696b87f50", - "0x00b82de1aa129698cca68f2628bab1079b35b17e437002ca53ed3255e1d9da34", - "0x0065c3db031004b4a6e4990921825f56f6f422d1286d4979c7f9d26c6358e712", - "0x00b9d89ee4ec898236d76f64d2dfc13960d34c857f9f14d1bcde5a6b3e34b7b3", - "0x00e6fb2d7923e923471898b2a6abd8e68b1e633fb5d8f2a97fe606e6da15543d", - "0x006bbfa2f0f0daef13ab7e09bb0ef99b279a6b7ebbbc12ba5a9f47b9106de112", - "0x006595e5c105f34c8c4c4d4e67d31ea16155682a65c1ba7f79cf27212b8d361c", - "0x00d1a2660dde4ab6a0ad877f0df31e2ff0cd0dc5323c01821f599d642b951be0", - "0x0081d8bcbe038387d02c809fadc3bce26132a1ad7a47e330ffe839ea1c89b3e5", - "0x00576b8bd38a2dcb3ec1b8ad9e096c202ee4fb55aebffc89a03d2d47f26add5e", - "0x001cba28aaf197f41e1dc41a81d0c88fee35fffb6d042d4487154caa422a6d8c", - "0x006b81e2330ab8f4d1ce4db000b983bfce4791b7abf2efe5595b55360dca7969", - "0x00b4401865c0c3946f1d81289ab27a6033fcbe235401c37f22bd02c7c2e24428", - "0x0006127b874f1cecb3957e777b4ca2fe721a97d2fdad5a2af4f68413ba979959", - "0x00bb7c0a9934bd781f9f1c681acc25f427f07bd2e78aad85a501d3b606984495", - "0x005d76103ead6a757f8fabb9c72020d6bb90ec103d3e6ea2f8692046cdcbb45d", - "0x0019709bd085b1f93613b32fdca2c6dedd0730a646912fc2f49339ad308144f0", - "0x006eeca96beb05e0f9f698616df386f9712d15f0cf1c1c5cfd6afc5225c66948", - "0x001eb5e07beca7bd38bf6c4b02e7997ecd13980eaadaa86d6ef58c2d3918c62d", - "0x00fe00922708a2aad3a04daa28a593b6bf6acdcd823d4625a931c0a6485a5aec", - "0x009f237894bb526fce60e5c637901a1d3e08d385a075700e6b022717c8f447a7", - "0x001cc87573a2403b57c33c7183741d6d36c15842cdda37d23778d145d14da4de", - "0x00a9adcd8429ef9b8f3d3ae132171c592dc0802fad274195e50ddb73824694c6", - "0x0047dc2ffb61192b0c493947c88b1ad1ad7dc0ffdc3e0c04cbafaf769c536220", - "0x00c059a88961db19f636a82854f64d1ded34fecd9c585ebf9d4aca2394379e28", - "0x009351d93deb3b3ee7a35aa01333ea9ca7d61c992964c07401b25647bb37ea37", - "0x00db6b15ffa6ec93d39147b7a9af6aa98bcadc690909f308f2503a780811cf9a", - "0x00fd6c330d8dfd651c813ca035f477797596fb899bb11a768f1b1a52ea85755d", - "0x00c7774db0f4e18244137cb81719fc2eab000d9d153103ed8dd8f32c4edf1c13", - "0x00afc4f9d1ff14d489dd68521e0ded5455d70830991dd6e2708a58356ca12e7d", - "0x00929192a946977e99104ee11d804b4a08e3d3da6485657ca0627e4997379710", - "0x006f0745aadf72ab233cfecfd29b3597360c903c1e84df03e0520ceee23b4a57", - "0x0046f5e6db10eb3714b755db5c5e7c2b3ac2668774fdc08c735441279ad42d3f", - "0x00ebd085fbfc64309b050d27d23aa593384f8675192df988f0622d2326d4b5fa", - "0x0051d30985d7420fef891dcf954577f43f72442dd14958007069161715fb81b4", - "0x00412c89c8f0decc36298b1fc5ba23469ac29cbc49c69daaead41bd19dc09582", - "0x00f8fce0cbef040beb905b34ae2c996a0ef885682bbca113f8285d2db57577b8", - "0x006c0ceaba27ceda641a17b1427740c990e1e437c77d5e23266872cf00a36c2e", - "0x00893b6de2c88c4a7683f0ff07674b3df94027059859af2e7dc961c5dc5ef422", - "0x0035e01687f7b8d267ddbd5d06d920c1dd38bd2df81ea60b19c5462473a330ce", - "0x00859df0bc08c635e533612e5076771e2828591753e04d3334e3e0d05433f144", - "0x00cd9272cff295baaf871105b6ec5122314d3ac7c2ee1b2f9d0e7879318634a6", - "0x002c87cda016444dbc917e11d0d8335f61ede22f4fe50626bb5f6ef828730dac", - "0x008224e5fe0d50a304acd9ee9c68e192b08f6467a546e34706768c971ad66147", - "0x003f1a06b9f95b85a086f203180d62e04cf14a37d78619467625a2d1f1633f78", - "0x005cc6b58453d764cd710d8ab736495432f18e38d08c003727dd87bae7b42c93", - "0x004454633281b2a338fa9c95968a5b275f6e1e5aafad780934864602f1cd2087", - "0x00e5c8023938a790e06abc1b8106aa928f46c2250bbbd4775d1a54cce7baaacd", - "0x001f916f9091b389c433ffdc4213efaa669981e189ebb69d3c284978e61bc15b", - "0x00e98e83d99d75d0fea9fefc315b8948d0f9a7acf672da99de21c3404da94718", - "0x00feceb7c5e1072097e2a845688360588446cbe818d5839cef07ad1e2993bae6", - "0x0005cb012c5aad05df939c952d4aeccf8fe41c374f89cceeec9f052b9e4d36ae", - "0x00c5120938da314252f6bcecd19c59c6dba4ec7b5c8e520d843d4a2de4f1b600", - "0x008a994849701000b98dd8fcf80ce7b201a879c16669149dff6402bc40e5a7c0", - "0x00c97d832d3751bc73fc6fede1bd7cfa98dd2c4bbb68a6c8383839300e682450", - "0x00b28f05bbfec9df9bab03e383b61e03be7eab8296ea15b4dc9ae7018b05f410", - "0x0045d0948a36255ead2a4e3f67a7998d1f43ee582cf8e2fe33956ecfbd94a3f3", - "0x00803739861d21c9fed48738f35ef388d3f824a867c3adcc13867a00f7aaa841", - "0x00cbf27734572c73b5a951d1d670c4424d6a334eb0df45d45eb6e4e32bbcc1bb", - "0x006626f2d2e74ed28ce5e8e928a6cad27acc9af56f54bcc011c5e82c797f635b", - "0x00ed10c007e316321f34cfb631ff8260203cae956ae96e5af80c6422a3898917", - "0x0063d2fdb6e2c228381da5d260f4b417408d813df544d3a6e8bb00801d051bc8", - "0x00fa593e59765b7a27b7c31f5328abbc901fcd4984bb548637760c7d9626a442", - "0x00b97fa0058eeb124eef202db8a976dfb69ed659cacb39f23bf56f948fd7c796", - "0x00f94c2010645d948185e5c3a2ac60462840e4a871a92af1f64df8886a580286", - "0x00cac18445eceba6c8725cd0de1263d5c4173e5d0cf7aab73d738b6a31a45a85", - "0x000a2113239fe3d27b3120542813e1bebd70cdfcfaa953296fa32af0d0737178", - "0x009f960132dc779a78675640b618f3752d1790204bfaf8159cff245718f7241a", - "0x00e67a98c71548b543e46295c54f2231970d238c26b24b9daed786aba53a2545", - "0x00fb5df950e6965168f0a8f3f66864b1b620d6a96fbae80716c76f59c3a281df", - "0x00ed3914ebc916dcf26e790381aed9a941d5c69b262037cd75736e96362e2094", - "0x0087f910e892ab621049823d5631488bb2258fa10af61e8ca5b7dee6ff5422dd", - "0x0039d386b2a5d26debe8f0fd33593877c4d511c07f036693aa8a7bffd79479bb", - "0x00bf53f9ef776b2dad1e14cf570da2b3c6ec5188abab81f5b629d7a6331c43b1", - "0x007ec3f9527a354470924841e137b1df52cf2eba5ccf5b9f5d9b886749bff249", - "0x0053071b4a36a52a417530d34c3591139d44ce602dd2c8eaf988a95746395db3", - "0x000587592f2468934db51946107a54558d95367c0576c1ce536744fba4492d71", - "0x0065af317f0fd32d37e628f8e18c9174fbb669203ff313a65166b7431668cb6c", - "0x0044e779e4e05417f85967929a69a34f86ec199d2ce31c4848271b9daedce37d", - "0x009d0d7d8695c61575a96975e8ad5bd95322eddfde0a6af9e1a7df016fc070cf", - "0x00c187c9f42d0b9e52ec528b8010a89dad2195422406a6e3985fe3d93fc67b23", - "0x003435fdf41c90a3026d126b5c7d27a4613961d4e9140781c2d9da7cb93c5177", - "0x00a4d559a67cfafa5586f4dd41a127feb8922538dc5fa6f674df6d63b2c51ecc", - "0x00a9226ab679d1fa7fddad4a15866812cb88b3a4c4b36c2026390fea5b69b389", - "0x006c9b8b90fa6126ec0aace713ba6b250b0667032cfddfca72b473d92a5007cd", - "0x00a0af11b05e1aa5560947d6c7addf8ca31018d34f2dc6d32b3d0ab074e63738", - "0x00db831fc2d3815776aaba48befcd028892967d4699164bd5074f8d157853d53", - "0x00cdbbff416de0f6e41582566437308ba8c076848019d74ad8b49627c51a4f73", - "0x008179ea3b56e7a97e80c54948dca87bfc121970837357339727f1620c444fee", - "0x00569197e1d57f2e55dc558445e60eb39874afa6398f62d7e5b13c7122f0920e", - "0x0033b1475d787c2328f268fa21ae15aa7f23c91f1807c4252b4af906b0a5017d", - "0x00ba222d8faab6bab3fe7924f542c42703a4532ec2b12db64941d6da94042baf", - "0x00440007981d35f9807cec4ab3c1fccb1a7663b4b519319a8ff702168148cedd", - "0x004b6a9db0814e8745b843820b311ef303424f7d59b36e8196b431eb4ad1b5e2", - "0x009974c2cf09239241ef41cc58a9876f8e139cb9901a4fd601661e61738effe7", - "0x00497d94e7ee3502f82e0372b6dcb2c7d6a6baae2806e8f33e1102b8b09b9a42", - "0x00caf15f143864b6d30bc45cf25e31b4e44d059e9ee5d3b680a0cefd653efe0d", - "0x00434f6eb2de9d610084a97a35db3c96eb243fd1c32f05c2838366978de98723", - "0x00c295e4bbdc97aa43b76749cc47e59454add92f808ffb8da24578bcfe3172d6", - "0x006f9d8f49484fbfce068b40e5a8a861c2f337bda1d4a9f2798b7b6930df2812", - "0x005bd671744dfe868cd0d6cb537aa55aa06384c9c6a996cb4c9ed464c7dd57e3", - "0x001c3d99745d675ba6ecd235d74dbfd695e266a4d81305f4b5657ad324874b27", - "0x00a2f2e6e5c4841bc4b10bdca84461f16fc075f1571b5755f05630cc92fa14e2", - "0x006b1592c2792f603b60674378f9497d74c510028b91e488de73febe4861ab07", - "0x00bd696fd25342d9857e95ed3ec8f9e98d115f47e6bb66036785e8883939987d", - "0x0015c4a748cadd901e0c9b8349b807c87b6831e006005fc9b413c8c9bd698fee", - "0x00e107f7e3ff4ecbc45df43d5d1cec06baa93f01d4b4615a9453414084f403a9", - "0x00efb6503304bcb43f887f3f0486c57dc0ff4e4e669e32687e889f3e5d46b9af", - "0x007a9dbf1a582cf78d81a3a40e932e2bc00ea172b755d780920034f5ea6e1b60", - "0x00e7eecf2c063dde782cd63eda3ba4b42f9827e68711d317e414949fe9cb0710", - "0x0008935dcb8e91efc2b9831d4bac1dc4e56b98a8159a40cd232c178d5fc5cfde", - "0x00cf1838d052786e8dfef6a7883190317f4a73357652d5d665202cca1429deb2", - "0x0010c3ddf277ebd93bb2d5fee0bc7d0edb843359e64c5dfe82c3b0d48efa873a", - "0x00c824a9533b66ab045697eedd253fa18cb1e95d850249d3f09c2a938dcae0d4", - "0x007156d6b02b018cba8760a0af3756a3b94144076ce812e11ea9b00d050c0efa", - "0x00b4d9bf8ede6d11f69b972edbf54e36e94707f49fdbb17300caff5b7a1d070a", - "0x00013d8a25340fedd8e15e8d25ccb630aedb822013524edb278818c9cfcaa81b", - "0x00394cd7963cd247252695b972c18ce9682a027a22a351d06181645c929e82d6", - "0x00de672f48d3d8eb72d64a03e3672b70f9239c913e3fe02eb0c35f722406e1ac", - "0x004508757a2c12e60f996b6848ca330fb8cf405e12865aab691bf974752ff42f", - "0x006d7f4d16aa07e6c931e737cc01a9415c9b02373acfca42f3dae9526f71fae2", - "0x004e7f67cc8442552e1c0e09d9f758a3e5a869e284fd3f8bbaec144c7e9a3bac", - "0x00afb991b35b029c85b0ce6acf7ea08c11e33a5e7fb6d92fcba5217e5ffd1a62", - "0x003f485ce8bf7b480c4c4734ead950995025911a1d48fbcbee5095fbccaecc0e", - "0x000d579c7b1e0ec1f4730f510b9c72f956117d17c8a3e6e5446feaf5b9d4a50f", - "0x004c890392d4210e246aa06c0053b88d0bd1a53f5e4f64bd3bab3f5d9ae99c82", - "0x00625cf279886246d867cd940c2b3bcc756668c95c8ed06025055e7d38c675a6", - "0x00b1d6b739b9d1b27a244adf9bb95e7de44f940729d73bc50928bbf4e7a075ad", - "0x0056dbd27a9debfc94f76a80513b02c16280ff7015f6231530bd24d860650416", - "0x00d25dac66eaa0d1bec2a3e5a4a477a4d5478d15c628f0c1ddbcbc1631bcc567", - "0x0063e82a55d1561156305314214f1ad41985feb85435f9a31dfdc7503446a8d8", - "0x005e83f1c176cc85d3196e495e6d2418374c83b2e945e632ac5ebcb51e5ba22b", - "0x00b82bd386fdeed319d28d5c0c7b979759b86cd6112475169a5dbd8c447743ae", - "0x0043f95a57b0747d61d6528638f74c23a9292bf01c68fa7c9a2ed646300605fd", - "0x00b6a28c85cfceaa33b6ff1e7b633844f464ea90fe4803ab8d6c70cf789ddd27", - "0x0061eba3447dccb6af71f4d2ee1a0a2b1c536e4e9719b034783e668ee4d22c93", - "0x00da3da7305e90e2470ad554f72c3fa39f0ab2ff4a027da47d6fa339eb54d458", - "0x009aa07e92693637da6b27b1a59b7269ddc3f6fde9c2f7f0b0757709ad5f10d9", - "0x0095e4e9ebc98e0fd1a463945051c4fad05fe8e7a40de7ba0955481c23246e5f", - "0x00786591f30ea8cca4d2e6cf5e8e167280fc88b492ba3d66a4e820c4b58ddf31", - "0x00d293eced477f1b512b571a896748fa28fd7b959de24a27d18931cdec7f95ca", - "0x00488fb8bebf5aa9a9bb8fb15d198700f164dc312c78b13d7a549bd7302093d7", - "0x00ece734a1714105e1efca2a23fa52b530221dfbc77068d6102ff528a2a5bcc0", - "0x0004dfd8541ee0983ee999f8fb3319729345ae2b3874e3dba25d9e1cb2a86136", - "0x0045f7705a9d879316b815a2168c2aa064bac071079da801743be070c219399d", - "0x00080b5740d36fe624daa440e93a2726b3c06d73f7fff4ee665a2fa7348b43d5", - "0x00d7ca72828209ef2e035b944b77626bf623f4d5a47efac129ddd51080dbfc3e", - "0x00a8532039dd04a051582395ccce3f4b0ca8aa0bd97a14ad5a596795bc55bab7", - "0x00d3b7dc8a994af1eb3b4cf640a038752d50e6b13ce2ab32ae9fa3c4094bda53", - "0x006cc4a20d6fec9047e3216c530863d6937f07a772545c8a5b0a6d7c440b1ea8", - "0x001ce20b88ba8332c8dd90f2b68f22cc0485ec1dedea804e2cacbc8678ad069c", - "0x0026104e7b5f85abd4de1a71197f15ad38742bd9e760914368c4b18670379c36", - "0x00b01e7c7738117af7cebe580cce6d7a7e612f682d56ec276cb1996eb8900d37", - "0x00f4485c9ef6dda339253649b1f9d67e09508c3bf3da93953a5fca7e6e3978bc", - "0x00793bcbe79176a6c421979524aa30b789772322ba10fae14225b629fe602a56", - "0x00ff6805402adc003952288a2353935c668264ab168c10ab655a1d77ce168d1d", - "0x0068cec87c83f4ba2cbbb2ec4dc16984e6d86261e02900d88e17f89b8a8eed7e", - "0x001d932cb122169859d58ec76cea9a7e93322ae34e59fdf0d69fe03731a23b1b", - "0x00c31104b882eabdb66a593989ba644f242cf5bd93bc558be98baf02f595946d", - "0x0073547358ef777cb56870a820a78f20697c40498b51d11e0dc34d6711f4e24e", - "0x000851cac7427e53b2f70000c0a2c7c96d31f80566f35986a22730f35a9fcf91", - "0x0035d7defd9d73f7a6bd058f93938e352e372f580d7098058b2d8751043f9b16", - "0x006a5adf37eeb382765b95f83ae4e95c9df07d89fb47481b299664aa254babc6", - "0x003980f4a613aa9dde7568b58f4a86c9c832cecf63d2800e6ce4466fa47a95c9", - "0x0010b01decd2829c49145c579cc8e6b8b1066ab168df17c7f2ae4b218c396225", - "0x007cf6b636072af9ac70356d3d42b567e39d1c0c725c1dea9a8dd2000185a4da", - "0x004dd769682eb9d81c506a8305de20847da1a6b6f1b0b62c9003ad4cafaa6a9e", - "0x007194cfe26ae27ce1aef7afe598369b3d08cddda1175f059174c81f391a9885", - "0x00322d54b321e759ff7d83d1e28aadb279abe9d4d1baeaa8de5ccdf42c2e0d16", - "0x00f3f115f2b7025c38ea32578820435340af0036dc7360d1a3cfa69979090872", - "0x001f7bee2bf91a6d0ea6a10496489f6aca2a383905803c545c7ff40f0f711142", - "0x0011a91dba977a45fbdaf8adfff1eb57b66b8f87e7db1de8b8d4c4eb9ccebe8f", - "0x001e57696e18d9a688cf0002eccdc684c15cad451e679215e8a65f862e3320e1", - "0x006421b1cb7bd2b13311a859c59da97fbc3d5d5bc25aefd900ad4e16b8b3b0cf", - "0x0026b17fc8bc48c88e047c8b528edb21835a18af2e0d874d381303aa904eff0f", - "0x00c1961652e30e94d73fda8d799e423d8bc764f6d97dd8ede1a19c6c5dc70464", - "0x004a6e001397659e7a0bb279be9b7903f532e7b44590f00b6848754bae009d42", - "0x008a9dc9489f4523e93daa72821dd65ffaaec5717b18598c93ec6ac079be3069", - "0x00da341e23397c124f0d53ac401cbcdac3c44747c1bac1096c6d98c0da183d5d", - "0x006c58a3f37c5df707e8d94c2972beb52f15e47355539b9addc0174d6c6be209", - "0x00cb187f0e15164cefa73998eb47927a9916aa3260c64b60a3d2d6f652904e21", - "0x00ba08f432383d58568473298f2de33e1f8ff2166a2c0ec30fa2f77c55d4a045", - "0x003462a547dae02a2afc2acabbc6bdd6d564c04cd3adc5ecfcee0851646d7e60", - "0x0004498ebc76965512143e2f787b1616d4f25a3dc0faff3e8683c587ee70d949", - "0x0021f3ce4afb60658b25454056f963f050534837c6ba9e4a7644623ca7f54783", - "0x006d6e9c5e2ea31cafffb24c503396b596cee93175fafdc93727e4e3e6c700f1", - "0x00ef307836469011447a855cb184a328141b2263b4cdc9b1e7414f7c419b801b", - "0x00390b4f404ecfff6e61d5ea37e9d75f30d3dfc700b2555495d1f31ac8341c8e", - "0x00b887045c4b1a3daaa05c483381500a4d462982b2ea46b255886f513fa8ccd1", - "0x005d616f0e3db7ee09628b2b5f553b7af1ed979b2c627b15feb2e2a3655c390d", - "0x008cb16a58c81f3ac9242693bea36dab1c50b074ef01ac832250d6a4302071a3", - "0x00e12fa70a8ecafaef84b55ba80724b6cacea2737fbe24cf88abddbb787ac08c", - "0x0009afb6dfdb9ffd01daafafb6286cfe2bac31f92985a50964163072902afef1", - "0x00a8bd1773264a1d771aaa2af0b6acd9123bae285aa5514f984b16723d012868", - "0x001416245c921a142996e804c835df3f152603640503b91e1695efbdaba4dc2b", - "0x00c918d3e883e038e1622256e0b92f6e2b483dc6d18c306efad62b49e82ae128", - "0x00f3b35c543b95d32e7bba0a9d40d8f2707e7761e25122b1641b028920750774", - "0x00b76f6e2559d53433fd0f7a199bf872490e516ee6cad92a6b5ba4cd3ae186c1", - "0x0089ba99c77ef9780b4d155011a2f4be68102064f5de3c9b7e2e301e40526dc0", - "0x00be2d0597949f9d9c9504d62cf42800915108f7874bdb80227ba6eac6ef21f9", - "0x004a2801a7cde7cc3f2832a3679272e0a3e5d8392b8e2ee39ea2af9e44c329ce", - "0x003a6669029fb7fdb889d5f2a61bed8afde5b92658cfb1b9790740b7709dc500", - "0x00744d53993651b565cf3ac0be186f072b57d58e01790106af3ea9adae1dd9fb", - "0x0072c624b81dd98e2341f99652ced6e5534b0a3f0c0ae34eb18f1eaedc384a5e", - "0x00a9ade86c9d45af0b9d462a5b73cc0fcf8d23948da0d8a879e5d319e0c466f5", - "0x0080b54ef2ded4dedbfd66ef0ba785c940d875fcfc8046d6376bf027f65b696b", - "0x00ce8285bff4f9bd5f1fd8871ee0cb94afa7495c6d23111b7269db4028a6c80c", - "0x004033d9de20b0a2adbf35cfc89a91148b1a3c0cfc810ae87e978f7ab158bdfa", - "0x00fb37db0763807dc792922432f401e2aa6f0b43b3b0d99f0fc505c41deacb9c", - "0x009042c835698764223756a75e4e754d7872882ec1b6487892dd40fe7e947581", - "0x0019469e129651a23956b741323800a8003ad1f154c82057536f1479fcbc8eb9", - "0x0085a7dd1da394824ebcd8c349512ab79109e2d69e120aca982a54e6253efad6", - "0x001654187a7ddf702ed68ff0314da3400e77c69f205d62f8d4c4829f9c0e4f7d", - "0x00b032c8a30c02ecfaff36a090c65c5ed0204d83a2508ec5b930ebf9ec3c2a94", - "0x002537946c16ad9446d343d31d6b3a6da11b522106b62da38fae227827ca4c61", - "0x00ee302398f310892e0dfd2c30dfe79895528ec3cbf6dc19b898c2970729ffff", - "0x00acc97dd23e719129e5990eedaf3d1e21da53ebbdc0385f7632ee42c28e8ed0", - "0x00266d99956b450493165e43a9bac9c75e2fecdfe698cde7198f9825a0307abb", - "0x00c0891aeb4aca038b55ead25ed2b2a6fd08d2e03617c0ba507869b5ffab3ec9", - "0x00661e6ba65aa316a460e18997db703d4f419e24fccb80e45c8ec5778d1068a8", - "0x00a9c9a8c5cf6fb7ad0407acbce39711c602305c9acd0ab571a4ae022aa1fbdc", - "0x006ca97c7f6f9b6e5e6ca99572bdb5ef6ea1ef1674ed72b0b65e860db70534c9", - "0x00f646a9d6393cb8a6d739fee207bdcee1e4ef5885e293e91f8837f2f9dfbce6", - "0x00409f54eaa65d9fde410ed788caf4328dc8c11c7da7fea0bc65e02543e32d09", - "0x0007f5c48dcd6dd9badabd9be9b0ae377d1235818ca2e7dd23869a4bc1d05a8d", - "0x0047e7238f9a0789b896bd145b1cd27d89615ff4e02f24b69c4df920970fdeb7", - "0x00b1870d17a845e1d321dbf9df2782a031ba2c1694ac17048ea39e3a279b32e4", - "0x0097ed075b27eda5a524bb0c33d1c16000aa42c945ace6a6b3f6cba29bd55486", - "0x0047e4a3c59ef42a2439c4054e2092f634d1e4be71edda6016a9e36c66b75818", - "0x00b6cba9846a1c443e1384be55cb8289a37de3e01ef6ea93338e615213ae71a5", - "0x0055c2809553071e3328238505be68c0f6b92943120e337930599823f072cbbf", - "0x00ea39ea4611fe1dfc8233d0c9c849ab55488df89dff6de6dfca46888ca192b8", - "0x00f0bdc36eb0e9dad5ff34bcc9f0b41bc48d07509698463a874bef497c861016", - "0x00217d4617657a01b0e5718bef2c24a9046f291f5472b19b43ee97852898e8d6", - "0x0032dac077fc4d8b956ce1317d9469ed367482415297e1e90b685b1fc43ff436", - "0x00b8711e7a071cb7b56a056ab9fd6177c38e671449c65cc4e6a9a8c3f23d038b", - "0x00561fff112ca35dc86d3324a8c34e951a9ed2d9805100c8c87d35241702681f", - "0x001672d552d381810c18254aa00e15ff776c5624bab1856437824b1c022392ce", - "0x00f60c036bd0d0f20d2c717cd667cd36f290048676938ca2eee79fa9acc28119", - "0x0080ed0fb199b0258cdfe5ce1bba69aeef285f775b497a30134f26bf3b218911", - "0x00484720db954a7287a71b3aafb3c309a20175e377529c70f8fe949492339e05", - "0x0028cf2c06b89102b18a48d58cf628e98487ebc4325fbeb78d9c0b39f7eb6236", - "0x00db83e1058527ef71062910be25fbe1244a6761d60cc2710ebfebb2531658c9", - "0x00cd66e2b6d3cc96966047f2a6d210628de71d4579116df407aa8713c5816f58", - "0x007210d79dd986fc766d83f84b26d47889394345fa0bdba93f4b1fc927924375", - "0x0078fbe505229973b34f50bc7d800eb5e54f38584ebf346075b4b91c6575eec3", - "0x00cfa6bda52b6b9b5260308cc6ef7673e7a816deb11240175bb24f3f44121255", - "0x0077d6ee969ace06ff026c4232e04b9a7d91ff661b4aa595984f78fc2fc647be", - "0x005c9a73b0dc3b552016b09f935c13851dcf923b38b0f9b565185e1322ee1049", - "0x007005acd61cc31a25bcb1c86f7fd494c96b2c6edb1bcff9c963e91c4f937c9a", - "0x0093f62703055f2acfb1ce64b01d997072503f2b6739225cf46f1b0b2fff76fc", - "0x004f95a24b9ec9b5debdeda93b837ec389825cc41b2b0d4ad99cbb9b34e1399a", - "0x008bbc99bb2931303f81974758301d3667bca9c61b7cff15b4e98d6c51a2d40b", - "0x0012d93de24b10defac6d8ab6cc14cf17099a58d55c74519efcd6db0cda04c2d", - "0x0012d2045aa8610ead37eb583bd8883b55ec25e97e07de162caa530676b24c4d", - "0x008948c810a65d05b43102985960cbabc1351bcafc9c57b005300e197e4b89ec", - "0x0065751b37243be79651133c8a9dafc3a434999bb33f82c743ca826ad40b7e24", - "0x006de73468028ec48414e25e31bb6154c4c9d71d7c40396b9a9dcceee76907e0", - "0x00d5fa9707a1c546be3dd8ed53c83c701e5ac9f5ae5efac8e6bbd98fb0d336eb", - "0x00a8edcda29f05d7fe0e83ec541e7d5e0650162decb4cb19623ff358f5be62f7", - "0x00a3d83bb966e0f8a72a78d4758432c19c77054980a8fc622cc826c885a5c219", - "0x00c5c2500b03d552f2ec0cf6b96247c38d3f96042376752832d93b895e3656d4", - "0x008a2d8206f35775723a2b8b7c0d7c6d5ddf0562d9e360db11857dc9e92b9fd8", - "0x008c3a1409f27172db6c7fc7adc05a6a3b693de2824648b36533e03543ab8181", - "0x009eaeafcea45fe3ea3919d8ae2f55e057779d4ca17f65b9e86b0e8e337a4b38", - "0x00a03033165e54784b15dc62c28eaaa7f1f4e2ff511e1729717e3045cbe83013", - "0x00998960de16b36ef856cb58a5076f93fc6778993b83220acf056c9d55f9a6b7", - "0x00a496017feb079dec75831874e7f10b7cde8df653af66c19984f534383943bb", - "0x00d2ddc484cd66a011147f0b759478413ffaeb2803d5ad9e3615d5d635fe7144", - "0x00dcf5b0287874dd87c97dceda2702f398087a25e3f5f0a5e0b9ed68e8d464bf", - "0x00f210ce35ab7693a0437187f16a7928dec107197d9430942875250080cee682", - "0x0005db2d6c79fd4fbd599a298b2c936ac244d283cf3814ff42d61a77da755364", - "0x00480de62399d8f975b616c06de7e5f89334051b1e35d91d5bdebccc2e2859fc", - "0x00afc8d62a7d2b953635e396ed755c2c8a9130827f6bc416a9676b2fb452d72e", - "0x000e595ce3aeea011114b7f0458bcf35dd112f5f84b65ac8b6d87e14a126da08", - "0x000fb0493b58d3a8541b39685a930a569118a285877a389664a54800dd8d0999", - "0x0048762dd339e3d7c2b2ffa7659ff832408439df6d6a12a7d74e805a64e9e437", - "0x00d596b111641be8ce5560ccb7909fa2d1396fcc014d0a1b85a7428ff86978a1", - "0x00f12241e3d6682392e65c7277353b477bf2a1db9cfa2be44065f63822dfc4e0", - "0x00aa8231b45f9c7e2fd0210affac698932fa89f78dda34a21c7690f119d0f4b5", - "0x00dfe4f32cd8929f7edfb45424ea5123054ff8b3cf3c0e1fb40a7bb7775b3d21", - "0x0059fb6fdd15b4c49a247816956ab5ccca31a7533bf6e4962f0b32ffb48be944", - "0x0038bf7726e4aabd1a6ee826ee8249a35bc792b134e848ac350efb9ec1d14c2f", - "0x0096ea99f28904f5059cd6ff82e80a9e99923053abb9148f04aca00ceb486aa8", - "0x006556e173193ae07fb43041162ef5e009e33433ae6bd7df4b20c9d7b372e71d", - "0x0095df3415298995a4087cd4f1582205efd7754f6ef946a1b73b7ac949eeb1ed", - "0x00b7eda6d48e90c26712b625efcbf9727e5aed6d36200d9e1a5833321ce3b5f6", - "0x0033c17c709b639e33b568dd4f60c7d2c71af4d28ff90570e6e193d26b5bdfba", - "0x0060153aeed79ca04c20b4070468dbc26faf5891a5df6c915843030620b5b614", - "0x0029c3bfc42b9cfc82e2bf4d52cb47670af49bf1028cad6e6894767813b2be1a", - "0x0014b72401d4bf7b31114d0c3c26b136937b13cd5843a394dad41fa778566d0a", - "0x00b7755c9458c686061f150fd48d240c9069794ec778db6cfedf61f1519643fa", - "0x005097979a6d857e9a1581f1ba3aa21acef7a3c765d47a37b6ddcb988fb52aaf", - "0x008498158549c70232c861894475c612daa5d64db078546396c50a166954d320", - "0x00102bf3372e5c28041ec1505e0a9678596fab9967ada6156b7546bf4066285a", - "0x00daaee3ad08ecf5b38e69a70d305b7bc96efc1cb4d99289f72d738b9e23eace", - "0x0090fab262a6059137abca96794e43feddd453f2ead489117ff739957eb6bba3", - "0x006049d41185c94b4ab6e0354a86719201c1aee19546cdf8493bd1e81c004fc5", - "0x00e7dbe10471ec8ad58060f4ef0eb17b25b002aa979ac08d6d03b0c417e60f77", - "0x0021b8d731ca7a24bd1c6e58d2291450fbb6a950bca4cbd8bbb4e63cec3c8ab1", - "0x00d9c607c5882fb21b92f570dfbf4c7b9525d3da2f5124acfeda662a54d2f464", - "0x002be5b4db952607075ba6ed781d38168fc27b412bb67fd9cbc19ff5066514f0", - "0x00a05524194f092d4412455321f096267654e21df7566c782c3d712f8bcfe1ca", - "0x006f4f7d2d3de4189b3fa02cf7f0cef266620c72611de4dca2dc8e18e2d763ef", - "0x0041022c77a6aa6c2d445ec2262e26745d58a409c0046bfea0a0525b0f748895", - "0x0092199f6538b4c0195ef48dba387c35351e88a1a3c030b888e21f4cb8323f05", - "0x00293645a899f76bc8a1fbd2c1c7efe5b4a9d507918502000992efbb51011f60", - "0x0074da5b7e2829d67bc4c79cf9b1e78f00f6ddcdc858051dd7ee4cc1f925ec18", - "0x007c9f970668b6578c805799b524a36e4f9d0bd59074163982b5fe4c733217cd", - "0x004162ce1a5b24b66a7de04543a98e40cd7642f6ac7017f4e189f6be8662ecdb", - "0x00b3d99610106ec1f812fe0f5231ba4cab4d1754f217071f3ff5f7b433969e48", - "0x009d7dc08d508ec044cf2586b0a5f215684e0407db7390e28af84955a3165e18", - "0x002a54af38f59bb7ad99cccf08157311064cd26cbc31d7a6f8a2050430cf12df", - "0x00634dfc782ce17d0c583528c670886ce70a555d3be42a0bf377db313de3410b", - "0x00f4fbd9fa0608dce992ef251b3d68ed912eeebd6a6756ca654d1e3bc6a3f39a", - "0x0055796fa0685090728af59d441704f74bd85f75e507bdc000e298b2fb342933", - "0x00ddcf0b29027616546167319dbb263747f91298f743bf7280fb1ce4c6cc5747", - "0x0097e9eb907fa16d3dfb810ced857ae805b6f36bf6e24a260aad068881440ee8", - "0x002b873d99eb62fca06c2e72bd872848c45f1d8f38bd05fa7fe396bb938a2e39", - "0x007505014763582dc3009f488b11f0f5a1f1e80ce370d6c279c818dbae21372b", - "0x004c0bc970105312e78d80cb1fb4ea0dedb06430058d6917efb0c16240fbbe92", - "0x0054792388230a394b7133c8dcb644ce477dec4975dd1f6a4e247eff6c32588e", - "0x00e1a0e351c1fdc95b88e2d3edc3cd88d15d714380099bb1dfa12067a04f5602", - "0x00cc933a196908e0f083e130c07528b094037b92c74bb0fc4fd6546192740edc", - "0x00eeb5cfba3f5d63989adc24f1dcf875a6af907a541f6809e62ce1a4dbbb1a11", - "0x0008a19c7933639087771172e8638a3675e33c6630b7fd901e115f5ab2251e42", - "0x00d4bf83c694e7ca5a63fc8bf89bb261d70c19cf495cfc33114f2396650ffe17", - "0x00a6ab05639fa4a4b634ba063da57fc9a6baef246d03673e7f3cf0d9fb16de1e", - "0x00699e3781d1a49af75590e48f3d4e6a7d81ecb5a78eb9bcd1fa80d25b5dc41d", - "0x003ef6de9b5c589d7a3b4f30aea1ea08a97fb6a6404bf37ec5504c5752b0f6a4", - "0x00f3ae3a93fbe0ebdebeefd121abbc0ce765950d40261063ba6117c1110d498f", - "0x0083d2cd99fcc40a4c7a2a742691bad197d4ad53e44920038b39c3e4924005d6", - "0x00fdd09bec815874e3a26848a3cc0b29225ff87419385b8f94f0d3a44fa0e089", - "0x00f923677e08cb610950bf7cc4d27df21c7d1fa14b969cd7392924a696b75a25", - "0x00ac51d27b8a8f459fca2eaa01ae85c814af4e0e548daaf3d5fe3f4a7a2020a0", - "0x0094701cd0b4ae19ab085afb2316d8f559eb8a8d81e9d342552ada721abe2799", - "0x0066365258465f584cec3e37ab0ebf3f9216d835f26123237013d19650a7ac36", - "0x00402032be6d26ea8fa1fdfe41f5205a71dc126cbd169d7ed5ecd0b01f2bd172", - "0x0077e181ba4e01ca49c8f08b6b63bd1c49a24818dd47315253ff67a7ff5c6fe0", - "0x00592a19fc5e00c50ec5c619279614d87928a6dcfa86a304eddc736fa12b25a9", - "0x00b72403bc8ddcf7095150079be551db86914a3b982a5e67709bebe3df291a6d", - "0x0027a666071c954b6ecbb1663a9683bbac38b0f10546c52dfa69997095a9c0d6", - "0x00390d4e8e1b28e498c8e4c160ac7d21e081e8375b301543320cfe51197cc406", - "0x005b2e7bfd08886719b2e673d65936d68655a034c9c4834282873474769fc854", - "0x0032420c144255fb4edb3e0d22fd59b35340d0a7a74039e281031d3b452d9800", - "0x001d050a728c649e7aec361f259e5e5757e0eef826182722ced6c5e122442ef4", - "0x0069a2279f8cc23cf9446b70d8ec025243f4278f7c6ea20402a6f6d27fc3ab5d", - "0x00c0b611a2224fc66b9890a4307bbd5a134d0a15a0c3fba75389e1b96577cf04", - "0x0032b94f760391c50624b626ccb74c2d72ff41ef56a45417388ff9daa3bbd547", - "0x00ef16974c80019ae0b0b631433f7ee5594b7e4e65eda02b01278f63b271eae7", - "0x00cc06ffa62b8cb12e1c9f0a79eb16eada591d8b8fa70f3396f90dda8bb4f2b6", - "0x0074c8c2c1d84c1d6202d2e20a05b62de79155dacb0fab4646e83daa84fd4c69", - "0x0038157f808bf17ee0a5bc8a8acda426b38fd5ca0ab80951782932c5d0c9c7e2", - "0x009059d0280983f24981e1a95de80c3664492b455c038c9be00f50749d632f11", - "0x0096559ba577aff2696028690877693dc52f07ca721a7d7553aacafd17393ef1", - "0x00bd7c6272b42ac7205dea4d5dd2d5874eb97e15d596f08866cebc5cec7f24c6", - "0x0041b812202d55296df7d47f1520934cbe378d60f9c0bbefca21bad1fb0335f2", - "0x0046cd913acc3cd16414ee1eae07777a489b4bf15a2820fd3097baa3de5da280", - "0x00f9c2ae9f3fff3d3bfe0761a682fd51eec42c9c1c33092f43621eacc6a68400", - "0x00a5e59d03936b14146cf70552ddd33290b2a892ade5cb2fe74389eee36c303d", - "0x0047be7b5eea3b502b91236ddfc93df72a8aeed993412a761b78b99e4648fc1d", - "0x0089eed3e596fe002301915e7251ac3907a14179a2e22e5555719d2c78af3af7", - "0x00f18ad1dbcffec3ba086e8dfb19c3f054f34dd5c62665497d3222fcac9c338f", - "0x00626b0d015e7cdd4d13a97d498059a4f341cd9169e8561f02a3746c15485f81", - "0x00e87174b78e5070f64b18deef4b4bed1507dfbc95ed53370fce13c6c42f25eb", - "0x00d6b0bc1959ce15124135490d2930047268a82e34cfc2910494c9171dabe191", - "0x004e5b3147d777a3bbf235d8fbcfffda62be7d41370c3e81c2dab75496721659", - "0x0089a4050e736bfc6ee6ae6dfd2ca19af625fb68e4686823ca901a556cc74b12", - "0x00b51c9b9ae4caf000ac8510c45be95fb3a985dfeca04f66babc054f12a8be6b", - "0x00c2418704a6d6d599b4167643be571e460c33b88aa7bda5526f810dc1062062", - "0x004212f364f8d0557b912336f78742d8220e85c4e82fe9e029da475161799b20", - "0x00e414e06f2aea7ac7f9447371477182e38cac663ee3d74ef8bd726766c1cde4", - "0x002b831cd0102a507a3a79e1a522d4a8f0ba947ecdc7b31e38c09783222bd099", - "0x002de598eb5b42a4e7a10d377638b6ded34d130cd59902fb490ed3bbfdf5402b", - "0x0072b51174bb9c421229e955394dd594f7c44600d701e80f47b20b473462b7a3", - "0x00dacd8c36027d4a1f712ed0500e5a93c46cb0326bca1486293bd235d63daa90", - "0x00e66a6d98dc335ee91f44fe54292bcc22baf95aaad1547200a88f9ba0932798", - "0x00f0b092c92f1848396e4f8b6fcb5a7650006bcd250fb61599e996c364ed6c28", - "0x00db5869cc1e5e3b594dd4e4250c4dd446d31c6344dfeafa1ff339827a2ac2e9", - "0x0082e0bbfb54d9326adfcf2040f650438e506498dc6b32f3b90584ef09305347", - "0x0058216aa87aa505adec13a4e9b4be40ca1452c4584ebe9f84fb1d2ce148b135", - "0x00192435918b999e569997f880b1c9eb9db98a8c580c99b0173d9b7e5bf84303", - "0x008dad1bb65f21c3ea82e6fe2623c550b4a3cfe8c6dfb79ef97b77efbd88c0f6", - "0x00f8a14e988d5e0a4285842523ff64f7cbdc8dde817b72a4072abff07d8539c4", - "0x007171252adf76eb3897a57e0f565dce28ebfbc3aad498031fafd58f5bb6a72e", - "0x00d3e1e3b900fad00c2c1be9fe63b39cb8958468f71c1523a5c7023079fda99a", - "0x0078442f2ce373a49f88417d921908ad1ab0863b9499aecd6a0edc6f6505a9d2", - "0x00e15eb6d09bb440400fe301159866d6add5f56c906a24916d90f860e05551e6", - "0x00c327250870ef6734c1dfe580302360cd235f5a0605aca9a1197e263e87c178", - "0x002b4d422f6844280324000bf44339c9b0a48598bd81f649a548205920c2adf6", - "0x00faab41f2cf26027730ac78dc444bdd6338de6ae5341b4406b3ba6d80cc2971", - "0x00dcba5deab25edb0ca6f5add9e9f4d36b88a4adaade4262a1d07f154ffb4bff", - "0x0020772efa3b24c42bc01ea949485bebfc6bf03c9be80d573cde650f9f359575", - "0x00eb785eef4ca0f66109f7913518c0cbed0e6e3585dbbb47dadf756fe79dddc2", - "0x0037fb1934311f1bd0268d61ecc312c5a54d2906bad5a8fe5e05802ddbb9b98a", - "0x002cc2a2fc86bc4299dc446eef84639c93dec0f438f33219a3b5af8912c61084", - "0x00b4091748714489ecb634c47cef630e1cbea1669f94fde6674fb9e19288ca0d", - "0x00968b1772eb98e304993437b5eb6654a5899671091cf6b8cac002b2150001a2", - "0x005e7dbdf94a95140f98db3128d42543526f0f6efc83b3ca22fe538c433bc5b1", - "0x002b6e6edb84dae70a5c0cccc64c3c8e1abc132ab9edd158ca5cf92ae59add34", - "0x0023b2e04f4af1ce58208cf9718bbb45cfae1950ee31aafac39ae6357feac75f", - "0x009973e488bedfad6ab93c33a975af8ac588f1e81df42d36dbcb593c679d89f1", - "0x000751599bd51fdd4b4a747d02f2eaf671d5c322193bcefd43f30a07d5432eb0", - "0x00eaf0b87a45431fb41aee5cacf4f7d266dc9a51bee21580e711941664a1b2d3", - "0x0035e4608811d77ad97fb20c283715bc8ac76196898cafcfb570ab294b7d2858", - "0x0055d5cf2a94d3cd98920f232d8fb3fa22c46437369c201b6de71032bb3ee3cc", - "0x0082f04ebd3baa6b6f9d0cc6fb0c92ea8f15cf5fc27ec9718f21a14f8eb09b63", - "0x00ae37fbe3459adce07b45fc35476e2b9c41d586acf0cd2a18cf509f3b3c08e6", - "0x00164540b3ae1688f379dd4f1873eec2b7ab6700230bd34962adbd7f4aa9ea8c", - "0x0027fddd235266b54c4f348ed59e70e6c1cffc14e743517a7eb07fd15b0431a2", - "0x00555c532a06d63e531df3de39b26a20c5f7ed54cc32b66ce5c6b673ac681f74", - "0x005d92bf45d9bfc85a1a8e7281631b8a4206464858d144392c157d3c5e0b5f01", - "0x009bc493067afe64a880b6da5fb5f1c3bb4d232ecceced74ddc15f069e441205", - "0x000b50dd3b1f0680f1b2d43c81a0a66f521ace5c6685fd9c13dee816e43f8e85", - "0x0007b54a7d55a84824b3c652d5cfbc1f252d337d9e27b681f2425859d0fcc90e", - "0x0029311bd6809b80124de04db0836b010207abb5a1c0c2e5639e29388c52eccb", - "0x00c42c757145ce367dcbd0e8bf1d7de81d873488096ea6ccd88b3953403d7eef", - "0x002d0b31be6716a7f533336800c1f7e6506a644696880a54f3da44f837c4b5ab", - "0x00ed205d788b03195a32416c9c93883d59644680cb88975032f8321e0b94fcc4", - "0x0017619cbcfa828629587488069dbc7ff205c84890823fa0c336fa52ecca3e5e", - "0x009ab0bfe81f5af6d1daeea6ced79e00574632607edb16f48aa84c5e96050b56", - "0x002981c4f4d4b85f6e2d65e01160555058b056bdd17e24b3934ffdd37a38af64", - "0x005f66ab0c33bacd650bc2c3f37457fb3aa8008bbd96105d6ac5fbc1b0ebafb4", - "0x00f623f102c60deba54e75e23f2193567bea7e0b8b572fb2196f3591bb5e89f1", - "0x006b88ea09650ae8e34b3e3e94dac4bde8595d1119105c461054d1f105b9aad4", - "0x00ea7d52ef74a94ec89b11bdbbd43f3616ccb5a5195f24fabd46579ab21ca6e9", - "0x009c0c2abba646d55471850556b0f45ee59d4c6f17fdb58440e654fa2f29659d", - "0x00ac034710d0eaacf1ce171ea0bf8e93342f3cf452bc0ba08d745673c314b917", - "0x000b5d43a8b74d3066fdb89793a12b4a205da8c7dd6f27a67bd5c7dc76c9f76f", - "0x0073b9aa68afe300d5739b6926719db7e3cb040a93621060a5ba76f74c7e9b6d", - "0x00a06235c58c0000064c210f15bf8ee1ae4384e1bad464258ae743e432d96ffe", - "0x000e3313fb5bb0775ef510c6c2b2a7562bcb91e5d3153d4121c3b2818504b9f1", - "0x00a5363dbcba0410a9256a96cebae752620b7483d3cb19365f7870155d0e95d5", - "0x006b6bb243779ea267ecdbe821a7e639fe925b5118fe74c9f58f86e3e7083c7e", - "0x0070b0028d3407b02eeaa816a6fd7ce6f89e515dd84101b33606b88d03a85c80", - "0x00a2f438bd7997a72155438a46e92aec6df5db9f8962cfc17dcf289b9b68d520", - "0x0040239249061450a0d8c77d7a604f8d633ee7bbac2a087b6884f1bc123558b6", - "0x003e36a893a8b911f2a18f7139f1cf22b01e3fe7ea2e38b67c1a43b55b8336ea", - "0x00978143ae5b309aebc7c97714878fdb5c4c7a6f859c6bfefbec2ea92598d0a0", - "0x00ec5f0f47a37c4b6935e7bae756405a449a4abf2902c48dd435eb2ece0c1d15", - "0x00cadbcb3c86719ca1427234c2f931f315e624c8f8756f691e546c501591916e", - "0x00fc72b00ccb764d6420a14bf31b0080e9e1cc38d02c3b3734f813ba179e63da", - "0x008e3c075b3b9116c6e21489b750a0aff10b0db87188aeffaca35d3f782357a3", - "0x008e466b9eb264e84d6ed99aff0206942e6b7283a5a88a7201bb5a89baac6b99", - "0x0043046a364960d0fa1a1cf43ecbc07f224767bdab8a8b323e540f302c4b8443", - "0x00a014111dfbca436cc249678fcf79ba14162fa9d28e42ac563c05046c782a69", - "0x0081c0be4228e6f18973ff864cd41bdd772a847b57cd106644ee70099cc7b596", - "0x009277b21e2b06988b271d0cb0af9624d994cb894e0444155b664f05b31feeb4", - "0x0029e268031faffe37dc6296b2b77f81508ce511d75a499d54da0d96369e0d3e", - "0x004103229ecda07f2fc9ef7e0ebe1b2c2fd99b4b875f9856dd5c5e35e72c93e3", - "0x00616312396b89125cbabc09e74d545f397789240c536ba4f39b226f0b467dd1", - "0x00679486beabf52631223dc04ed39d7b3ff26e9f56609b587d8bcb74bc0e13b7", - "0x00d93fc63692714cfb113e50c2bf10f0963344c2c9982686edbadc286ab137d1", - "0x00a4c8d59622580491ea4b07e1777c0a5b9c3c7d35cb5eef20c196df60e3687d", - "0x002dd063325975883a311bee3760f5814886fe2142b88f91a94869e82fb4cf9a", - "0x00b59bb79b5bfdb1b51e723e5e6dfe345e50d4e61102f770a356f371cca1cafd", - "0x0018a22cab9c4eca43f9a364ff22842e637fa0981c67755df11a134f278de900", - "0x0044cca4c37bc93c12fcad395862f29f9cd39cf050c7b8eff8be743369ae509a", - "0x00de40aff78eaa74e9f7ed6f1b7c7a06fa9df3938515631b5c30f978d2198300", - "0x00fb0298ac2468436c7cec5b0e9c25233dbc06c94134eda688c9a967fdcbc130", - "0x0087ca5125de8ce4b5ef973b1e0494adc5d41b703067ca4b1f6ba3228dd4ea88", - "0x0027ddde931a385c4c7f7b992125d3c0a209e71a36644970170db7b673b69aa5", - "0x0039f76dad1a2b49cc65cda1c97f996a21447b2320ac46e3cf8f7da852cc9026", - "0x002de34b3d6bc958035b2b57cd80ae5ffeb17534337d80c005728714de53de8e", - "0x00c4dfe4f22b613d29b5b0e28ebbcd016e84a43168da46b0521822bf2a257d14", - "0x0041e799d0c373d2b1ef6921be31d6f0827387e9e19220825e873da4dd9fbab8", - "0x0021a99eba035761bc4dd19fd87b8d5079c289497c942c9023d25973510b3742", - "0x00b0d37a0eb3735e6a55afc8c7e57f5e160dc30bd6468019788da2d27b96759b", - "0x00bf30f8b3563533737e4be28ec349e45e67fcd81318d4f8e53aafd2f2ad597c", - "0x0077d4990830670e3863d31db4f3ce62954ab950f6bc6737e2ed1aa66d85e300", - "0x00d997fa3f42f65892596ed49c1a7a5b77db1e816d61114a6f6e605e06a42ea7", - "0x00ed7af15e6c065e851baabc83b524ecfb032e77fb9ae63a005a2eb81fd33c99", - "0x00eb0a10582156270dfec4232dca2c28a683e3b3b5c3eb4ff1b005efc1d10f19", - "0x00d5fd441995b347391ebad406bc480a5b819c73af1989830f64e7d3397718f3", - "0x0068418a26b36dba791dc8c574f3f113552f692f501c5f195d2aa054e0a2a892", - "0x007518cf85e75ed95334fa55ee5ebf341ba4467692098f21465b39597d2cd35f", - "0x0033a2c8aa616b948579d426ee403f858f7cf4f893ff0f4dc10a39042ed34a2a", - "0x003fcf16ee44efe5bfbd419d4b0c437df93d209d29eb5f2784468dba39d52286", - "0x00cf14b3d06768a4f8e3d8c4a750a72b64a15b40361532a1d110b7539f84e135", - "0x00cd6e6d1df77609fd7fc8cb3192b94290725a064de6e8f3ddf67e1ac0edbaee", - "0x00e9b542e054c8ee647531621bca9c3cb1fd7229b7e78215206f556f45555a2f", - "0x009428a2e69910f4614badd58afc732edb8c1c828e33c9b928d19802b4827906", - "0x00802442282af8dcd3f2f4e307f78b6db0b1cdea4180b54875c7615f39025e80", - "0x00eac9f396cde654588fa3ddcd1c02fb67471d46fa6cf75a66d458c188614c8b", - "0x0043db2c78b98dc917c82f403acb6c7637d77f9b78ef35191ab65f5504896fe1", - "0x00f0932e30acc8d8554b496c09ad84dff13002b8cdae2fbb5307c8a6872e666c", - "0x00b5ac28c7aedca0a7f015d9a0fb4e33db30f278266fe07462470e6e873fddda", - "0x0078626f66518fd5b756a0bd154cf58a9a43b1b91da0bbf99bb0cea380b6c6ee", - "0x005cfe096407fd6a81066f14a495f77bfc7cab57eafd38f60717ea84b053ddac", - "0x0090f9bdd92b3c2ffa75a3ef70c163e2666b2012051fd303c976ac6fdadfa765", - "0x001ed3187603927a0d54e3b5f11cf1747025a64fd74f638835c2abc7636936c3", - "0x004f6b0e48d2e599114f46a4a7ca06bfc2b6d1a138abde15d5c0356648e0b620", - "0x000204006daa305aeffdd9c662614eb56236f772f55f84d54ac4b1fce77bca3e", - "0x00c947625d2e5a47d9ddc83caa8d08e7c15389122a9518d681fb77008007fd93", - "0x0057e0795f0fd63508b002328596534a0afe56df1c75d7907eb9a97cc9ffcf92", - "0x00e4dd42e02e368b789ed2e013b29f655acc73cdcd2152deb0a348f13bc52283", - "0x0042c1f3b8625af56499fa22f1cc9aa50857b665af9d59ade878b4ef5f4e30f9", - "0x00891c2dd8c837960a07146a93de27562eb06cc9ccf287f02377c62320274c36", - "0x00c1a1cc9361c0392c79007acef33fef59381622ceda07e715071bc260724b71", - "0x00974121c30b2f2b3f9572ea8fc358cde0a5bae6e8acba3e616262140e09c1f1", - "0x0060860f6a0562f7f15c2a3a31a2ca4e8438ee07eef3ebdda28074b76ddd7d2b", - "0x002683851b781cbb5505cb4dc28b03779303f214a0921ca431c018c1924d0e32", - "0x00c7930a4d3f0156cd33f7933fe069012a5018f4d7ae791bf78d73f2dd6d7530", - "0x00029c262085df0f677aa233a4cf69ebef7a75235f89dd0c1a3c950c9d2385ec", - "0x001db2937fd86c799fdc72eca9147e3550d1065585885f187ffdbb4eb33f2494", - "0x00f549a1d51c88bb1346ffcbbfe842f222a22a8dfa589038c72074a90eb64088", - "0x0078667e3d201a88c4e03e3983130b51474d42a58886478db9d621910067adc9", - "0x003423abca055983bb638b1d4c8266d4cdedab104161a807043ff8e6c0f3913d", - "0x0081ca1bc8681dc8401c096a8e00cc001a5d78ff4487bbe8cc123a4fb5905742", - "0x0051121b11a844b5b30d3ce7791f0d33c4e149f7e78a78d0e6cee8d80fb23dae", - "0x000660f87a3cdb53cad607700257662dc4ce7befb1e819f10daf04b8c28332ba", - "0x007c26bf786d1a9e283f6b93b4e656d234b9ed80c67f972fbea92145618e125b", - "0x003a1a96fcb937a7f3ffe3d11605cc8464fcad93990db68057c0988857874fa2", - "0x004968f1d37d38feb58a89ba3820e50a5a68df03efbdb182fe0c9ac4c85c2c53", - "0x00e3143eeb5e59b0cc30660c828ae84b9e5507cd92a53aff80ed2dee70a55042", - "0x005b7a1986caf5a8174886d8e487f9107a46ca078c5f348714428b124036e4f4", - "0x00562682977e9f57930b7b2f3130520332e76e890aa4a9e0128e9c6613b662a7", - "0x00b083cb8e8f1d64be69876b979cea8c154b9f667074f678b3d1a4a6eb31a214", - "0x002769239657f87ad773404a9f2549211c25412271dfb57b76059e5f8200f0c3", - "0x00aaba85ea5f87e0f47c13aa3cab5b8f7ee889a92059670b9f69379b41be65d0", - "0x00b36708702fdef91ac6454d6f09e232e2dfdb3ccc1c53f595ae7bb1ca378f8a", - "0x00fbb5b2164f6350f811a8510ceec2ffd3fdddbe426c1ef7b4324790c88dc3b5", - "0x0002e1d6c3ec5a8e9d5e1314812f914befabc338ae15bbf90ed669fdf570d117", - "0x00a1913ad8b715ced73cec8a960bc7ad127648632c6d64dc9a0e8b5cac5153bc", - "0x000be0b83f17294115c1a087ed035eb4a5bf18881296436cf4bf3b9f51a00104", - "0x00b773300ca26de7d001de1d3535787309b4139fb7442102ff07e3e0342dde67", - "0x00050fcf0c0876a27de926585694e0048ef14c6b8f4d1ee757c7aeaafeaf1e05", - "0x005d558bfc6603800e93d2524d1c4f1d22f3760e782514e9dcb81bef54792c90", - "0x004b64fa5da331fbb080f87e8bea5854e890bf6931d147a0d9d5a04c18bbdf95", - "0x008c1a857cc026c0ca5f2f3422d544d265f1be098c41d17acef13ac303ac6d2f", - "0x00bf9224ff41d297be8ed84bfc8b232f6ecbb48b2544cd7a644dd47200907625", - "0x00da65ff8f8f9d9bb5918a334f043b5e4f3b6eebc57bb6e544836afed2f013e9", - "0x009bff7b93d682e90dbfb1d74196ea0af7e157c2d22c16d2dde0fa3d3df45159", - "0x009ecf2ed51fd2f8ac15c9903a8efa25ad306311d0e92ec7b4d8fccd0254932d", - "0x0045d5b5b79528ab4518ea5f149a9d7a1a3ccb2d1db616925636d6feaef307cb", - "0x0045ed6221fec61f74467815059e3885331daca8c2931e661b86bb4a99e35067", - "0x0022a7bdeb9f9d56724caf6383a20ddc5d5d632f29e6ba24053850ec39bf6f15", - "0x008a2fb155f227684b21ac494a2c02836706a16b9ece517e39f1bea82d3a02a4", - "0x0000ba19fe5cf8dcc74671dd43bd2edbc15d0609914c2aa4afafabd345c5891e", - "0x007df6a50e24de48a49923d4d2c905cc616332722fcb663c61ff3712cbab9899", - "0x00c3f4f1206823e140b891f2a8747a33954a466cb7dd885c38ed6714cffe9fea", - "0x0004def546f9b959d77844d258b5ca5544f07474302da68795409f0928232b4d", - "0x00fde46a16c4242cfa6be47b87166a5b0023f785b41735234a83eb74fcd4621f", - "0x0051dbc245a2077947ba455ba1c3602160e3c59698fadeb0828e2ea3808d8fb1", - "0x00187c83f0a5cf18ca3970aae39323a750265faeee0c59d5715df646332cf8a4", - "0x00ea1d548c59f6981a65f1db95b508e5ceb3dfc9035adb5d0db3d04e0d8474e0", - "0x00844a72ab5ba8b394dbb5ce94837f6ecc7bb909b7ccde6233ad18fd121c605a", - "0x00769c67624ce4e153f531ea4293090a1f94f66671e99f99976eaf357f2c43d0", - "0x00841acd621b9dfb17422420b0fcd7f7a31313e837942d29488011d15f575b68", - "0x00bb4d793ab42a89af0496ce239f2c1c22de534ec7770195e3d5a28d700115e8", - "0x00bda74583737476b1bea6c1f92fdddb7d8e25877f6187be6b674ca09a9322b7", - "0x008d57020f8fdfe37aa0a9e525f1e1cba129333cc57ee42f4f5772928d2e9cf1", - "0x003e3d05c52d155c7c796da073ad7b7c82695b25c5c1fb9093e6ee5af9859f7d", - "0x00ca8cce459b3dd8a7df9eca756c1fa8a65bf100c16409cfe18df4e562b7b568", - "0x001d89155ca7d77451651fc23eef91ed7d266934195d637e868b9ffc5b77deef", - "0x00565cbf92785c3c08c4e88cab5913d1bd88dfcf6a06a521f80eff885485e47d", - "0x006a4130ae567e8eb72b9e21d3bb9637380e91f88010e3551fdec59e2785e165", - "0x00b70458a7572e33479b35bc8ccadd038b9d79f82a1f27c55e2c5f9bc12cb3fb", - "0x008df6c4b1b88f68bb018ddc8307eaeeb54e495c1f10a2921666feba14902a00", - "0x0009b11df1d5424ca4edd8eb435ec78d350830a11a0f247fe0082b404250e84a", - "0x00c4a45408ecd9f5ac8f5bfd10a1345add1ea5d394d7c5c9ea6460dfdce8600a", - "0x00267d2e825e33c5f1882ee182b4f3df95ad09e633c4d0e2b49f3b6d70d9fa8d", - "0x0037d310928e052b9fbe2066e0a06aca882578f14d8c82b3c56c51b706d616fc", - "0x00eb89ae35fadaa7d4d1d080abcd3b8c4b023b35cbf11deca059a7fe7b58c44a", - "0x006aa1d93af7df5d69c1e50c5beb369ecb695331493182314c55fb761e3aa6e4", - "0x000fce57d97ece79f17915bc01302d696f958df690d2b757c702dfa51b4839b8", - "0x002511a48492e8ad15d1c666020d80ec8640c09f4fea99e88ffdaf969e628053", - "0x007413ae919641dae994be0b87e33e130baecf81e5023cafd825ba96dcc9edb6", - "0x00660f3526dce6106c945c6638a87aa361e8c2d0ccd5c35697179140ceec93a7", - "0x00a1cdf1a125a41be0fbd0ca445f0c3a2daac605b8a4991df18c088b98500beb", - "0x00fcb4d25a3cf57254e1db5c78d62fa255f3fd0844bebc59bda17046233c8629", - "0x00e1854a7b4f2967d3e508c93b92479bd0517eb59165c815fb0121aae9012df3", - "0x00b4405618b66c8a5758fa196cd50337642b2308276f5a29530411aafabe2cdf", - "0x00821d31ff4bcc14d1329f88a0f733bc406c4b1ccf79709253e343dde797b720", - "0x00eb04e18aa1d62d0e51292102628f8ecf9bafe112e0f9ee5ecd3a68d738d2b8", - "0x009fb4e1d8665aa33dbd4f64bfef86da2cd0056a5cd3be3b7b111b74c0e8e8a8", - "0x00881163850e2be179bc8b6d4c62f69e6d09189c6c197b3231bd7ca80dfd7071", - "0x0050ef48a6150a6af7e5e78678037d02c535a60e5294ece5b79970f73e65ace7", - "0x001bc3798d16af8352692601754c1a13233084a384c296cc564e9523315e6af5", - "0x0093ca9274b2744c9e382d3d56ef14a0c94e43b0f14492de3296e576c085b92c", - "0x008110f3e7d41e155cb6a09320132afee984a532ae627acd686462cfa1e165ec", - "0x002d385599e108c576bfd30603ea300dbf355c692a5b720e8335b94e517c25cf", - "0x00fbbf5ccd869b16fa371ed0d1c694840d6c6ac178e76501b90429e9d3cf820f", - "0x004f080c1ae5ada8b995a8b2207f03af97479ee57a5ce4d564d24d12481bf9fc", - "0x007253bfcd5eda0c0e93a19084b2c650831f3ee8c179a3d86eb6a3b2953b5e7c", - "0x00079e83add6efb2cc092a9f5e874bcb7b04504cae964ce9be1831d3f2bb0e93", - "0x0051e8988555abbc8256410da0d3fbab806f5f4db6e705d88e8d4c3e5aaba1be", - "0x00ef49fedfb5f1f118006f0bf777a9b7d62a6756e4902fea42e031e01178a7fc", - "0x00d6d8ccded4358d89426596b475de2ccef482b48d3e5200643d86d7e14b09c9", - "0x005694b86e45c15ec9ad63f0c30dfdc23f2df4d81bc8170681180eee28e38b66", - "0x006bd217ca307b9cba3457a47e2eb7e8bab39d84adc8410668450905aa7b4d41", - "0x000f4ac8e7e588f614af6cbefffbfc7caeb6be747cbde622276167d80386b61a", - "0x00cab2bcf27dd054222508846bf4b1b0384dff0ce58ee0336e4ee13adc4d54bc", - "0x0077a6d2afe3f9ca9a885a479042a419dc6b8592ee6f4a289547c682b991680e", - "0x006505d1d65ea5f8fcfb80ff011a7cb2462e451af2fab2419c23c518b471026c", - "0x004d8139f1860984f71985a15e6f4ef1d970b0b4cf86779b5efc9aba46de1d28", - "0x00b18e088f7872e9814bd07f96bef095606f77e3624df06402e1e192fb5b9013", - "0x007a0e9b4f733e2526dcfb60e64abdae60400aca33301286898715544a11c52b", - "0x005d1f38940350ebaacb628c58d12b5a9dac466106f4438cb9fda29013c857d4", - "0x00f528e83f574274764dfec83d966e53b4b32711c2d01a381665fd28fac38c94", - "0x0020134f308f6940d72205c32f3c9e39cdb2a5da5ff596ea30b536b0eb0d1b86", - "0x00698d613ede794dc44ea9d6cb1950ce1da6bc32239a1405d83e3133ff8f65ec", - "0x0011569f18e732261cf03a4bce81ccc41a23907b783f42250dc87014666ce539", - "0x0002eda4482e8d6aefd45d9cf8ffd48fa0fdadf65b5f9f289222d887614e2f24", - "0x0043babadc76fdf6d848d6ae291530bddd3b856f3ba433feaaf23aa4808f7be2", - "0x0040ca1e1a2e1e35e31a87be6c3b132c2f523f15705d0b51afa5d83e1615f53a", - "0x00c2581b99c40b18026fe2c1aa73151b27e3e5bb6a7eee2d4ebdd46fb93b4903", - "0x00ae0ff13151f1596a0e1513b53ae1a162adaec65b06f3afe3f2559ef623b81f", - "0x005af7fcf3923934689b4ed32c9ff5678fefeae5a00f6710074af1bc11094375", - "0x0097629be6e0d24c2fbdafb63f9fdfa61a55ba222a47ddff5fb8f84fe390ec1d", - "0x001d526cf1844b746e2efe0ad40c6d4942989368184318654cac4323f1de9e9e", - "0x004ea1163d5815a29a0376d95dd7967c2a93dcf3abacea1b1ae40a6aff754c86", - "0x00fce018722147568a48ca40a7387ef5b9d0833d39ea4499d2543d1dd949504f", - "0x000e9e509471d4f4264d1baf7bf5f726ff6f3afbc556564b43ce625307f54f15", - "0x00b616cea2c205b5c3e3dc46dc365c7081d77081305333b0847628cae6456f28", - "0x00ed9f0c6759624dba966298eca85ec8d50d7e7f358ed1fea537e1a2813f7b24", - "0x00d7837b54b387f3f8b1c8ffb27f5085f2aadce030505e251bf2722f2ed26629", - "0x00a46811b7d25c81c7a1a150b3142fc694a9b6c8074e7fb7bb91b74a9b0aba41", - "0x009a38db52b18e04ac4a74217a7c4c9b5d0d8abe908b6add6f04368a55eef5f6", - "0x00f24efa8d47d8378bcfd3f920d9282a46bc6c98243dd3b0987bdaa40302d101", - "0x00c2a61cae149e3904cce8c64992f85aeb22262de76d599aa6356ac5e78075fc", - "0x0091a78300ed0bb40283ac5b92d3979bc396457f4578256271b45bb27e1bbbcf", - "0x0024cb7533fcbcd1244fb9b3c7215188b3775cf0e407d0ead993cc7853c59ca6", - "0x00eb84b959b39f4e0248f9e4074794358ad2af2ecf610bf1a600d3030207e151", - "0x0011c7774a5558df6cf5af4528a9510bcfabad823f0f0fc25a52b406d46e87db", - "0x001108e419d0c2f783a04b1b810f53f1a847b985216b05d2c211a16a2bd06f4b", - "0x00e7682a67068e1c0b703286090647e5e93977c1d3352f11959d1dff3747dc2d", - "0x009508f3904681212761b1eca71ce1758a6aed0f0a05733cb8267b82c125fec5", - "0x000444ff11be6f5178c7175ec10e22ae4f8005fe6896aca25fd122d91980c4fc", - "0x006f7e76aee4d71aafb29bb42fcb81412cf125b2f330bc939397255a7fd55090", - "0x00108f389ade9406ad815b88b15472278a0ba0409f6ffba2db1edaacba7f658a", - "0x002507e80c190ca339f34b25f7fc14c7c9ff623a6cd63c12e02a8af5abba5026", - "0x00ef327d6bea8fe33b13369691352277d384e9326847fc5287330a9f2165b219", - "0x00d84f41ac36fc58f0ba8f031c6da338658e7badb2924b8628ef4510d0591235", - "0x00cf1ebc675da03ca64b3d930e2bf62b92bc0eff12dab2f9478f17067cf2bb21", - "0x00145942979d2b8e05ec3745aa5306706a006cc7ae95f691231d0a362cbb6a68", - "0x0022db9841a92cf92677ac7bd26a9b8ed82d54b0190d99fa0cde0d810a25a8c1", - "0x006874c045f8330ea928f51b4ca6a069369a71ffd17ffd1d9679524077a1b35a", - "0x0068480397f24b760c9c98080a9ba8a8cbd25b0634ac117c323593745705d9be", - "0x00c92ae3ad1810ef0122cc330dea145a56bb0011136461da7cda1fc3b44a457c", - "0x0014596cc5a6baf93bdecf95fa3580752cf2ee4ea980fd32b49784f59800b5df", - "0x005c8ca8973c24d90e87692fe89f55497a4a37e356537a3ff01f12bdb90aa092", - "0x00dc188ed323c43894b1c81f2fd5a9c71602e67dba3356800ab4ac1e2c1d5918", - "0x0066518050366859b45629f72ba26016a9ea62535f02fa82b523651df0b5d753", - "0x007442188c7b459ae9027d62e0408111c70180cb38696e9bb469661fad8ab200", - "0x00aeda161fb36670d595671d2759cad450e43e994a571509b7307da2aa723f06", - "0x00a6f430f17193d4c08b9e2e89035ac4d8bfab8ab646bc7da15b1e57704bc5dd", - "0x004ca5ae172216d54669382ce121f3a275d3e5fc044ff1e82402e2a7840ae117", - "0x0000b160d73368b23cc6954b3ab36d6e3f5bc8b200c8b2ca3167c0f63921b6f3", - "0x00a2a638f8dc3c94034a02e4c4c26f252ab536e3e1899f853527a0c5f596d11b", - "0x0053ee06a92c6a39f18a30195bb14dee57199a888513afb5ed96c293930fea69", - "0x008913ee1dc9d441d193909fd3f142cb3d9118a7ce0c29fb4780c6fc2005c683", - "0x001d5c6ac837b53f43847b0bfda41a7fd10ec9ca240b4a14314b16d5c6db729b", - "0x00236ac2c2651d2152a66fecc752a16761f8d2cb03ff26e5c7d40c6ba8cd2cba", - "0x008c397f7b243fb6c624af787f85e023fa5f91e1d6fc5a4e611d64bbb7742d70", - "0x008e86d281851b5d65ef3a4d1e0adfe21b2350e8ed182f827f4eb96a29aaaed3", - "0x0024c02be87b6af706aab85764988814006115cf32368cc999e161486a7365c4", - "0x0050da706549c8e7d7261a34204ee3ac75bd5fd13467bc76cfe1de3a4874ac73", - "0x0097b3ffaa681883d2aa3e43ab6808d44f29efcf58b5c72051c308e0b6f6bce3", - "0x00f77183d76edd10d28dd53e043ff91864cc55e219a91b8e444d1fa9b5ec9b8b", - "0x008bda8621ccb9e6d7ad9d7452e7a15ed36fed3349fa68616c27b061430742a0", - "0x00494e0aa240d8a8cc98a44ec7fdcc692bebcd9c8c5553c3e9ebfffffed9bb62", - "0x00582a238d24f79658f70373187bfa961a0c97cb79413bb25772781ebede8c65", - "0x004e3b24dff1e3bd91cd6a680a369826443c2600580ad22896b326692704acdf", - "0x00d99f54580ab536eb9c83b6dc46b3aa59f841e7209ae6596cc439101bd2b876", - "0x009a18ab053ee8b9705411619a2819881964e3869d7395f69a167c6ad005f03b", - "0x00eabbc443eab6b5681b34624aecff8486f9f46f2ca3d2bd290d80476542f376", - "0x003735f74c28745ac427e6a4b0b7777db70f193741c4fb3a3ed8432ee4e03452", - "0x00dbacf84091bc52f3c07adb8bfffe12aaf8abc03f13a2d7408d0cf6d0b3fbd2", - "0x0055f1971b168819a50aee02f4b5b444cae85266d11d30f58cb78a1996c44d6c", - "0x00041c059acd7c464cda3bcc426fa783b01e48e43bd6805dd610243ef8596c14", - "0x00c7c64b53c75ae5820dcdd3f31a7f03067e387b1e0ee47467addbe8f95a6f94", - "0x0081d7d1b01a25933dd08901144e4d5e155945d65e9f3e9d25d5fa336ea52068", - "0x00cbcb6203fd77f6dff2004d30917ab260c2d5de1e60b523200950a027fa2d1d", - "0x00fd9a38b9cef8161f8248e0bfa1bba169d2f8f6e08bbd12f721cd3bd1383d4f", - "0x005256e541218a56543d1a428f35f80b4e223349782050868671676f0172f094", - "0x00834a7a5ca767845ed4779e6b84bb76744370221339959060cd3b002b79b9cc", - "0x00fc510acc2b43f9999f70f33c28f9328da1a32ad9f76ba78221673229f1186c", - "0x0070eead671aa7a870a66a5ebeda458d897988f9c2ca504ecee4b0a1211c7654", - "0x00102c397adc498b428ddde3bb934383425e0510d7caf05e748af3ec0828c822", - "0x00d7e2bb5fbab534626dcd8dc17c0534c60cdc84479b6ad6a567bd0d42c5ab01", - "0x007f966013ce0d62cfd26987a00ec5c6340223cde34421f2ceaadcb2e0c5f96b", - "0x00b46b50616ea709b7b9cedc3d9350bfccfd8389d7db3d0c61feb4704b018586", - "0x008e01bb301e44ea4b792a73add7c93fc75e2791b6e8b538323b2be76698775d", - "0x005088cad74a7ea673e509bd39785182f7dbde615702b9bf0c6b6d1caaaccb05", - "0x00119b894fc7cc06e38efdbef991d31506d9472f0255938e2de37058fb374ad4", - "0x00dd55d25ade2c9ecbe29a1b60cad71ab2238319991389cfaa686ce92df47e5e", - "0x00a2f2a419de3953a02c2acadab62a8c75ffc5c5ba591c1d86c90babf1069830", - "0x0075e268e9d735e820c988689b5c9365e5f8f4a9a13103a1ea6b0d74cbc6644d", - "0x004534f640677f1a003a02154d9c676b6f02d67e633d37176e9396072d2eeffe", - "0x002e0ad5a2d50f07c485fa43078f0bbc6199e19bf181b4433c6f3eb9f34b390f", - "0x0028f84491466af62395ac7f0eb47ad27aa55c7bfde503692f626906d91da08d", - "0x00e9538d2f6375dabe77cdd730f4577c30070f6d84405c4b11764025e5b63355", - "0x003a359adf80cdc0e8169aa6e5854191c4df8c40d21a937d8a3f8d47bffa4be8", - "0x0049fba612072f6a39ad502ab6adc2c4917464030c26c07187b94615b1f515b1", - "0x00ca07c016fdf1492d559c4355168c7a1094c30ea725f43d546a970ef28d160e", - "0x009190671b2c5b1a64db617bc69220c610d0bf5cea5d113440b9fc0722fcc333", - "0x0027e1becace65ef820a7b969198142cde22c8e8f9b49a9db6959192f26f3587", - "0x00ac7b19c39414a8e0ff70d9499c3a60edea3e81db33837e1084a75899dbb30b", - "0x00feca08240358a3d9cad5081facb5373d7b5a187e90519aa4dc368dc458a994", - "0x00664d0a856917e53f3ae86cff7a2f507494bd9eab92fb6ddf930332e43c345d", - "0x007628a341a1d9170a3d0603bb7df61f5d8c0f75c825a3072dc08cf1890bbbd6", - "0x002055907bceab4216899125f71b8f8e7ff6e11d3906a45c18ad2f8d337905ef", - "0x0057963ffd640cfedfbb1c461d4a56615454d52a0d4062f2f8dcf8301ba1adc0", - "0x000a2234f6fc2f28499f1473b00facd1c5eeee9fd8821ee5dbacb79d5e6e4ff1", - "0x0019da34095714ed53ad090eda2bc9cdf0833ecc9569fcec272eafc3ac2a1f33", - "0x0096295d0c45ede71b5504d02035c0bc05cd2c4f5b1eb909c96d0c8d2bf4142e", - "0x00e0f8cec46c24e6e925edea4b94d38f2d9c7f9233b9f76296b7a59c520514c1", - "0x00b60827f815e65224c33175ef0e6cc78d1d4b39f98b7a94e45f96c4db469fe4", - "0x0000217e3247f7164f41d694ddfabdb3cefb6d248d1cc583f5d3223b75284c02", - "0x00775107d20ae35064648a3727e8e2b9c18dd4fec982b45bc7de5b73923f731e", - "0x00e015078cd0975060d0742080729ef60e01d13359fa7fd17e4bf4ab9c5c8e56", - "0x004e928545a69e9fcdd60306aab358803cb84ab248aee8da7009254dde182a79", - "0x006486ef2803a83cc18ede6f2bc98213fcaa62046be3b08918c09b4cc12fe770", - "0x00b8303d1c8966136bf0219706678ae22cc84d6c42c8d6a3191308f79d34e65d", - "0x00c1799307023adb77d8dea967595753ad9090d0c512568f58bb87d48793aa43", - "0x0066652609deac8c8c4d580eb9d4d3d98d375e85038cff0c9892a8a5119c0cd8", - "0x008af6666f071d471afd3394939e5771d14b1daa2d98c896ccc7438c51f44d01", - "0x00c0b836e693463f32b049e5d31fc966cde21c13a05428d277b057383e10fd76", - "0x0000f4d52679f0cc5a1e7af23b753adc14dba05db147298736b4f3aab62cb7fd", - "0x003936b4500362d18767b18d0824d669c709e05bd78050119a9a5fa3ab3c84c0", - "0x006c7b28aab8de729dbc03189a411309454f66bf7142458077156027c08b850c", - "0x00c6a89a60751800c298a6bc18b2faed7b2df137e7a6793edd31e2e6ff985a74", - "0x00c803cdf490b23bd5b0ea67330c028b6fbe3ac35f8a9a318cd69aaa47cdc52a", - "0x003a5666dac52fc68269b27b44c8690eaa995c42f1d694702db632086d6af501", - "0x00849d0e9b252b8522322b034b27c2bb68e4528bfe0f75ba17709901f688b42a", - "0x00add646a69972cdd16b2290ec6fa12afc9c96bc7d99be37212d12f6cdb4a438", - "0x00381c5fb7a77e6388eb5f92909c7469af764f27d9ab901cbef45f6e843e6dd0", - "0x005a7139d01c8baa5528c7fc59157cb2c49c628baab9c3ef6422f1140b6ac1e2", - "0x00804ee8b0a27172613b0be8785881a068b92cce35accfabfad88210523f564e", - "0x00f252d1c48e479853877b30d8c06dc9a59e2aac0be9e245fce4e8542416b0a2", - "0x00674074e43964a3afe009a4e4de3fbbe767d27cb1727a8a5d330be16084e495", - "0x009409405870d94dde70e188869e989cf6212c62495a47f644763c7434fd8a58", - "0x00b7ca67d0b62ee847e8e545405ce1fcdec1883353ea54f0befe21e432fa5eb4", - "0x006f52663aec0e95fac70376485a933d51329f27de604f6db108161932a1ae58", - "0x001d8975e6875c47df6308000f9379d2afa5a1ccc5da3756cf8bb4c32d945c27", - "0x00d18d674a9b02b9cc50cac7793a5948966fa3e5b40be5ae6774dd810623e7ec", - "0x000f709230189dc3165cb5979210daad95a5b9fbb8539c9d8d71c46530d72a63", - "0x0093b773e6a5ca2219a6b3fed02e00e2184e70ba055bad491604c6d969c22f6c", - "0x001a323dd93e9fabcb8a0df96c457a57e8e2145d57780375aaf889c9d8a89dff", - "0x007459faddc443ea711f62209f6c45dca37ed52375d246e693aa1d08d6b30bcb", - "0x00210b104e1f8e0c99d61206a7ae4bd716bbf774b7eb27359407d32f92e83dfc", - "0x004b61b9dc37dc4f246aa2e0bda7f2646b39b83fa27e45442eba67ddc79ca3c2", - "0x0050db8fa088727c0ea1b8a24ef8f4020deadde169591739130f3ffe463a0033", - "0x001f8b0175d5b04905fe081a65231318395a5b52258d07fb0189beb369a502fd", - "0x0064ca66978c44296ac027233efe944902510a0362efd66c2ce7ee6a8be43c19", - "0x007dcaf373a162095c24ce0ad090fbc5b86e055c34b70fc6c65f3e2f60bb1bf8", - "0x00982c9b171906abd046984344676983226a3cf418838018ceedf1ffe3de9864", - "0x0077d8a006572b8813fab61ce6154f3d12f2ec61e6662888f2f5279fc602534c", - "0x004dfb4cdd14662226e67ac4f981e8a446cda79d82d65b3e7eeb47d787c054ac", - "0x008f41f49b193f56cfb4d5140aa35fe2d6c41797ce03b706fca0710c75790c09", - "0x00893edd2adc5c38a4544e952655f79c9b9b4f4ae56ac7df4363043d0a35a089", - "0x00ea0247b48d845e42fb81c474343e7be2a99e02e379c3da17e497d750326484", - "0x00f4f4df1e0ef9faf02c848d7cfcabc2226f8421d8f745fdda324685478afd4a", - "0x008c4de699acb61c402968419dac950645b1d5f0a8e576fbb372a4b4df6da80f", - "0x00461af7766e32fcfe292337fe236db3e3ed8d8ef6f2f258efeef8fdcf487d16", - "0x002ee8187d14337e5b45bda6314ac6438bd26709297ae68fbe333882be8a3b20", - "0x00ef68d89466cd293a450d344dbd754daec056a4c0fc8265cf1ed54d3a8bceaf", - "0x00c39d0d028504a7033d80ee254fa52de159692489833146bc2d6c99b7fbd11c", - "0x00cb540c434a2e196542c84ed38ae8196e379295e4016ad272549ae906b82723", - "0x009a6745fb1235e1c746dc401f041cb5bd2f059234d2d9fb8601e9ab589f4fff", - "0x00e523a13fe340ca2afbb8618e003557cc7e127d7cafe295571ec651600461d4", - "0x0008492b6e31978961f59d1d47a02ab4243d1bea425134b8e164abf9cb0efdd4", - "0x0064b2981bac1dfa5483b0cf4796c8d6ca125efad2f090024398ec847e69650c", - "0x0082fba81399d98989749ed130c02cad4a243cd54ff71eb23eadb7a6d31b25dc", - "0x0009ff9f87c691dccaedec33f12a25cd393d6f5005ad9d4a0a0e164f614848bb", - "0x0029badbce2d2faafd63c5aa9fe443748f0ed1894d8713c96fb2308f098c0b1b", - "0x00e39c969bf2e0dafb59c513f0ca05b5d9c68725c98467440dfcd936d60bb296", - "0x0064ca8a53c1dc473adcc757870589eb1becacb245ec8e062aee3c01fa0fdd38", - "0x00a8c990d0597ceaf0d5e73008aee34edafc7c2f99b552933e94ecf46059eea0", - "0x00023bbbdca7321968bd665fff8fe0f1580ae4da60a2e359b4289bd435fc37a5", - "0x00dec6d3ee43d8b8e48844ceab1d937c62d0da17badbb5d1ad0d024dc7c88409", - "0x00ef74463a8f764ae4cfc85d9d2da5ad0cfb83617dfb98dbaee4f60c1c37d331", - "0x00bd51917e184e968908cd28f93fcbde494be761658e468e12aa189a2d8001b6", - "0x007c0d8448a9a2a8768eb6bca937d785d80828f4c56990b36ac3ba8369e733f1", - "0x00b60e28ed5596f80d555e06a5255fb766ffad1944852c6b6cfad33f3acd091f", - "0x001ec7fc56d14cd79e184c42333217d20e3148b127690520e269b8287f4f413e", - "0x007c826b1188b3163f13e38235a298e26d549132560e7d5b9bb5c4cea154265f", - "0x0076763fe90ac659473c3fa10d658e1f6c3bd5963e7d3cc27f8776ded50b79d5", - "0x00afb7be07cc43887af184d9b2c1f98df9451bf2a8b6fa960dd207f71a32aeed", - "0x003822c11cc46d4165924199f0010fb461c6383c905a38212837e2c0a9dd3e00", - "0x00cf521401042b4d40348d1ff1f04c0e1204a75c0fd525ad783c3cc211031022", - "0x00cc79e40a73868006375cc886ed89f2d26178a2ce40ff252fd7b516e0fd5c3d", - "0x00cced604baa3e5786db1dae0a3aadb881ee69e16e74908dc1293a28c80f40c0", - "0x00c424e2f2b60c910d1ab552995745e328898a6bf89287412ab9665460e0ccb2", - "0x000c6ce6660302f9952613646d9b8fd127c7eacc536c4876c95023ef8e199caf", - "0x00f5ebf18400e5a138d6410064d533796a887211a38f2b32802380380ac0fd7e", - "0x00c0f9ad51f1fce3d154d38ebc56304f79175b69f6cf912bdac2eea1d5a2b7c2", - "0x00325f617a66b3f16b4268b3f4095a91566d2f1626c284837f5fe4056d893883", - "0x000427a812fde4eb87de7e80787802d793dbe7d761e62aa3e6d0443ec795cd6f", - "0x00bb01ac2279f454ded47b4f886f24c8bf6a3b4c5d4bd91a9ddd494a1c63d4b5", - "0x006f81d775a51df76a45ee6e4dc946b8887244305eeeec6aad84c718a03f273d", - "0x0042abe0d13bf2896c9f19b62fcde90703ad9e18be7faf72e0507bc5ab787340", - "0x002d7a27fb528704810b11ab4bb3cd6d33debb8ab1e94cf6ddf7f5446ccbec02", - "0x00dd93ab4627aa895d4ef096b7685ed741a2b901f6a138ee4b3cecd704eb0f48", - "0x007ea2dd17102df4a4610295ccf474ab601dee62c5bf3a4362fbb51d8d0dcb24", - "0x0067dda7130b167c0e8db85b71f9d4f884d9d769d1d80ebf010d180d79a5b55f", - "0x001d9c1a1acbb3e9acaff6421ad9880f7c85eeb052bcc1e91692fd8fe7a3dd68", - "0x00dbc455870a1849973dc66bff013e147e2d774c7b707cc64c2ef084b82c851b", - "0x0047b5fe61cd7b6b4f51e6c2bd8cd4bfebaa7155afb368aef0471a4184fa0bf1", - "0x0079bd71992f76162423cab5d7b02258c0c5a1477f832a41c08cfb6b9fa9233e", - "0x004a8bd86f3e6e31e6ffd125dad1b9ffa27d5dfd14f85ce9ca1d926693cdab6c", - "0x00055c188c89250af43ded608cbb34f4b5b8de45993fdd8be5c5f92c45935f4e", - "0x00f201664a8e76bff376b62a6d46ee4e1451fd32c2288f6dcbc216829297f1b9", - "0x009035391ae3c7c35f8639f35a9135c50bd13a5ab2b15eb81e7472d718c85ac1", - "0x00cdebf25966caebeebeab624d4ba3d7b3d68e6806ec9f515c7066f52b49a82a", - "0x00240965252fce3f76048fc610c0e5d79242deaedc1e9e30d783480ba51d3c50", - "0x00edf5cb5bfe7161d54b8167e590177353d923d4c20ff3671ddc41d2014457f2", - "0x00674cae373b064d834f36edfb05f12c74d9f7a25814fe91ece47169e75d9a39", - "0x0071ad9ffe21b9ca1343629a502fdb90b3ed53ae6cb2fe5a81e5516bcf1306ab", - "0x00917e5999953767a18e196a80fae79ae4fef3bb9fce342de81945f898a04749", - "0x006f27b1281cf6e6b0e5ec12a6339f7c1b3acb039d38a5bc4c9cae67d691bf89", - "0x00a18ff97605ea633c60a4fa6763efe411737606ea3f7a8d9e01445e087f0b24", - "0x00a5185c2e0e3339eba8ff51e09b675c1ab7c5ace7a98e33e5ffce2605d24aeb", - "0x00cea2b81b4df3390d78771a9de9426b2cbac5f33bd3f983ecdd08680be8cf4f", - "0x00a3f28fc651ad7614a36d5b08b9a6e8d8229f2f337905ff13e9ac235f4709ff", - "0x00fefc822d08c83273c6582432c171dcf5265a22496097e66b33ee68779ab400", - "0x0024c393fc7a3f523b33a34411909ce7929e0333f8b807adf471a70a0bfb50a2", - "0x0085d2445ebfdff44d4c2cd8e07f55d0ec993d34c3efb25aeb704c73f01c09f6", - "0x004d683331014d99ac2725a9d993d0b4059ea223b7e31d74af3813bffcbb3130", - "0x00f41b4cf36d3208e99621ce733d354a006a7ae7ecb4c0968d073dbadbb6fe7d", - "0x00478a2f7b7cb66040b958d016432afb638f3d8fcd32f9d408c88e8c2d7df648", - "0x00ce7d3ba45022039c48fae4afd18cdb36e299c45cafa764328c38d3e0a0ef9c", - "0x003a12fab23caada924fd3d6c019ef1259c9cc304ab02dcb3dd072ed3a1662d5", - "0x006a80fbc35c26bbf6ed6df2f810f9bd44b4ee0b8076f48b4ea5d2eeae00f3ba", - "0x001b0d41f959428f337aa0b50c4e24e534e52a83a4b096092eca5873d70bc6d2", - "0x00f497ec2e2258557795bcff5c2df277e6251ec4905f0017e2b41642c1d2addc", - "0x0071cd93c85ab2dfab79298ed35454be48e9a3a345ba5e24954744b7a87b1a92", - "0x0072512b56f373b8ccb05d86998997bbd47c14c8c2377bdd67c44133123c6883", - "0x0094794ca3a4246c0e6047135b7e41438ed077f16fef9b7b96518ba834d37950", - "0x00a95f9e79854c280aea8e9f9417e2943ec2762a646dfed73c72bcafef5194a1", - "0x0029dccbf8157a663c2c4e736ec8b7f524fb2158e620e6a34a52496f37585e84", - "0x0063b903262eebbecc0df8747c6bf3ca4ba8641116868a6d2afaa987eb2ec965", - "0x009e0bdfe6e49dfc32f9c9c7e7993cd3fb8f6be6190a38fad20e64db2997cd4b", - "0x00460e501c7564af3e1717d76200a7d98fe2b347778f0d4e479878d893ea3b82", - "0x00a5d52737d0f50e88e25681ed0bb6f3e703c1537856ae7ecc18fa16fa84adb5", - "0x005225656c6cd4a61aa51d2d72cc2de7e92778db0457bc11fd16823d05d1adf4", - "0x0000d571ef44c866096d9706a5c4c2082a156c5aded42980f3ab3faf9573118c", - "0x00cd9acb959fa7c5eba13e45ad849e473894d1b810976ce65bccc7bdf7618694", - "0x009583c849a267b0661f3043abf775c315b5feac5975fc33381cbde33cac496d", - "0x0085d6ccc2f950949e87b4b3a76f5546742380347422be1b78e0844db3792fd1", - "0x0033944e00247a5a2712226c5067fb43f396f96218fcfa79553a1fd16106601b", - "0x00d433dc8fbc3fdf0d98b9bbd39ff30cf78eba28b2671bba8feac5f0725cc1a0", - "0x00521b4bb5c5d5675ffccf4d134c4d2c61b34bb48f50e7d9ed0248fffb5d250a", - "0x00de20e5083c57afdad62274b8a61f653d17203ca3b3978796bb8a5fc419fc39", - "0x008c02e3549140ed04aa5a80c47bf257f8b120c6e11f3e207d5a0462d6b8d136", - "0x004a5efa0b570bc3101d3f395ea473c58f1337c9f965efee56f01ee366ebb4d9", - "0x0017a8e4340c45fc07313f8b1d879618cf3c6929e076e72ddca28ff30728c527", - "0x00076e324f29cd5f138e9dd030e07cda9096e17208a3fd24f56fcd36376de916", - "0x00d067615a678881766faf0cf0f1061e6e0950638d7e83f61cb749f997925f1f", - "0x009f5a78e33e4d2b1ae65e8efd8dde16b9c57cb9b757a76597c8418fbb755952", - "0x001255b42490b7576e5c4e7d45742e557e8e0632b126439096819bceb83a6f67", - "0x00ce056f6c2ce1aa2846099beef049d0fe7194857a77dc6c53b15e3874b6b0ea", - "0x00328789d08f890c6ddb568b460a23372dda56fb30c4397622123c902f3b0deb", - "0x009f18f74cfb3987b2e49f1b685bf90fb0268a4c91c01ffbd9ef1935ebbc6ea6", - "0x00b440dc28c5f36ec86f47a99d2c62cfe59d80efca93f0ffc14e27df8d22902b", - "0x000c6a77b74bddd3ee6d8a4da66dbafd46671de68c48e372a1ab579f15be9ae7", - "0x0086a67d462288424cfbd79ca8b4478a74ab1c9b213388c3abf16dd732b25e01", - "0x0059293d1940c9b34b751a16746984ff27f12c853af142b997a973dbd0c37a96", - "0x00df07f6dff6d0b9ba69e2c38c7aa0cc48ba7761965d5b53e5cb0085bbb62ec5", - "0x009203893b6c573ce30925349a6e4ae86eaa576854391ee123c798a8f6fc0c9d", - "0x00b82067799880e173140291dfd8462b375381c698da9958d6c8cbdc0f14f6bb", - "0x00a80239dbcb4f5697149d83172c3abf04849a76637c1ebb2f0473228c6fd440", - "0x00ff27a0cbd5aa22bafdb4fc8937ff815a34b401708fa6ab21af96802dec7652", - "0x0035ac2ccbc1bc48a606f69a7b04e86e5575cc857b876df5b715c0b6936da828", - "0x00f4d3a2bb1ba0eb8bfacb451b4aa395dc91407a413430e168a30bcb417a46d9", - "0x00987a8d90f196ba2d3703f736c063fd2dd7afe3aeafe6077cf7e7d9768c14cc", - "0x00c761384c384407bb9cc03ee4730883b7a90652cbe148d568d3bbf46c06e59e", - "0x00390eb58be8348057c816fd69146603f4446d38119059c4f3be314decef985b", - "0x0032c102042079cb329e90a71abf160a2936716e129a4252ab2c9dfeaea86d35", - "0x005bccf7ac0055e048ba2554840c6fa949e9fde33fb429e45e50ebffa12640e2", - "0x00eeb1af7d16dd99b1de776ad3aba50827429382485766fa0f7901d472115d6e", - "0x00e94d64d74e248a84eb00621ee86e21af7a2e961e09460c0dbb8681e4f92c2b", - "0x00ec7c5dcd849b1c90081a0801570080a301c88089f10e083779fbb14a8996b9", - "0x004bba0512c20c49a6710d76868780612ffbee35374d8001d79425e7cc5ed0b4", - "0x008f33fa89948e107eaa55adb6de704198b6f981534be89baee435f196565057", - "0x00e6ab12712bae9e6dc657971003f8523df152e6c3e904d08f4e549df89e8631", - "0x0075f3a4c15b6b6a31ceb5a7af49f1ada67f2ea5665ced8e2ad65162d004caa9", + "0x00578d43f041e50b25334c3bb2b1d7b037430032dffdb0fdf0fac685436f9131", + "0x008c1ddb3fe16a677a7013dc46451258f676264a0e9ff88a7d2b4df400f3776f", + "0x009ecd55adce8af8a89840cf73e198ef33f6b6e3505196063428c1c3b3631847", + "0x0026dd699592efdf150163f27db25c766977d00f06483f41138bb33dc2038d6f", + "0x00bafc972a62bbb45b73d76b66dd3b0c9471478f0cb5882a1975940276d787ae", + "0x0078bc41f263e836de0668b2b8d36e6c933eb9552c5a91164260c3839f3715f6", + "0x0087a7e5c6def6f873838aac982367276385373b80bfcf84755db81ee8033d25", + "0x005b5b1e9a41823fd1dab140f135f6cf17aef196b629a654a1154f2f5f174678", + "0x00480478161ab98b58e8a10dbba738b41d6ab93759e93fc1d66c19d59227d5df", + "0x0074efdd3045e59cff41159d75ae01f472625953d58cd7349583155c367ee553", + "0x00a444b6344509fb27312f345f83c2113c41cbff4d8ea6337363c943e42c41d8", + "0x00a11e06a0c67b9a60aeb60b3127420d3fa2080b4f6dae4f5d0e992e8428a509", + "0x00c40b7dbbb27f50dc25c79721da892e4e97115b68e3313e9d53c946dbecd64f", + "0x00b88d7c03820a7c7d25c35cc79a618c2c46463e396fbaab854e010cf956fd3e", + "0x008e7a7acfb5b140e47f9d2e4fa661d2bd6a976b171a943be292f003fe6754da", + "0x009ac295beb428f23996ca47fd6477f5df08309301dc680ebc2763d5d690931d", + "0x006a9fcc1c94584274d54739b3f86da5b5a159f09b004a92e7c622a7a6dc8f69", + "0x00e10b93bd8d140e2edeeb714a8a1e3831e86835109861ed2cace5ac1cec5692", + "0x009055848acdc86da7e93faf0fef2c68183b876c58a2af4db73aa68f175dff15", + "0x006a6ce5c5e0cbfc14a0e9ab5198ceabf64bfa571792d990a1f39d303e859c30", + "0x000c65051e15d2d824cf89c82c935d78a1f68940ab182d297c2fe41961f8f7ba", + "0x001041d3b483d9c259411882871ccfedbb0b44cb063967267cc51880482d7338", + "0x0049d3d9689473dd75622f306e492fde2cd3956f0571726c50da5ee1c8d6d9d5", + "0x00cf26a939f1f2372455f9242368b7085fa1c1bbf9ca7abdbc1935dc5880c3ba", + "0x00cf9513e7cc82f2b961f888dbcc75916ae36ba95a5357d61079d9094ee16e79", + "0x00e124fed9a3c4b8508622e895f7b96410150378b26a98146a1a27f499e7978c", + "0x00bb9cd4b8255064004ab3a0c10ca6b677afc0f8488f236fe3db502b23607efb", + "0x000cc97ccc64d92fed5303a0d3d28e0564cb60e5990cd5ad0fc1d91c9b1e7a4d", + "0x00e872351d120287255393bafe2248c5bda50cecb368e48d6292f80f3331eb81", + "0x00137e9b02b323fbec450b31abe05cbd9084f571ceaf21b64b650468477724fc", + "0x002860ebb51dea6093ea3920ed948125222e592c9d9325f2315ce6675c1452a8", + "0x0064b99f602c801de1fc2436133847dbf39b436d278e45c1341a95d8ed174925", + "0x007fe8be09677b3127313b8ae72f94868141d2dec2678b16a91abff9c91b3ba4", + "0x0095d750e0f35d352bf7b8453cd8b08242582bcd4dfa298af3968e2b077b1ece", + "0x00c19aa73dc22d2cf409ea6ed8cfe4a0dd7aa8e3da04376059c1865102084444", + "0x000d15b904fed4af21b85e26e75f0f53cd6194a90dae40415631c058a3336867", + "0x007a4f3dd15f759cae1361898cc23172f281dc30c9d0fdab0c867c18eafa8e32", + "0x005187a3cec0faeba5539b5085f66f6804d0c5411be3979f4155b382edd4f8e5", + "0x004d657c502ffb0898c3e471a0c487bc50ba95262d4db7d5c1ad9d744451e03b", + "0x009a66b12e9053c55130d2ea7361fba5a7ca107828ae792aaf285526094303be", + "0x00bb5b7ca244195b72c6743b0c9fef4baeac9b862b15876adbbbd3f6963883b5", + "0x00aba2f973ffe6cbd6f3718ac9e63b27d15b38b73a302f6146998ad49542872d", + "0x00927c341096acdf5025b44818ada28c6093c6cf4c6f9450e801da847544c02f", + "0x0011100a4fada612280656cba9fcc31ea469ca673b7c1f3d50aaea8b681fd3e3", + "0x00d254c051e8e66e7994d314c6228b01567c32a0c06cbef9104161dc8a3cf3d6", + "0x00b515ce8da456c6a0c813e02bb1fdc5892c75298655174250d1be9019439497", + "0x001fddc6b9b45aa1febda3184067148961d3d6eff93922491f7beb6356352251", + "0x00fc0c4a7b3f379bf63fbca7632fc26416e741a20af72e67d29f4ebd8312db08", + "0x00b10dbc00d7b1ba96e1b2a6a0d11db50f1a632523194b1a5b82de76783197a0", + "0x003d340f701346533304dae289b8e36438a4d78d46f749dbcf4b081461721b33", + "0x0073d0c55961ebe517b4ed9f2ae2f987211d8c9637f359ae59e5c1b62026de9a", + "0x00b30793ed232625c9e6280816f879145ec6c984bbe0657f303a667cd6cbaf5d", + "0x007644d231b7d9ac5aa8b564c2f5953ce36b8d7f773ac46e1d3068aa8dde8974", + "0x00a050d09cbe1087db7421a4371e2044bbf4fe4ac10ce32b81b2286a91fa9941", + "0x0092ac35beb87f0ea1293b9274d3489d2911b7f4f899b87329bf6001e858bf91", + "0x00556462f5a7c7be56040794e0f42c816152150737061e6396a72b58ba3c6f15", + "0x009a31b0970c1d6c93524c4d0e3ac785c30e704fcf24386b3b551a477b41dfc5", + "0x00b79c801f9d3100593edcef89a249e82587f4eed8fed762e96dd45c9e4b9e7c", + "0x00c80efcb95afc30dc43f3369c2027e8c69da1a08ffddba606636e8d7403bdf3", + "0x00d9743040563b1b896fa73faa0cb209321f9d70bb17bb22c867d6f15e570fe5", + "0x003d855eeffedc36df919f2552df2f7f28e322e324fdb430f24d650a4ba55636", + "0x00bb331c61a4dd1d18b7944cf0316eac99569c6613480387e0a4f61ab3b27619", + "0x005d0cc62c90c99b04dec483e1c413f55692ecb8b688f7cd50608779ea9942d3", + "0x00462a9733f8c1f11ca2b46bce3fe6721263f89e2e4c622f425ac26789930bdb", + "0x00490fe12feebd382069f77dfd21aef3c5dcbdbcab180a92c6911d0684c975eb", + "0x002201f07d5f407b3d5a2661d8bfdc0db9b22eccc99afd25848165ca4161ac16", + "0x00294b1bf8998d1124ae9c80e5649a95fc68d3dab2b25d5e1c06fa60ac7d18f6", + "0x007bf04a8e5ae9d366546a47fb66745d74d516d8a98db096b3a831cf42a5f6e1", + "0x00868b68b7aa5217a45faa2e267b252cdfbba1ddf72d538e118f3ca6379d2292", + "0x001bd48c1ffe76f29d48f903232781af49d1b1d9f68497e2fa9c6d382703c063", + "0x002eb02f04f12562dab473033871c077adc62e3a32949e32a94ce30d780d56df", + "0x00e2fdc57b6ee5d4d13d5259a1af1fdb3a2d193d1375978aa286be3fcdeb0fa2", + "0x00346b88f8cc57edae7ddd57c9bc726d4b57ab11d0759c7ab313f9fe973c2631", + "0x00558719d97d204cd5e0406a9eeda04b4d60899cf40bba85217c62e5679460e6", + "0x007ff92e9072f8ea906361dac50b3f1e0b1087fc20773aae56566bdd90e61360", + "0x00dc78fa48451ac5578bcbce68c276d8e89bcda64e291db1b14ddfa9abf27ddf", + "0x007b78b6959d28a9f76cca2dc7c364fa81f9f5c894a6af655890fdf172e059af", + "0x00c8aa31a21e9680c72c2a94b1f5ce7033a385295f90013facc764cc295794b1", + "0x0030b6b59280e3d06e539afffb37f498a199a4a9c1c6696c27fe21ec56dfd8e4", + "0x0004a3d927cda7f76b04028598ddc19183758f2ff6ad191d22f2e8a1554b804d", + "0x00b3b47d0c763a0113e4c346003b52a8be90f3eabad0cb167a97454e8402563b", + "0x00713cfd9e596c4e7e601f608fb37c946925485583f62c8455017b0b8c091cd2", + "0x00cc1511a3a3b29217def16011e7cb0803c48ac48fc453df77319226f1ea228a", + "0x00999bf591a8ae14542b098f4e4f31f8b734f01f75e4d9dbcb4013ed1c58dfbd", + "0x00d99567037d6a0e166d198fa50bfb2458a47407ed32f5f42b22575e1a93590d", + "0x0099cf79f66dcfecc205d6137cd4b1a20d5e25b664a994692003680fdae83447", + "0x0027ec3971321572f8dbd83056f7c29d3403b6036bf343ddb227dc325ec71170", + "0x007bdaf6b369ba9987ce11eb7192f99fcde995c0e9533479c9d612aac44d562e", + "0x00b5c4b5d2118afee96cf2b3ba01b5c842f02d60eb58d8e0ef613c64406de186", + "0x0032586531babd7d5cba0e9756a468987095ada2eb6e774d256fc2779bb2fd5c", + "0x00c032942a14748c943797972137d2a3159e7936690789aef301a570298f2323", + "0x00bb18d9096c13b375b7a51120a67c9158cbfa8c7bc2ac620ebde1c5a53ac8b6", + "0x0057be8436404bff13eaf719d3e947b020f073ca2a20fd38a328c245d7937576", + "0x000c86ed6a4699b49f29897ebbb4540a088d3d8363ba2a821fc8760d5528f5d0", + "0x00258f54aa27dba5cfa5f20efec02d95da16c928b37116ce5a8d95ca164f5d93", + "0x00fab329be1b06f1d4b8c9026953f6b23d57f426f0b9683a98573def4cafe90b", + "0x0077fe89cace67a357ddea71bc59a97331d2ee782ebb469fada14933ce4458d3", + "0x00bbab31a886f73cece4cee6865ab89e8473bd363358ba3691870365b6c2ceb9", + "0x004553a6e85145ff8c1179b055353fc81811b015190def011e86c842ce176b4a", + "0x00d18ecdb99ca70caa1d68436a839ce876a2e69f3fdd25eb381b2dc9fedfeb4c", + "0x00d7716cf8aae7b791b8aebd7ac745216462e06b392c46a106d44f977d195864", + "0x00488c3ab96e133b4f28713ae2c5d3dec9685477502add7ce166a3a6bf0a9cdc", + "0x00d862f57a4c3a4da8a9c2dea5a532dbc87ef26275e4bcb29635f2475d45b659", + "0x00f49a576d8b6429babb9ea90659d9395dc29a0f757a8e50e03c8c1f41d8b8e0", + "0x00b1d64f39e73bc1b4315a083b05cdf9183021cbdd71a8b03965321a376ba4b2", + "0x00ade6fc194e89206722ad93e5176b4247d4e42be1113a21ef03b7a50cefcc0b", + "0x0015c9e49ae21c5c8c860c44df9920cc3bc8468e11e38797b2e6b2d0e07a75a2", + "0x001f0ab3f199ebeb003ee98401aa5fb063b31a6c8fc60cdec2a6c5b5175cd7da", + "0x00fb066c26cdc21941ce7673d8300f2b35fe16610a8013056c84c1d1eb14a132", + "0x0095714a3857b3dbe91f049d2f4274860c26773e57743fa3540e767c8a011d64", + "0x005e346a82003f4a43bf5ec4bdb24b9835f998563b537f8f1ad075185c39d835", + "0x002daf22be437e7e0fb23822f908c88a8d5f92ed3199ea1bbe60e621b511a9ad", + "0x0064685f603d4184a0b911a7ee30588ce73ab085d64ed5b2560b42de3b437203", + "0x005738f8981276962f2eb7528909f434eb80390781748ffbf50654066750535e", + "0x00105a81244452c5258ce039d5770c34429f04094cd6dae35e92b07ae10293ae", + "0x00c3ab90ae46e13d5483e7f12ed243a04381e43651f330d523e7c807aa6beb1a", + "0x004e5e1366a19115d3eba08f05819a6190e2b0af9c02f17690b28dd0bf3fda2c", + "0x00266082a1079976f35538167d03b046f643f77f7451a4ad5ebb18e31900d0b5", + "0x00e30de9dff80573b9274cd424ee1448f9c5b0b71fdbb85288a18ff45f5f0c4c", + "0x0095a0d9ff9097255e3023a8d7bdb7f4f7a2632c0014386bcd55d863e1fe204e", + "0x008ed7ffae78f20f2dc86b69f229bd3ff03486b23ff7bb53a3a8404f8f955022", + "0x00cf79dcbee8d086ba0ccfe19500899e2b9fe03a803e5b8671869626e4537dd8", + "0x00643aa28829de548e0c3e3f7fa3ab8d521a913e18848ced0bc9b488548f3ce0", + "0x008f23a3be4eb55e06502c5027f6a212410e45350b6ff1287aa30a7b24aaa773", + "0x006f0f294ce4a3e98d439723fb7d2f411063eacad23be3aa4d166dbfe6a7a5ba", + "0x00b73b03632bece76fe3103dafb8f809326a851969227a4dc537cc3fe8cf7122", + "0x009f6bcb01b119e3fcb82c89d934e63be7bfe9fe10b857cfa02ffe30bfcfc76f", + "0x00f6505d2d063d228de2d4d4d6abe43fbda85436a6cd9f7f7ddcb872dce6c589", + "0x0057723f4290727ebc9b7263043f7135d61e91ac96d75b84453f94eb8b5db5e9", + "0x00d8f0ffee2bb5d20a4da326b91ac4a8668c44dd21dee89bae111466915848f8", + "0x00467362fa742a03a8fd6ac63b4db9ca85fd908ff454429cc2a70b15372c22bd", + "0x00f57d11128b45d015f845f0339f897b9de7d46deda79bda2d6018f3ad17a48b", + "0x00d5ce7ce79ec12a4a1d25f5236bd8c42bb806551e1bbfa175ffc40754d86199", + "0x00c34cfa7170d4e2a29514d8957df8b80e635d7fc8063591e3149beabd4b94a1", + "0x001dd35eb986d3b186bcedb428f737309be36242c54753a682ecf1ae056eeaba", + "0x00dabfdf7f06242646760fc1ecc84c1512072f0dace0160001b8bd955aa8b003", + "0x0080ab93782b07b9f6a0588db61bb7d0ebed1648bd61165341b9945d90f426c7", + "0x0059dd91bc34ddee4732e10dfef2e2c5581f572fffb95c7f965f7e9c40a1701d", + "0x00443b84e97f199f0f05600c5e17eebc46c69c80867056372061f401aac9ea95", + "0x00e5720aa7a191766987f1733755d830805a7f90f554949c06291fc9b80f0dd4", + "0x00b968e4ab4ad8348d80e3e5364350c556c4a10fed5c30ba6d43c21867171060", + "0x00e2381180a151482e5fd1b189650a058dd132177065784b6d583bc486331668", + "0x00ef283c6ba2f03c894c48696e32dab434cb3b8565331dbab56f0371fa14f476", + "0x008d20b241951d0174f94cc741c0ba97ac495c255ea9e9417009bfa8fa3cbb79", + "0x00a1172bb798e95caf9f4d097f15a310c4ca770fad655a492aee05aaed6d8303", + "0x00742390f7115fb6ae3375f2139f92a73baf82d176201dfc4f30e1016d8741a8", + "0x003b23308efaa2caf7e0109b45a2b971b9c30aa205eb2b852ee1b2113c09150c", + "0x00937907d1ecc8d65a82b435df3fa73a0883e0b525a95759c75c24e27719c3ab", + "0x00df41f709bfc7383d2c1c27dfeabde2cbfd856c7280f0740d37d5ab3d1b5e0b", + "0x000d00995a6884dc6a170393de7f39ec1764e8f52a1c0f514d46e0372a5097fc", + "0x00a517d633ca5726ed5c54a5de033173b84c31b2f338a0c0474d78fcdbc3a613", + "0x001fbcd26e22abec08dcb65357b1fd10c6622aa23c19c76bda6886585820efd5", + "0x00794915682a26a9d94fe849b3bf279a502e9588b2cc364af7b221c3268b379b", + "0x0060631112819b2a3f7d5054d3c10a522910305fa31936f110a60024292d2729", + "0x0001e44cd0ce0bbc9aa13ea68dd3c35686e947280fff550d8ddefc0bf57d0591", + "0x007b188e0ff582b0e87b39a7bfbe32d04821b07810d2151f626de7cefb8b512e", + "0x00142308cbe17c13fb38affffe05212244b1ee7aac8d71fd3b3f556b4dbd3c85", + "0x007df65f49081160299ebf007f4744a687c78339eb37b7bbe424d8639c920def", + "0x00a71f2705a8f1cc2546f9ddbe9e0cb035af979a1ea1ba84d1830460b021e206", + "0x00562e33649c802b03d55fec9e59a129a4a5ee8283f3cd953553b22a8c7d527d", + "0x00300052ec57fc469959f56e4fdc4dc6be108774f6c863951d3bad218205a226", + "0x0007ed69838a4f2320ce49b8dc705ce5e2893bb1be3d616aa1e2f6c233e11d6e", + "0x00d038a12a2eed1a0ded1491071197f91e79de98fd858209c44a1dc2a4b6cdc4", + "0x00193b086099d6881b4ac3731bf8dccc6c6f625ba4aa22f3634001539f644dbb", + "0x00f6b9f5af808f4b905b9a3500d97baa2787231e953cc53cb47a762ec63b71f0", + "0x00866e5e01e37e6c09ad54ecbaa5d467c6ce7ea5cc6adf4e4cc382d7c253ec6a", + "0x00f680c6bf22ea98c26649a86f8a9c6c5b1449c2ef71a2be6f5121f4ede9b9c1", + "0x00c6c3ba338e314ce2a76725ac11ff670603441d540007b8f9e9a5f641438bc2", + "0x00ca429444fc5ec1859eb70e85a614f7c2d0b0bbe25dd775e90236455875e871", + "0x00d94c71ecd5b35af0ed68f6c1b5f02e14c73b36ebb14f691342db8958577994", + "0x0031284d881c8739d0bba660826494493d411eaa7af6252fa0bf2e03e913a3f1", + "0x00f983077fb8e8e20b4271e0cd2e15a6dd0104d1b4f178108acc8886ff52fa21", + "0x003d30f6d0954285df1f7990b62d85596845d3391aa754e91944ab5490bd43f2", + "0x001db9cb5dd2e2043bfe4deb31595b13373a3fa69afb263f2e29965cea8f2731", + "0x00b06838986312e765ee8acf910c4dd340d63d524eeefd500ae75a4282359d3f", + "0x004bfedc70ac9eb7e7b67cf688aa74256e9ecd31d67dbc4e458f5cd851b7dc5d", + "0x00a750e4437f9d327f820bf1e43e35d8bf667699de65c0635f7dc19c556e564f", + "0x003f3d0069b4dc5f67fd1d679d4fc270122f8ead1de0e543a55de03bdf8f831e", + "0x00fd8db1caa043ca23ea412b34798322574a8407f8f63eaf0f9c399b4168cd4c", + "0x00b0239bd6e95a7a7cd87c83d2401184ab6feef674baa03416d8b0a66862738e", + "0x0074cd405ac7b0683d142a2bc7b6c55d2220247c0e86f670a58db9c29a1b4923", + "0x00e5ff2852d6d4f13ae00d01171c793d21bd5d2cbace1fcc055ce01558001a95", + "0x002e75838f758b096f292a210f8716ecdc03f69c59a9284529e0550f96744395", + "0x0009546b4a9b2a3e62ef89cd5523c5490c8ef6332cce071e34175a0411289b94", + "0x008330447aaa237b11837364269b459804292b3afb6b180be9b01adfe1d880dc", + "0x008554d853c5fe4399883ea56900202d1d4fd3c34156fbb8db992f59712d53a0", + "0x007fcd50e985c70d9dffb4d6aa8f2b586277bc3a882bee8809711aeac7a44361", + "0x00c2bd819f6ebc8d4a41b75f526c444ba19c860f112aed13978a930279a02383", + "0x006a74066d06b9e5124b439684ca38be64aad45ddf43f98b27f58c56a09861f0", + "0x00f83c3832c1366e40cc18c3504ff64d99ca00fd099e56d404d9d1046dc9bdae", + "0x006a2365f9bb663988b22343da9199ab431f4e83ad926eb49a6370b547a4da33", + "0x008a258e0791cc29b28bd35165768f3fdcb465fbd68f69efa3b56a8d9beeddc9", + "0x007060fbef8522e02d7f4ac61cd4885ab1411b6d2645c4bcacb461fb4b7faae6", + "0x008fefb297ef57edfc3e078f3af1ed41c68ba13474e7e9762d271a139f0a371f", + "0x00c31d0fedb29319a96e84eabdbe7b5e412ffbd1b77cbef251e44361a8422246", + "0x0037305452089dfc1d0f2aa61ce0b33b8be693804dc63b38415ea3e8018b8320", + "0x00f8c7d1b46d07529959b63c87e7aaca51713e7bc8d52c237c0f2a36a9ac2a43", + "0x00d3aacb19abea338275cf20070122aa61a99634376cc190d1fda23f09572c7b", + "0x0053b44fe190c102f9b41dabc2f6409ebc092b2ae14ee6a2c6ce22fc3103eb8d", + "0x00f4ec27aa05a96a81a6b1ba90f334386b179fbe5925310b4b594b7eb714e872", + "0x00eb1b465091f6b8cb0870753e54e736dd64ff3095862b45a9153519549272cf", + "0x00b818af9f935456f806e494fd0cdce08e95adcbc5039830e291948b46a98aa2", + "0x00c7469130ad3a807dbec268b2ed545144c7a085ca4af3b94388872647adfd10", + "0x005a901b2a819d41a13197b83135f8e4b71ee85139b72e73e60d6861703eb6fb", + "0x0015247f138311e69ec61a773947757ba25ea8dc2966a96334fa6314e9d8b56c", + "0x00d7925c5e2c2751ee57dd094b573316dbe145dfc260ca47e2f15478cf0a92b8", + "0x0002e4bf0435704a0a09dce89caca05684237d72a1d92f44a0e635f0d1edf579", + "0x005e9f967369eac066da3c70d6625698a554fcef2bdbc3889a9c53b2f990fef4", + "0x00c557b55796669e2925cf25c3d55a2735f24c5a0ce25abc68c7279f4e491686", + "0x008615968c010a0b8076110269d207ec7656645c78826f6c0db0476c377fbfc5", + "0x007383cc59dee2a4e3f0b07407d5dceb2418e518fb32f032ab80a426d9237637", + "0x00042c65b1e8dd40a1d6d00b3cbccf3e3938019c3e8e8c242d876bab76362ae4", + "0x003e69f9a233da7a9ced17b6543d09272a0a9c743506e96dcc98856a28aa9de6", + "0x008dd71adfe6382c4697bd1c48d3789a3025579a8a2367f73926079992a8e791", + "0x00a52c7c2e9283d980fb37e90985475df7296f3e69240c180bb38e52e4939b76", + "0x00167b8a9de2d7c07f4fc21fb0cfa1f967b9f056e63b40e0dd2605cfcde421d8", + "0x00443f74e5e6fcd1b10760bb3a5a577102cbfe33a40dbedb863640567904fb74", + "0x005ad3630ee5f9d41b29efc0848824291bbff2bdfad895cdcb7b12d3a78e4667", + "0x00cf333800097c8ec23ab0c69f915bf4bfb9488e503b9a288033f6a48e5c62a4", + "0x000ed51f87c9a56af472ceee7f295c78acba29b046aaefe1ef024654f06513e2", + "0x00ac4f6db9980e2ca5a6bb0096b017405a5ad01ff51a65f750e57888f6a40ad0", + "0x003025e494c1d3efae152e11fce47e929c6b8583c6d35bd6f860afaa46437f73", + "0x004427eae7b7ad50fd81555c98f30a9f8927f396f40853e0bf3e95ebc5a8db83", + "0x001e631e60b75f5fd624333ca0806da3d6d45ab093b1b8253b117f260ecc2d5f", + "0x000da2b3a0b6444644a433f7b6c3665ce901e842e899da009aad29553f1bfc12", + "0x00b1397e2203247ec0aa1b9f43b73f43e8f49ce8e354af54ff5dde3df5e51e6f", + "0x005d3a15c4c758101ee4d68c77ba0af001c0372fae2affd7d2c2f5cffb510f11", + "0x00ceedf9aac775a6e84d731333b8f5a3cbc58700c6c2543789183931a64be27b", + "0x00994fa90e9e18643ca25f31e310521362e6226e6325cc6151341a41ab150708", + "0x00a96946881fe9a5784474f88dff8603b6a2ed33956773863c6dbc1cfd6a5aa1", + "0x007523c2ef7f6c8735bb729bfb90291d3ad923c41d9c340d75d8f08e6c33f500", + "0x00087655ea93a5126109ab7fb557ca21214e5cee7633b3229202dab608d76436", + "0x0096d1224fbaf6d461feb12dce458cffc05bda5dfb68a6498d67c9a0972053ff", + "0x004d2d2ec10ac14268affeb121083afcbf103eaed7b30bf9f3a9d49c5b36350b", + "0x0054e29c96179a295ac8905af4591f4d5f21ec687aaec76d4dd117b0cc53c318", + "0x00cfe3622487c45d5d47aa724dca7fea5f0ef8b00879d4eaf9d5c8f1f7157c58", + "0x00b8e59c57c763b3b9716eb87bdc2d08f059b0841b5c1c59dff4e31fa6fc75b3", + "0x003b603e449fecfca351b40abf48be5526824f81fcacdea677139d058601e8a1", + "0x0029012c7a4d828d86075f5fb6549dcba2d9e4de4677e89278878c39b4bf92b0", + "0x0006161fb07523e3234c2f60ea402e8f3287bc4fc6740f4b0656222a56c5d5cb", + "0x001427ed7800ccfaae3cecc09708ef7947f35d9eecde32b364975eca8c088012", + "0x003cd8a2693a8431a041a59c7de8cc4bb688855b684896981d41c5d921dd364a", + "0x009021eb3f7a66000246ece170c75273d9ab905e026cf02024dddad4cc61f54a", + "0x00a77401e16b28e687818fda6c991cf9d1fb3f090433975ccf08e76812771720", + "0x008c1c25b01df0dd9740eea32f55e92f26154cb17070cae87a4b1ea760e11e6d", + "0x003a82f7ae6b8cc9990bb5efcd7037eb81227f55bd2b2ab9da3c322dd67d7cb0", + "0x00b11705ac6bee66a2545db80ed7f7057b5937335a29ffc547741d5fd412b326", + "0x003d9ce928033ba7d226d2b628f25719ba542013acd53814887b490f4a180cba", + "0x0024c99f45a6d14404a59048fccdabde6e3ab565450eb9899cf9e5f1c8cd849f", + "0x004c827e1232bac81b840913aa79905474448c8295fab9c4805871a8db731d1f", + "0x009f3bc3b5cc1dd63773e2ad1800152783a2602933caa679119760e3c1ae9118", + "0x00e51600c92a4eb77385b25100fbf2730490900bf5c73a25e6ef778c132ecc1d", + "0x0041c57e0bfa00ce329b2418d167c8d858d74611996c3e2bdb49d041e039065f", + "0x00cf16dbba23ca07157819273519263321cdfb48e2310c29658b115bb0cf1c03", + "0x0097ebcd1af54d99b4524fa288162a966410f500a85387ecdefd4033b556773b", + "0x00d5d547d8389741aa534bde2737b1d51879dd0a1bfc53b064068b99a8989585", + "0x00c8f7239e34ce9ca82087ddd79d6252a7a19f4ac074abd2cea5e431ff823085", + "0x00d3ed29e8e8c6db192c72a649bb65d6253faaa69969a6ec79b95b8a7b221896", + "0x00c35f1308a3c3e9536300c83b884d2f8216ef58b8b21b8b04b701b6c0cd4447", + "0x00bc830cd79ab04d7d50615e8eda3d563486c96ca9f4707940d07dd140a408d6", + "0x00c53281fed38fdc84c5d842e92c0f3a4fe6e05771cc117177607d7bffb8fd98", + "0x00c8a2b339fdb7a1b08d322d5e4a1d1ad8fd7acc39ad5b9df402474d9680dc97", + "0x003ce1688dbdacb2f93a0e9c7e812315ad99b4c53980d57353d418806f4cf14e", + "0x003435dd91d11c9c042ce9e8dd41a7a441fa6552a347c292c9a100eb7ed83985", + "0x00faf43ac8a31358d5f648aef904445d2c6267560923b0de6b9f49481b494d11", + "0x005b06f14f6bc33b9513510e4560519b3b54c6f3b8bd9cbd72b95a651bddfac7", + "0x00dd6769011d6513b502a02cc67fc9758d784547ff25c5859c152f3595cb189a", + "0x0019a533814eff8f0d9f42b44be70dbc6b0966bcd514da615ecffad6b83223c2", + "0x001440f624766efafcfcec13105ba32ef96e2eb3bbfa343ce7bcef8a73475049", + "0x006d3271557c4684430032623bf72a57ba663d83e3462d489aa8f56aee05c5c2", + "0x004cec823af0f42a25b26ef9adf22714c83849cb38ff75e5e1b7dcef2b4d9d44", + "0x00372c6ed4248a06db9d58046b72b07a8279170c5231d17a18ee75c503552111", + "0x00f45456461cee1e37855147ae30823388b7723b147528614510e4d9cc58d5da", + "0x00c8c0a707a74b396d4df253f4838386990636026356a99413c0260df7db8052", + "0x00f20ebc42325a78e74719bc0051f7fd9c4af34eddaf02672756726f42d6272a", + "0x0029fcfb9bfd11993863f67b37d5fff9d265195eb1060d9901a50983584fdd89", + "0x00ce46650067c026e42aba4d37045c2d978e85c9241be68ab1491d4c6724964a", + "0x00304d516caaf5e57ee7333bb733a972dbcb9beeaec156ea7e4db160e54f5bf1", + "0x0089ffaf051212c856505e0bc081e9377ae84d74150dea6681535ed9a8121250", + "0x0060e3ebfbf24189f319f856c9cc3585810cc9f0b84faf843c555d1671949d26", + "0x00e58b5e812cc112e05773106d1f1ed3203e6fb84472aed4de38367266450c08", + "0x00f430901b5e3ed316800405a04b937452230b95f5ed9e7920b12cb714995b8d", + "0x00640030d112a9733fe6b1152ab08533254d581d76267bcd26fcc6a1fc045f94", + "0x00372e9d04e1698868aa8bd3c167f5436a6367ab79feec140a56cd4b1ba62ea6", + "0x00d5e370b8c6730c454e68722cb9a37be1056fd359668d118f372f5ee4ac6829", + "0x00b52762e5346f9dea64392b833ad2967489f8390f3c19c2f290133c1cb19f49", + "0x00067102b9895dcdc07fe1f7fa49d8ee9e60d99eec7c799eb43ee217820786f6", + "0x00fa7596f56da982fc484656b1c13a1722464c736cf8ad0ea613d10910fd70a2", + "0x001f42e65fa2d985d678a4a5ea1f6cf4aeca8da9f9e7e1193c0ef7d768aa106c", + "0x001559ffd60971f0517773119be557414ba35fc4600bb4e04870ba6c09e0ba30", + "0x001ed53666e366ca3326058e57411c2c2f66446279e2038fd5860a41fa06c8d5", + "0x00e61211ca273ecdde70bf2d46a530cb3d5ef3a2b6d137d0565b552149a8c053", + "0x00a80cb61439612d3a50a64811a4f42a8af99d8fb26461680c2d06729ee1cf76", + "0x00fbf64622c55642e875e9ea3108fb198cc24832bf03b01a802bf1dcc2aa12d7", + "0x00eb7db4ce4ae3958e3d03dfe4a99d11cbf2c6d224b30ec876d87a5d2b10f11a", + "0x00cdce3fe1e8018f2a7cbc481b84e28c2f4c022799fe54aae56fc05720fbbe85", + "0x00655cd4c2e7e3561dd5fd670314c879cd61d1114425b61e310c8e337b18ce3e", + "0x002b57050aaeb58d5f539ea1739b71c191bca2df6642cdfee9888057fb4969a9", + "0x00b7fb604e759a9b6aad1210019573e8dc1fe913ccf46cdcf15e404ae273954f", + "0x00d239cc56362b69f935eeb4dd5b9aef11579303e05b7f8572a9606ccf7ab0e2", + "0x00834bd8c4a9909fc5b5dae5b81c2d900eacb4bd74a3fb5ef80969ad03f47bf4", + "0x00d0abb3ff815e8be8394744fd580a5e794bf50fbb59973b5bf5667d05081aa4", + "0x00fbb6ad9031289ae63e790a332325372a84fdd95757cadb25584427ff965f23", + "0x001c95b6c4a6fe9c71cc76bc4fc1b03346f80afd7e9038c7919b920c89561092", + "0x00a110c81f156060c7c83f97b82cfb1d0f1e24831669b8f14727164fe224ecd4", + "0x008eb2cec91735a8c912e3f62e907c5785c3048b7f7f24e3d650c726e1258611", + "0x00b8e228e8608e97de9cf062cc26f8d7fae29cb5b2e580d38024f3d78334801f", + "0x002f7b59fb5c3fc560418997c96d64775cf6f12084106ee45828045148221cb9", + "0x000d7fe04cf2b7463b1491350d666f265fc3a3991dccb98db17ef0069f1ddfc2", + "0x00e9cc7662f54126b2738caf510701c6162d67b3ecac048d95e7238adf2858ca", + "0x000f6ba65b9405223b328a41c3e3cc312bacb9d7f65233d8cc6b29003e9ab57a", + "0x00bc868ca5047fd8c463387c9dbea24a56c16e535b8c961dbd325d1308d45173", + "0x008b6f9640a6a6436a67fee6e9106206d9546a512acd031155805576667ed093", + "0x00ac26747a9ec2629facfc760f06c04d62739aedae228d96a9d471781c412e91", + "0x0091525bc02f5f98e068c4fc556727982907c15316d807d5d06aa7951eb6f8f5", + "0x0065b47f6893c1173c767ae7f9fdb6b115d696d67f458db203faf796c68432e2", + "0x00cb2b3983ce23f70c915249729edc6b77ac36d929987afe33339fb08a621dad", + "0x002347bd513f7fe2a279baa0d6a1165192c05434ebfe58be91168cb968f6f02b", + "0x00c20bb7dffaf03931c818bca0a1d752c3cecfb281f85cb4f902bb1708ff6e17", + "0x00e9204943f3c0c404301f55fcf39af7b4786ea03472919d1f87df39544db3fb", + "0x0000b6d1c634b4583696167dbd75d3beadd072cf1fb655d403cfd10c1253baa7", + "0x009c1207cf649c0e907625ed0a07ff783f61c9b9b40c8976983104f4dd690c71", + "0x00291334f05c7055a92eaf148b78b8772dcb4dbd0202cedcabbd486654e5cd79", + "0x0056cbf2e343645c3485dbbf894c991a5a09030eaa4c898dd3e8224794835834", + "0x00463507f3581316b7813fe773e68042738e1caf498019e827d64ac500d1960f", + "0x0091975e35ecb4efc52d1149b07e8b3fc4c34e5eb7ef18d75f50110d561dcf29", + "0x00ebc497743a04302732aae5b9681d3195fb9a83a212311ad0c2217cd389806a", + "0x00efe1e5ffd5df0c8023f1b14dec8ada8af0a4f83aab10946b924708f0aced9e", + "0x008864664262164e1cc333a9df453e951e0c8b643dd5ee3cc14884da43371927", + "0x002141c99dd0c6b07cda2c063720df7ebff1e4feace6395cdfba7364bc07ab91", + "0x00cadd328e4ff6939ddf37b02189d7965dc5ba2379adf5351b070dd5735e51a8", + "0x009fe5191f3c190600145f796aaff4b57f305b4e803cb4f226a46431e90a16d6", + "0x002a1bfc2240dd886145d93943acdd06e7caa65faca316f67df36be141140e7f", + "0x0000a8c3c90dd5a723b1e8004b90ec4c03189679b7fd24e7da1ec436744d95bc", + "0x0044393919fc7e624e0dec063c9ae43a1a3e1162ec475aa4811707c16d4bc259", + "0x00f54d2a61609cad53fedfcd927bcb73e77e280bdc7907d8923c9018a31de6b1", + "0x00a757ebbb46b4bb969e920a8f316720e513f4edaf807dd069a82ccb45160871", + "0x0016e952c8d5f4b81e4a6fb14258607cdc8b89ecbbb347f364b1354d1aca4875", + "0x00c8917a4360f1f36806c46f1c255ce97b5c8248e158a6f8ca4f20d471ed649c", + "0x004c29fdf5dc82205c4e8bef9ca931aaefd2f37c85168fe033074428439070b4", + "0x0005ef155ceba75da577031161523ea99eb9459439f189b79ce542631ef18b18", + "0x0024d86302086673a8d6fe242b4f75d751f2de04beb90cf9416e19918b59f434", + "0x00357a655d969fc33f263b97157ecae96828e35b67f9acf5cc070e982408bb43", + "0x00fc0e422fa16588652c71251b0ea3db809e07b73d2ba2703d2fd9d8661e193b", + "0x002d15ebba724a79bdd2f06f0c44c8565e83d1ebb54c2b1a1591296444fc631a", + "0x00b85541fbf7a120a0c1e0e22b78dda9855c5f94b1824121fc932a489339473f", + "0x00bc2324bcbbee379602e502fd7d45d8e053c37e2a2425773309107c334da5af", + "0x008b9eef0fd97b8ce20f2677301756a5eeca5980ad5920f6bda6df2815cf577d", + "0x00201f7f67886fc2fec37e2e5a67c1136da65d35dce8e47391819df6cdf01fbd", + "0x001d6d5734fc3709a3b9927fa28110b7f59eb179a1a05ec09ed9f48b1c7b6d75", + "0x00d44d330382f744012a369e549db008a841809e376e083618c9633115ff2632", + "0x0058e4ec139219fe7520aa5eaf72aa29624ec76bbdd2f07b536056e8e477ff83", + "0x00d77ca010b80d372c0d5a3abb476c3e8971ed50a4f62ee869c280a28ae9c238", + "0x00e0a03ab52e37a55adfd9f217bb43a6888e1fff5d2c6b516286193bbe56a9b0", + "0x009daa109d1ce7fbb24ee83e024a0b7c2f86a877354383379dfb93405cf24b8c", + "0x00fd473c8e0e8385f1fc93084c1fd725ee63ee2d435445f4c13a2eb7ece497e9", + "0x00dc24ae34f92848d2835a9bb1fac178bd37979c725ea31f5ed57a5b46f96a3c", + "0x0018e614f06801337df497b91f20643b6c7097c7aa2a7ce2226fadf07079757a", + "0x0012af94d997e09956bf8c8ee8ca5bff6139593c3c9c966c0ac214bede9fb144", + "0x00094def406335f4022a92be68ee03ffc750bdb7d9429a55f70c686ff031e053", + "0x00e5000c6b083b8bac149bb0990c4daf08b5a935a40c8484010b94a097fd2488", + "0x00840b821e2d52f41da3299977c7c9d1e85b933baa63b3f7a33d59fd7ec8c581", + "0x006ddf1dd8bc93c78ef442414dd57219a30494de77e7681cdfbddf0451046a1c", + "0x0069792786cb01d3383143141248829d33a8c176395702f96a4845f0f27fc540", + "0x00aa15eaa42396f412951628a429cfb7918a587c234993a8c04760a1b2b23b5e", + "0x006d566de4c8bb17b806d37954ac39104b2c6114c0a70e2bd2b661c6ac6a7367", + "0x0007a4901396283e452d558181ce56def64d1d2b030ef8dd3cc093c747bc2c4a", + "0x00cd5b89fb72dc870ee9f27f63b37ac46f9a151f991ee6a6e1d7a0b57aa2eda9", + "0x0010950bd0da8cee3957ccc4d7d275301d1a294e1deae74ef419e2810b161f70", + "0x005b0a39268256c7a9f5845216aeef688fe2479fc78d166956cad1c31b82172d", + "0x0036d45e03a8cfc6b0ce8bad5f8ff778fb8f836dc6d741a6f50ed571894dee13", + "0x0037603a0cef977a3e47ef3cf7d767fd1d4b31889d5cf706292792aa1a52dbd2", + "0x00b8ad0dbc3da24f6a10f60bc01e58520df0e0ef3eff15d12f03e597734a40a0", + "0x007f51cb29f97b179ba6c796fadfc9f76a34f8b1a3a76de8130645b2152daa78", + "0x003e1b4eb051aef2ce33dd1d0acdefd99fbd2b41ede83c86f93373bd6ef2fcfb", + "0x00e5c3c291c700d0e50e9679381e0c4cf98d4dbdb9683d20947509281d212efa", + "0x00db1c308d2e8060a17e86ddd772906b6f87f59a0adedda10055c83e6b899ed0", + "0x00baea224519324c9184da59e361c08f7918e41c275e6af0a3ea932b7c1cbe99", + "0x00d76fea2d91c69555e3b5617df53a73903251618d40ace31528c92a61cb1255", + "0x004aa0c8816ad1830f42db907b850af3ba94bf706c8955935001c17d4ff3388d", + "0x00d960e5f98c85028e6c2fb85bdd426624b3d28c3735af2754f5d5a52cd5f8c3", + "0x002062a3e5d61950c65eb07624c5b87093c78ba23faed1fcc3eaeb528f243884", + "0x003ff0251d2640df9bdf18c9a8d73e12626cf6904b3953326bfb38c812694347", + "0x004305bdb2a898347b4cf415a35b5c7d1cee7958c8b5cc701adf521bf215e9ba", + "0x00b1c68a5d373c6f04de840483ef22f9d5abfbce7076f4744aafaaf0169cac58", + "0x008c79503cba956bcf3f05ad268bcddba0bd9e998b272242a744a6b8dbe6c664", + "0x006ee06b8df1961c69f022faf53457d47758e02a8850aedad03a9ae0a0b3e6f9", + "0x00c2140567ec52ac2b9041f3b61582f512972b8c376b0fa518efc69102a4a736", + "0x00c27707238bdb9f95e5293fa24d1e5ca4d7f8883b98480a05ef2014a0d31647", + "0x0010b77fc147f7ee574fac6c01ac02fbe076b5dc4ecac99cc4fd3568525ccb52", + "0x00c1eb2c62f1d1e17d0c1113c5fcf7ce332ab0f4257c670a38622a83632ad1d5", + "0x008c98648d5b1592772c9b03f4c30bfed4d276dd6909846b011860a4d7c12452", + "0x006f8ec64e35d5448bccfb03743f16c71df5353b3c91f5606daf145683d4f7f3", + "0x00421ca2ece2675ddf65f147bf3bf7844e35b4cae5ceaf9b9c4c0195502331e0", + "0x00fb191b3ce04810375b5a13d2b9135b65219a13e2be2874fa20d227d8306f6b", + "0x00ab29802898923f97fbfa37f0c41bb51d6059260b0311e647f99f87c323fc92", + "0x00e185b9193bbaa1e00cb8c14c6d2826b17e9a7cd1924fd437040aa294b0f246", + "0x005c6b09cb0ed9abb04a2b69dfacc55c6dcb70ddf2b0225319eedb97b7e85264", + "0x00188205e7c995255f73c535a2d4714b8930192eecce368fbdca2b6cfacbc670", + "0x00ede90e48f63597548988336b9fe8ed97d27590ddb846db07cced7a3764dfa7", + "0x00f51629505fd22e65ad9faec4778e09e25151e8e1bc7c05ca94dc3ae59db028", + "0x005addac251fdc37015fdd966a08eb2342594ba14959caad4b6b2d281b26f259", + "0x008d802f0f8be223b6727f904d8e3bb15112415152638f4c19e4a58ec780a67d", + "0x00ff0f07a72ca4452ade82c61b549936c7114b24874d3ddfe1660156e8db066d", + "0x0056374752298fb868de7eef0ec8b25c503e3e808bfd821aa1b56c1129b36b2d", + "0x00bdf3f73be40591d4fa190c43da7d0153d7e4ad396c03eb92c667196fbb5bfe", + "0x00e9195fd22d207c051a2a0aba2cf98409d73c7d10dc4057f2987f0614a195fe", + "0x009fe81382b481c52d68bb49530ab1dced37d644fb0bb9f349d5f14188686b60", + "0x00a8df96937da63283f9410d79bbbbdaecd8a92f8fd5bdd2694f1c0b1b6262b2", + "0x00af75314f0606ec85d0ae9a4dd7a5e6dd69dd62c4a86098efab6b719b5e6e73", + "0x0021fd05edbafa17e14b42e613d38ce8f901a3d20db14dc7751a6b6ffd569e12", + "0x00fb5fea52783286bbf41c5242b8f914bcf6a5441c962e6222a417851379de11", + "0x002ab134b0b97a2a28dd8e83f28405ae16f20d5dd09d094dfb08ea0767a336b7", + "0x00f750004c68c478e70d62efd058eba44cfa14683bb4cef594dd4e955c2a31d1", + "0x00bb96cf7ed3a1aef2ac7a0d521c129b3c56f65d08bdc59fe8a6e4db0ed814db", + "0x00ac3878cbb5760a6e633125ee30d1e4024eb1d33d138c641fbc64149bd15594", + "0x00f66e6e272a0273ea92e31908d9666f73f298954839a5616c0c20af39941dc8", + "0x00184ed96f271a4b75c811f87f56fc31d99353e26266092a52aad77db23dfdfd", + "0x0055a5729097536c57674df10f6ce6f9e351e63db2d9ac58b8b29d819bfb66e8", + "0x008cbdbe895a31d12948402d67005f9026160dd42b034206028798eb070b3c9f", + "0x006746cde2fa6f8143b716a0c95bb446646f1cda9f1e32680fb77c6a34f6a638", + "0x008734667959f352187a39ff6beccb3cebb5e913e91da935003792a205ef23dc", + "0x00c0ed6c8fec9547aeb80f63d2c294bfcf3c336c837d926d0dc0462924ca4674", + "0x00b53b7a6542729a2d5effc5b3c9df77d3a31741ebd1e70d1f19d5f9f6590be8", + "0x005c0e80875f68cdeeaa1dbee7822b3273dd08c797849b8a7446363363c992d1", + "0x006a70b49f9a8d1b1ed94fb422649de7379ba94a275c68df95b8dc4304704246", + "0x0089e039c63f38f1dabeefbd0ed86ed5b2c17322cddf16716b1c1ea1e4ef5c52", + "0x0040adc7cf5495d2d6edb5a422ab920a83c64e0374eba4ec64d9f77364a98c33", + "0x008ff2dee36c108d7b6c9feb6214c6bb4fb34f62f16ac7a86b99f569d64d40a8", + "0x00ce054f696f09f517bd828aeb81e87eb916e0a0cb539518806c91f69545d0c6", + "0x00a20a4c4bdb3d0080f18a90c6dfa5ef7c152c34af92d6c4d92d754e45fb5c96", + "0x000d07dd5eb4f7c4f809888b722161f30708afbcd52530bdc77ecb7baa75a8b4", + "0x0077fa6061cd79fd8634c1a2e7d698c404ea9253fd4ee28ba766c2118b275f6c", + "0x00b9b1f9595e62977ebed7dafc3b388fecc19c02d89c6425543df201dea54521", + "0x00649abe31e6f3aaf1706eae59310d9ad97677b0b8bdfe39eefbef0fd2f88ff9", + "0x00fec07d236b5ed92d62711b024040312ec1985504583e3ac3fff68d98a37852", + "0x0089437ca12227b83148ca33ba8ec1a379f4ff3e6a3719187cc665d25da365ba", + "0x006466e9ec432867ffdc3320d25f224b7b72ca1d703acea10f581e68843383fc", + "0x00d8500f4d749fc62edccbe7e65317a0325a0664d5eced6893922312ceb29236", + "0x005440b286cd762d3deeb0ca5f027658a99ad93dc1f3f20dc68df2cf6e9b5faa", + "0x007f30632d4d626d70b60574d96949ead72063998c005c4beb759d8145970ef9", + "0x00909a3fc510db029cda97511602c513ad86aba5a59621c7749d163bfa003fdc", + "0x008cd24f0a7cf4e423a524d18a143870f49c668bc913e5d053e092a892585152", + "0x00c4e3a7028e9877934d333d4f8ef6f8ed49fb619292f6d545eb1d3be6321cd3", + "0x00455bea0a889df93d834833c3f34f4586a95ac432248aca0aa9dca5885b69c5", + "0x008dd6c93d8edb2e2a205b15d4aa39dc02d7924df8e6d1e6aa164326ad932207", + "0x00a991623c3bc3863995687399bf95f0087841ff99abdcab713b7fbacecb4a2c", + "0x00d545c7703da835ce26b13dd30b9dc56a474cd77f5c1404287c904c1f658465", + "0x0072d4507c69fad98f167d6673b5a6948a4a3515f9d6f1a6fba29a5a95f1d136", + "0x00f0afada1a46bb9da240c7c898b95b6bbab9fcd959f9b7ee890dd6c4f4deb4a", + "0x00f2f0f614c5998260208cab1f86827b89ab955e864b89d1a9d97ce6b233383e", + "0x003a1150fb617f1736826722946d54fe2cd9f10d0674b8b4890ba94fdf6f1e23", + "0x003a59bf266aaf3c610e861e1dcbd471c30936210e4270af5838134daa3f03d7", + "0x002e88ad76cb03602c0a25a815afa27fb6f582396732b3b8c60f6f8e8c4b4ff5", + "0x00536b1c62274e9af2ca05b753cccd14489ecf7226a745e5e3e9f34e3e370fe3", + "0x001996a8889507901c8018086d987ea8b67002e2fa2fa92ed9a628532372d42b", + "0x009dc53cf645c360cda1dad98345f830f144159640d871014c1b1cb9f0adb9c2", + "0x00f0ca99abdc0e783e8604b8100ac2d8118bb56c9be1b9f07ab26dc5c91d280e", + "0x002a2c369810928b5af07ea0827c90a96a55d717a40fd8119f00db6b1e78e729", + "0x00ad6864a363d0f6e5ae3887e45dcd9316f19e083580f5e13e9d8ce81119f4e2", + "0x0021b6fd88fe82e81db8b703e1a81ca3bde2509faf7d0ba635d2146f18cec297", + "0x00422421b6b5cdfcb93fddabba13fa19491029683c39b41f30eeb5a78a64c4e5", + "0x00a2b7678a71ac153d81d944f2bf5a2e9e84cc0c83a14b843f149bd72e7986de", + "0x0038ee8c7a7dc63c3346e09e1518df4771c900c9820a4b746782b3c863d597b0", + "0x008ca1a3c2f4f4e736f1ed4d87e4f567a9c802a5424caccb83a134fedefe82ed", + "0x00dfdfc05481a892fa9717697035e7c36aa73ca7e0b16d610dab603cba7afe6d", + "0x0059a7b2902345b4c0b8cef85697cf0fbacef99fba1912b6b011b78b27ec9a7c", + "0x008559773f573d2dae717b344a61603eeee5587254979658f319fa6227c229a1", + "0x008e155eac4dfff3102f2deb1345e6dbefb3fb211972fcbed534deb111163339", + "0x0024a9535fbf4ba57dfa098e93ff9838da0ca1ec428bf40b61a77eaa80a9af5b", + "0x003f20a0e912ee9dbde0e97b426dd0e03fda38546df9f7fc002b203ff5b655bb", + "0x00c528a84eb0f3281c89edbcc8919c6ff4ada91514c454a3211e32504761ce9f", + "0x00cc11de3b8e5a288b7e4272a897d35e6d36c391d9a88aeca824e5a044df92d9", + "0x007605b8dc3b8ba7d4d04c8b65140f48e0cc9327def9b098086f892d0734815f", + "0x00a74fb96c02cfe23fce0b4b98ebc4b9e31d0aaa169cf3d29c93602007d2ee9d", + "0x0035546e0e09775bee66d8f19a420fa9ec581caa68ad277f444579ff848b4a04", + "0x00f904ef3967aec255f2562e94d1cbfdb4eb5b2625034ca4e94d2df811e7d338", + "0x000e7dda9ec3b8380028ebe014d0b99d5528240d722c036330830b9c15c71535", + "0x00a71934896ff3bbe9a6fa7024c0038d22b4c4599aba99cacf52246c77bde0cd", + "0x00661fcf3c597c0738dcba554640b550b0d32a0909a2ad8135f45cd017625cec", + "0x0083993aaf8951a77de115d5b7d3edf4abdffca39df4515530384a7c7461d141", + "0x00f07f0c72d6abfa7283aaa8ddbed50b25c771d279a6d93cfab0c5d24b13629a", + "0x001afa0563145f6849031e3f590c628aad1bd0ff9a81598fa7fdf6a5d49eb390", + "0x0007009227beb93641af18cd6bd14b1d1aae11d135d2b7920334e9afaa2965d0", + "0x00db2833bafd7265d994c2c770ca096c76ed8aa135d4b098c0fbefa40dcb66df", + "0x0082f7c776a02fb25d6886d50a22bfdaee36c52dab674b5c2911863557d97f27", + "0x00a3d666beca8180be5dc774bdca7ac8f286935719d83ee68e786ffa17785d4f", + "0x0003e99913e5e8a85c0b8232873ec5b877db25dd8fc5f59c04de435a193ff7d1", + "0x006c9babe4e252bd3d9d092f878bf5e43802d8c22f256a3e8f0e50c7b78f1b2b", + "0x0043906d8dbb1dd6b73ea755924360be8595bd99ac80522330f9be8f6a131f02", + "0x000c952ee4f8db29140021a75549944b6c9bd7d30f4c9c8061ca6d61a3b93ca7", + "0x00f2d39d2906a24b8ebc6cf65844968c3b8bca61bf36b9a0654b1eb466e098cd", + "0x0007cd435d87b57ba3a2885d5ea176388e3b41e874af685784a8e67bd71db795", + "0x004826a3f354770fd5761e7e22d9213d4c30f3bcadd3c5e665020a31bb572faf", + "0x0028de709b0940bd0619a343b312d6ae5900ca8a1b643073743be90451c8f93b", + "0x003d8f439c4596b0086e6ce7a077b1ab20d38754b880f7c14a9893405f96aaa9", + "0x003e53a2b6caa41d04640d55ad3b5009262d2c1f60c1bb4e5e7161224db2c84e", + "0x00aee0f180fa9c8396377d25fbe4a6564019c90c29fe62a8f92928f421c6320d", + "0x00744c92cfaca9de76b1db96ddf9fe10483ad7c941d709fc0e072388e6e092c4", + "0x00cbe9a1b8be150069bb6347ae7dc5b92d6a63d8b2e71e48e6ea84c8315aa3e3", + "0x00a5afb92b839238c63bb3111699702b4dc6f297e608e4c0b0f3837e76c97042", + "0x002464f205628a84ae10847d85485709f2cb641c74ee1fd60c9798f403084a61", + "0x00615c2a9dac4dff6d4629012900d7845a5fb0b20d84e43d1e43af8a2fd5bb4c", + "0x00460252300b17e1dc383ebe450007f925adf23d743392e57dbcc066abfa71fb", + "0x00bbd0d7ce4c1c2622e4b88e05d5f44ab2871e0830e4d200c6547bda96edba66", + "0x00e597612e77e1b03511d4b8942c0298a7c04563bc0152db7354ebd136e2b3ee", + "0x0016557c201242a9f3641390bd6c5ac879b75c21c85f9421bd288f1ec74c0b1f", + "0x00dee67ea58cdbe97d5f0a6098b65afb8b1a77f5fc0a33cb4cdc83b8c5e5a869", + "0x002f7dbca6717d449613cefe5ff4336cecff670f8f9a1840bfa8cec974b518b7", + "0x006bfc50f94b4740ccea0b1374d994b9a1da59b3ff567c0c1b4f284bda4303fb", + "0x00631eb45a1d0260ffeca492931a3fac60a61548e866b7766a199b35bdf69eaa", + "0x00635fadeafa0d3109a35ecfd5ffa64ff17dffcafc66d44ac1793a4f2fb1f09f", + "0x0081a875451ce57e8ec40740b24194020e4565887a00b3e63c499ec8df41e33d", + "0x005892d5a29a186f6806bdd7d19dd561bde46ea3426cdfe623eded04bbe47c06", + "0x001bc11540e8236eba12a9bcbe42bb866cdea59917fc70f4d26334cb17d48ad6", + "0x00ae508c4cdba09a33dcc076f5c41a9fbcf14aac947c284676128cc98c36663c", + "0x000ef01284c788f303e77b6dfba3277646ef024c695b769871ec3fb1f7e80aa8", + "0x00aa15a85964b2761f76c628c94a85a4132d0de2f56e4228af249a59d79802f5", + "0x0034dec5604e45c017032af945a141dde919a629d88253559d8743c0df3b47e4", + "0x00e2bf24139d7752ae3eddcfdd5d3966c3f123355ce3c718d329c5cd09c46e74", + "0x002ca482fc0dd55d3e15d7eee019a7ac63afef0681a3d77bfc5f91a2a9efc9ad", + "0x00d1050c18b0bb9e62ea01b3848eda382aa3a9ae0c728139669a5b6ed281fc45", + "0x00a7def6012800e7337f32a2288db7954541ae5b39308d138aec3f98e950dbf5", + "0x007d85517ed1b314242237dfd94c445e9c9184e005f8eaf2c9b50fddb18f4916", + "0x0054c896747451e3e737c736c11913356f8220d68bfb418d9ff09f3e9e45c889", + "0x0016c0b72585664f1b4ebc5da937df987ead7f2505e502c547d2fbb1d5c00a7a", + "0x00c6713eda85b2457f2506d223085186d8ba7578869235332d1473f4069e4322", + "0x00141acc879ed5fbcb594ce1d2915aeab077b14aacac69b3f7e0cb51c4886532", + "0x00607210591876f70cca333dde488f01144bdf791f6e916304cd1d5af82a99ef", + "0x00f1b6183fe628a6693f38d878f7c9714c92578602d644039d60748271bce30d", + "0x001e0df4443607e7019764598749ba87f2ba5399bb707b3a72c624af44e39260", + "0x00cc7e0670ed61ef504c3b012d36364df70fcae96b80505e313e4371035eb412", + "0x00d7776caf2c112bcea4dad0e2f086fe9b367318af20552ad89f1629d493d786", + "0x008c45e467c46492e30d6a530909c6aba230410fb1e10eb9004bae44fea78fc3", + "0x00b28303342ee9f3094a81d530d935db1283a751d9b5840a8f706ef400322508", + "0x00b103049290bd9b03cf9cf93b39323537029065700c496444b29dfd934feb00", + "0x00bf855f5cd30eaede975db777ef130e0f1d7776a61215c6d4dac3369fd27d9c", + "0x00acbb365576f11edac23edef27ed9cea3a7182e1a41804e498612da2875d339", + "0x00f8e7abedfb7f75b64ba4a5dc82acb01f275077b1e1e292cf0893de63fcb018", + "0x00f55a0c03c22f55d775241b7f9bf56ab2de8175dbf08cd6afb9a2402438cc63", + "0x00c1af397db0bb155ec19d19d24c1e519ab2d7e8f4204393f1839493da58a87d", + "0x009536fe888673415fab5a0ccd587aef5d9656018ab01c5cf6b99e750ad3eeda", + "0x00fe47f6efa1a4c52490e78f3846eabc6001d94392f070584e97f67fc30649fc", + "0x00a6928cf41afcd03c5db75b178b40591af2aa718d2a5a18f6f18f0b43d4bed5", + "0x0057d7e94547d3ef55a0bb621b6f6005d7172daaa693d9d055b910d92245259a", + "0x0088d5d1477ccc696104c8817c42eb3ac5c21baf9987b3b5cdf3d10321099e29", + "0x00137356dd2c2c7fafad21f38dbed01e30a01740e9d67b980b819c4c7cdcf405", + "0x008e9896d16c5b0f36dafe3bafcf8b1eef3c23337eac3b01622ff75b6ad6d27f", + "0x00ca1ca0817b531ec96e952f33f95c7355717f9e12aefa7d77556707553af4a6", + "0x000423edc5b2cda58cfbe301df1ed585b0ea93dd86ea2ddd55271fd45c6e2caf", + "0x00a1614dee2cb5f74a4d7de7699483ce984999e429b5fb812c6d244d1351dc93", + "0x005025aba41f51ca85339563747bf2ba81d6a1d8a4c183b22c9714d58fede22b", + "0x00e3a3c48e3f5d84052f433e938452ac07998511ec244971990f74c985f11902", + "0x002e04effe571f39d3b1149c44c380a45ef9f1f8b033a3d3737f24f507531eb8", + "0x00f7ffcf80d2195f025d23e9b76de3c7b1b0f2fa4748f5da71f11f22fae8d1dc", + "0x00493222e73304f1f43f6bed16057c3ab2aea20bc43c1b8ce663a11cb033c0af", + "0x00d7f1856086fc73efafafc47dd945a74c9043b79a0f23c3a0abcd8ad4222b92", + "0x00e4d0d528a91dd9a13e144ddc401d9abea4a1b9a9d126af0945a5994b9eef73", + "0x00e5ce130ce2a7057893bed312f854d5a1c3d78a4c0e0df3c78bad8985261611", + "0x00d1ecbb2f325e7989b53f1b45a28885c59158ba5e0fb8c7f6aa9a9f19f2e038", + "0x001ad47f590e8d8fc32aa5dabce0c104b677e1f6d3c4c42fa8b60d2b6d06b2ab", + "0x00b0053c38e2a19040dcadf23fbeee9c2f525d0e19a6712947432718c5acdcf9", + "0x008b77831fd02616523ab7d566fab79741e2f507618d99ea07320a238c6c6c80", + "0x0067d40f755ee4c63cdd9fce7fbadae3c1c5e65cd3cd8081e904d43ca89d8056", + "0x00e2bfaaddbc7cc917ea1479e724697b486c133b87fe6cfcad7784780f98e1c9", + "0x00564407b037013a205b05c9359243897592440305a0a20190e70d8349249917", + "0x00c139d64ce95ac253055a44c1b70056f8153265f59dae6d41b76178bd4eec5b", + "0x006edd15ff128e1775f15c9fb0c704235d611f3aaba14d1aa619f0a05a922f6e", + "0x008e5ac9b34a4a92394d19533938b92a21efacc7355fc9a75739b8cbce1b5298", + "0x00c83ff1b0f60694b190b99007d58573f876706116da2f581a5b5aaa8861866f", + "0x00e41323e5d71373e079bce185816b995dcadbb6bff1e1b2069465bd25f2fbaa", + "0x006af0f5565c96a494deea44b33e890737449409954b797e80e74a6ec6e43663", + "0x005cc71691a7d44ca214766c073aff6aa26de7d6598b18619e82643af12c7cba", + "0x009ae3c3aed9e63aea307b6b7aac913d6717e461d15741fcedeee116279d724d", + "0x00fe1e6ec5a8264b017ed2820afdb888fa8e7403a0bfbebe6f68360a3e3bfb2b", + "0x0070da2f8c6dbb137e625a3c449012941f9d16062d765d73659bc9f322ad8f6e", + "0x00a2ce406f6a4bbe60bd53831e758971aa5aa19d65a7ee92aeb52a2c4923f633", + "0x0049c6e8613c1befecd4c8585ed360f2e566b395f7df07f4a9aa002935ee2671", + "0x0036cf1ad0eaf94febe13b674d2f6a3b830d709d9f05edbfc7462ff4d83f12e2", + "0x00ff1fc2b862a75f823dd4fba92b14b9783f4309043e1aa241ed5ca692773b71", + "0x001fa1c540ec26e6a3dc37b74b28e5d8ab7eebe2969eac94c5d0a350e844fe4a", + "0x008c01720f3634b731387c18ea8576defc45f4e8a4f939a9414a97c783508c1d", + "0x00564257dbb48f271f6cb7f484f4234f5ad8dc397b769b8bd1f17c58305f0536", + "0x00379fb37ef3e206d8b6b028aa06a98404cbc16383724ebf3f72096e5fd12600", + "0x005a177d52a9b785bd822ed7b0fb22bf9f36b3a92b53d7bf082ae54a83dcfb7c", + "0x000f9c7b02c3b42d5820e5298030304496bc4cf24767b43ff8ca3fbe97bcb8b4", + "0x00510c5ad81c4344ea4230e9f87c3ac5fab6fc182212d028f8a8a0d521a41afd", + "0x0016cc6fa35686c054d80c0e63b3a6fce915ca5e7ea09ea8e69478b8c36fb731", + "0x0082ce97486c8c3292541069b6343e3cd3abc762313cf4ddb3dff3ad5b65de7f", + "0x00aeee1f8e089a98a370755fece332a68adfa1dbe3a02953d770abbbe4aeb983", + "0x005524661fa1ff7ec198e4c08ff6582096716265de4a8cda965d88e98e3b44d3", + "0x00f5eebfd1805f2785546498dc2cf8eedba90564f6da43630c222bd9a8f6816e", + "0x00ac20ed809bd1d79b0743d482c1bd0e6a8bd6d256271a9e9eab3889dec9fc0c", + "0x007dda517b8b56a65e1146cda92594b458a98acd435c9badb48ca4ff3edd8ea7", + "0x002e910b6ac608f55cf0ee37f5247ef7b040ce6a7de71990a8bff26dcb54025e", + "0x007de36c75a5c9ad3159e006cbb7d4c8eef697b80fe30649be3e0960f2381b9e", + "0x004bcece90ef3bfc65fa6c4c91458f2c205f4994044beefabb12a655442d33b1", + "0x00ffda3dbebabb56f4d62b54038e90bc371f48b372a3f7b775903cb790582f95", + "0x00f11065a07a0c28c83237a2045eafa9960226a27c3e945e59a6e3b4f15b16eb", + "0x0046fb4cba845316fdd94592a3a5de90500f79f24f0394f1ad0c4062dd0a6f78", + "0x00cd5674917561029c53fcdc239e4af2f606ad5663698a52db7fa611a3c91c15", + "0x00369fffe79c35644be45b98360b9d54b1e9d31b83a8c523605be6dfc94fd857", + "0x001e95a3450f40152adcc535851a3e6c0fb3df1a3e59583bea7661d84ab3666c", + "0x0026eb28842dfbc1cc996cf3ef83da7ffd8030f11714458232955dc9fe95a8a3", + "0x00d17ac17d942136b4ce271c05933274c42091bcc54ccb12372ef8c0388cf730", + "0x00318749db4de3108d34ca9cf3b21e222cd91a0a9c645fb883eedf8c5205733d", + "0x00315985f352543b45f3fbe7ad94bb4ea24a0473c8f124ddca69e02817f2c12e", + "0x003b5aa530ac24999ca687c7344bb5b90148d0d87c960a4f1b0fb068c45b1d35", + "0x00b9886d0c006ee2736a6a6687de43ec563528134953c9cd39d1dbed199e0c2f", + "0x001d6535187369a6a661e0925e88dc023296fc333aa1a358864bee551eb2bd20", + "0x009899d4b91646ad02cfe0226165a82b6f789bc07558301f7c7a9ee90ec91d10", + "0x00c4c737d5ae82188bf1583bdde5768c1413b682a4a23a5501638cc6dc1ae166", + "0x002398bcd0fa3671190a74240c1891aa6d85abb3b45b7331f6f8c685a917e827", + "0x002d9e5432ec1756b279ce5fdf96eb71d63ca1546cfff7867059e287bc3f0c5e", + "0x00421b3787295eb5fc21207c03af136652676462c9cf8ad4ba5a10586e769ba0", + "0x00350b52802bbfaca002d0e268acef9920c86a4ab21dcd7d6a34a11581c13de7", + "0x008eeb3e6e8e03955fdf2f7e398b340e4e67e768dcfc120fb677f26bc6a45384", + "0x002923b8ea3cfc0c1b9127d0e44d68a19664607e48465d96e69b53662239d087", + "0x00bbe343caab431effafa5b4e8741823808effabda6e2047ddfbf685c1a97186", + "0x001c6a9dd94993da74826229c51ee636df37dbb7390d673c4eef34c7e0d5525b", + "0x0065b2f768d7cfbecb907cc1d98936107fc09982045b991cf16b85ae631778fb", + "0x00a4096fb94055bbf51d21dc5f4b44810b11f358d9d3c6014d821ab6d8e2520b", + "0x00af0b8ff1d6034f2234eae5191d3f57da3abc1519cf571028f9d3dc4d830a3a", + "0x00f6005bd94e3cf79266f4f90b082b7d93c07492b0ba20164f6e48b5215fde02", + "0x0046e3cac093bb3977326ba19ccd1a1f7e770cc8b08dbd38d3dd2144327b1620", + "0x00af0f32a85afdf5206e896943347bc7214da505a36965c4d5be0fb843f24614", + "0x00033abb82b7274dd0ec956df5f33e944db39727481182338f27c8db5f173f53", + "0x002235077c0d53ea3c30bc68dbb161c6e5a472bdcd1c016434fadc9c1ff74a98", + "0x006e2181920546770c6f4efef7d6b3b547096e43dc6fb7e5105f43a7a484da68", + "0x0062607dcf405e3cc5d4b4909ed1f71b4b95e3399289ef233c1381de56b6c904", + "0x0068a498f85336d3e1242e5125c56bc348599139c72a0724cc49a0bf802b321e", + "0x001c7c8d345c4160f9659c1311a82e618f6ddc7a26862580ee7cdd5006c24892", + "0x00a3587c53163dff704789146c796027770ab738c60d275e6f044629cab52ba8", + "0x00da3365ad6f9a2975202353997021f60e71bd37e5b8e9d1988796b8f5357e43", + "0x0029a520be0f4044542b4a906de0af4ec65e232b02f4a17077f1738827c39425", + "0x00410cab2daf88854c72b56f5198ca47750662de198b43654744d70b1a576339", + "0x00c699d2deb82985f62f9def0acd27e44ff848ae1ff7c0ec9c9613b38fd54d1d", + "0x000909f60d1d4f89a2fa9307ba788ac1acd1d7dd0d78f899c9c57a1f468a3357", + "0x00f2687370eed8794b2ecce425d88e33f8242d05dbe571ba34903a14d95e891b", + "0x00198d47e1b4e419601ac167d324ef4554089e6d501b010b84bf264a0e20d79f", + "0x000378b5dcfef287f274aba0d42f4b83c9050efe46209c4924613e5fd3154443", + "0x008727698a90815c2f7cf89b3237df105c591c41d7e201743882e53dd726a021", + "0x004b2c536852b39af3b37f38d86b4cf5344857b405480a2937a302bb42ca8bfe", + "0x006761ebf156b136664f5f92778d9d16d12d6e1f3fd227b2e688e218fb0e9a2e", + "0x00f15fba34a67de48bfea135e8314825094ae6433b8784d644bb65523f8867f8", + "0x006df54cfd22c6994da5a651dfb11b8f7bce4422672d2645120ebf3bdb5f9045", + "0x00b3811b364d4520a134d54673a9c97e04952920d1c360a209c96c2a79eaea4f", + "0x0055206a9ea94de30a58f121c2245ed80c2ad62a6017c926decf285fe110208b", + "0x00da7b679e79e39e158ed71a9b7424ad08b4bba7c2919886f232672158e07233", + "0x0087b0ee4d0458ba866031a5c9a2bbbedf10c2494a5d8665a1bd04e619dd2632", + "0x00700aa238f47feda0cce0c37d43ea675ea7fba392fe58739b4ca00c88b7e60c", + "0x009f945062a9717cb7a330074bd6cdcaa1d7f17b6141794b97b4e6a804ba896f", + "0x00e298bb7cb442dc3aabdec9be6399e9ccb3ef47708c21f6ca1cf7bc3226f89e", + "0x005ef053018084ad3dba81ac3b54839bb1da568824cbfa0a97fdac6620e5408c", + "0x00b08a4c1676b9a5a2e08d912865fb02713ee0ba1c5a84290021ae5cb67ee348", + "0x0049b88b3e5f14917e2750a7176ebc1c0eae9152d23f8d30ac10ccbebf8f1a96", + "0x0022d5ca38dc6d91383d2d3d17239c5867527147ea9bd98d4b501ca56b626839", + "0x00c8edb14209666368adf17b456de719ca620e984ae2d8f2b14e21acfa598ca8", + "0x000bbdadcb7e7b6dd200c4ba8ca6fe14f6c6db720836b9f739ca9b5a8731ab26", + "0x00bceace5630e59c29f7c90c2227067d5a79f16770d98d5832642e17331380e2", + "0x00c17640e8140bacb22bfa851d1d35097f0013b144032342e5dce5186a2c975a", + "0x00627352f3209286700bb745d522fbf8df1b5d1dcc074778039947c1eef5a5c7", + "0x004ae7450d8a695cb21ec142394da3f0f500b07dee7b63bc88f89034a9d9a7be", + "0x00fb4570bb0d3c99302f91009a82a76bfad0ac39ef1c3f77a2a7bb49f60f8e1f", + "0x0016f7772793651ee4692254bcb589a4fe18dc8ff1c32c1a4e23c8888754590e", + "0x008c693a06ca63b8b03e23a190645c6710a894f7e1519ebb9bda88a578eaccae", + "0x00e5fe3b8dc1ed1bf3d1b98ac8f1a54d407c352b0d4867d2411f297f864cebb5", + "0x0018219ea955f9c2b9ffc5a228f43b76d583dd6865de9ff57fe5f6f18e90fa65", + "0x00da8bdd7895e44791d1436d806247d0c7e233e4a3c0d81e4cdfc7d9d7b2d9bf", + "0x002ab236b7b972200d03df41a686da769200f17707fb1fdc46ba036f235fb961", + "0x007a6a56e7d2e50df18ff008694204e1e497877a5b4e8b76c162e7aa6c22e973", + "0x00b184a6426e90274514014c073b9c7712d401bb03f9fb0a125aa867c1f3d3bc", + "0x00c62a088ece9694a537568fe3117652effa695ecdcf0123757a6118c7169add", + "0x001191a12e8fce172f2736c3d60d8a6c28626f09e0593d07b26f16081b32c8ff", + "0x0035a547a9bcddaab6f0dbe5d5f2190b05e3ec4b2094fffab1d5da8e453e62e1", + "0x00ec83c47e1dafb5c8c158ff65d77be051d762cb89c3f6e30fde1427e6f6d46e", + "0x009fa8ff679a2a0a4fcb5b22cc18914176b54dc3c7e666534b4eb10607444cf9", + "0x007c52f5c9a3747936c504b29c1f48dc3ef7eff53af015c47862b589b76ba5f2", + "0x007bad765ebb25e8f5d4e5f37023136681e105bebe287246ca80535dc2126934", + "0x0009c9126d49dd05ac4b972ca4eb38bf561a57f904bf3e1a01621de4ee3cceef", + "0x0027376a5f7c8ae393c37ea9f7ce2d5cf02691e38ab4001dfe4c69b1620b60e8", + "0x00627f421267013f2cf8a6c2b0fea08e60ef42e27b2a1cf4ef9ca851050b07a0", + "0x001cdbd40d871785a241f2059f7226ab7f52adb24de078a72b287f760538e279", + "0x00794e04b2fefbf60cde6bd40706bc4e7bae4c4dd3ec5c9e86f60bf85c8b11e1", + "0x00a0f8bd90448159219570ffe3800c759bf3b95913453e352d1108693ff49af3", + "0x00acdc46d8b6f9714425a08160f18245409830b49f6891a11412ee7f5ab2a49b", + "0x005e9039506c8b15e1200e3a957b0fa78581e412548f12bad62e6db79e1e747d", + "0x00561ec4b59e3fb603d2368905f6990e4063d58fcf32eb6e63f0282fa0974322", + "0x00e57984a179a986ed64a592aa1ea6ab6ae2933176425e1d228f2812ae0d889e", + "0x003500f3d7122b41fe27078513cba1f2ea8a51a5cf5813613b2cff82771ad389", + "0x002c8e78ca4b682ff89e22029f431651e8e15c7d0d0fdd83d44555d0fb0dd25c", + "0x008783e02b3dd9bf4fe65f89f03b58c5a6b3d822cf1655cc241234e9563520dd", + "0x002ca2bb5a795666ba51bb9cb01b2b3ec7a3c7974a5dacef56e993e79f8b1376", + "0x00a38fc87dac35c6dfcada684d2b47f0af175140af9bc906834a622ebcc21f9a", + "0x0066d4b869505855761fd5ec89c9e3a668daaf7eedd4c0f27b6f41bfd156e2bf", + "0x001f3b05d8d1384e0c6dfe592e1675a5579fdb388e319fc2cf53e4b8d3ff000b", + "0x00b371becc28d8c66be7a9d5e053061b709d6a402d41a964c3cac85277477d6f", + "0x001b8a19bf68201d749e94373ab899837eb803de0fc23a539a7d52f909a6c22e", + "0x000bbb66b4247a108e66a4b58d53930b7c77985043c9d81edc85a43d67ffc93f", + "0x00137c6f9b1bfe88fdd7fbf7e00fe16a0d86594f6ab138f5b856b92b9fb57059", + "0x001b97efc361fd8b90f573d5f9fb831cf7792efb59d067938a870773ff002431", + "0x00dc67fa7038294c732ba51ab0ac21506163f3df15075b844e1249a88727e1e7", + "0x00b00ffe5b062ccb77baf0e6b372772e28898a4f9b4ac289d24f4cd38b7e1d1a", + "0x00375c14972f58e3da2249d168bc1fed0ef17644545800ac376da98b6d4c1d2c", + "0x006d6867c499b60773827ce09a5d34d75260c0aaa6356e74cd8614b535c159de", + "0x008775c4ec0a0c51900f2f9483db4cc019dc83b46af48ecdfc8958a6f0b77891", + "0x001ddc732b1cacc736678399eb62723715a3616bb916cf9065caf4fa36034459", + "0x0077f8217269c35dce737eb0b64733c83891dc8484ffb560592bded450eaa7ae", + "0x006ee828f26826b1193678e4b029edf47122399ba13d41b48626242f3f46f727", + "0x006c10c18af4d6e0c2620d30a152b4cbcd1bf1c45f78e620ee0d50af02b24fab", + "0x007f86395552dd090a4daafd4e23804a59a1a030a657b309c2c1f8e838f922d7", + "0x002b008332921c404a616dbb2db663f598be93d4ca857ba3429f7b82a3def34e", + "0x00f489dcb10ba2699a731032160987f9071c1cbe4090e289cddeb51cf2e7f547", + "0x00ba2a046b900cb8354e4dc07c8410c165343e12a4c51bdaf9d0802ac61b0edd", + "0x00396cd3c94c193aed303d1f7a89455ea6a58af473bfdd1f367b9315e6ab2e93", + "0x00a69c15043ba8fd582d1e6950dd24f08ce651eabaa2ca9870abee0576e0d095", + "0x00469a2a6492dec2bff0acc3169da4d244856435c44545f175761985b22614b1", + "0x00ccc7b964c286c5d94a6c4482ce37c2a4a13adf2a8012bac1f6bb305de582c2", + "0x00e0f2f06b219cd3e1db685bdd1229c422570c5cc7bff38114bf5cfe20d9d167", + "0x009f728750639c4f96d5b80f5d2d4524f67ce3f7eff3a9fbd1fe0eba762031f4", + "0x00fe54a5c08c8421cefb33eae5660fa547d4eb9451da923a78f7e5260dac2442", + "0x005ede7dce6b73dfb9bf0b56fe954e171047bd3013c73a50a8fce792cd03dd70", + "0x008ca7663a803b374ad621292ed8a882b99dfa008624356887b118e7409a0bc2", + "0x00eb270c23ad0661d6ff80c5c9d2f16a010fef59a55d5d7409061d2ed2588172", + "0x00602b240652d573ebc080802af8ee36fd57ad2134a6899ed8d1f14d72832071", + "0x00542f16afa1c5f48f80fb2b9613b81d3367ea927581f6e76d1ac7487e665532", + "0x00a9e676b4079a55d38465e38e9f571e765870cd56afd430b449f6ec466d1e53", + "0x0087771d0d2c3213131105e236f4bd977b5caf2f6d8f2a29fa76012cfef2dff8", + "0x0080be21e26da89cd04b89d62fa0377056d5291709f3e48317f43b5da776080a", + "0x000ae081debebcb9b984e7a4bf3ed2df8594e08ccc60cb557a83c4f66010d1d1", + "0x00190c767653e21da5d3c5475312ca1353659f79d7305269c6cb8b657af0fa1f", + "0x001e020a8c15d97e86ae90fd125e595e9a420c49ab020ea98b404c565002908a", + "0x00a1703412b010db0e01cef183ebddc9a398e76f6f0a77301201e79d07001972", + "0x00bc338aee6b23df256bbc354f943435e7588e63c92ba2fcb6f15c9a0036a028", + "0x0040d51bf7980b36b796aa20ed639a6592c97671a0ea4266d484c4a763bd2c8b", + "0x00601dab93b22e03c90b84813419f93b3784b1e9971959aece586896e29817ae", + "0x0037644acd46c1eec8ba09390bb02c839d972c29dd3a2dafcd07cef3f6399c01", + "0x004195f89c9ec29dd2d944fd1a8967a2d5508d7c834742eb08fc051a90b29f16", + "0x00961785f8a7bb2890fa8cfbe0993ee3271500dc6fe9ddacb859b8594a614e79", + "0x00265abf1173c9df95081f9a7c5f3686ca71c11c82515cdf97368f86e4cb2fd8", + "0x00114f29cde13ad52ad1db5ef3da6ef1c8c60d9f270115e7d3e7f2d6cdc0d9be", + "0x00d7b6f71bd4cb2f65ec7781743f042563637d4b3dda268c9c1e59500fcd4a06", + "0x009e9822765f21f911cd63e731ea0c11b0fef736181d2268aef34fb55baafb59", + "0x004a42d830dea62d7116fa0657cdad9e79ac7eb307c099263289464c463287be", + "0x005b75874a0fde8e1c8ab5343bbbd9aedc80b5b215c0576c929d157619217b68", + "0x00a7b362ececab2d2c8c13ae6d129448bae0667aca2fa1296b8ccff05fd312ef", + "0x003f37a490aa4f43103af3e3073d7826af6236e6d6bfed5465f24491da1c1e6c", + "0x00a90a141e6d06e4e29e79efeacec91edfae7612581d2418f33fb725fa7400e1", + "0x00a8915028e26310943c311734a19ec2dd7d84ef6e98c7d05ee46bb54a7590c7", + "0x00fb76add26d7c5582e1682aeeaffec7956f7df0a7d18c4b0ac8b61d297651c5", + "0x006c66c4d8143ac281edef1f1a594128ab388c7b7fdb85c353999d0fd2b9691f", + "0x009fa9ddf89dfa37ac79c5a18dbd8573c9a0e27c5517f60e82f0e05c8892c712", + "0x007ffe8d5bcadc45dae7c30a97a64b4ad5f1ee3743a9a6229a29bca313ec7d8e", + "0x0009c3fc85f8fec72e33b82b5daaafa5dcf31ad7e1afe37bad9e679f4610a27e", + "0x00d5d9ae6f08db53f4399aa5fc7dec997e48f66b5e2ce1ab0ec61c0750127b6f", + "0x005c77ea569fdf4c5d020b8875299a71cd98631f24977db2f67d179a4412535a", + "0x00174e8a6d94e8aee09c5e0ae9d2d5533ff365ff2fedccb5e02b82e208b8d49b", + "0x0000c9cad232e6395616f02a132c6625e6a3403500f2399a4bf4953140ebdc95", + "0x0090881285e2caf2b7da98985e5bbabc33e0113cb613bac64c64679f6b3f989f", + "0x00dfc2f8d3e135b8a2b0006801f33a90c5a7a0df0484bb3947256d9e8c100abc", + "0x0003847ddc6ed5730319591e735581da65e5967810514351df9e3417466fd75d", + "0x00a310e501668c264d6365be857abe7b7e66892724f2d4339cc29fe6bfd73b94", + "0x0034212e00a5fa1112158519473df23875fd5cc969a85fc90ddc51d5eefd61c9", + "0x00680f5b49de8277f4155b7cf07ce9abaa1fdfa3bc26694805c679687c0b8ccc", + "0x00cf9a9e212b2d7a572e13456410374d8a6a2ab9f0f24544e9c38e926772c31a", + "0x00f323ec242436f7d8d44020cfd0e635b0f150becfdead01eec6b433c5d11daa", + "0x0018c5e0afce29966a2d929ec82f62b9123cc1115f7a76ac7f95a9d7ba69ae85", + "0x008e7567b24b43a5692336bdb34a808575c18a272e73c71b4949dff4cbb1ea18", + "0x00865118e58dbd42fb4fd4dd96fa0b4fdaa057b5e66c3602205aa3a9b8d12ea2", + "0x0018a10da461c08dc97aa2a9e6a60e65e5edfac04551dd3338f91f0981bbecc2", + "0x00e5d899d5b7e55960904e6091e2d1382d507ae7a9018cdac090c9b71d8f8a12", + "0x00a35468f8d216ac07ba8b38ea5c93d6a6f52f071c5fca296d5d036cd60c46d1", + "0x00eef3139238f601cd2d2173f5e441af295ec6cd0c0efea17b2e3a83135471f6", + "0x002769405cefd3db62ee6fc9f65807254af58eead753ce39c6c64a3afaf58333", + "0x00e89ce79fc77e8e2362b659491063ba0ea946189cb39b4df1c422ca334e3022", + "0x005e9dbaf57c48cbcaa54c193bd9121df987f0c1a0e6073ca2690142b9f22f09", + "0x00088468267eaa52dbd642d0520deb794bcf4d20517d94c6ecd2e0b28afeb894", + "0x003927bb8eb9bcd25e758ee2cc5a3e89c23fa4b4f824dfc316b5130e1354679a", + "0x00a661e8dacf1ca804efec24a59bc6d75ab44d7f8ef5b31c0be2f1518b2b6ff3", + "0x008125cec080f4130f2ce97a1237dcf1e154fa4832b3f19f6a37b241bfd9d2a4", + "0x0091b492f6dfa733701ba602a98349e55a8b819f87cd6c50ad2f03ae9288aa9c", + "0x00a91141476a76b3411c6996635eacaae56b11dd286d8a8eae672dc2220fbb14", + "0x001b23aed13af21e14d9cf0f5500dbd43b103a637ccbe9e52738cba7b9c70d83", + "0x00fd743113921c6846db1602c95497bf800f4f4cb030ac985763448c460f757e", + "0x0036d2bc4ea27e1d3e5f082cf9da3e98413da55d48bb561f6ae1d96d1600efc9", + "0x00734c01eebdfe281bfc4aa19ed6a48c20a21026f288cbb3be828307167f02dc", + "0x003a57d43ebc83bc118419a301482bd3de97f9bf1b9e7e98725f9e453cd0daae", + "0x003f669de44965410615d4b4a54fa55c924a49685d51ac6ac985d8679b5fb6f4", + "0x002f5fc1061af5d9e4c9259ecaa1dab8ae1dd8e9a60fe4aacf43a22c22714ba1", + "0x002923b9a381b1f51bab4c47e46c88f50ea9b9d857532219c29e4087a1b626f6", + "0x00726ac5c7108337908fd5552c4cba9cc509bd051ec7110186a98b433392f810", + "0x00b68fa15281e7e2c4cf4f77ab0962c51b9ae1843a3bbe105b5c850fb1f0a5de", + "0x00de2a7670253122d05fbeb5e9173f102fea26551e996ee42e3b6856c4e053fe", + "0x00270266c79aaa2d65c8b61a99b48bc32b3341240aa9cde060df922d4215a576", + "0x0058ae10a11bebe52a9ef7c1ce16d063662f8af9dcdd3bfabe3ed564b0be9d14", + "0x00f9159208c8804381ee45529cf830f624f2e4d4c3d01b17b84e4792abe6d0cc", + "0x0000c37840eb4b2ef06a5cd1532614c90a1fc5fda3b3cf9c2609ebece740c7e2", + "0x005267050d2a8312e139b855d6a36393fe3ee52d72498b9562d0669944a1da01", + "0x0095f0efc09b1bb49e91a63e421abc32994863db5666668e39472917c1ef09b6", + "0x001f4d8bfd0cdab2e32d206ac4e98538f5597d23946e8c83c6e496eeb65fc72a", + "0x00fe4ad3ef5a71412d9fba4460eb093d6ec740d38360fc89c17bc7362379f3d4", + "0x00a29bbcf4dbacc031b71ac62ea577634d148eac466f274238b19517a72ecce0", + "0x001385c2bf0d089092e66a5b4468a056de112c88f618ee5443aeb9035b35fa4c", + "0x00abc884167b4974f9988517e674c165a8b24279d2848ffcc12e53f40cdb77eb", + "0x00e077cfa06b593ff001b8bd409438dd31c1283ad8feee022d0d0d54cd562531", + "0x00aecfaed78bb0e27b0b9b5ce9960eee09334d556a34baf7433036190f969b5c", + "0x0052aa6fef5c8da7bd4693a3f494a6dfb3267b708379948efed69e696deddcfa", + "0x006b33874720a9bc9c5b2cfee84c5791d7f883259ec898e72f57ac968f60eb28", + "0x009f09445c70ec4a7f55e0116d6dc33dd93df7a0c6860721b1660a86fcd523a9", + "0x00d174b6420d81bb5a5308eb6aade26923d22dd8d60dd79475b164551c7643de", + "0x0028ec3d1e5ec22fa284d45def8c0d97e7f2f1a1e8057afe7a745e6c7898e355", + "0x0088b74fae1d2485b2393fafa3e2f887a6e916b1ee8fe7a6eead1e9dc74bc673", + "0x0054716297cf24223a89d573a5efcac22b7cdcf8d57ceea84624d2f2771d4b44", + "0x0021352e6d4fe252e8fbf30d723bfb69d3e627f820a21dd6adbb2b83db0b1a89", + "0x00a71c887cd749e80e8e356e40c9b8a5e81d480169e3665e97847a910f000af3", + "0x00ff544bdf4ad0d5fde152142e83aabe239afbe915c26bd71cd7856d9fb606ec", + "0x00605bdd46721f704a6704c62c066e75160bf24f709c0eb5402b4a066e2b3f57", + "0x004c54120a67ef67642c68bba2538e8e5ee395622da93fcd30f5f9a8226c1f5e", + "0x000e61ff22c05bc4d312fa1ffaad9e603de0aa468cae727e0b774c65e4f6c4ad", + "0x009692405e7cc5cc0ed49cf951da4ccd6e3bf78808cb82c7d5bf698f6c901393", + "0x00d25990aa96912e00b17698244476009b6b3091d0a5965dd94a232a5b9af35f", + "0x003bae82d33ed4f77b72ac6d0cc13863cb37222ab9057b5e3320f0a3b2feb60a", + "0x00e379743537cda2d25048b928cfd8913019f20c66f1f7f4337fd9643c91fb00", + "0x0008ff39c95c444dcd451d7c7612a634b93b91063c35e7919a379baaa13591be", + "0x00a509042dee9a82aa55c81f3c40f61f635779928e9ffcfeabd7e2f01996fae9", + "0x00179af0c679a37d7713b8c60e58dc18ac03455f309014e61ea489b51818dddd", + "0x00122924375fd015628b8aec8a3b8123b2c7fa2ecbb9762b0d0322a93e90537c", + "0x001dde22879df890ae4440ed8070b25b4b322ef31a8bb9bd62f946cdfd6fb4b3", + "0x002cd7dbc0aa86897b4be42152a447e99894a51cc904687026815cba7447e7e0", + "0x00d99af4220caa6da793cb4c6c63c58c46dd6a89ffc0981554916666675b8cbb", + "0x00743faccbb1e17982c21e1f00d0e2fcc37f3f75e6dc38a7f2180c093fe3d7d4", + "0x001bac07b686f1de2fc50a3d7d4718e69d522e956364212b150e1e9a06d306f0", + "0x009eb333e68d3426a500fd65caa900bcb724db2130b8c2a4c5fca194191d5e63", + "0x0083050446655c703b91592d65c0984de7deafbd5d53cfe5e762dfc871e2761f", + "0x00123192a4f7502afb1dd12b9631330b2901e2fde01c048718590ff5188ac502", + "0x00399a9e2dc4c0eec24c3f0c0499cb841bb5d3350cd7532596727d8d8b182d27", + "0x007bd7eb4828660b20343e2fecfb4a32847763f45ebbee46a5a9835761a59e88", + "0x003089c5f5425eb54fd2ec28b4d4327f61823a8f2452d9bc021d2f5eb6692016", + "0x008f37b3a53fc4174b4ef0daac0b7a5b0d14fa6997b71436101eb1c9b7bb471e", + "0x001df66c2e7fec0d700bf0ff1fe79f8b97ae6382f74f6f2dbb8719df23018a95", + "0x0092acb80f4ea0d1d9ce07db293af5abb7f2de24c6f4e8a8f5a0ed29891a4988", + "0x000927a1ce3cb35de266f5eeabf50e0bdd27377012b3b56880a089463efa2e5a", + "0x003aab75cb8f4b21c51587fb500e0eaff573c8b42788b29c2276ba2869c7d8bb", + "0x00da850235fdcfaa5d1db2ce751c1870df8ebb5e132cb664007c8b5ebb70a545", + "0x00b9865a688d49a15835afe14d3966aed49f5f0bb840509fdf002fee6bbb6b71", + "0x00df1a98df2df91be201f342c6fc1f6968fa95a70b6b080f9073c5b53d722aaf", + "0x00ea3ebed52d6ed37b068b4584cb152a06a357c6ad99fd04fb6961050172436a", + "0x00b7d0f7aa7bf49eba73e6bfa21e4b1a09dfc3c374ba5559cd49ca29d7021815", + "0x00833edff95ae7031e687f0cc921e64c09ec5fe2567dc42f88f136440788287e", + "0x00845933da913784231f9ce2003d6a68205cf7aed4f00659aadfa345678172ec", + "0x00372731bdff60c01cec3a99c1fc4e4b47de861e08aeed8983480a9de634a5e4", + "0x00bb008c81c1a566572b42ee774c2dc581863b05831bf5e645ec96962501dbd8", + "0x005b491ac79d1355832c45dadc1ca1a944975bacc28b04d00ab57332e68bfe2e", + "0x00a90b236cb48a54ac70cda38f1776fcd7398c477ad3f0cc7fa3d13129ffd5d1", + "0x00167353fc67ba25994d3001473ad7bb4cb4025c79b41913fc0830124601bf30", + "0x00119295154ac30594aadb834b9483ef3af1d3253bb604b6e79a40556bb6f4f0", + "0x00a8898b63b2ab4e22690adc2d523fdef4c8782edb64e075cf05dcdc1b090edc", + "0x00773f28e3879ed3fba1a86ba292448da856eb1a4fb7b038b59a1cdcd51db285", + "0x004294fe9fdd3d0417fe044ddfd360d09833e04cd398dba2fa018f0ecc827fab", + "0x0009f745c4f310e5f6fe9ab6c2b4bc35535cb32ce511c1a72c6bb2cb3d25337b", + "0x00befa487c7a3696a75c4cf36fb1ddf12a1cf03481e7137fab7b28ac55ee1226", + "0x003b2c1fa0a7ef76c2ddd4fa4a79256f69b026bf5db43df841d88614a40cd2c5", + "0x002f4b3c98fddbc449b91cca5675ed8626bafe401519cfe0627da29c82e1376c", + "0x00002159a42ed7b57c4d73da2bd9f420728f8d4eff09b0c2c5e677c33cb2dcef", + "0x00fe4d3f501fefd10ff2657911c7aeca0916f326ff2ba6ae0daa8799c7e98ceb", + "0x008f9da976e8796ad360d9ad2a87cb9567e726c53c118cabaf2790b5c7d098b8", + "0x008751f1135bdea8679f6a49c95381a7ddbe561e5e85c369523dc8e0146ac0d3", + "0x00bbc1a064b5a40349b6824f5692db02c758edee30bb316871d2a5f7967d604a", + "0x004870a015969d28bc2be27b4be442f00bc7eed2b63c9c76143e378b1357a817", + "0x00ebd004e7de1003e6f4beeabaa7f1ca6a3047228d1dbb2790f0764a5c261d35", + "0x00caf36fa36117449fc6b3ff1180c1ef1e6f75cadf5e4044209b0f5c8b607666", + "0x00d3d849e4d7283dded573a18324a66152bcac48f787f9a2d98326c0e105180d", + "0x0009e97d94bdf44683ae6e226c969014445d8f1d80293275e7c65a184f120a12", + "0x00b23c05001402a74284f35cf11790d34660b17d97d5022dc15204a98f0c6554", + "0x003c793fcb3c42d90448a6090738979930d04ceccc82a7aa6c7888372bb6afe5", + "0x00d2d35338ef4ad56627aad5a26843f221e76c930d57ece1a480c94c62c34b30", + "0x0081a87cd1cf66101ae48e39e7a9b447a582e1fe8496b972825b5f824ef5ca3b", + "0x00de5ed613f4c8541993074f95e26e9d9f8a3e3e72d1330c7b4af33ed3485df0", + "0x001fc252845c9cbb3675b8606f1e2b87c4de2639817b55610304ad8c1ad5ccea", + "0x00e0e47b0dddf0f4f19ed5673c3ba1efa383b178f9e63c4e675975ff073bb2b7", + "0x000184dcae551a4f427a0aaf38cdcffd58e1c9b2662f2be8b8b481dbf24a0ee4", + "0x008d54764bd32f85daef0af7b9133c23d7903ef18de33a0d4ff2bb304c69c781", + "0x00e5b9d11718112a1b5335cd29d4de904cbc9669ea81e4007dd97c6ebb645bb3", + "0x00a9161993c43c4d9f87ccaaa72063ec0299994db79302290246e6eec2b5e661", + "0x004b0c40182d466dca8eac07afd94760136abb11cd30d99a9a4b8edcaf74eac4", + "0x001313c4c4801fe3e110280828c3738c0d175b45286d6c1128f795ed245d5693", + "0x0073169a5fc6886992e12a4fa02a78d2e933a9df27881460c2ba4da00c5f5807", + "0x0044cd10759a6ba08f2f5f28573282ea605d2167f52f5d355e8af7756c49140b", + "0x00739fbb3d467ebe3c2f9856f2f0101c76df08859ed8400a4b307a05b4ed9dfc", + "0x00c9d11e0b280ec0ae375052bd26b062eab5b08640ba682d59209b1d7c26f568", + "0x00ffb2a1895f14e065a10fbe44e354fdc65dbb28ce6571ec1627d5eaeef85a12", + "0x002e4b96d57045441972c974706dd6c72660fe7450e82366a51f2577ecf50d59", + "0x00679748188b2cd57d71e356502ae4599ce693360ab0a4fd88d58bcc8b420fe6", + "0x001f8a45821e7d7978e96627faaa44dd1231c163368d4cb2a1d32821ff63729c", + "0x00f0501c92e6f3df5ca617b6f185134c69c310943452200c5fb5fc87df686557", + "0x00da964fd5fce9c631453c572cac86621ebcb9a7726f6eb6f59638901c507df7", + "0x00fce799379d1b1e4dd8a0d8d75b11b710f4e5ffd605fbd5e31c8caa303dfa32", + "0x00cc83df8b0a72aef0da0da7e346f27fa137a34cd7fa50bc3b95993e60f6fc76", + "0x009d093ef2e4de01477049f7d6e52597e2bf5019944b09d4f60c642e3b729fe4", + "0x004c78379ecdee7845eee4a318086a56dae0757749bd007bb86e83e4c581028b", + "0x00567d50f78a3cb1c67847e813ff8ccce9f227226d4cadece824f5876e49d6bf", + "0x0014f098190bb8bd9254291a12cddb970c590a2c15b696c367a4d6c0682cf92a", + "0x0057143d105f0f81de410a6d2ba0194f5ae77c2f39e5cdf155e807497d15d50f", + "0x00f9c6f6e3425e311031461c01e9baf02970213b89c51e2559ff35e2556c71f1", + "0x00fea2c52aa6e2384f7e0be11e09de011a43322e0df7c149cd91cc21449c42ce", + "0x0034675ef6709df12f812b230d910e683fabe35394ca79e16e7c5ce35e6f49d9", + "0x000a8db43236793fa847a181c7cc3826b6d74baa3c6f8da8d66fc2e6a42e4720", + "0x000692bc457e1f3483d88a63695285216ffc3047130c64bda589db6e3df59c6c", + "0x006077bee60f1b2f7ac4b5e65250b32d311e2671955378a86e80cb2a0c4b824a", + "0x009aef501fe0e7f3ae4cbc6709e2b7f3ccfe8796e3282657a3ecaf7a1f31587d", + "0x00d356c23fdf0feedbcf1603322bb5eccb3eb6a7e0c60f7081911dcdcf97e88d", + "0x00cf0d997c4c681b6b2505b28a0b088cc8da1ae86a9f75d1b8ad0a90e5bd9885", + "0x0092f95171bdc8f3a1d704ad330ad822f68576de9b9305ebc7bf35e9a6317cdb", + "0x0038e5b6bbb4ed2527db139a1fafca1e9315661178288580ac7deb1bd8d1e26e", + "0x0067d2f1570a04214472f892b736d8aea37cbe95e349a0d695cd358fa9f5b249", + "0x00472d78a0e58e90a60bf1e6c673702bdd5fa79c7e90630dc707175ec1a02d45", + "0x0071b1bb00287492e8653601a09cfe7203e3e73455243574096f43a98fa8256f", + "0x002863d63b3929ad84e0d0efc8c3df63f8ffa747cc3cedb19175b3e54b20c646", + "0x00a6fef2e3823b8bdb77a6588110a9cd36a7678e37c1a38656c69c6366650777", + "0x00b269d64cfff1a256cb0296eb7c4856c2e90c9d05d1cd110a20165a62dada09", + "0x00f5881da3d667fd0d054105e82d824ea07fc54aa17ff93074c9ff32069451b8", + "0x00db725d03edfd9f31eb8912076abaebeb30ad7127afd868383a40694ed006e3", + "0x004fa386aeb561a392b84fa60ad613ccb84669461bf2b855b7eea7cbad24e057", + "0x0032a5d5c55cee5eb1c50b45d8e671ab35fefb5d9fd94eca33eaa1a7a85ef2b9", + "0x00d3e31bb1405028d7b615d6593e51141598d45af8cba8371000e1b1a09246b1", + "0x00529423074d74612871dd6644eb5fe1dafc427f8bcb1fac7d43f53dc41c6ee3", + "0x00e0c965c0bb8c807a4898901fb30f9bced900e8b16599dcae9074b5dc36a33a", + "0x00edbce0b9ca8c0c8293db8f6f54084987dccfe668115838c05cc867ef044822", + "0x00e8d97347ca53bcde2d01638ce662753dfc3c0c265656d7c37a3c841ba3afd1", + "0x001ac3b9f9aae2d672ed1ff9ba7c283a1ca274d043135650ae0dbc594fbb0ce5", + "0x0058a0ea7c2b3c748072d70c255717034ffe9129cf9cd7c21e4837b47943add4", + "0x00a5fbc0f3807868c89d8f6143ca78aa415302b0b4b392798e7a9341a849377f", + "0x0043f4f91970c2721fe282c2205421536b43aa7ef4cd6fb4c6b527c324643bee", + "0x00a632e7af7251287cdb39e9f49bc44a132f9bfc8f18bf277fc7119bb3d7c210", + "0x001bfe4274ae40da83116e93299149303f6b9ecdd08b98c7510c4912b2639fd4", + "0x004be0ade3771c19ceb861e913ee8b625ca65a030d835f989b3587129fbe49c5", + "0x0056e39bffb5ba939f3d5080683108668cb18f14d95220aed641fcb623f494eb", + "0x00a3eb2a02e417e56d17229383b3c276fe484c229876157ab831fa539d1e29e2", + "0x001c666b4abb783808901ad67c53f9fc5e06a104c134d741d323f14659b02ce3", + "0x00dc9dcff33d403bd77b6f754fd485cf320377dd2ba9e4da0537a68a006d3d00", + "0x00daef04d2de2f2574942a135fb4b1e7524416997f8597e72aaa2ca6ab841a06", + "0x00dd281f15e896e7ce40fcaf9fb8402867ae33f9a992c76e78fcde216092acb4", + "0x006a56e8669cb555268672ded50212ed042bbcaca87209e5dbf30750249129dc", + "0x00b516a84fc8962c0f8369a943253abdfa8f609067f09989967659f8618d0470", + "0x009f202c09bbdaea9db09f49b5e550210ec3b2c4c530e4e86555faec28a442ba", + "0x005d786cc722eb262fddef23c362d96b8a2b3cf659f0fc39f721bf5184170b5e", + "0x002450bfc0e1df9e3f64094be072aa20e769e9f9ce164c2fd8cc303fac8d1f9b", + "0x00db58c3fe0e631c948bd2e5b1fe9134bcdffab8f2ccdc7c066dc78c2abf4bff", + "0x00c037b8d2642ff4eab9b8f1024bf8590635e901f04721cdbbf84667b41f4417", + "0x00dbbdd4a2ed8607327b0bd2755423b1df309e1dd4c8c650fd8f4be3e63b4521", + "0x00931e59d5c328411400af2fa634897bd19c5d7c6ab2cb31503032d0aab2d9d6", + "0x00684078aa752b5ee624fd0b0ca99002bd99571db012eb971398801a1cab9ef5", + "0x00e9910e6c54e8d2f517a6c763bf9b6ee6dba6e8eeecd889752973c3a6b21255", + "0x008df7df42630253f423bc75bf74908fcf32d5613890578c333aba7a45dcd5ca", + "0x009521c259ce8cada2ee081eb502a09c361d9750803792c5c5a9368c814fcc4b", + "0x00b19016fad1a6820aa1b283f74d325f004ef75aacc8ed5b070e801d9ce9b94a", + "0x0009c0f49ed7afb01a510699afa5e4d259139f5822211d5cd83ea5b8d63a12f9", + "0x006c70a70ef906a624bccdd19b28712f9df3be92543d71627dad2e0687efcef6", + "0x00b5312512a7df3fd71c972c4455172320772e4d42a149dd9bef0bc4919c48be", + "0x00e5b2e8617cb3601e8000461f71f01cf797cf732302d0859118c868fbee063e", + "0x0015315714bde8eb1e9e9993a260603a7fdf53d2c4d8deb2964e8a9efe0be6fc", + "0x00cfcb27f28265842a8a09c85758653e8e0d8425f08c47ca84f385400e2fe623", + "0x00ec5f3ff75a42ec99823569f2c3ab7e4bc2dcff824c9cc3eb26ce7ff430449c", + "0x004211f68dc1437664b53729185451169d507d3113118386a9a31970c617ce5d", + "0x003a626153e3014be32609d9df4bf9793647898abc7f9c9617a12b38f68d5681", + "0x0039e65d3cc5d7ccb80f16a160c3c64c92642f2ca47f1d2088c57a9b18e1dbb2", + "0x0082be09431245184e59019901caf8116c981f8fccacc4a44e32f8bfce775d8c", + "0x005c0a9d17df9a96cabafba9ea94bf891b4940a88ebba483bc611cedb3d7c764", + "0x009be41a54367b0e250a4809e2312d1729d67707b5635a5c2697451de52eb83a", + "0x0039319e8bb94c83b9e28d70f9824e27e7e51546d0110e99d3ec3a1de3736eb2", + "0x00538dc21bf9835a47a8f02159fb75ce547af28aac2668db6edbdff9ba4edfdb", + "0x00f91c3b76ce1277bdf344a5b3aacb13e4d64c1a96a8bb6a4be9d18ee700f251", + "0x000baff02bda85c7bf3650f776c760cc4214aeb9e8e8192ff176ae80babc403c", + "0x00196dad97f4bc1f93fcfcff4f754b4c7397049c78fb4a2f407d1503f76abe0e", + "0x002e6f6526fa14540471e57c578510cb628990bba62ef3193f5757e048c933b0", + "0x00697f19eda8b8fe006296c530fc7e35c1df8efe1623ef5a6b049d47c817a523", + "0x00e9cdea2a2e692c6bb7a1e497282495c3d132db44aca5841a99bec09679ef90", + "0x007aebb60041f6ae5d5a01447fb4703c4e866610c37beb8dab75b858e5f88c5e", + "0x0061075df819feeb3c606bd610774fac37db66262ae12eb1fb13459584b70d66", + "0x00d42cab0afc61aaa5f72f99215a6acb518b087215acc228ddb42147a7b7e7c0", + "0x00864c9090d607dd0de6db93e0165a4f83091458e25c9956d5d143f766fe693a", + "0x009d852a9139688ea87e49935a607e7d76948b294d5e63d09f27da2b7f0fee42", + "0x00accb8d13aa6d81885ac785499483923b1e1359a909b89f19ce489cd01b58e8", + "0x00e2a767e1bb7ab59c7b8ee3ddeeed90f7f75bb2e8dc16af79aff476677fbf82", + "0x00684bae9ed5f1763fa0c985d884fc88a8cbe5bd3072b54cffa843c80be4aff3", + "0x00f06d5d5de585203a7d9e2ad6f4317cd0db5637bb72a7606cb91f730efa6be3", + "0x006a02bdb8c551fa65e84714fe65769b76843cad2836b23a08a6b136050be456", + "0x0021f99757db2adf7c3c6d4a3a8d26355eeaa485f30bd8ff395a62c5896af1dc", + "0x004ff31f843561e5a9ebe5ef0f8f6cb1d85b24025b84b25aaebf39ea8761d700", + "0x007aa202b18a873c6fc866a5d1de1d36a9f3fe1155b4203da8cedc981184d343", + "0x006136ad055218ac36659f843b539961e02a668a27c5465e39afcb38fc697336", + "0x007967fd79eb3c580ed5220622e5526d77d764b119bd333603f11763c3efb07b", + "0x00bbc3c7cd5781921224c9c58558cb8cf447b6a450f07299d6d6c61a8eda074b", + "0x00e963afe31b4206435fd393f60bee69846def054be386020b3323c56646a1e5", + "0x00cfd2383f1d277b786ac9a49281e88386ea8429fff5a7b77cae6f707da2dcf3", + "0x000c9bc1eca10119523302a8595ab28d909974b296e742e4e47453de73aa34fc", + "0x00f3d98ab68b177df2e7822b012e56a47f94cce0978516d8b8ceda353b38a7ee", + "0x00bda596281daca5fffe62257c07885425cd0ab868b50c9ecca4dd0c9ca6cc00", + "0x007e79dbdf2a73c764af2ca536c09074f743889c12fbd68e6fe131aa4f92c418", + "0x008e5e18c2d6ce5550882a8ce8289d2f180ed8520d59987913b5a48c8ac24b87", + "0x00e9d1175351a02c0992fe80a23780c22390669cb00dd2bd4429cc086a060819", + "0x0019501180f48011b2953c9c632e727d1a5bd5a6e9eafc3ad6d272056d4ac780", + "0x000a55288c11408a3b36adf1946bc04a83a492a7b2c2a73d453b4fe83673b20f", + "0x00bf9310111257d619b3cdd6369344f43c179082d54c1ca9c379bb053bff9422", + "0x00c11be50442a1ff3d97eb9f063479718811046197c0a75d03929c545f2f30fc", + "0x00ad499c2c077902bb44cb36cba5f9619dcaae391b52075d84f846a463bfe2f9", + "0x00b90be8d5bc7f0b91a86ca0a28b402fd84d38258aa061301daa5982d534f0fd", + "0x00121228edff23042c9873ee4c161b0a106245bbbe02acaf11f4c1e881e21629", + "0x008281ba44e9b4aec225ef730db3b3513725739b002377dde0398a66e90858b0", + "0x003e67e6fed8cb267f61826d10802b76d174015be4da448ef6d289a08bd719d3", + "0x001e47926407e2b02a96ac26662902ac8b2d0cffdc456712ac23e744ba148ac1", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -4413,19 +4413,19 @@ contract_class_log_fields = [ ] [inputs.hiding_kernel_proof_data.public_inputs] - expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff1b30" + expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c70e7" [inputs.hiding_kernel_proof_data.public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x2ad6fde853521717c1ca3718c050ed1bba49a6d75f58f6f226df5f9280a79f69" + total_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + total_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" + root = "0x2d7278322ae3f2f02196f7b5eb323c037067b5a8bb27bb36e5936e01618b922e" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] @@ -4433,26 +4433,26 @@ root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" +root = "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2d77" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -4463,7 +4463,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hiding_kernel_proof_data.public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [inputs.hiding_kernel_proof_data.public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -4483,8 +4483,8 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 [inputs.hiding_kernel_proof_data.public_inputs.end] note_hashes = [ - "0x2295fa9f079bf362a4f01c3b07d9f912f9b484e5ee527ad7a528025a165b9352", - "0x27f0738f58cf7f88e6845175913245e6f82475f464578de70619eceaff66402e", + "0x21c7e2027864f293ff502b26ca73419fb7de391a18467849bba3e7debd669312", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -4549,9 +4549,9 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000" ] nullifiers = [ - "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c", - "0x1567c8c1ff81dda9727361df23c92849c46772567aa0bf3723db03c3751e9d2e", - "0x1cb96ed0bfe97ed05e23f013062425e5ce6599fb6430b162e69edfc317d5bf82", + "0x15664292cc693dcb31f3638ce704a65d0776e3d3a3a0138517913a429ea63c4b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -4697,66 +4697,66 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.hiding_kernel_proof_data.public_inputs.end.private_logs]] fields = [ - "0x2c3715409dc4762ec9a9a602d199ea9932d61edd3fd32c9891fe5ea5a722acde", - "0x10433733db106ed8336b9b799ec2debee9fe2da75f114f567eefde5abf9f74d3", - "0x17440c522b009a136c2207db86790b05464774690523c7fbf949ad381664d0ea", - "0x0a5e8928a4d74ad3256e8a697cfdf84b7baae32abad67b2de7c36ffd67acb665", - "0x0b1200621e156c6d79f463e17e81b96f11d18d716ca5222e7276e07d45845a26", - "0x04b2b64d09e487d10d557106046a94a97f2c40f4316e6667a2c2d9a99db05385", - "0x193da3d713c24b85e1c8f22dd8ef575e88d19c6732f8fd17e370cf64e65b3e04", - "0x08569203e8f3d028234ed200df77bca848c9b4b015ad8797c37669a5e5d1ee0c", - "0x13a9b2003409ad3d4f38caba797acc77092ddd431af25a955a83dc6f5b92cc93", - "0x16fece01bc0b0205bcbaca2904d5674d10573bfef038f94d3e5d526596da2ae9", - "0x0a438177a05071eaeb1862f154b187315de4dc804e275b0f2258baf4700c6d64", - "0x0959244a76e5e861ce5b8833101b91e19d758109d68cc174a6f9eec9c7afa008", - "0x03533d18a1c3ebcf22f820a243be161c9798ea59a506572e32e125c53b7aee7e", - "0x1e2b22ea302597bfcbcfdefcda48b60e35fce9c70f46c6cb90fa6db6e8d4dc6d", - "0x28fab93b8cd28d8d2a993badc3d1a080902feecfab019dc7c00af0ea9f6f403d", - "0x104c4c81c135af94af35a1eeb49b1262e5c53e25ee513731ddeb9f6496eea2ab" + "0x2e6635123c11ea371de1f0de5f7297edba9bd1ee4419a2baa9017834545196cf", + "0x22d45c5ecf33caca73655293c9c044de949350fbeb99751edee46bff7266df18", + "0x00aca686dd1494b88f1e99b9e0bf383beca6e79ee2fee64787081f71b3b55667", + "0x1c314fd1d2ed42ff85cc036bea4bd2fb15d110b6faa48ed8b0669dc30c94dbbd", + "0x2df45aed68ae9a8905fbe509e7f8d23f2fb5e9762f55c254e7f88c49b0506ff0", + "0x1195fd070cbaeed0ceb7aa9e8a9e5fee29e5ed025d288c9a56324d21601de372", + "0x001e27b9bc0a61e287574cfaeb9ea8a875daeaa683218bb33d95706d602269ba", + "0x0f4d2a7c2cdd6d3437522a159d3cbdda6402e5a5d7a9a1ac24f82727330bdbdf", + "0x2c2c768c42de26d71a1fa968c89abd1759a227ea1d15c124f45b20debc4320ea", + "0x1310ad0816e6c567cc27b94659907153bf9da9325a909ec25551a80f11b1bcea", + "0x0172c17ffcac570994c8a7f61065d71781221f210cf9931696a8acd553e68995", + "0x23e5bacd81360b2de450b8e39300120dc63d6312a525b0ebf2dea8f312d27fb3", + "0x1fba8519bacf0550c03873c8575c9f820db6d1b877e27f4e1adcaa0471394f95", + "0x03550ee6245d89cb2586fbcccd88e8052c64379c7e19103dff6bc53bb7a72aa5", + "0x2f530df6da91d1a2a47cb71cf6cb966b5253f4b412a454dd87bdd6a141eeca71", + "0x139da0492d7abf2cc4f359067e959399a31cb8b685c447eeb85ebfdb4faaddbf" ] length = "0x0000000000000000000000000000000000000000000000000000000000000010" [[inputs.hiding_kernel_proof_data.public_inputs.end.private_logs]] fields = [ - "0x1b7f52b7a346b47077bab6835a0810e5d75e977fc3f3fbb0436055bcdaa167ee", - "0x2320e89fb76918e7dc48b13861302dbf78af5ba8d5a20da77d19781ac32b9bc2", - "0x2a99619c0d4d380dbc3d53d03ed35011aa9c296a507fabcf712f43a0e5a10850", - "0x02e5d98e7dfbe7653dafb14afddd7e00f403b5a60816d7ab961823bd3cc4b628", - "0x223b37d6caffe87e91cddafdf65c4f641a609ff13350d02654b0fed1443088ab", - "0x2846b9aa4544f8f8851554f5d0c189c188756d734112e1eedd6840c8aeb0e66f", - "0x21cda3f228d55fb1b37f2b7c7a5d42066007143db17645669521ff58956fa7bf", - "0x1d8d79951d7389e5f9dfa963f93e399aebaa346e9ce3b3a5da1b45e4600a1553", - "0x15eabc8ed921f60621fa4fa35214748a7593f1c06a1e66b76092f789b4960bc5", - "0x16babb28d68725cb64d6d7558d49fb921c480359488fcdfb5292019239a50563", - "0x015e561b49da425d081b87bac01336defa1e29ee50d01b7be798ac28e05b24d6", - "0x04bf1a23807cb0711511a6140caf195df55fcf029842652243034ae2ca740648", - "0x2789cc422a86395739004c513cf6a15024e3adf5f2e238b18e1b4f1211a9383a", - "0x00c4e950cfe804e8a3623fe768c82b7340b0216f93c00351c53e2144364cfb51", - "0x2fd9827b4118b7ef401dff1727785e46fdd31947d2e733f4b39076f43652c18a", - "0x158ca7fba6e7fa7b3eb7c062751182d93b4e36b5c77d2e609e246b810650e59e" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.hiding_kernel_proof_data.public_inputs.end.private_logs]] fields = [ - "0x07d20bd951900d3094f2894e3c76c117114e3150dc3197e9e325e42b4487c6e2", - "0x127157561e774918ba656738fb61ad37f92086431bd4f1e4842ab11928b0f8d2", - "0x2e5cf59c8f2eee7a06d14cdedb8fe58945357cb16f4c792094325909a12924b2", - "0x0e29376c31f2aa7a156c6ce6d1fc9529998251d8500604658f173ff86adffa98", - "0x20761b8be9a186cf6a1730b8a1e99049a07e45c005e66d27b6e0ef15a2833e2f", - "0x1adf679b2441cf3535241924a35164cf8309256721e3f9fcb860bc2acc462b46", - "0x06a613741497b7b7ee978a495bfed7d19bbf76c462d268cee17a3920b1b1abe0", - "0x10ade06e253c1cfd65f24246211fb703c157fd9b563ffaf6ab01b6fba4635155", - "0x2311c6b104555d4d9afc7d66be6b47a41f8aa96eb77f613a75fc952da5975ccf", - "0x08431c3838d7ad6198c1d33ff138953ace3520551bd95b69692609ee11ded216", - "0x1822c33cf8097138c896bb9f7aad7def909a6859d5e640919fd16ebcf153a0db", - "0x11203b31ef49d39fb85a5ea474116c334c156091ab468493a480f13ad1ec1849", - "0x207a4712bacadd2f631fe253cb62932a7acb586dd6dd1b10e0fbe733f61a8f11", - "0x2c862b0eb14b1325a0ca63dda4570f718541d998fb4aba96339b7913b80757c9", - "0x1bf17ee7d3cf2487dcf1eb7a3647b0920c9e68aacc0a33c9a424d4ee6601ded3", - "0x2c70c9b7da7d7df78fcae182d124d7041209070f76d920e5d5c2d7590c385ea1" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.hiding_kernel_proof_data.public_inputs.end.private_logs]] fields = [ @@ -6048,22 +6048,22 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hiding_kernel_proof_data.public_inputs.gas_used] - da_gas = "0x0000000000000000000000000000000000000000000000000000000000000760" - l2_gas = "0x000000000000000000000000000000000000000000000000000000000007d76c" + da_gas = "0x00000000000000000000000000000000000000000000000000000000000002c0" + l2_gas = "0x00000000000000000000000000000000000000000000000000000000000722f4" [inputs.hiding_kernel_proof_data.public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.hiding_kernel_proof_data.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" sibling_path = [ "0x242211eb4067563a1667c912cfa2492c7b8bcf5e2b97fde4d26fd9bef12ee5f8", - "0x0e20194c2fc70cf5d2006345608c9f5abc7cdaf2cebe11870301359962bf326e", - "0x08c3364c5142d8fe956b12902940b54a7be36a42ce00cfc5831385a9d55cbe99", - "0x166399703d23a5c22febc6185f8eb93c72b65906eefef226e643c35fa0022adb", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x0bd0a68a914cc9453fa207323a819e6b1f4f432a1ea1e3185a55ef85fd1d4e68", + "0x1c3b50ab3c647b6d36f1830308d4542ce50afddf32694ad04eb0cd74c3745ac8", + "0x09ef85eaa102507d30f8dd98ca7ac4118e672d857aa409ddcbfcd5ead95566f9", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.hiding_kernel_proof_data.vk_data.vk] @@ -6215,16 +6215,16 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" hash = "0x0adf07f9ae6efe161812ba23ef36c864880bc3b0a8461ffaf756f4400c7e9f80" [inputs.start_tree_snapshots.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [inputs.start_tree_snapshots.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" +root = "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.start_tree_snapshots.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6249,7 +6249,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", - "0x1b250005eb96ff625256d16bb83fedca81f8952f06c2d3031636c0e1d8c9fecd", + "0x096edd31a317c6cc09d90028076aa45ef130565dd27e9d6bb76ede7390bb505c", "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", @@ -6284,9 +6284,9 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x08c286d5f8584ac20b64b63f763d4ec37d3fa13244234a3280f34bbc70a32d53" ] sorted_nullifiers = [ - "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c", - "0x1cb96ed0bfe97ed05e23f013062425e5ce6599fb6430b162e69edfc317d5bf82", - "0x1567c8c1ff81dda9727361df23c92849c46772567aa0bf3723db03c3751e9d2e", + "0x15664292cc693dcb31f3638ce704a65d0776e3d3a3a0138517913a429ea63c4b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -6351,8 +6351,8 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] sorted_nullifier_indexes = [ "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", @@ -6417,9 +6417,9 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] nullifier_subtree_root_sibling_path = [ "0x09166b559c0f096e897bb202971954b6c576adc978e55de25b96e97269f0e461", - "0x0362ef192033d8dd7561fb3d5599ffef50988df3dfb2d2a62db522b4dd468396", + "0x0e60bad1964713fbdd46c647c5eac792cc80a557602143931b895d1cd0367840", "0x2e5d15ff444e6868f293419113070aae8ce133e2ab4d2705a6a696caf2a17e21", - "0x11b6672806903af07ce5206700433633952804bd3668e15fac8868f0695bed72", + "0x2e7e6d33d178e492419788f2c1939a32602095f55adab3b2c2a8862f6d5a2981", "0x2842a7e5a723d69a6f6c088fcc7b2e289173ca583987359c712c15ee44806960", "0x2bc8d89815dcd02215ab5a89956f9743a205a7fd71e002096d7c250ffc3544bf", "0x01d2012039a4d9492bb83367eead0282083ff9011b9c3884c96022f90dcf7432", @@ -6455,19 +6455,19 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_preimages]] - nullifier = "0x20847724d5be09ca0af6e9b36ec5ce1147d557c6a4a2c61bb2aa4d62bdc08e66" - next_nullifier = "0x2bd24d9521cfcd8b14bb5f749a761545f4fe94dcc56618d57bcfea385a5db168" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000145" + nullifier = "0x14a78fd09108f21352c459933d7249a29259439d15d464562ffdd3e76d9c8a60" + next_nullifier = "0x190fcbb9384f74f5537b08d81102312ba13fea5a3bbfa55589497863ca3c05d4" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_preimages]] - nullifier = "0x1b292354acb3ba526050467dbc93d2d505c80e73a41b7d2fb0c09cd32d03875f" - next_nullifier = "0x1ceec3511b2489568c8344be81e970a769044dd97be95562536c6867e09b8677" - next_index = "0x00000000000000000000000000000000000000000000000000000000000000c1" + nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_preimages]] - nullifier = "0x1546bc72fd1c9f595cc29ec322397f0c1306a17f5de02a12ae937e48b30f316d" - next_nullifier = "0x16c07a80d3d164d5d8082a5dda9fb5d5f0de35fc2bc4ac2fa36182ed91ce381f" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000146" + nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_preimages]] nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6775,18 +6775,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 next_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_membership_witnesses]] - leaf_index = "449" + leaf_index = "327" sibling_path = [ - "0x2941a7272bf49125b7e5c8f9c8a06939064d366f933f8ebfcbe4257716243dad", - "0x19b8970c3845d2244da0851d0f9b631fae6156a9846a5598a0216fb537fb37d9", - "0x1fca8e5d48b8e1a70cb333a4f5ca28a3355ec77b582acf926a4a17d42c31f776", + "0x11e4524abf621361d914b2e2a9c620e31e8c611d5c9e2dae20810eb13fcb4d3f", + "0x0ab52f1e5cd20bd58359a914345e5aa1c07f92b3ff66c9549637a8029eb7c875", + "0x0b1235834e142a7ca83f6c68a977e24e5101e53b2288fc95dd63456f0d3c3724", "0x218d6b91b3a210e878d135aab2560fb2801db442dbd439ff2efd1fdfdfeeaad0", "0x0b926aa38fc854f094d02c0b719a75e50a7d4a0ef11685217c6568095b41fccc", "0x09c18d449a07bd072b1eb2b042e466fde1f82f740d57ab0ecb3ff368b3868abd", - "0x0df0ef1adc3691e5553b5304a971c203841eabef3423142e2e3c0bb4cfb01a82", - "0x233e166aa2a44dc5f9bcfbba514493bab8b8a00e3dd56e0d813888f5d06203f8", - "0x24bd80edafc13493c1edb17a018f34698eca5bed3b768dee95961dc577560e4e", - "0x29dbd0f2b5aec42761b1d801d1f899352dbb3b8c358abbf17c97069b6827de9e", + "0x130e440f3661265e95d02c65c164bca11f068700d185c854e8d8d249c88ff343", + "0x23777262752a110196cfb8aea4336fcf72709e5aa223ecdd70026cdced152de2", + "0x022583491e3efb346bd1c50a927a25b3cbcd82418dda6780c05be0e5654cdca5", + "0x2d8d44b58b661a6bf00468c07860bc5742006d7e6b1749d9a049a18376e80500", "0x2842a7e5a723d69a6f6c088fcc7b2e289173ca583987359c712c15ee44806960", "0x2bc8d89815dcd02215ab5a89956f9743a205a7fd71e002096d7c250ffc3544bf", "0x01d2012039a4d9492bb83367eead0282083ff9011b9c3884c96022f90dcf7432", @@ -6822,97 +6822,97 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_membership_witnesses]] - leaf_index = "327" + leaf_index = "0" sibling_path = [ - "0x10ef06a0c859785e8d7fcbbf7d1a624f045c1544816d195838405eaacd740010", - "0x2573a0e9cf295372545c619b8c9329e46b01b7ab974cec3bd12def9098d16620", - "0x08db730f7a5e1eed62556f1a919321b5e4f5ab9cf68cd8982fd80e1cadc6369f", - "0x218d6b91b3a210e878d135aab2560fb2801db442dbd439ff2efd1fdfdfeeaad0", - "0x0b926aa38fc854f094d02c0b719a75e50a7d4a0ef11685217c6568095b41fccc", - "0x09c18d449a07bd072b1eb2b042e466fde1f82f740d57ab0ecb3ff368b3868abd", - "0x259490a13493a82580afd12e91ff42f23d398b46827e29d819e2a64dfa907c47", - "0x20b151f51c25e2fbf0e6eb3c22eddd39b87ca1836592ed50d5d8fd3b489ee69d", - "0x24bd80edafc13493c1edb17a018f34698eca5bed3b768dee95961dc577560e4e", - "0x29dbd0f2b5aec42761b1d801d1f899352dbb3b8c358abbf17c97069b6827de9e", - "0x2842a7e5a723d69a6f6c088fcc7b2e289173ca583987359c712c15ee44806960", - "0x2bc8d89815dcd02215ab5a89956f9743a205a7fd71e002096d7c250ffc3544bf", - "0x01d2012039a4d9492bb83367eead0282083ff9011b9c3884c96022f90dcf7432", - "0x1778f17c8e296c4932de3439ce9789f59b83d5d3b856937f72a288ae1bc374af", - "0x095c78afebf8964a4900d8fd66177a0984fb2edc4f356630aa51f907c85e84a7", - "0x046adaf8a40ea8887051610d6ab46dd6b048b5d9c53059df80986b5bef657f6d", - "0x1e11d1859ad659a0335c8fd61dc426014864e5a55bcaeb257f9d227feae35f6c", - "0x0d5672a31f96065cfd886a178fb8a68f39359e072cc46059f829646a54bd5fea", - "0x002d4f87866c996c7cf08f9f2586b9352c6cb232f63f1f409442e79544ed1fea", - "0x1ae0d30f052aa078af8db1a19c5b29221eede6254d8456d4cfee32c7a1b65478", - "0x1081707dd8a7f5c1a530083104d13fea9af029da4d2e61245362c1f3ecf48196", - "0x15e1c98c82aa0a3259bb22b05652d09fd002a68bf0e1d7653bf43e362fd9ba1f", - "0x27f95c7a4ac6c88c7de9875b118e512b5e2d37a2831fc024f8a19b8bdc93fdf7", - "0x2554df241c43f2f76d7a85046a677f6d9427a26ac0cd46ac0b50c4ed838a674b", - "0x2f195708750d44098049e52b6adfde393658f69efea5a667ffee73f6cc80aa50", - "0x0b7a6d34dcaea7f093ac0b9772051418f48daae9bf84cf17f70a296aef62ecdc", - "0x1b653bd3cc2dfcf3f3b3afb2d217a9b88780027696d7768efd448c49a19f8224", - "0x2df1dcfeb9b7af5dcb96a8b534dd71ef3d552a4137be5614178cc1495f7f75f5", - "0x0f0331f8536e68b278f5de7801c132c4147fdfaf87315d527d151ae390381ece", - "0x2f2d601c41f429882eba885efe4ce645282a3637cbd0ee792e1ac739039330b6", - "0x0d516d0b39971ef19fe22dd4ec75c46671f4565bfb058d2680822b9553744dee", - "0x2f2b3594d5c121e620d1c673958d592972294602c0f3e4fe3492b49fc8ee9b0b", - "0x16d9a5f4522dfbf3ffd8faa23855178b54891fa521cf64dc8b2ce9870443cb08", - "0x248a6f54e4dc5bd76713782a6b65b972110f1892ef8c95cbf20105b6f12f207e", - "0x08b23d0504724cba951bcc67ba6181d9a4fd3a8b214095edaffb0d7c8db16dd9", - "0x12660ba2b4cee62a89cbf769915ebdeded1f9b6e6ebb843944ec836659c9528b", - "0x0eb5f9c7ca6420724b0fc9b01a3662e3fe6f51c54d3978a61171326bf3ee92e3", - "0x0fbea79b7a5d8b5e9d1177db2431cb7882995d5ef59bbf97e0e20b5ae3288c40", - "0x05b719cf2bc233946ac8066663c68c9fe008f7fe6c22711946861ddbd61ab5ac", - "0x05fe8d565aede597081b80f58cac87763f6c9ee43a7ab0a5f2b6baa3a97802d2", - "0x2fca418f250f4226d90e9c46b86a7fde2b88532fd817811a5de8b9c5bcac7298", - "0x06c52a2b4d052ab23fd5106d1e8b198fb13c934bd5a27f7e06bce496e1c6c205" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_membership_witnesses]] - leaf_index = "448" + leaf_index = "0" sibling_path = [ - "0x09828dd1f15420f5ae235412b7e16ecbce1b932812b73b7564e762bfd566f9a5", - "0x19b8970c3845d2244da0851d0f9b631fae6156a9846a5598a0216fb537fb37d9", - "0x1fca8e5d48b8e1a70cb333a4f5ca28a3355ec77b582acf926a4a17d42c31f776", - "0x218d6b91b3a210e878d135aab2560fb2801db442dbd439ff2efd1fdfdfeeaad0", - "0x0b926aa38fc854f094d02c0b719a75e50a7d4a0ef11685217c6568095b41fccc", - "0x09c18d449a07bd072b1eb2b042e466fde1f82f740d57ab0ecb3ff368b3868abd", - "0x0df0ef1adc3691e5553b5304a971c203841eabef3423142e2e3c0bb4cfb01a82", - "0x1cf8e3ee3a38d1b5aa62577b1820cc6a13b2bd9af440383c958fb833e05e831a", - "0x24bd80edafc13493c1edb17a018f34698eca5bed3b768dee95961dc577560e4e", - "0x29dbd0f2b5aec42761b1d801d1f899352dbb3b8c358abbf17c97069b6827de9e", - "0x2842a7e5a723d69a6f6c088fcc7b2e289173ca583987359c712c15ee44806960", - "0x2bc8d89815dcd02215ab5a89956f9743a205a7fd71e002096d7c250ffc3544bf", - "0x01d2012039a4d9492bb83367eead0282083ff9011b9c3884c96022f90dcf7432", - "0x1778f17c8e296c4932de3439ce9789f59b83d5d3b856937f72a288ae1bc374af", - "0x095c78afebf8964a4900d8fd66177a0984fb2edc4f356630aa51f907c85e84a7", - "0x046adaf8a40ea8887051610d6ab46dd6b048b5d9c53059df80986b5bef657f6d", - "0x1e11d1859ad659a0335c8fd61dc426014864e5a55bcaeb257f9d227feae35f6c", - "0x0d5672a31f96065cfd886a178fb8a68f39359e072cc46059f829646a54bd5fea", - "0x002d4f87866c996c7cf08f9f2586b9352c6cb232f63f1f409442e79544ed1fea", - "0x1ae0d30f052aa078af8db1a19c5b29221eede6254d8456d4cfee32c7a1b65478", - "0x1081707dd8a7f5c1a530083104d13fea9af029da4d2e61245362c1f3ecf48196", - "0x15e1c98c82aa0a3259bb22b05652d09fd002a68bf0e1d7653bf43e362fd9ba1f", - "0x27f95c7a4ac6c88c7de9875b118e512b5e2d37a2831fc024f8a19b8bdc93fdf7", - "0x2554df241c43f2f76d7a85046a677f6d9427a26ac0cd46ac0b50c4ed838a674b", - "0x2f195708750d44098049e52b6adfde393658f69efea5a667ffee73f6cc80aa50", - "0x0b7a6d34dcaea7f093ac0b9772051418f48daae9bf84cf17f70a296aef62ecdc", - "0x1b653bd3cc2dfcf3f3b3afb2d217a9b88780027696d7768efd448c49a19f8224", - "0x2df1dcfeb9b7af5dcb96a8b534dd71ef3d552a4137be5614178cc1495f7f75f5", - "0x0f0331f8536e68b278f5de7801c132c4147fdfaf87315d527d151ae390381ece", - "0x2f2d601c41f429882eba885efe4ce645282a3637cbd0ee792e1ac739039330b6", - "0x0d516d0b39971ef19fe22dd4ec75c46671f4565bfb058d2680822b9553744dee", - "0x2f2b3594d5c121e620d1c673958d592972294602c0f3e4fe3492b49fc8ee9b0b", - "0x16d9a5f4522dfbf3ffd8faa23855178b54891fa521cf64dc8b2ce9870443cb08", - "0x248a6f54e4dc5bd76713782a6b65b972110f1892ef8c95cbf20105b6f12f207e", - "0x08b23d0504724cba951bcc67ba6181d9a4fd3a8b214095edaffb0d7c8db16dd9", - "0x12660ba2b4cee62a89cbf769915ebdeded1f9b6e6ebb843944ec836659c9528b", - "0x0eb5f9c7ca6420724b0fc9b01a3662e3fe6f51c54d3978a61171326bf3ee92e3", - "0x0fbea79b7a5d8b5e9d1177db2431cb7882995d5ef59bbf97e0e20b5ae3288c40", - "0x05b719cf2bc233946ac8066663c68c9fe008f7fe6c22711946861ddbd61ab5ac", - "0x05fe8d565aede597081b80f58cac87763f6c9ee43a7ab0a5f2b6baa3a97802d2", - "0x2fca418f250f4226d90e9c46b86a7fde2b88532fd817811a5de8b9c5bcac7298", - "0x06c52a2b4d052ab23fd5106d1e8b198fb13c934bd5a27f7e06bce496e1c6c205" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_membership_witnesses]] @@ -9783,16 +9783,16 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [inputs.tree_snapshot_diff_hints.fee_payer_balance_membership_witness] - leaf_index = "120" + leaf_index = "118" sibling_path = [ - "0x13d5c2f78d433c774b2f9be7bb5d666fb8fd80452d0896af987365d04f9f681b", - "0x25f3536c3eb76fd96d5ccdde3cbbe50f5548e23683bf9f2cbad67f53d10537bc", - "0x2835a744c1a26d89fca8be670b7b8d7a2473a3eb7fd72bf533a007d6cc443772", - "0x2d0726c97dd7add62ef5c3e71e02ff90e76079e2650f2217ec0fe5e678b0bb8c", + "0x013c095d61087adcef13cfdeb887287dba3806baf73093ee460023cfb7730f22", + "0x060b5c8a3d6c10c09c2c4ef7897592f838ac2433c4ca664adc73ae6bf507aff4", + "0x2523970382de270c1acd87f98b4ed454353257f9c689dc608f7dc1b6ca23741a", + "0x12bef12e0e192e65178ebf9707e29797e5afdace0a42a17d796d1c40e5b7501c", "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", - "0x27c696ad87d2ae17e4005225c67d015eaca8a9c6e97dec181f97f15e2c1ff894", + "0x1ff2ba9f5f44162476e89f994a79debf4b9af550a887b5b484d18f5997553566", "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", @@ -9828,18 +9828,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [inputs.fee_payer_balance_leaf_preimage] - slot = "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3" - value = "0x00000000000000000000000000000000000000000000021e01deb310ea6e1140" - next_slot = "0x133d35b9030a815b221f9205ef080f220fd8ba968e9bd88b60033b4854e100ad" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000085" + slot = "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969" + value = "0x00000000000000000000000000000000000000000000021e0219674fdaa32380" + next_slot = "0x07e3196f3e5be886c078da1e359a784f0451f3b454344a3c6482a090708f2547" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000087" [inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.constants.last_archive] - root = "0x00f30d99838de8d9e0b40bb5f19c53ebd2cea2e4e324a6b48a4db2655906ad63" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [inputs.constants.l1_to_l2_tree_snapshot] @@ -9848,13 +9848,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000041" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde078" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [inputs.constants.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-public/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-public/Prover.toml index d2414328ae1d..41eca05ca9e8 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-public/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-public/Prover.toml @@ -1,9 +1,9 @@ [inputs] anchor_block_archive_sibling_path = [ - "0x1444237c68ff756b5bcab6ef4b010657fbc4911b8a806638579f1df27f6e43f0", - "0x048c76bde3b9047f9f34f7fe8811109eafa422f663c1825d2399df06f4f11689", + "0x09ae38c4bdd7cdbfee06b35cc61272ed229c502820948e040a4acf7081f149e0", + "0x162a8906e43df2f5e1ea3d0d32a2ccdcd0d4581e5307025f0796d0b64f937d13", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x08ead7d93a6e0ab74b47c029605a16640557a4c3e830a2f6294aea4559e5325d", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -3547,57 +3547,57 @@ contract_class_log_fields = [ prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail] - expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff1b30" + expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c712f" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -3683,7 +3683,7 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000" ] nullifiers = [ - "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef", + "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -7069,13 +7069,13 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.revertible_accumulated_data.public_call_requests]] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x00a5e40cab902df3efe088094577e83eb92103581c990f351edf1dfba3778905" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.revertible_accumulated_data.public_call_requests.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.revertible_accumulated_data.public_call_requests.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x1be490a4b344f41827e94113f628fb311efc1abac19bc1e84b08fd578708964a" [[inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.revertible_accumulated_data.public_call_requests]] is_static_call = false @@ -7402,18 +7402,18 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" l2_gas = "0x00000000000000000000000000000000000000000000000000000000000903d0" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.public_chonk_verifier_proof_data.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" sibling_path = [ - "0x1b3bb563a5febae9302424bc9b80841523b8773b3e521fb20de577a64e78bc9e", + "0x0a7fb889325f39bec13ee8f853c529ad8458c39c703cf4277c5b066d8d2eee15", "0x0a2d5d1c88992fa153310bc96af4c750c81353526f8c7dfe2b069ed57136e696", - "0x08c3364c5142d8fe956b12902940b54a7be36a42ce00cfc5831385a9d55cbe99", - "0x166399703d23a5c22febc6185f8eb93c72b65906eefef226e643c35fa0022adb", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x1c3b50ab3c647b6d36f1830308d4542ce50afddf32694ad04eb0cd74c3745ac8", + "0x09ef85eaa102507d30f8dd98ca7ac4118e672d857aa409ddcbfcd5ead95566f9", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.public_chonk_verifier_proof_data.vk_data.vk] @@ -7421,94 +7421,94 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" "0x0000000000000000000000000000000000000000000000000000000000000015", "0x0000000000000000000000000000000000000000000000000000000000000aef", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000001a8ea793d4cdae748667e6cdeb797ade65", - "0x00000000000000000000000000000000001cdf44a19565682df1db9105c2cd50", - "0x0000000000000000000000000000007d45bf53693d1e5f8c726b3b9090a3bdba", - "0x00000000000000000000000000000000002ddd08200eb9544a216dd19a8b59c9", - "0x00000000000000000000000000000096b0edfeb3ee3338c818b6e462ae496f95", - "0x00000000000000000000000000000000001bb979e3cd7d8111d021237de30bb7", - "0x000000000000000000000000000000e785a70c5bc29de6993bcd63514b5b856f", - "0x00000000000000000000000000000000001b6701a1a9de0c4e25c2eee81fbfc5", - "0x000000000000000000000000000000ccad5e1b43ec3cad430d126196ed4b784f", - "0x000000000000000000000000000000000026c8cfeea88730a069f9f8aae45eff", - "0x000000000000000000000000000000f25307bf7ae8166628fb8ca2aa186d80cc", - "0x000000000000000000000000000000000022a312b7a1b12f670d059924fde061", - "0x000000000000000000000000000000cfa8bf07d4dd07bd309194ad43dcf460aa", - "0x0000000000000000000000000000000000167ca0ccc32845025c5a76273b1b08", - "0x0000000000000000000000000000002a2f6be8e93ea920cd14a7b043ef6ed5d1", - "0x0000000000000000000000000000000000277ea66800e42f0b7078688718305a", - "0x0000000000000000000000000000007f88f1687491d3f3326c737061282c2e20", - "0x000000000000000000000000000000000019f0c295284fc42024aacbd46f9ae9", - "0x0000000000000000000000000000008a6e059479dbef05407682d018e1d7fd0d", - "0x0000000000000000000000000000000000276f6c02388d41b068d36f0e4082b0", - "0x0000000000000000000000000000006fe39d9df6859556bc04a2847a62aad7ff", - "0x00000000000000000000000000000000000faecf34f51e503f9c5bdf6f57aca8", - "0x0000000000000000000000000000004b4587deb70388b513862ba57de24e4596", - "0x0000000000000000000000000000000000167c35f16800e5924b66b6c395c2e1", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000351e060c59f2f13ceb5c631381e110552b", - "0x00000000000000000000000000000000002eeb2d2cba09260a9e138d0d24555c", - "0x000000000000000000000000000000d3bae05ebcb86c7b4921f00e4c579e9c5f", - "0x00000000000000000000000000000000002d4be8ae9ebbf085739d2c52d2ab93", - "0x000000000000000000000000000000940377e34f17c5ad22102cca865bb574a1", - "0x00000000000000000000000000000000000a723717bfcee9dcb71e21b6de10f8", - "0x000000000000000000000000000000991a4b02291df9c14b77e2473315d673b3", - "0x00000000000000000000000000000000001e89b95cf6b2ad2506d684fc7b7a30", - "0x0000000000000000000000000000004022b331528bfac4bdb04464fc89ff83fb", - "0x0000000000000000000000000000000000196330867786a8c08738881b739ce0", - "0x0000000000000000000000000000009df8b221819ebf22dc413d730b0c8a1e31", - "0x0000000000000000000000000000000000276ed9c7e725f586bf3b0f7d5f1594", - "0x0000000000000000000000000000008eb30c526734ef3a740aea96282908f962", - "0x00000000000000000000000000000000001624f456603c219b9f79b39960c61b", - "0x000000000000000000000000000000b9e9ead3a80d73be248eb82b65a23dbaf9", - "0x000000000000000000000000000000000022e03caaedc42d8b4b100610f33723", - "0x00000000000000000000000000000004914aab219c2e5c1388d1c5b276006436", - "0x00000000000000000000000000000000002426e1277a7907df8ec2e0e609f0a6", - "0x000000000000000000000000000000508e79b26489525bf5386a5c910dca5a5d", - "0x00000000000000000000000000000000003063b87ddf8ff817e547fe4ac149dc", - "0x000000000000000000000000000000f106fc4afe6bda7761c0d4ed7ded72ce1c", - "0x00000000000000000000000000000000002547059f6e3ae71ef9efe2be7dc5c0", - "0x0000000000000000000000000000001c8589cec2b200eed912f3e76cf5562b2b", - "0x0000000000000000000000000000000000154c96e49bb18fdd1aed7abd315822", - "0x0000000000000000000000000000009c4fcdf6541a1a4fd3d01630e1bba3fad8", - "0x00000000000000000000000000000000000e2b7c9dabb30e63d6cb909551d6d8", - "0x0000000000000000000000000000003e17757fa84eda964303f6fea5cca55ef1", - "0x00000000000000000000000000000000001efc4c896804eb95a3b76060ee5db8", - "0x000000000000000000000000000000514fabf9f6c618a2c084e1e9e64393459d", - "0x00000000000000000000000000000000000e851da603a179ea88a694100ed72e", - "0x00000000000000000000000000000081c7f92e6390c9fbe0627a879ecbd8f8e4", - "0x00000000000000000000000000000000002378d597dead1c2952534dc50aa04f", - "0x00000000000000000000000000000033435458f18b0436847ac2652e1aab3a81", - "0x000000000000000000000000000000000010f0f995d2e1ddfc2e2820abac64f5", - "0x000000000000000000000000000000cdc9c148beeb2652667b2a4be097432e98", - "0x00000000000000000000000000000000001790fa444ce77b0f17ced05ac77644", - "0x000000000000000000000000000000b4e0fa181577e0fce2a73e33cb1c7ef76a", - "0x00000000000000000000000000000000001248979a0b4c713d52467ef1091214", - "0x00000000000000000000000000000078b68a818812e294d27ed5173181eca67b", - "0x00000000000000000000000000000000001202f015e527e07bc8aa3b29bfc68a", - "0x0000000000000000000000000000002e37c769468f1d3bd64860032eeec60c95", - "0x000000000000000000000000000000000013a9a82892cb1b4ba982fa96f6fe5f", - "0x000000000000000000000000000000a4f97445c3ce77b60a4f89e090ed25f90d", - "0x00000000000000000000000000000000001bfe48767b9d9852929fd6c6ef7489", - "0x000000000000000000000000000000009788ffc458269e32c68d8529122209c6", - "0x00000000000000000000000000000000001ad94133da104b491b0533c283058d", - "0x00000000000000000000000000000082943f7e3e8277c5573c7bc01ee756e08e", - "0x0000000000000000000000000000000000093e0b3b3b286763d72202e7d89bd3", - "0x000000000000000000000000000000661e1803122d810a714ede90be3cff69ed", - "0x00000000000000000000000000000000000d11450f56fe63fe8dc9c9bcf5e0cd", - "0x0000000000000000000000000000003bbb3abba3a132e8d8f45f371281a8162a", - "0x000000000000000000000000000000000022484ddb85caad7259d40a2feaf9f0", - "0x000000000000000000000000000000d5c60aad9d3206ac85c01b2bbe07bb882c", - "0x0000000000000000000000000000000000064dbab19fabf630e0a01c9c644f28", - "0x0000000000000000000000000000000c6d39a6cc1814cb9c474639a2c85d7696", - "0x0000000000000000000000000000000000052e9746024ad3039b28344dff0160", - "0x00000000000000000000000000000082d5e3a922fab44e31d4948721b4c26f6a", - "0x00000000000000000000000000000000000209322634f0a5d2a3bd73f1e3eefa", - "0x000000000000000000000000000000ae542b5e28179ea83bd48b32d82857e6ce", - "0x00000000000000000000000000000000002e46a1b641046cc74f095ebc925043", + "0x000000000000000000000000000000b684f3822d696c3ecf484a7fe34791f63b", + "0x00000000000000000000000000000000002e9cd7590551679f2745acc9a6166b", + "0x000000000000000000000000000000c0fa18a8ea0c5477840072169c70c27083", + "0x000000000000000000000000000000000006fed68edbd8843dd0ab879a772fc6", + "0x00000000000000000000000000000026e7b1ee3942c1a107eb829a4a1fa2804d", + "0x000000000000000000000000000000000009789bf7546013a4f03234c7cf7806", + "0x00000000000000000000000000000008b9a37ec6fc3442e0c17c53d3e10b0b85", + "0x00000000000000000000000000000000001ec5dc87962d6200825abf3d662edc", + "0x0000000000000000000000000000007d544b6605780427b276080dcba2d3a6b1", + "0x00000000000000000000000000000000000e462e18915af1093432e4b54d56b5", + "0x0000000000000000000000000000002d05ce754d8790322afa554bb538c82ce7", + "0x0000000000000000000000000000000000217fb463fb96af6e79b1a94df4de2b", + "0x000000000000000000000000000000988e396bb90b6bb7bdbf004d58ee206dc7", + "0x00000000000000000000000000000000000ba1855ea83b7c95ca53b8080e4d9a", + "0x0000000000000000000000000000000542d08371517becedf53f97ab311ed352", + "0x00000000000000000000000000000000001da797344377e013d7ace7bd0b582a", + "0x00000000000000000000000000000020166ea9997b1c239d34547f165b8d5982", + "0x00000000000000000000000000000000001850619eba2054f9f41324786599c0", + "0x0000000000000000000000000000007b9e1bf48be054d6a7281d9aef57fa66c6", + "0x00000000000000000000000000000000002a965ef9ba89270efb7a138db9f3a5", + "0x000000000000000000000000000000b8eaa90b65a792f984baa676b46045473b", + "0x00000000000000000000000000000000002bdf1ff1c21dbc118d6b878d504e6d", + "0x0000000000000000000000000000001ff7882b2fdd2ca32c857c77a380501a10", + "0x000000000000000000000000000000000005d51203c3526df0478a7275d46c7b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000598c8acc7fbfa779ed23372aba38bee64e", + "0x000000000000000000000000000000000001984ff4c3c19be7573bd5bb20b210", + "0x000000000000000000000000000000cd57f43bdf29875704dbb8e152f13aa037", + "0x00000000000000000000000000000000000dd55c58c84f3d5e854644f37177e4", + "0x0000000000000000000000000000001f02ca88c525a96b8563b48a7aabfc6b24", + "0x000000000000000000000000000000000002c93e0923d1b6d1e60d43a3928487", + "0x0000000000000000000000000000003c44cb74e2b6818ca4c75759ea23191cdb", + "0x00000000000000000000000000000000000e4db22c7616ee8c3c75b705bc7668", + "0x000000000000000000000000000000cabb69affcf99d1cc46c03c4140cb33f47", + "0x00000000000000000000000000000000001c15d7c93bbec9b2c897220b1c1420", + "0x000000000000000000000000000000090d5378c110fa9fd29af632a34cf84470", + "0x00000000000000000000000000000000001c8f5e33fd9b7841bda781b9a1a2af", + "0x000000000000000000000000000000b268933977ad81d4b2a90d89d86fef1cd6", + "0x00000000000000000000000000000000002f05ee0ba26ee4625875220a4e9f51", + "0x000000000000000000000000000000b79359439c800d1ff8759390cf8e9877b8", + "0x00000000000000000000000000000000000907e60e1332a9c7d1543b5429af59", + "0x00000000000000000000000000000084be3aaaa5d4b2ce869b94d84b180886c8", + "0x00000000000000000000000000000000002bf2641799eea22ca7c17fcd0170bd", + "0x000000000000000000000000000000ffd7944bc577de67a10fa61e563e39a199", + "0x000000000000000000000000000000000018ee5274d9d59c7a4e6ea4e9086857", + "0x000000000000000000000000000000913cedb17e467b5ec128fcd30a5d8f45a4", + "0x00000000000000000000000000000000000c36352a17ffaa1baa9f6f4ab990f0", + "0x000000000000000000000000000000d1d15826519e7557e9252e25cca7b68234", + "0x00000000000000000000000000000000002d8d82a0d2a2dafaa5c30e4fd0beca", + "0x000000000000000000000000000000f366069eb603ece7d5dbe351d3a7f8cb99", + "0x00000000000000000000000000000000000119a645221fedcdd2f0ccc55659aa", + "0x000000000000000000000000000000d4c5aa8f13dc73d1efb124730021df3c0d", + "0x0000000000000000000000000000000000173a91d164168b2a104f8a445923e3", + "0x0000000000000000000000000000001e0da0a289c24c20d61d63757e40d52e9e", + "0x00000000000000000000000000000000000873f2a70e71f36a677fac98b0f223", + "0x0000000000000000000000000000006363e418625d1a87b6c793a3fa67b62c8a", + "0x00000000000000000000000000000000001ad07fff2f60d183c6bbb52a88a076", + "0x000000000000000000000000000000602ed6d6e8441b84b20d5cf2eefe2b5730", + "0x0000000000000000000000000000000000011db44c3dd41d17fd5a5da5841ab1", + "0x000000000000000000000000000000ef6dbd36e70930ca9ecea70731b3ae2952", + "0x000000000000000000000000000000000012198e0151358cf72269f25d98a7d6", + "0x000000000000000000000000000000a9c62bc5e4859d84a6b71f0eb9ae002076", + "0x0000000000000000000000000000000000146b4d83228248fb4daeceb484a5cf", + "0x00000000000000000000000000000024272119fa5ea3659f5cc93e6906346041", + "0x00000000000000000000000000000000000e6f203351dc3d501e96deeacd1745", + "0x00000000000000000000000000000042723ba67f449f887a257cff0077f60df2", + "0x00000000000000000000000000000000000d5d772ba32d8ea22a4a0ca387da7c", + "0x0000000000000000000000000000008768ff19c1d3a20e9d334a1dfc81d182a6", + "0x00000000000000000000000000000000001f094f6d1eb8ebb46d7095f5cc262d", + "0x0000000000000000000000000000000efeb2b7db33a990c506e101c73afeed1c", + "0x00000000000000000000000000000000001381f886e9f8fd1aaf0824301d7f8e", + "0x00000000000000000000000000000026555700b99ad174e75f4fb2d54779813b", + "0x00000000000000000000000000000000001c184192b5ddd9b083ea27a2d01025", + "0x000000000000000000000000000000182a4013ec7ec4cabe96b2bd1a6ab6430f", + "0x0000000000000000000000000000000000266cf97a9846e58c82026b73f6be09", + "0x000000000000000000000000000000a0520688f4f47af3d195d4177dea4f6e70", + "0x000000000000000000000000000000000006dc9cef5b50392a5b25ffcd69e751", + "0x000000000000000000000000000000527d7c6049997c4de9bee2ace160dfd14a", + "0x000000000000000000000000000000000015e9a964515f16d454fb7d7e2e565e", + "0x000000000000000000000000000000cbf8b366a6c9c4395540c30f766a303cb9", + "0x00000000000000000000000000000000000fbb75e876fd119e954d22ceeea95c", + "0x000000000000000000000000000000922cfb797e0ee95d7bb31ceeeeb4d433c7", + "0x00000000000000000000000000000000000f2223f49c2f01718041ba6c8ff4e5", + "0x000000000000000000000000000000a0d4ea1e1c31cb33177efc4f9a6e1652ca", + "0x000000000000000000000000000000000017d878dd102598b8a90d658d650bba", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -7529,12 +7529,12 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000b2cda22d682b80465a610820a455ccfe00", - "0x000000000000000000000000000000000014dbf65b57cd412e5a4e51e2e8fcb1", - "0x0000000000000000000000000000009324a599f7e39fa876752e4178e66cf056", - "0x000000000000000000000000000000000012a5445413899397985b2de3535efa" + "0x000000000000000000000000000000a353727eecbeb2708a0ba7438c9f67ac9f", + "0x000000000000000000000000000000000016d8906c48c640faac59aa0947b8bd", + "0x000000000000000000000000000000c14d66a59de329aabcfb5715846504a4e4", + "0x000000000000000000000000000000000009a577481460dded82d652c6abc7f8" ] - hash = "0x0c77683b8fb3dbb3c652ec7c75c7edab0f9597a4763fa388ed23a1a7dc7d4ba0" + hash = "0x1ef80142d10a45fb61f3a4192d352f1d813530777b10ca6db9613ccf5d025640" [inputs.avm_proof_data] proof = [ @@ -23942,43 +23942,43 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.avm_proof_data.public_inputs] prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" - transaction_fee = "0x0000000000000000000000000000000000000000000000000022e452ad469ea0" + transaction_fee = "0x000000000000000000000000000000000000000000000000004d2c208a4b8060" reverted = false [inputs.avm_proof_data.public_inputs.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000b" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000043" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde108" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x000000000000000000000000000000000000000000000000000000000000000c" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000026" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2e97" [inputs.avm_proof_data.public_inputs.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.avm_proof_data.public_inputs.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.avm_proof_data.public_inputs.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000003699e8ba0" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -23997,18 +23997,18 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.avm_proof_data.public_inputs.start_tree_snapshots.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000003000" [inputs.avm_proof_data.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" [inputs.avm_proof_data.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x1cfed5fd7ef032befae488393236dfabcdca928fd71b5775b02eeeca5952b149" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" [inputs.avm_proof_data.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" +root = "0x17809078aea757181529cc251693b3402311164785b07da22da983ca02d24ffa" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" [inputs.avm_proof_data.public_inputs.start_gas_used] @@ -24033,10 +24033,10 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 [inputs.avm_proof_data.public_inputs.effective_gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000003699e8ba0" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [inputs.avm_proof_data.public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.avm_proof_data.public_inputs.public_call_request_array_lengths] setup_calls = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -24365,13 +24365,13 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 [[inputs.avm_proof_data.public_inputs.public_app_logic_call_requests]] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x00a5e40cab902df3efe088094577e83eb92103581c990f351edf1dfba3778905" [inputs.avm_proof_data.public_inputs.public_app_logic_call_requests.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.avm_proof_data.public_inputs.public_app_logic_call_requests.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x1be490a4b344f41827e94113f628fb311efc1abac19bc1e84b08fd578708964a" [[inputs.avm_proof_data.public_inputs.public_app_logic_call_requests]] is_static_call = false @@ -24771,7 +24771,7 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000" ] nullifiers = [ - "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef", + "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -25133,18 +25133,18 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.avm_proof_data.public_inputs.end_tree_snapshots.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000003000" [inputs.avm_proof_data.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" [inputs.avm_proof_data.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" +root = "0x1b9b13fad9b8c5689ecb8b3449c932a2d4ce5b1bb6c66b151c74151b7a909287" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" [inputs.avm_proof_data.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b" +root = "0x042e24ca2f4d3cda89d63c923672cba1d069fd15c9575270effd23fb306ee5b1" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" [inputs.avm_proof_data.public_inputs.end_gas_used] @@ -25225,7 +25225,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000" ] nullifiers = [ - "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef", + "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -29473,16 +29473,16 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" ] [[inputs.avm_proof_data.public_inputs.accumulated_data.public_data_writes]] - leaf_slot = "0x2935995b8343928a25acdb09654bdc27aeef345ec185caa48fb0048bd475fbcb" - value = "0x0000000000000000000000000000000000000000000000000000000000001c20" + leaf_slot = "0x1e116153847a288031b32de76feba5606af7f48ea6844ed7f788cb4937c97651" + value = "0x0000000000000000000000000000000000000000000000000000000000001f40" [[inputs.avm_proof_data.public_inputs.accumulated_data.public_data_writes]] - leaf_slot = "0x0dc02e099550676b3dcfd522010d4db9d2c47a4556dfa28aa20a4a0eb35c54a4" - value = "0x0000000000000000000000000000000000000000000000000000000000000af0" + leaf_slot = "0x22d51324ad539ea879ef28ac3e794fc1fa95103211f0d355b7edbf0795a37e5a" + value = "0x00000000000000000000000000000000000000000000000000000000000007d0" [[inputs.avm_proof_data.public_inputs.accumulated_data.public_data_writes]] - leaf_slot = "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3" - value = "0x00000000000000000000000000000000000000000000021e00afaeb15ed67ca0" + leaf_slot = "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969" + value = "0x00000000000000000000000000000000000000000000021e008a3dae486615a0" [[inputs.avm_proof_data.public_inputs.accumulated_data.public_data_writes]] leaf_slot = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -29747,5 +29747,5 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" squeeze_mode = false [inputs.last_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" + root = "0x2d4409306059501fce0434d5913ad345e014fc870961be182b636a307b3d06d8" + next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000c" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml index 9181896a6389..a86acdd36df9 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml @@ -489,8 +489,8 @@ proof = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] @@ -570,10 +570,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7d1b34e" ] state = [ - "0x0dbad51bb440650e97a5db6945e0b816676a7c99a97b61f7575f7ebb0302cb74", - "0x153f707b3f374da7de4e7558dd131ca1b276367234300e2061ebb6a80c9321cd", - "0x301693101ecf5431e14201ddc3e55cb8715203dcc3e3d159df5c63bdbde17381", - "0x223072f1c5ac6c338cf08c7043aa64605f2ba6feec29f658343ec4db85070b27" + "0x28ceaed15a6167592482697da06ac405557958a88659e8a294d4a863e97f8cbe", + "0x16710e00e80f40036d0a39c58a3269bf0e03b7c095b904499bdab6f3ef5ccd71", + "0x25a44adf4bb8ea266cd5398139a046115f57ab3cbbf9827ae3edb4dca94d8fd1", + "0x13551db592560b9a6d2ffed579ee3530d463b8baa035312dccd664e01e077a66" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -581,134 +581,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000008580b9a8c85e4a3c1e7b1089bd79f3bc28", - "0x000000000000000000000000000000000022dc01e3ed0e1b10bdcff9d093431a", - "0x00000000000000000000000000000054f9950035e8ffae852707e9d1a9032e59", - "0x0000000000000000000000000000000000276c56cb94e0545b3bfd85919a8ce8", - "0x0000000000000000000000000000009352ff9d82645804416a2b338260fa235d", - "0x000000000000000000000000000000000010a253776d2bdcb7129acfa2e91ac5", - "0x00000000000000000000000000000095babbbc4a6d5a9b68707c3a8e1e9508e2", - "0x000000000000000000000000000000000030157ca77e90f7ee9155c1009b06a1", - "0x000000000000000000000000000000068047e82e283284235befaa9cc7a1838d", - "0x00000000000000000000000000000000000bcd70cc5042e81e440b1ea5ef3c3f", - "0x0000000000000000000000000000007702a95c1bf5e2923ca69f26cc2d7efe0f", - "0x00000000000000000000000000000000000adeb0e8b1074c68de2b2172f21c5e", - "0x000000000000000000000000000000520354133ccbbccfc69be0c01b92abdf0f", - "0x00000000000000000000000000000000002dea248e3c2fe054c698a861bf4c27", - "0x000000000000000000000000000000f93b6112b7de5c27298a81c68d502b7beb", - "0x00000000000000000000000000000000002be3a33fc9502b0cc8b9427fcfe50f", - "0x000000000000000000000000000000168f01ff83f4a014a90db19e5d882a0a0a", - "0x000000000000000000000000000000000008876edc3cc7e3825dc194e21cb011", - "0x0000000000000000000000000000006d1df389f06e514e1829af3744dc64294a", - "0x000000000000000000000000000000000022e86ef68622bd107e5080cc062a4f", - "0x000000000000000000000000000000d137fc89e86049cb1b141b67b3361b6298", - "0x00000000000000000000000000000000001d7ad7d0634dc08d7d9816b5b6814c", - "0x000000000000000000000000000000defd2454e2c3a75ec8e0730bd3640b9408", - "0x00000000000000000000000000000000000b189f6ee9395b1ca5771c361501d7", - "0x00000000000000000000000000000001fccf755f5b30a7d544b2f78ce075cb5d", - "0x000000000000000000000000000000000026f5423942948047e155a519b195e8", - "0x000000000000000000000000000000a9efc76daffb8dfe2a39570b2d5d046767", - "0x000000000000000000000000000000000026e7dd89fe96952a4603c2b5555538", - "0x00000000000000000000000000000008262b430328dcaab242dd8acc504e8ac9", - "0x000000000000000000000000000000000015f3ab1410f0e5dd3e00f03b9f563b", - "0x0000000000000000000000000000008fca5ff8ed9a5d41fe9b451f02502dd1c9", - "0x0000000000000000000000000000000000266aa6e4947434ef18adeba3700713", - "0x000000000000000000000000000000d93cecd04341f5da304f3c92f0670afc43", - "0x000000000000000000000000000000000020165b3fd2bfb72a4de3dc68f66eed", - "0x000000000000000000000000000000094a6d376eb3cc1ba94b4da00dea583eac", - "0x00000000000000000000000000000000001caf7742d251b04f3517f0f1e5a625", - "0x0000000000000000000000000000003be5647cd472ad0b06a48f632997e3eea2", - "0x000000000000000000000000000000000015fb4d9ecb8125b3243cee37698c48", - "0x0000000000000000000000000000000854a3ab5bcbca1e86d4949b1b7c5f4b0e", - "0x000000000000000000000000000000000015450314fbf315448dc3379dc82214", - "0x0000000000000000000000000000009c2c55d2ea5bdf5fc5e28f1a78b1d29625", - "0x000000000000000000000000000000000020b36a8406ec64352600587cf04194", - "0x000000000000000000000000000000f14d08d9dab6a54412d741166146188ae6", - "0x00000000000000000000000000000000001b5a34ccd7eaf5cd09ab920011552f", - "0x00000000000000000000000000000074b7827a59faf701f7f41df26e5476c40c", - "0x00000000000000000000000000000000002decbab1c87b933da1625951860793", - "0x000000000000000000000000000000751aab48a0e01094128242ea0aaab63ff7", - "0x00000000000000000000000000000000001a2a334289adf8d23d4d52caf4cfe6", - "0x000000000000000000000000000000f6a41261290460b25e1e7d7bf69b564ae6", - "0x00000000000000000000000000000000000296925feaed4585bb03319f126d96", - "0x00000000000000000000000000000055b70d653ebd7df04f720951e76a27369b", - "0x000000000000000000000000000000000019744937a687edc9f46fb8323a46d9", - "0x00000000000000000000000000000047978fda5b64d8fc4571f09da3e8ccc7de", - "0x0000000000000000000000000000000000139de6a387109f47ecbacc74e03742", - "0x0000000000000000000000000000007f5afdfcb7bcd85aa293676e18e899a03e", - "0x000000000000000000000000000000000006a2971c1c947f4cadb07ebc9bc980", - "0x0000000000000000000000000000006cdb69a57b7f7a25b99e18fc0f83c1bc70", - "0x000000000000000000000000000000000028f2a76a01dc3cc927cdba29383e9b", - "0x0000000000000000000000000000001bbc4d6033de44907975ce473bc0f4f148", - "0x00000000000000000000000000000000002642f26fc1850c4b9b7fc4cd860ab9", - "0x000000000000000000000000000000ac996074e35eb268f6ebbe99e9c7d26c47", - "0x00000000000000000000000000000000002262620617978a01f75646f1909969", - "0x000000000000000000000000000000e63aa32bcc098428f407b5e07d9cb26118", - "0x000000000000000000000000000000000022b294b6a7dc4c17319f9a91a1b443", - "0x000000000000000000000000000000649d9ce9147431632893f55d3c6bbc158e", - "0x000000000000000000000000000000000020698c9b0787f14aa66a57bc232ec1", - "0x000000000000000000000000000000b4fde29f9bde909609d70bf9862dd65cf1", - "0x000000000000000000000000000000000005fcac9b75cac50d87ca827678c070", - "0x00000000000000000000000000000071e27b0a0dd0e2180985072f4a949f0c1d", - "0x000000000000000000000000000000000025d2d1388eddcf016213f1cadc763f", - "0x000000000000000000000000000000b216bad715cdfa7c382d30d7a368cc1346", - "0x0000000000000000000000000000000000302dbbf78b13a6d71d1978b5607145", - "0x00000000000000000000000000000002ebdec49969d2ff9220240bbcb8730617", - "0x000000000000000000000000000000000027f41cad8540e47008c1da90340ef6", - "0x000000000000000000000000000000e8259148321315cc34166a206fe910c6cb", - "0x000000000000000000000000000000000013444efc30c7688d961f36de252af6", - "0x0000000000000000000000000000005b7c7ad432291e9dff1dfad51159e50dbf", - "0x0000000000000000000000000000000000205ec973a0d1c898c1def7852353b3", - "0x0000000000000000000000000000007940a7e88fe5ce47af688975c92be1b62a", - "0x000000000000000000000000000000000015bdab44fe41eec6ee62ed58f55ff5", - "0x0000000000000000000000000000003693b90aedcd664eede665df6f376cf526", - "0x0000000000000000000000000000000000207c38fd6851d1568fe18a83585f31", - "0x000000000000000000000000000000f1a8a60975b9b092aab1421166be08c2f5", - "0x000000000000000000000000000000000015450d2e8ea17db209302582b886f1", - "0x000000000000000000000000000000526e857040a344bd434bfdbf94d3a49196", - "0x00000000000000000000000000000000000d0112b922a852c4754ab3929d6d02", - "0x000000000000000000000000000000d88041fa28c8118a58ceacbcc8780844b5", - "0x00000000000000000000000000000000002584170ebef150b71c5e6aa93e2fbb", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a2c4fbcbebac01e208127093cbf44780d4", - "0x00000000000000000000000000000000001ca34545a074b1cb689aa0b343402d", - "0x000000000000000000000000000000a58c28598055d8818a6dbadd0018904386", - "0x0000000000000000000000000000000000152154cbc213630f5c7ec1ee37751b" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000f944590031f1d3b251c3dc90ea2821c71d", + "0x00000000000000000000000000000000000d31fd1a4942efade625e012c77df1", + "0x0000000000000000000000000000001e9acd89b92c18e3d89b881b26312bb12b", + "0x000000000000000000000000000000000000736f00a23cbea07da614d8b767e4", + "0x00000000000000000000000000000012167fb1f0d3b9afea7d534404e3b36b53", + "0x0000000000000000000000000000000000021e6d056d0d40c720927abd39c872", + "0x0000000000000000000000000000004ea3f0c21ee1056b3e2ad9c082242e5a2e", + "0x00000000000000000000000000000000000c574204fd079871ae599e192d72c8", + "0x0000000000000000000000000000002654c5b2b175f95fdb2ab405dcc4220545", + "0x00000000000000000000000000000000001fd13a35df71290c2354c6c5f610de", + "0x000000000000000000000000000000d5e3b3464d67c82f035b33016912264b04", + "0x000000000000000000000000000000000009fcdab45c12d2f313f95b94a1dcb8", + "0x000000000000000000000000000000768c5a9d8ca0081f67ff3171a7ffe3ba49", + "0x00000000000000000000000000000000001cd676b8d32bb0bb898d83a9f49a2b", + "0x00000000000000000000000000000028650bc3473de217fbfec1e9fb10e4e999", + "0x0000000000000000000000000000000000260c000ea0ebc3db3ba672328007a5", + "0x000000000000000000000000000000f1948fbf68599bf0628f118156de61f57f", + "0x00000000000000000000000000000000000033e796d200425f6a499de18dbfeb", + "0x00000000000000000000000000000016a35cf8fc5f017037adf860723e6346e5", + "0x0000000000000000000000000000000000088cf6d72197800bb1300677f734a7", + "0x00000000000000000000000000000047169c153b6cc24bbac1e4126410779ccb", + "0x000000000000000000000000000000000022b70bfb92e8c7944ae65a49b7effa", + "0x000000000000000000000000000000425c661c37104ad33c2054f3cfde9954d0", + "0x000000000000000000000000000000000000c36b8ecc5963bef022dea4dfadcc", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", + "0x000000000000000000000000000000862e0c485b99696417d296ecc2b2bac316", + "0x00000000000000000000000000000000000ae46fcce211297d2d7fcab27fc041", + "0x000000000000000000000000000000551700c158e12cb40d8ea4ef2563b6fb43", + "0x00000000000000000000000000000000000b515d88939b250a4a4758e4e2ea53", + "0x000000000000000000000000000000f4bae0ad0baeb9d42c7fe2ae3d18c98fad", + "0x00000000000000000000000000000000002a20d66bd435a17fdf1eaf345d5933", + "0x000000000000000000000000000000ed8a8ba528c7088b1ae4730572e1ec32c8", + "0x000000000000000000000000000000000009506de430d6b9f9863e6f10cd35fb", + "0x000000000000000000000000000000682b627744ce0319f4d9191675057282fb", + "0x000000000000000000000000000000000017de059961f8c12752abd299396f86", + "0x000000000000000000000000000000b975958ec262178729e94350c0e7543fb0", + "0x0000000000000000000000000000000000220ce50e394560e53f025e094d17aa", + "0x0000000000000000000000000000001fca3a68a28d438e85e9dc955856752779", + "0x000000000000000000000000000000000028f8f3400bb3b9d19b02ec709e2ee4", + "0x0000000000000000000000000000004e35d073460b0634ebe216d49a3dca9b36", + "0x00000000000000000000000000000000000cb0f5827b08075c405353f10ba632", + "0x0000000000000000000000000000001ece860550ce14fae74eda0123ded56a74", + "0x00000000000000000000000000000000000a34b258bd3daaf8f9edd201c25ed3", + "0x0000000000000000000000000000008cb28ae85d58a75302229585a9ad114c2b", + "0x000000000000000000000000000000000014aac1da344ad32659c3036510fcc1", + "0x000000000000000000000000000000822b45036d5c2befa8a20df910513570c4", + "0x000000000000000000000000000000000011244b388e709fbcb7f54658cfac43", + "0x000000000000000000000000000000389de9951eb8fad7e25e4ad0a9229d2275", + "0x0000000000000000000000000000000000136e6eb0ee251f9b12336cb7bb46ee", + "0x00000000000000000000000000000088f21d9f6c7c54ce4e9a4c103a91b54a58", + "0x0000000000000000000000000000000000187f2beab9a05ca29d2137ee7cbc19", + "0x0000000000000000000000000000009c703a5eb43dcef0686e08fa57ef452f68", + "0x000000000000000000000000000000000012caebb183f1490d3e4f2a2c583ab6", + "0x0000000000000000000000000000009dab4a0aa8d4954a8e1761db3da148a746", + "0x0000000000000000000000000000000000230a08da3b62fd6479b4230760b686", + "0x00000000000000000000000000000081a00a1e38bbd5212603f18ef982a5189d", + "0x000000000000000000000000000000000021ae0f9df38f1e70fa3c26867f4ee8", + "0x0000000000000000000000000000001a722dbd34f841b4823cd055149fce642f", + "0x000000000000000000000000000000000002df2693a9b134670cfe72bf29b363", + "0x00000000000000000000000000000007c906c328630b844b0797e34cedccd1ec", + "0x00000000000000000000000000000000002ab2ae39dd9c0259f7dfb1dda47e81", + "0x000000000000000000000000000000ac6642a4923aa2df07a00a9d3e462b0ed1", + "0x000000000000000000000000000000000015afb7af6c0fc23a24457aa887df9c", + "0x0000000000000000000000000000004d916ec23ef29c0b6134f208e3535671d4", + "0x00000000000000000000000000000000000d37c6c25852903d79475133d414e8", + "0x00000000000000000000000000000029ad212431ba1972de7ee0ba9f12113be3", + "0x000000000000000000000000000000000005c2393db23155844d4f71bead84d0", + "0x000000000000000000000000000000c69074efa82a4910eaf8ab8689d7aafcad", + "0x000000000000000000000000000000000029f3d77437006a0eacf1a149c4b8a0", + "0x00000000000000000000000000000030926853da69d4016eca2f1f0df5e5316f", + "0x000000000000000000000000000000000014841d3291aecd45ea0e05657dbed2", + "0x00000000000000000000000000000052fdb060fe666a3f686088f1f6996a1cf9", + "0x00000000000000000000000000000000002be878eb09939603b391aa9ee0393a", + "0x000000000000000000000000000000d99de3b49476e64c0138037838cfc63803", + "0x0000000000000000000000000000000000260874b43f32c373783efe7ef200a2", + "0x0000000000000000000000000000004951edbb25e9c6b65d446e3418b2b3f16e", + "0x00000000000000000000000000000000002300fac13ab48d40a91114d1ff9627", + "0x00000000000000000000000000000090b8d216da73861ee276dddb17428d8c09", + "0x000000000000000000000000000000000028f906106984e5fa78812869cc1aee", + "0x000000000000000000000000000000ce2aff6eda49d5b8be6ee42104d2aa21e0", + "0x000000000000000000000000000000000002833f671993d2b772b5dec0e12056", + "0x0000000000000000000000000000008be4e7cfb1fdf317a33b7bc3530625e6b8", + "0x000000000000000000000000000000000023404bed8e224a350755410e5c96b2", + "0x000000000000000000000000000000cd9a812fad3fe3a89983e416b70529445b", + "0x00000000000000000000000000000000000b66296ff191a2cf6dbe6ca03dcd0c", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003e895e3756deb16393c59a6a9d3669ce0f", + "0x0000000000000000000000000000000000262d7f27b9058ca9bd2e0620f9a3d3", + "0x000000000000000000000000000000b98c4ce00d755cb57daf4bc1b860536fc3", + "0x0000000000000000000000000000000000017137ecc6753555f49859a34eeb62" ] - hash = "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6" + hash = "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead" [[inputs.previous_rollups]] proof = [ @@ -1201,8 +1201,8 @@ proof = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] @@ -1264,10 +1264,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7d1b34e" ] state = [ - "0x0dbad51bb440650e97a5db6945e0b816676a7c99a97b61f7575f7ebb0302cb74", - "0x153f707b3f374da7de4e7558dd131ca1b276367234300e2061ebb6a80c9321cd", - "0x301693101ecf5431e14201ddc3e55cb8715203dcc3e3d159df5c63bdbde17381", - "0x223072f1c5ac6c338cf08c7043aa64605f2ba6feec29f658343ec4db85070b27" + "0x28ceaed15a6167592482697da06ac405557958a88659e8a294d4a863e97f8cbe", + "0x16710e00e80f40036d0a39c58a3269bf0e03b7c095b904499bdab6f3ef5ccd71", + "0x25a44adf4bb8ea266cd5398139a046115f57ab3cbbf9827ae3edb4dca94d8fd1", + "0x13551db592560b9a6d2ffed579ee3530d463b8baa035312dccd664e01e077a66" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -1282,10 +1282,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x095ff6c475ee1af84257c77b73b727e6ebf0cc7015e0318ea5ceb14044e637a8", - "0x28810b36811d26c3700f0c7867fc191986df3ef57ea3a195b396ae8e1516b1a7", - "0x0d0d075374c48ade348ced65280060db0bfe6c16752688a5d65a07afc55cf16c", - "0x0b29f6eee3031f85d7f5ce02982c80e8fc06b552319a441c5b0fc3521d9c801c" + "0x019c8b37514a1a54433fb4ee411ccaf6da8c99234b4e5d11cc5f6b95c3989bb5", + "0x026875d420939d38c5495ee684f0a31efd5cab908193ae929d1c426d68bb9409", + "0x1a8c7e8add3b6e5ee547b84164a1d59756426ff82c71128c0627a7c01c830220", + "0x081d1fadf8d9a49f296a172486009b0c5f64d52de31142cfc01bc2b08387210a" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1293,131 +1293,131 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000008580b9a8c85e4a3c1e7b1089bd79f3bc28", - "0x000000000000000000000000000000000022dc01e3ed0e1b10bdcff9d093431a", - "0x00000000000000000000000000000054f9950035e8ffae852707e9d1a9032e59", - "0x0000000000000000000000000000000000276c56cb94e0545b3bfd85919a8ce8", - "0x0000000000000000000000000000009352ff9d82645804416a2b338260fa235d", - "0x000000000000000000000000000000000010a253776d2bdcb7129acfa2e91ac5", - "0x00000000000000000000000000000095babbbc4a6d5a9b68707c3a8e1e9508e2", - "0x000000000000000000000000000000000030157ca77e90f7ee9155c1009b06a1", - "0x000000000000000000000000000000068047e82e283284235befaa9cc7a1838d", - "0x00000000000000000000000000000000000bcd70cc5042e81e440b1ea5ef3c3f", - "0x0000000000000000000000000000007702a95c1bf5e2923ca69f26cc2d7efe0f", - "0x00000000000000000000000000000000000adeb0e8b1074c68de2b2172f21c5e", - "0x000000000000000000000000000000520354133ccbbccfc69be0c01b92abdf0f", - "0x00000000000000000000000000000000002dea248e3c2fe054c698a861bf4c27", - "0x000000000000000000000000000000f93b6112b7de5c27298a81c68d502b7beb", - "0x00000000000000000000000000000000002be3a33fc9502b0cc8b9427fcfe50f", - "0x000000000000000000000000000000168f01ff83f4a014a90db19e5d882a0a0a", - "0x000000000000000000000000000000000008876edc3cc7e3825dc194e21cb011", - "0x0000000000000000000000000000006d1df389f06e514e1829af3744dc64294a", - "0x000000000000000000000000000000000022e86ef68622bd107e5080cc062a4f", - "0x000000000000000000000000000000d137fc89e86049cb1b141b67b3361b6298", - "0x00000000000000000000000000000000001d7ad7d0634dc08d7d9816b5b6814c", - "0x000000000000000000000000000000defd2454e2c3a75ec8e0730bd3640b9408", - "0x00000000000000000000000000000000000b189f6ee9395b1ca5771c361501d7", - "0x00000000000000000000000000000001fccf755f5b30a7d544b2f78ce075cb5d", - "0x000000000000000000000000000000000026f5423942948047e155a519b195e8", - "0x000000000000000000000000000000a9efc76daffb8dfe2a39570b2d5d046767", - "0x000000000000000000000000000000000026e7dd89fe96952a4603c2b5555538", - "0x00000000000000000000000000000008262b430328dcaab242dd8acc504e8ac9", - "0x000000000000000000000000000000000015f3ab1410f0e5dd3e00f03b9f563b", - "0x0000000000000000000000000000008fca5ff8ed9a5d41fe9b451f02502dd1c9", - "0x0000000000000000000000000000000000266aa6e4947434ef18adeba3700713", - "0x000000000000000000000000000000d93cecd04341f5da304f3c92f0670afc43", - "0x000000000000000000000000000000000020165b3fd2bfb72a4de3dc68f66eed", - "0x000000000000000000000000000000094a6d376eb3cc1ba94b4da00dea583eac", - "0x00000000000000000000000000000000001caf7742d251b04f3517f0f1e5a625", - "0x0000000000000000000000000000003be5647cd472ad0b06a48f632997e3eea2", - "0x000000000000000000000000000000000015fb4d9ecb8125b3243cee37698c48", - "0x0000000000000000000000000000000854a3ab5bcbca1e86d4949b1b7c5f4b0e", - "0x000000000000000000000000000000000015450314fbf315448dc3379dc82214", - "0x0000000000000000000000000000009c2c55d2ea5bdf5fc5e28f1a78b1d29625", - "0x000000000000000000000000000000000020b36a8406ec64352600587cf04194", - "0x000000000000000000000000000000f14d08d9dab6a54412d741166146188ae6", - "0x00000000000000000000000000000000001b5a34ccd7eaf5cd09ab920011552f", - "0x00000000000000000000000000000074b7827a59faf701f7f41df26e5476c40c", - "0x00000000000000000000000000000000002decbab1c87b933da1625951860793", - "0x000000000000000000000000000000751aab48a0e01094128242ea0aaab63ff7", - "0x00000000000000000000000000000000001a2a334289adf8d23d4d52caf4cfe6", - "0x000000000000000000000000000000f6a41261290460b25e1e7d7bf69b564ae6", - "0x00000000000000000000000000000000000296925feaed4585bb03319f126d96", - "0x00000000000000000000000000000055b70d653ebd7df04f720951e76a27369b", - "0x000000000000000000000000000000000019744937a687edc9f46fb8323a46d9", - "0x00000000000000000000000000000047978fda5b64d8fc4571f09da3e8ccc7de", - "0x0000000000000000000000000000000000139de6a387109f47ecbacc74e03742", - "0x0000000000000000000000000000007f5afdfcb7bcd85aa293676e18e899a03e", - "0x000000000000000000000000000000000006a2971c1c947f4cadb07ebc9bc980", - "0x0000000000000000000000000000006cdb69a57b7f7a25b99e18fc0f83c1bc70", - "0x000000000000000000000000000000000028f2a76a01dc3cc927cdba29383e9b", - "0x0000000000000000000000000000001bbc4d6033de44907975ce473bc0f4f148", - "0x00000000000000000000000000000000002642f26fc1850c4b9b7fc4cd860ab9", - "0x000000000000000000000000000000ac996074e35eb268f6ebbe99e9c7d26c47", - "0x00000000000000000000000000000000002262620617978a01f75646f1909969", - "0x000000000000000000000000000000e63aa32bcc098428f407b5e07d9cb26118", - "0x000000000000000000000000000000000022b294b6a7dc4c17319f9a91a1b443", - "0x000000000000000000000000000000649d9ce9147431632893f55d3c6bbc158e", - "0x000000000000000000000000000000000020698c9b0787f14aa66a57bc232ec1", - "0x000000000000000000000000000000b4fde29f9bde909609d70bf9862dd65cf1", - "0x000000000000000000000000000000000005fcac9b75cac50d87ca827678c070", - "0x00000000000000000000000000000071e27b0a0dd0e2180985072f4a949f0c1d", - "0x000000000000000000000000000000000025d2d1388eddcf016213f1cadc763f", - "0x000000000000000000000000000000b216bad715cdfa7c382d30d7a368cc1346", - "0x0000000000000000000000000000000000302dbbf78b13a6d71d1978b5607145", - "0x00000000000000000000000000000002ebdec49969d2ff9220240bbcb8730617", - "0x000000000000000000000000000000000027f41cad8540e47008c1da90340ef6", - "0x000000000000000000000000000000e8259148321315cc34166a206fe910c6cb", - "0x000000000000000000000000000000000013444efc30c7688d961f36de252af6", - "0x0000000000000000000000000000005b7c7ad432291e9dff1dfad51159e50dbf", - "0x0000000000000000000000000000000000205ec973a0d1c898c1def7852353b3", - "0x0000000000000000000000000000007940a7e88fe5ce47af688975c92be1b62a", - "0x000000000000000000000000000000000015bdab44fe41eec6ee62ed58f55ff5", - "0x0000000000000000000000000000003693b90aedcd664eede665df6f376cf526", - "0x0000000000000000000000000000000000207c38fd6851d1568fe18a83585f31", - "0x000000000000000000000000000000f1a8a60975b9b092aab1421166be08c2f5", - "0x000000000000000000000000000000000015450d2e8ea17db209302582b886f1", - "0x000000000000000000000000000000526e857040a344bd434bfdbf94d3a49196", - "0x00000000000000000000000000000000000d0112b922a852c4754ab3929d6d02", - "0x000000000000000000000000000000d88041fa28c8118a58ceacbcc8780844b5", - "0x00000000000000000000000000000000002584170ebef150b71c5e6aa93e2fbb", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a2c4fbcbebac01e208127093cbf44780d4", - "0x00000000000000000000000000000000001ca34545a074b1cb689aa0b343402d", - "0x000000000000000000000000000000a58c28598055d8818a6dbadd0018904386", - "0x0000000000000000000000000000000000152154cbc213630f5c7ec1ee37751b" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000f944590031f1d3b251c3dc90ea2821c71d", + "0x00000000000000000000000000000000000d31fd1a4942efade625e012c77df1", + "0x0000000000000000000000000000001e9acd89b92c18e3d89b881b26312bb12b", + "0x000000000000000000000000000000000000736f00a23cbea07da614d8b767e4", + "0x00000000000000000000000000000012167fb1f0d3b9afea7d534404e3b36b53", + "0x0000000000000000000000000000000000021e6d056d0d40c720927abd39c872", + "0x0000000000000000000000000000004ea3f0c21ee1056b3e2ad9c082242e5a2e", + "0x00000000000000000000000000000000000c574204fd079871ae599e192d72c8", + "0x0000000000000000000000000000002654c5b2b175f95fdb2ab405dcc4220545", + "0x00000000000000000000000000000000001fd13a35df71290c2354c6c5f610de", + "0x000000000000000000000000000000d5e3b3464d67c82f035b33016912264b04", + "0x000000000000000000000000000000000009fcdab45c12d2f313f95b94a1dcb8", + "0x000000000000000000000000000000768c5a9d8ca0081f67ff3171a7ffe3ba49", + "0x00000000000000000000000000000000001cd676b8d32bb0bb898d83a9f49a2b", + "0x00000000000000000000000000000028650bc3473de217fbfec1e9fb10e4e999", + "0x0000000000000000000000000000000000260c000ea0ebc3db3ba672328007a5", + "0x000000000000000000000000000000f1948fbf68599bf0628f118156de61f57f", + "0x00000000000000000000000000000000000033e796d200425f6a499de18dbfeb", + "0x00000000000000000000000000000016a35cf8fc5f017037adf860723e6346e5", + "0x0000000000000000000000000000000000088cf6d72197800bb1300677f734a7", + "0x00000000000000000000000000000047169c153b6cc24bbac1e4126410779ccb", + "0x000000000000000000000000000000000022b70bfb92e8c7944ae65a49b7effa", + "0x000000000000000000000000000000425c661c37104ad33c2054f3cfde9954d0", + "0x000000000000000000000000000000000000c36b8ecc5963bef022dea4dfadcc", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", + "0x000000000000000000000000000000862e0c485b99696417d296ecc2b2bac316", + "0x00000000000000000000000000000000000ae46fcce211297d2d7fcab27fc041", + "0x000000000000000000000000000000551700c158e12cb40d8ea4ef2563b6fb43", + "0x00000000000000000000000000000000000b515d88939b250a4a4758e4e2ea53", + "0x000000000000000000000000000000f4bae0ad0baeb9d42c7fe2ae3d18c98fad", + "0x00000000000000000000000000000000002a20d66bd435a17fdf1eaf345d5933", + "0x000000000000000000000000000000ed8a8ba528c7088b1ae4730572e1ec32c8", + "0x000000000000000000000000000000000009506de430d6b9f9863e6f10cd35fb", + "0x000000000000000000000000000000682b627744ce0319f4d9191675057282fb", + "0x000000000000000000000000000000000017de059961f8c12752abd299396f86", + "0x000000000000000000000000000000b975958ec262178729e94350c0e7543fb0", + "0x0000000000000000000000000000000000220ce50e394560e53f025e094d17aa", + "0x0000000000000000000000000000001fca3a68a28d438e85e9dc955856752779", + "0x000000000000000000000000000000000028f8f3400bb3b9d19b02ec709e2ee4", + "0x0000000000000000000000000000004e35d073460b0634ebe216d49a3dca9b36", + "0x00000000000000000000000000000000000cb0f5827b08075c405353f10ba632", + "0x0000000000000000000000000000001ece860550ce14fae74eda0123ded56a74", + "0x00000000000000000000000000000000000a34b258bd3daaf8f9edd201c25ed3", + "0x0000000000000000000000000000008cb28ae85d58a75302229585a9ad114c2b", + "0x000000000000000000000000000000000014aac1da344ad32659c3036510fcc1", + "0x000000000000000000000000000000822b45036d5c2befa8a20df910513570c4", + "0x000000000000000000000000000000000011244b388e709fbcb7f54658cfac43", + "0x000000000000000000000000000000389de9951eb8fad7e25e4ad0a9229d2275", + "0x0000000000000000000000000000000000136e6eb0ee251f9b12336cb7bb46ee", + "0x00000000000000000000000000000088f21d9f6c7c54ce4e9a4c103a91b54a58", + "0x0000000000000000000000000000000000187f2beab9a05ca29d2137ee7cbc19", + "0x0000000000000000000000000000009c703a5eb43dcef0686e08fa57ef452f68", + "0x000000000000000000000000000000000012caebb183f1490d3e4f2a2c583ab6", + "0x0000000000000000000000000000009dab4a0aa8d4954a8e1761db3da148a746", + "0x0000000000000000000000000000000000230a08da3b62fd6479b4230760b686", + "0x00000000000000000000000000000081a00a1e38bbd5212603f18ef982a5189d", + "0x000000000000000000000000000000000021ae0f9df38f1e70fa3c26867f4ee8", + "0x0000000000000000000000000000001a722dbd34f841b4823cd055149fce642f", + "0x000000000000000000000000000000000002df2693a9b134670cfe72bf29b363", + "0x00000000000000000000000000000007c906c328630b844b0797e34cedccd1ec", + "0x00000000000000000000000000000000002ab2ae39dd9c0259f7dfb1dda47e81", + "0x000000000000000000000000000000ac6642a4923aa2df07a00a9d3e462b0ed1", + "0x000000000000000000000000000000000015afb7af6c0fc23a24457aa887df9c", + "0x0000000000000000000000000000004d916ec23ef29c0b6134f208e3535671d4", + "0x00000000000000000000000000000000000d37c6c25852903d79475133d414e8", + "0x00000000000000000000000000000029ad212431ba1972de7ee0ba9f12113be3", + "0x000000000000000000000000000000000005c2393db23155844d4f71bead84d0", + "0x000000000000000000000000000000c69074efa82a4910eaf8ab8689d7aafcad", + "0x000000000000000000000000000000000029f3d77437006a0eacf1a149c4b8a0", + "0x00000000000000000000000000000030926853da69d4016eca2f1f0df5e5316f", + "0x000000000000000000000000000000000014841d3291aecd45ea0e05657dbed2", + "0x00000000000000000000000000000052fdb060fe666a3f686088f1f6996a1cf9", + "0x00000000000000000000000000000000002be878eb09939603b391aa9ee0393a", + "0x000000000000000000000000000000d99de3b49476e64c0138037838cfc63803", + "0x0000000000000000000000000000000000260874b43f32c373783efe7ef200a2", + "0x0000000000000000000000000000004951edbb25e9c6b65d446e3418b2b3f16e", + "0x00000000000000000000000000000000002300fac13ab48d40a91114d1ff9627", + "0x00000000000000000000000000000090b8d216da73861ee276dddb17428d8c09", + "0x000000000000000000000000000000000028f906106984e5fa78812869cc1aee", + "0x000000000000000000000000000000ce2aff6eda49d5b8be6ee42104d2aa21e0", + "0x000000000000000000000000000000000002833f671993d2b772b5dec0e12056", + "0x0000000000000000000000000000008be4e7cfb1fdf317a33b7bc3530625e6b8", + "0x000000000000000000000000000000000023404bed8e224a350755410e5c96b2", + "0x000000000000000000000000000000cd9a812fad3fe3a89983e416b70529445b", + "0x00000000000000000000000000000000000b66296ff191a2cf6dbe6ca03dcd0c", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003e895e3756deb16393c59a6a9d3669ce0f", + "0x0000000000000000000000000000000000262d7f27b9058ca9bd2e0620f9a3d3", + "0x000000000000000000000000000000b98c4ce00d755cb57daf4bc1b860536fc3", + "0x0000000000000000000000000000000000017137ecc6753555f49859a34eeb62" ] - hash = "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6" + hash = "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead" diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr index 58b47bf68d13..00910d1f1907 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr @@ -1,15 +1,20 @@ -use crate::{point::Point, traits::{Deserialize, Empty, Serialize}}; +use crate::traits::{Deserialize, Empty, Serialize}; use std::meta::derive; +/// A request from an app circuit to the kernel for validation of a siloed app secret key. +/// +/// The master public key is exposed only as its [`hash_public_key`](crate::public_keys::hash_public_key) digest -- apps +/// must not see the raw point. The kernel reset circuit derives the point from the master secret +/// key hint, hashes it, and asserts equality with `pk_m_hash`. #[derive(Deserialize, Eq, Serialize)] pub struct KeyValidationRequest { - pub pk_m: Point, + pub pk_m_hash: Field, pub sk_app: Field, // not a grumpkin scalar because it's output of poseidon2 } impl Empty for KeyValidationRequest { fn empty() -> Self { - KeyValidationRequest { pk_m: Point::empty(), sk_app: 0 } + KeyValidationRequest { pk_m_hash: 0, sk_app: 0 } } } @@ -17,15 +22,12 @@ mod test { use crate::{ abis::validation_requests::key_validation_request::KeyValidationRequest, constants::KEY_VALIDATION_REQUEST_LENGTH, - point::Point, traits::{Deserialize, Serialize}, }; #[test] fn serialization_of_key_validation_request() { - let item = KeyValidationRequest { pk_m: Point::deserialize([123, 456, 0]), sk_app: 789 }; - // We use the KEY_VALIDATION_REQUEST_LENGTH constant to ensure that there is a match between the derived trait - // implementation and the constant. + let item = KeyValidationRequest { pk_m_hash: 123, sk_app: 789 }; let serialized: [Field; KEY_VALIDATION_REQUEST_LENGTH] = item.serialize(); let deserialized = KeyValidationRequest::deserialize(serialized); assert_eq(item, deserialized); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_separator.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_separator.nr index 55cdaa6a4b1e..ca4f7e1b93b2 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_separator.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_separator.nr @@ -34,14 +34,13 @@ mod test { key_validation_request_and_separator::KeyValidationRequestAndSeparator, }, constants::KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH, - point::Point, traits::{Deserialize, Serialize}, }; #[test] fn serialization_of_key_validation_request_and_separator() { let non_empty_item = KeyValidationRequestAndSeparator { - request: KeyValidationRequest { pk_m: Point::deserialize([123, 456, 0]), sk_app: 789 }, + request: KeyValidationRequest { pk_m_hash: 123, sk_app: 789 }, key_type_domain_separator: 789, }; let serialized: [Field; KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH] = diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr index 312ae5bb5c58..fc6063570354 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr @@ -2,15 +2,15 @@ use crate::{ address::{ partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash, }, - constants::{AZTEC_ADDRESS_LENGTH, DOM_SEP__CONTRACT_ADDRESS_V1, MAX_FIELD_VALUE}, + constants::{AZTEC_ADDRESS_LENGTH, DOM_SEP__CONTRACT_ADDRESS_V2, MAX_FIELD_VALUE}, contract_class_id::ContractClassId, hash::poseidon2_hash_with_separator, - public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, ToPoint, TpkM}, + public_keys::{hash_public_key, IvpkM, PublicKeys, ToPoint}, traits::{Deserialize, Empty, FromField, Packable, Serialize, ToField}, utils::field::sqrt, }; -use crate::point::Point; +use crate::point::EmbeddedCurvePoint; use crate::public_keys::AddressPoint; use std::{ @@ -66,7 +66,7 @@ impl AztecAddress { // positive one (where y <= (r - 1) / 2) by negating it. let final_y = if Self::is_positive(y) { y } else { -y }; - AddressPoint { inner: Point { x: self.inner, y: final_y, is_infinite: false } } + AddressPoint { inner: EmbeddedCurvePoint { x: self.inner, y: final_y } } }) } @@ -112,15 +112,15 @@ impl AztecAddress { // / \ . // / \ . // partial_address public_keys_hash . - // / \ / / \ \ . - // / \ Npk_m Ivpk_m Ovpk_m Tpk_m . + // / \ / / \ \ . + // / \ npk_m_hash Ivpk_m ovpk_m_hash tpk_m_hash // contract_class_id \ |................... // / | \ \ - // artifact_hash | public_bytecode_commitment salted_initialization_hash - // | / / \ - // private_function_tree_root deployer_address salt initialization_hash - // / \ / \ - // ... ... constructor_fn_selector constructor_args_hash + // artifact_hash | public_bytecode_commitment salted_initialization_hash + // | / / \ \ + // private_function_tree_root salt initialization_hash deployer_address immutables_hash + // / \ / \ + // ... ... constructor_fn_selector constructor_args_hash // / \ // / \ / \ // leaf leaf leaf leaf @@ -134,15 +134,13 @@ impl AztecAddress { let pre_address = poseidon2_hash_with_separator( [public_keys_hash.to_field(), partial_address.to_field()], - DOM_SEP__CONTRACT_ADDRESS_V1, + DOM_SEP__CONTRACT_ADDRESS_V2, ); // Note: `.add()` will fail within the blackbox fn if either of the points are not on the curve. (See tests below). - // TODO(F-553): Drop the `.to_embedded()` / `.into()` round-trip once the custom `Point` wrapper is removed and - // we use `EmbeddedCurvePoint` directly. - let address_point: Point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)) - .add(public_keys.ivpk_m.to_point().to_embedded()) - .into(); + let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add( + public_keys.ivpk_m.to_point(), + ); // 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 // 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. @@ -195,73 +193,55 @@ fn check_is_positive() { // because the blackbox function does this check for us. #[test(should_fail_with = "is not on curve")] fn check_embedded_curve_point_add() { - // Choose a point not on the curve: - let p1 = Point { x: 1, y: 1, is_infinite: false }; - let p2 = Point::generator(); - let _ = p1 + p2; -} - -// Gives us confidence that we don't need to manually check that the input public keys need to be on the curve for `add`, -// because the blackbox function does this check for us. -#[test(should_fail_with = "is not on curve")] -fn check_embedded_curve_point_add_2() { // Choose a point not on the curve in the 2nd position. - let p1 = Point::generator(); - let p2 = Point { x: 1, y: 1, is_infinite: false }; - let _ = p1 + p2; + let p1 = EmbeddedCurvePoint::generator(); + let key = IvpkM { inner: EmbeddedCurvePoint { x: 1, y: 1 } }; + let _ = p1 + key.to_point(); } #[test] fn compute_address_from_partial_and_pub_keys() { + let npk_m_point = EmbeddedCurvePoint { + x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab, + y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7, + }; + let ovpk_m_point = EmbeddedCurvePoint { + x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484, + y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b, + }; + let tpk_m_point = EmbeddedCurvePoint { + x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762, + y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a, + }; + let public_keys = PublicKeys { - npk_m: NpkM { - inner: Point { - x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab, - y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7, - is_infinite: false, - }, - }, + npk_m_hash: hash_public_key(npk_m_point), ivpk_m: IvpkM { - inner: Point { + inner: EmbeddedCurvePoint { x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e, y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95, - is_infinite: false, - }, - }, - ovpk_m: OvpkM { - inner: Point { - x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484, - y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b, - is_infinite: false, - }, - }, - tpk_m: TpkM { - inner: Point { - x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762, - y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a, - is_infinite: false, }, }, + ovpk_m_hash: hash_public_key(ovpk_m_point), + tpk_m_hash: hash_public_key(tpk_m_point), }; let partial_address = PartialAddress::from_field( 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de, ); - let address = AztecAddress::compute(public_keys, partial_address); + let address = AztecAddress::compute(public_keys, partial_address).to_field(); - // The following value was generated by `derivation.test.ts`. - // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data. let expected_computed_address_from_partial_and_pubkeys = - 0x2f66081d4bb077fbe8e8abe96a3516a713a3d7e34360b4e985da0da95092b37d; - assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys); + 0x05f9c48c02e4dbd18d7e165f999c3b8426abb1911476f48e68deef42475d6145; + assert_eq(address, expected_computed_address_from_partial_and_pubkeys); } #[test] fn compute_preaddress_from_partial_and_pub_keys() { - let pre_address = poseidon2_hash_with_separator([1, 2], DOM_SEP__CONTRACT_ADDRESS_V1); + let pre_address = poseidon2_hash_with_separator([1, 2], DOM_SEP__CONTRACT_ADDRESS_V2); let expected_computed_preaddress_from_partial_and_pubkey = - 0x286c7755f2924b1e53b00bcaf1adaffe7287bd74bba7a02f4ab867e3892d28da; + 0x0fa1c698858df1a99170cd39d5f4bfad6d0d60f1f8afa3dc92281ee60b36f3bb; assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr index e2698c8475e7..cd5f1f9fb95f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr @@ -35,10 +35,11 @@ impl PartialAddress { salt: Field, initialization_hash: Field, deployer: AztecAddress, + immutables_hash: Field, ) -> Self { PartialAddress::compute_from_salted_initialization_hash( contract_class_id, - SaltedInitializationHash::compute(salt, initialization_hash, deployer), + SaltedInitializationHash::compute(salt, initialization_hash, deployer, immutables_hash), ) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr index 4f09babab178..8b50410bfabd 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr @@ -20,9 +20,14 @@ impl SaltedInitializationHash { Self { inner: field } } - pub fn compute(salt: Field, initialization_hash: Field, deployer: AztecAddress) -> Self { + pub fn compute( + salt: Field, + initialization_hash: Field, + deployer: AztecAddress, + immutables_hash: Field, + ) -> Self { SaltedInitializationHash::from_field(poseidon2_hash_with_separator( - [salt, initialization_hash, deployer.to_field()], + [salt, initialization_hash, deployer.to_field(), immutables_hash], DOM_SEP__SALTED_INITIALIZATION_HASH, )) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 027f1e7ef243..d204616a106b 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -291,6 +291,16 @@ pub global DEFAULT_TPK_M_X: Field = pub global DEFAULT_TPK_M_Y: Field = 0x2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f; +// Precomputed `hash_public_key(Point { DEFAULT_*_X, DEFAULT_*_Y })` for each non-ivpk key. +// Used by `PublicKeys::default()` and the matching TS `PublicKeys.default()`. Verified by the +// `compute_default_hash` test in public_keys.nr. +pub global DEFAULT_NPK_M_HASH: Field = + 0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26; +pub global DEFAULT_OVPK_M_HASH: Field = + 0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b; +pub global DEFAULT_TPK_M_HASH: Field = + 0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0; + // LENGTH OF STRUCTS SERIALIZED TO FIELDS // TODO: figure out whether Noir is sophisticated enough to derive these for us, these days. pub global AZTEC_ADDRESS_LENGTH: u32 = 1; @@ -301,7 +311,7 @@ pub global GAS_SETTINGS_LENGTH: u32 = GAS_LENGTH /* gas_limits */ + GAS_FEES_LENGTH /* max_fees_per_gas */ + GAS_FEES_LENGTH /* max_priority_fees_per_gas */; pub global CALL_CONTEXT_LENGTH: u32 = 4; -pub global CONTRACT_INSTANCE_LENGTH: u32 = 16; +pub global CONTRACT_INSTANCE_LENGTH: u32 = 10; pub global CONTRACT_STORAGE_READ_LENGTH: u32 = 3; pub global CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: u32 = 3; pub global ETH_ADDRESS_LENGTH: u32 = 1; @@ -329,7 +339,7 @@ pub global L2_TO_L1_MESSAGE_LENGTH: u32 = 1 /* recipient */ + 1 /* content */; pub global COUNTED_L2_TO_L1_MESSAGE_LENGTH: u32 = L2_TO_L1_MESSAGE_LENGTH + 1; pub global SCOPED_L2_TO_L1_MESSAGE_LENGTH: u32 = L2_TO_L1_MESSAGE_LENGTH + 1; pub global SCOPED_COUNTED_L2_TO_L1_MESSAGE_LENGTH: u32 = COUNTED_L2_TO_L1_MESSAGE_LENGTH + 1; -pub global KEY_VALIDATION_REQUEST_LENGTH: u32 = 4; +pub global KEY_VALIDATION_REQUEST_LENGTH: u32 = 2; pub global KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = KEY_VALIDATION_REQUEST_LENGTH + 1; pub global SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH + 1; @@ -748,11 +758,12 @@ pub global DOM_SEP__IVSK_M: u32 = 2747825907; pub global DOM_SEP__OVSK_M: u32 = 4272201051; pub global DOM_SEP__TSK_M: u32 = 1546190975; pub global DOM_SEP__PUBLIC_KEYS_HASH: u32 = 777457226; +pub global DOM_SEP__SINGLE_PUBLIC_KEY_HASH: u32 = 3452068255; // Address pub global DOM_SEP__PARTIAL_ADDRESS: u32 = 2103633018; -pub global DOM_SEP__CONTRACT_ADDRESS_V1: u32 = 1788365517; +pub global DOM_SEP__CONTRACT_ADDRESS_V2: u32 = 4099338721; // --------------------------------------------------------------- @@ -1240,7 +1251,7 @@ pub global AVM_DEBUGLOG_BASE_L2_GAS: u32 = 9; pub global AVM_POSEIDON2_BASE_L2_GAS: u32 = 24 * 15; // SLOW_SIM_MUL = 15 pub global AVM_SHA256COMPRESSION_BASE_L2_GAS: u32 = 12288; pub global AVM_KECCAKF1600_BASE_L2_GAS: u32 = 58176; -pub global AVM_ECADD_BASE_L2_GAS: u32 = 27 * 10; // SLOW_SIM_MUL = 10 +pub global AVM_ECADD_BASE_L2_GAS: u32 = 18 * 10; // SLOW_SIM_MUL = 10 pub global AVM_TORADIXBE_BASE_L2_GAS: u32 = 24; // Dynamic L2 GAS diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr index e4415d7b4b95..24f79b64b047 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -9,11 +9,11 @@ use crate::{ DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_NULLIFIER, DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOB_CHALLENGE_Z, DOM_SEP__BLOB_GAMMA_ACC, DOM_SEP__BLOB_GAMMA_FINAL, DOM_SEP__BLOB_HASHED_Y_LIMBS, DOM_SEP__BLOB_Z_ACC, - DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONTRACT_ADDRESS_V1, + DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONTRACT_ADDRESS_V2, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FUNCTION_ARGS, - DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, - DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, + DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, DOM_SEP__IVSK_M, + DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, @@ -25,9 +25,10 @@ use crate::{ DOM_SEP__PUBLIC_LEAF_SLOT, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, DOM_SEP__PUBLIC_TX_HASH, DOM_SEP__RETRIEVED_BYTECODES_MERKLE, DOM_SEP__SALTED_INITIALIZATION_HASH, DOM_SEP__SECRET_HASH, DOM_SEP__SIGNATURE_PAYLOAD, DOM_SEP__SILOED_NOTE_HASH, - DOM_SEP__SILOED_NULLIFIER, DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, DOM_SEP__TSK_M, - DOM_SEP__TX_NULLIFIER, DOM_SEP__TX_REQUEST, DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, - DOM_SEP__UNIQUE_NOTE_HASH, DOM_SEP__WRITTEN_SLOTS_MERKLE, NULL_MSG_SENDER_CONTRACT_ADDRESS, + DOM_SEP__SILOED_NULLIFIER, DOM_SEP__SINGLE_PUBLIC_KEY_HASH, + DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, DOM_SEP__TSK_M, DOM_SEP__TX_NULLIFIER, + DOM_SEP__TX_REQUEST, DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, DOM_SEP__UNIQUE_NOTE_HASH, + DOM_SEP__WRITTEN_SLOTS_MERKLE, NULL_MSG_SENDER_CONTRACT_ADDRESS, SIDE_EFFECT_MASKING_ADDRESS, TX_START_PREFIX, }, hash::poseidon2_hash_bytes, @@ -142,7 +143,7 @@ impl HashedValueTester::new(); + let mut tester = HashedValueTester::<71, 64>::new(); // ----------------- // Domain separators @@ -193,8 +194,9 @@ fn hashed_values_match_derived() { tester.assert_dom_sep_matches_derived(DOM_SEP__OVSK_M, "ovsk_m"); tester.assert_dom_sep_matches_derived(DOM_SEP__TSK_M, "tsk_m"); tester.assert_dom_sep_matches_derived(DOM_SEP__PUBLIC_KEYS_HASH, "public_keys_hash"); + tester.assert_dom_sep_matches_derived(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, "single_public_key_hash"); tester.assert_dom_sep_matches_derived(DOM_SEP__PARTIAL_ADDRESS, "partial_address"); - tester.assert_dom_sep_matches_derived(DOM_SEP__CONTRACT_ADDRESS_V1, "contract_address_v1"); + tester.assert_dom_sep_matches_derived(DOM_SEP__CONTRACT_ADDRESS_V2, "contract_address_v2"); tester.assert_dom_sep_matches_derived(DOM_SEP__BLOCK_HEADER_HASH, "block_header_hash"); tester.assert_dom_sep_matches_derived(DOM_SEP__TX_REQUEST, "tx_request"); tester.assert_dom_sep_matches_derived(DOM_SEP__PUBLIC_TX_HASH, "public_tx_hash"); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr b/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr index fa2ce232d0a3..f96851c0d0a1 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr @@ -12,6 +12,7 @@ pub struct ContractInstance { pub deployer: AztecAddress, pub contract_class_id: ContractClassId, pub initialization_hash: Field, + pub immutables_hash: Field, pub public_keys: PublicKeys, } @@ -30,6 +31,7 @@ impl ContractInstance { self.salt, self.initialization_hash, self.deployer, + self.immutables_hash, ), ) } @@ -52,6 +54,7 @@ mod test { deployer: AztecAddress::from_field(12), contract_class_id: ContractClassId::from_field(13), initialization_hash: 156, + immutables_hash: 789, public_keys: PublicKeys::default(), }; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/point.nr b/noir-projects/noir-protocol-circuits/crates/types/src/point.nr index 289ee5fcb2b1..c5ea3b076b2c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/point.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/point.nr @@ -1,174 +1,12 @@ -use crate::{ - hash::poseidon2_hash, - traits::{Deserialize, Empty, Hash, Packable, Serialize}, - utils::{reader::Reader, writer::Writer}, -}; -use std::embedded_curve_ops::EmbeddedCurvePoint; +pub use std::embedded_curve_ops::EmbeddedCurvePoint; -pub global POINT_LENGTH: u32 = 3; - -// TODO(F-553): This custom `Point` struct is a temporary workaround. A newer version of Noir dropped the `is_infinite` -// field from `EmbeddedCurvePoint` and changed its serialization from 3 fields to 2. To preserve backwards compatibility -// of our onchain serialization format we re-introduced our own `Point` that wraps `EmbeddedCurvePoint` and keeps the -// old 3-field layout. Once we're ready to take the breaking change (e.g. alongside the v5 oracle changes), delete this -// struct, use `EmbeddedCurvePoint` directly and reduce `POINT_LENGTH` to 2. -pub struct Point { - pub x: Field, - pub y: Field, - pub is_infinite: bool, -} - -impl Point { - pub fn generator() -> Self { - let g = EmbeddedCurvePoint::generator(); - Point { x: g.x, y: g.y, is_infinite: false } - } - - pub fn point_at_infinity() -> Self { - Point { x: 0, y: 0, is_infinite: true } - } - - pub fn double(self) -> Self { - self.to_embedded().double().into() - } - - pub fn to_embedded(self) -> EmbeddedCurvePoint { - EmbeddedCurvePoint { x: self.x, y: self.y } - } -} - -impl From for Point { - fn from(p: EmbeddedCurvePoint) -> Self { - Point { x: p.x, y: p.y, is_infinite: p.is_infinite() } - } -} - -impl std::ops::Add for Point { - fn add(self, other: Point) -> Point { - (self.to_embedded() + other.to_embedded()).into() - } -} - -impl std::ops::Sub for Point { - fn sub(self, other: Point) -> Point { - (self.to_embedded() - other.to_embedded()).into() - } -} - -impl std::ops::Neg for Point { - fn neg(self) -> Point { - Point { x: self.x, y: -self.y, is_infinite: self.is_infinite } - } -} - -impl Eq for Point { - fn eq(self, other: Point) -> bool { - (self.x == other.x) & (self.y == other.y) & (self.is_infinite == other.is_infinite) - } -} - -impl Hash for Point { - fn hash(self) -> Field { - poseidon2_hash(self.serialize()) - } -} - -impl Empty for Point { - /// Note: Does not return a valid point on curve - instead represents an empty/"unpopulated" point struct (e.g. - /// empty/unpopulated value in an array of points). - fn empty() -> Self { - Point { x: 0, y: 0, is_infinite: false } - } -} - -impl Serialize for Point { - let N: u32 = POINT_LENGTH; - - fn serialize(self) -> [Field; Self::N] { - [self.x, self.y, self.is_infinite as Field] - } - - fn stream_serialize(self, writer: &mut Writer) { - writer.write(self.x); - writer.write(self.y); - writer.write(self.is_infinite as Field); - } -} - -impl Deserialize for Point { - let N: u32 = POINT_LENGTH; - - fn deserialize(fields: [Field; Self::N]) -> Self { - Point { x: fields[0], y: fields[1], is_infinite: fields[2] != 0 } - } - - #[inline_always] - fn stream_deserialize(reader: &mut Reader) -> Self { - Point { x: reader.read(), y: reader.read(), is_infinite: reader.read_bool() } - } -} - -pub fn validate_on_curve(p: Point) { +/// Validates that the given point exists on the Grumpkin curve. +pub fn validate_on_curve(p: EmbeddedCurvePoint) { // y^2 == x^3 - 17 let x = p.x; let y = p.y; - if p.is_infinite { - // Assert the canonical representation of infinity - assert_eq(x, 0, "Point at infinity should have canonical representation (0 0)"); - assert_eq(y, 0, "Point at infinity should have canonical representation (0 0)"); - } else { + // p.is_infinite() <==> x == y == 0, considered on the curve: + if !p.is_infinite() { assert_eq(y * y, x * x * x - 17, "Point not on curve"); } } - -// TODO(#11356): use compact representation here. -impl Packable for Point { - let N: u32 = POINT_LENGTH; - - fn pack(self) -> [Field; Self::N] { - self.serialize() - } - - fn unpack(packed: [Field; Self::N]) -> Self { - Self::deserialize(packed) - } -} - -mod tests { - use super::{Point, validate_on_curve}; - - #[test] - unconstrained fn test_validate_on_curve_generator() { - // The generator point should be on the curve - let generator = Point::generator(); - validate_on_curve(generator); - } - - #[test] - unconstrained fn test_validate_on_curve_infinity() { - // Canonical infinite point (x=0, y=0) should pass - let infinity = Point { x: 0, y: 0, is_infinite: true }; - validate_on_curve(infinity); - } - - #[test(should_fail_with = "Point not on curve")] - unconstrained fn test_validate_on_curve_invalid_point() { - // A point not on the curve should fail - let invalid = Point { x: 1, y: 1, is_infinite: false }; - validate_on_curve(invalid); - } - - #[test(should_fail_with = "Point at infinity should have canonical representation (0 0)")] - unconstrained fn test_validate_on_curve_infinity_non_canonical_x() { - // Infinite point with non-zero x should fail - let invalid_infinity = Point { x: 1, y: 0, is_infinite: true }; - validate_on_curve(invalid_infinity); - } - - #[test(should_fail_with = "Point at infinity should have canonical representation (0 0)")] - unconstrained fn test_validate_on_curve_infinity_non_canonical_y() { - // Infinite point with non-zero y should fail - let invalid_infinity = Point { x: 0, y: 1, is_infinite: true }; - validate_on_curve(invalid_infinity); - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr b/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr index 4aa7bdd77d45..c312b1a557f8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr @@ -1,101 +1,67 @@ use crate::{ address::public_keys_hash::PublicKeysHash, constants::{ - DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, DEFAULT_NPK_M_X, DEFAULT_NPK_M_Y, DEFAULT_OVPK_M_X, - DEFAULT_OVPK_M_Y, DEFAULT_TPK_M_X, DEFAULT_TPK_M_Y, DOM_SEP__PUBLIC_KEYS_HASH, + DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, DEFAULT_NPK_M_HASH, DEFAULT_OVPK_M_HASH, + DEFAULT_TPK_M_HASH, DOM_SEP__PUBLIC_KEYS_HASH, DOM_SEP__SINGLE_PUBLIC_KEY_HASH, }, hash::poseidon2_hash_with_separator, - point::validate_on_curve, + point::{EmbeddedCurvePoint, validate_on_curve}, traits::{Deserialize, Hash, Serialize}, }; -use crate::point::Point; use std::{default::Default, meta::derive}; pub trait ToPoint { - fn to_point(self) -> Point; + fn to_point(self) -> EmbeddedCurvePoint; } -#[derive(Deserialize, Eq, Serialize)] -pub struct NpkM { - pub inner: Point, -} - -impl ToPoint for NpkM { - fn to_point(self) -> Point { - self.inner - } -} - -// Note: If we store npk_m_hash directly we can remove this trait implementation. See #8091 -impl Hash for NpkM { - fn hash(self) -> Field { - self.inner.hash() - } +/// Hashes a public key point under the canonical single-public-key domain separator. +/// +/// Defined as `Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, x, y)`. +pub fn hash_public_key(p: EmbeddedCurvePoint) -> Field { + poseidon2_hash_with_separator([p.x, p.y], DOM_SEP__SINGLE_PUBLIC_KEY_HASH as Field) } #[derive(Deserialize, Eq, Serialize)] pub struct IvpkM { - pub inner: Point, + pub inner: EmbeddedCurvePoint, } impl ToPoint for IvpkM { - fn to_point(self) -> Point { + fn to_point(self) -> EmbeddedCurvePoint { self.inner } } -#[derive(Deserialize, Eq, Serialize)] -pub struct OvpkM { - pub inner: Point, -} - -impl Hash for OvpkM { +impl Hash for IvpkM { fn hash(self) -> Field { - self.inner.hash() - } -} - -impl ToPoint for OvpkM { - fn to_point(self) -> Point { - self.inner - } -} - -#[derive(Deserialize, Eq, Serialize)] -pub struct TpkM { - pub inner: Point, -} - -impl ToPoint for TpkM { - fn to_point(self) -> Point { - self.inner + hash_public_key(self.inner) } } +/// A non-owner's view of an account's master public keys. +/// +/// `npk_m_hash`, `ovpk_m_hash`, and `tpk_m_hash` are the [`hash_public_key`] digests of the +/// underlying points. The points themselves are not exposed here -- they are only known to the +/// owner. `ivpk_m` remains a point because address derivation (encrypt-to-address) requires the +/// raw point in-circuit. #[derive(Deserialize, Eq, Serialize)] pub struct PublicKeys { - pub npk_m: NpkM, + pub npk_m_hash: Field, pub ivpk_m: IvpkM, - pub ovpk_m: OvpkM, - pub tpk_m: TpkM, + pub ovpk_m_hash: Field, + pub tpk_m_hash: Field, } impl Default for PublicKeys { fn default() -> Self { PublicKeys { - npk_m: NpkM { - inner: Point { x: DEFAULT_NPK_M_X, y: DEFAULT_NPK_M_Y, is_infinite: false }, - }, + npk_m_hash: DEFAULT_NPK_M_HASH, ivpk_m: IvpkM { - inner: Point { x: DEFAULT_IVPK_M_X, y: DEFAULT_IVPK_M_Y, is_infinite: false }, - }, - ovpk_m: OvpkM { - inner: Point { x: DEFAULT_OVPK_M_X, y: DEFAULT_OVPK_M_Y, is_infinite: false }, - }, - tpk_m: TpkM { - inner: Point { x: DEFAULT_TPK_M_X, y: DEFAULT_TPK_M_Y, is_infinite: false }, + inner: EmbeddedCurvePoint { x: DEFAULT_IVPK_M_X, y: DEFAULT_IVPK_M_Y }, }, + ovpk_m_hash: DEFAULT_OVPK_M_HASH, + tpk_m_hash: DEFAULT_TPK_M_HASH, } } } @@ -103,70 +69,97 @@ impl Default for PublicKeys { impl PublicKeys { pub fn hash(self) -> PublicKeysHash { PublicKeysHash::from_field(poseidon2_hash_with_separator( - self.serialize(), + [self.npk_m_hash, self.ivpk_m.hash(), self.ovpk_m_hash, self.tpk_m_hash], DOM_SEP__PUBLIC_KEYS_HASH as Field, )) } + /// Validates that the (only) point-form key, `ivpk_m`, lies on the Grumpkin curve. + /// + /// The other three keys are exposed only as hashes and are unverifiable on-circuit; the PXE + /// is responsible for ensuring they were derived from on-curve points before persistence. pub fn validate_on_curve(self) { - validate_on_curve(self.npk_m.inner); validate_on_curve(self.ivpk_m.inner); - validate_on_curve(self.ovpk_m.inner); - validate_on_curve(self.tpk_m.inner); } + /// Validates that `ivpk_m` is not the point at infinity. + /// + /// As with [`Self::validate_on_curve`], the other three keys are now exposed only as hashes + /// and this property must be enforced PXE-side. pub fn validate_non_infinity(self) { - assert_eq(self.npk_m.inner.is_infinite, false, "NpkM is the point at infinity"); - assert_eq(self.ivpk_m.inner.is_infinite, false, "IvpkM is the point at infinity"); - assert_eq(self.ovpk_m.inner.is_infinite, false, "OvpkM is the point at infinity"); - assert_eq(self.tpk_m.inner.is_infinite, false, "TpkM is the point at infinity"); + assert_eq(self.ivpk_m.inner.is_infinite(), false, "IvpkM is the point at infinity"); } } pub struct AddressPoint { - pub inner: Point, + pub inner: EmbeddedCurvePoint, } impl ToPoint for AddressPoint { - fn to_point(self) -> Point { + fn to_point(self) -> EmbeddedCurvePoint { self.inner } } mod test { - use crate::point::Point; + use crate::constants::{ + DEFAULT_NPK_M_HASH, DEFAULT_NPK_M_X, DEFAULT_NPK_M_Y, DEFAULT_OVPK_M_HASH, DEFAULT_OVPK_M_X, + DEFAULT_OVPK_M_Y, DEFAULT_TPK_M_HASH, DEFAULT_TPK_M_X, DEFAULT_TPK_M_Y, + }; use crate::{ - point::POINT_LENGTH, - public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, TpkM}, + point::EmbeddedCurvePoint, + public_keys::{hash_public_key, IvpkM, PublicKeys}, traits::{Deserialize, Serialize}, }; - use std::ops::Neg; + + global PUBLIC_KEYS_LENGTH: u32 = 5; + + /// Catches drift between the precomputed `DEFAULT_*_M_HASH` constants and the + /// `DEFAULT_*_M_X/Y` curve points they're derived from. If anyone updates the X/Y + /// constants (or the hashing primitive) without also updating the *_HASH constants, + /// this test fails and `PublicKeys::default()` would silently produce a stale value. + #[test] + unconstrained fn default_hashes_match_default_points() { + let npk = hash_public_key( + EmbeddedCurvePoint { x: DEFAULT_NPK_M_X, y: DEFAULT_NPK_M_Y }, + ); + assert_eq(npk, DEFAULT_NPK_M_HASH); + + let ovpk = hash_public_key( + EmbeddedCurvePoint { x: DEFAULT_OVPK_M_X, y: DEFAULT_OVPK_M_Y }, + ); + assert_eq(ovpk, DEFAULT_OVPK_M_HASH); + + let tpk = hash_public_key( + EmbeddedCurvePoint { x: DEFAULT_TPK_M_X, y: DEFAULT_TPK_M_Y }, + ); + assert_eq(tpk, DEFAULT_TPK_M_HASH); + } #[test] unconstrained fn compute_public_keys_hash() { let keys = PublicKeys { - npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } }, - ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } }, - ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } }, - tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } }, + npk_m_hash: 11, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } }, + ovpk_m_hash: 22, + tpk_m_hash: 33, }; - let actual = keys.hash(); + let actual = keys.hash().to_field(); - // The following value was generated by `public_keys.test.ts`. let expected_public_keys_hash = - 0x056998309f6c119e4d753e404f94fef859dddfa530a9379634ceb0854b29bf7a; + 0x0b8c7b67576d3ac859a7fab578b2b2e305c67eba9e133b0fa46af8d19a50b8fc; - assert(actual.to_field() == expected_public_keys_hash); + assert_eq(actual, expected_public_keys_hash); } #[test] unconstrained fn test_validate_on_curve() { let keys = PublicKeys { - npk_m: NpkM { inner: Point::generator() }, - ivpk_m: IvpkM { inner: Point::generator().double() }, - ovpk_m: OvpkM { inner: Point::generator().neg() }, - tpk_m: TpkM { inner: Point::generator() + Point::generator().double() }, + npk_m_hash: 0, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint::generator().double() }, + ovpk_m_hash: 0, + tpk_m_hash: 0, }; keys.validate_on_curve(); @@ -175,10 +168,10 @@ mod test { #[test(should_fail_with = "Point not on curve")] unconstrained fn test_validate_not_on_curve() { let keys = PublicKeys { - npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } }, - ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } }, - ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } }, - tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } }, + npk_m_hash: 0, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } }, + ovpk_m_hash: 0, + tpk_m_hash: 0, }; keys.validate_on_curve(); @@ -187,22 +180,22 @@ mod test { #[test] unconstrained fn test_validate_non_infinity() { let keys = PublicKeys { - npk_m: NpkM { inner: Point::generator() }, - ivpk_m: IvpkM { inner: Point::generator().double() }, - ovpk_m: OvpkM { inner: Point::generator().neg() }, - tpk_m: TpkM { inner: Point::generator() + Point::generator().double() }, + npk_m_hash: 0, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint::generator().double() }, + ovpk_m_hash: 0, + tpk_m_hash: 0, }; keys.validate_non_infinity(); } - #[test(should_fail_with = "TpkM is the point at infinity")] + #[test(should_fail_with = "IvpkM is the point at infinity")] unconstrained fn test_validate_infinity() { let keys = PublicKeys { - npk_m: NpkM { inner: Point::generator() }, - ivpk_m: IvpkM { inner: Point::generator().double() }, - ovpk_m: OvpkM { inner: Point::generator().neg() }, - tpk_m: TpkM { inner: Point::point_at_infinity() }, + npk_m_hash: 0, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint::point_at_infinity() }, + ovpk_m_hash: 0, + tpk_m_hash: 0, }; keys.validate_non_infinity(); @@ -212,26 +205,24 @@ mod test { unconstrained fn compute_default_hash() { let keys = PublicKeys::default(); - let actual = keys.hash(); + let actual = keys.hash().to_field(); - // The following value was generated by `public_keys.test.ts`. let test_data_default_hash = - 0x023547e676dba19784188825b901a0e70d8ad978300d21d6185a54281b734da0; + 0x147a900f3e1abdfcc56355d65ab9bebb1016400cb9d81ee1c977d0df16bb198c; - assert(actual.to_field() == test_data_default_hash); + assert_eq(actual, test_data_default_hash); } #[test] unconstrained fn serde() { let keys = PublicKeys { - npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } }, - ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } }, - ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } }, - tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } }, + npk_m_hash: 11, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } }, + ovpk_m_hash: 22, + tpk_m_hash: 33, }; - // We use the PUBLIC_KEYS_LENGTH constant to ensure that there is a match between the derived trait - let serialized: [Field; POINT_LENGTH * 4] = keys.serialize(); + let serialized: [Field; PUBLIC_KEYS_LENGTH] = keys.serialize(); let deserialized = PublicKeys::deserialize(serialized); assert_eq(keys, deserialized); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr b/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr index bee6737454fd..932691b0b577 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr @@ -1,4 +1,4 @@ -use crate::traits::Packable; +use crate::traits::{Deserialize, Packable, Serialize}; global BOOL_PACKED_LEN: u32 = 1; global U8_PACKED_LEN: u32 = 1; @@ -11,6 +11,7 @@ global I8_PACKED_LEN: u32 = 1; global I16_PACKED_LEN: u32 = 1; global I32_PACKED_LEN: u32 = 1; global I64_PACKED_LEN: u32 = 1; +global POINT_PACKED_LEN: u32 = 2; impl Packable for bool { let N: u32 = BOOL_PACKED_LEN; @@ -166,6 +167,17 @@ impl Packable for i64 { } } +impl Packable for super::point::EmbeddedCurvePoint { + let N: u32 = POINT_PACKED_LEN; + fn pack(self) -> [Field; Self::N] { + self.serialize() + } + + fn unpack(packed: [Field; Self::N]) -> Self { + Self::deserialize(packed) + } +} + impl Packable for [T; M] where T: Packable, diff --git a/noir/noir-repo b/noir/noir-repo index 4f77d904a259..f1a4575adac5 160000 --- a/noir/noir-repo +++ b/noir/noir-repo @@ -1 +1 @@ -Subproject commit 4f77d904a259301b1784dbb1e1e7b82e5e0e2260 +Subproject commit f1a4575adac59af0a86b036cf73ff5883d142a91 diff --git a/playground/docker-compose.yml b/playground/docker-compose.yml index d48663150b0d..7d86f4bd03ba 100644 --- a/playground/docker-compose.yml +++ b/playground/docker-compose.yml @@ -27,6 +27,7 @@ services: WS_BLOCK_CHECK_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 P2P_MIN_TX_POOL_AGE_MS: 0 + SEQ_ENABLE_PROPOSER_PIPELINING: 'true' healthcheck: test: ['CMD', 'curl', '-fSs', 'http://127.0.0.1:8080/status'] interval: 3s diff --git a/spartan/aztec-node/templates/_pod-template.yaml b/spartan/aztec-node/templates/_pod-template.yaml index 67bfaec31a23..bfeb7e899cf9 100644 --- a/spartan/aztec-node/templates/_pod-template.yaml +++ b/spartan/aztec-node/templates/_pod-template.yaml @@ -217,14 +217,14 @@ spec: - name: SLASH_VALIDATORS_NEVER value: {{ join "," .Values.node.slash.validatorsNever | quote }} {{- end }} - {{- if .Values.node.slash.prunePenalty }} - - name: SLASH_PRUNE_PENALTY - value: {{ .Values.node.slash.prunePenalty | quote }} - {{- end }} {{- if .Values.node.slash.dataWithholdingPenalty }} - name: SLASH_DATA_WITHHOLDING_PENALTY value: {{ .Values.node.slash.dataWithholdingPenalty | quote }} {{- end }} + {{- if .Values.node.slash.dataWithholdingToleranceSlots }} + - name: SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS + value: {{ .Values.node.slash.dataWithholdingToleranceSlots | quote }} + {{- end }} {{- if .Values.node.slash.inactivityPenalty }} - name: SLASH_INACTIVITY_PENALTY value: {{ .Values.node.slash.inactivityPenalty | quote }} @@ -237,6 +237,10 @@ spec: - name: SLASH_INVALID_BLOCK_PENALTY value: {{ .Values.node.slash.invalidBlockPenalty | quote }} {{- end }} + {{- if .Values.node.slash.invalidCheckpointProposalPenalty }} + - name: SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY + value: {{ .Values.node.slash.invalidCheckpointProposalPenalty | quote }} + {{- end }} {{- if .Values.node.slash.proposeInvalidAttestationsPenalty }} - name: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY value: {{ .Values.node.slash.proposeInvalidAttestationsPenalty | quote }} @@ -249,9 +253,9 @@ spec: - name: SLASH_DUPLICATE_ATTESTATION_PENALTY value: {{ .Values.node.slash.duplicateAttestationPenalty | quote }} {{- end }} - {{- if .Values.node.slash.attestDescendantOfInvalidPenalty }} - - name: SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY - value: {{ .Values.node.slash.attestDescendantOfInvalidPenalty | quote }} + {{- if .Values.node.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty }} + - name: SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY + value: {{ .Values.node.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty | quote }} {{- end }} {{- if .Values.node.slash.attestInvalidCheckpointProposalPenalty }} - name: SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY diff --git a/spartan/aztec-node/values.yaml b/spartan/aztec-node/values.yaml index c16fb422b64c..b9d8732f434d 100644 --- a/spartan/aztec-node/values.yaml +++ b/spartan/aztec-node/values.yaml @@ -147,13 +147,14 @@ node: validatorsAlways: [] validatorsNever: [] # Penalty amounts for different offense types - prunePenalty: "" dataWithholdingPenalty: "" + dataWithholdingToleranceSlots: "" inactivityPenalty: "" inactivityTargetPercentage: "" invalidBlockPenalty: "" + invalidCheckpointProposalPenalty: "" proposeInvalidAttestationsPenalty: "" - attestDescendantOfInvalidPenalty: "" + proposeDescendantOfCheckpointWithInvalidAttestationsPenalty: "" attestInvalidCheckpointProposalPenalty: "" unknownPenalty: "" # Slasher behavior configuration diff --git a/spartan/bootstrap.sh b/spartan/bootstrap.sh index 15d908e4409b..4a4a19db9d69 100755 --- a/spartan/bootstrap.sh +++ b/spartan/bootstrap.sh @@ -183,8 +183,12 @@ function block_capacity_bench_cmds { } function bench_10tps_cmds { - local high_value_tps=10 - local low_value_tps=0 + # Mix: 1 tps of high-value + 9 tps of low-value, total still 10 tps. The + # high-value lane is what we measure for the headline client-observed + # inclusion latency (low-value txs pay near-network-min and are allowed to + # fail fee checks, so they would skew the headline if measured). + local high_value_tps=1 + local low_value_tps=9 local test_duration=${TEST_DURATION_SECONDS:-600} # 10 mins local timeout=${BENCH_TIMEOUT_SECONDS:-7200} # account for initial committee formation echo "$(hash):TIMEOUT=${timeout} BENCH_RUN_ID=${BENCH_RUN_ID:-} BENCH_OUTPUT=bench-out/n_tps.10tps.bench.json BENCH_SCENARIO=10tps LOW_VALUE_TPS=${low_value_tps} HIGH_VALUE_TPS=${high_value_tps} TEST_DURATION_SECONDS=${test_duration} $root/yarn-project/end-to-end/scripts/run_test.sh simple n_tps.test.ts" @@ -259,6 +263,7 @@ function bench_10tps { --target-tps 10 \ --workload sha256_hash_1024 \ --output "$run_json" \ + --inclusion-records "$metadata" \ --wait-for-pending-zero \ --max-pending-wait-seconds "${BENCH_SCRAPE_MAX_PENDING_WAIT_SECONDS:-3600}" \ || echo "[bench_10tps] scraper failed (non-fatal)" @@ -399,6 +404,13 @@ case "$cmd" in fi fi ;; + "wait_for_l2_block") + env_file="$1" + source_env_basic "$env_file" + gcp_auth + source_network_env "$env_file" + ./scripts/wait_for_l2_block.sh "$NAMESPACE" + ;; "single_test") run_network_tests "$1" "$2" ;; diff --git a/spartan/environments/alpha-net.env b/spartan/environments/alpha-net.env deleted file mode 100644 index 563054a0f9bb..000000000000 --- a/spartan/environments/alpha-net.env +++ /dev/null @@ -1,91 +0,0 @@ -NAMESPACE=${NAMESPACE:-alpha-net} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=8 -AZTEC_SLOT_DURATION=72 -AZTEC_PROOF_SUBMISSION_EPOCHS=2 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -# Install chaos mesh peer isolation after Aztec infra deploys. Validators, -# RPC nodes, and prover nodes can only peer with full-nodes, not each other. -# Requires P2P_PUBLIC_IP=false so P2P uses pod IPs that iptables rules can match. -P2P_PUBLIC_IP=false -CHAOS_MESH_SCENARIOS_FILE=network-requirements.yaml - -AZTEC_MANA_TARGET=2147483647 - -P2P_TX_POOL_DELETE_TXS_AFTER_REORG=true - -# For mbps -SEQ_BUILD_CHECKPOINT_IF_EMPTY=true -SEQ_BLOCK_DURATION_MS=6000 -SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT=5 - -CREATE_ROLLUP_CONTRACTS=true -REDEPLOY_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=128 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=5 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 -SPONSORED_FPC=true - -SEQ_MAX_TX_PER_CHECKPOINT=72 -SEQ_MIN_TX_PER_BLOCK=1 -SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/bench-10tps.env b/spartan/environments/bench-10tps.env index b4782d9e35e8..e7bedf0d9e58 100644 --- a/spartan/environments/bench-10tps.env +++ b/spartan/environments/bench-10tps.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-bench-10tps} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a DESTROY_NAMESPACE=true DESTROY_AZTEC_INFRA=true @@ -30,7 +31,7 @@ VALIDATOR_REPLICAS=3 VALIDATORS_PER_NODE=20 VALIDATOR_PUBLISHERS_PER_REPLICA=4 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" VALIDATOR_HA_REPLICAS=1 SEQ_BLOCK_DURATION_MS=6000 @@ -47,11 +48,11 @@ RPC_RESOURCE_PROFILE="prod" RPC_INGRESS_ENABLED=false FULL_NODE_REPLICAS=5 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" +FULL_NODE_RESOURCE_PROFILE="prod" REAL_VERIFIER=false PROVER_REPLICAS=10 -PROVER_RESOURCE_PROFILE="hi-tps" +PROVER_RESOURCE_PROFILE="dev-hi-tps" PUBLISHERS_PER_PROVER=1 PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 PROVER_AGENT_POLL_INTERVAL_MS=10000 diff --git a/spartan/environments/block-capacity.env b/spartan/environments/block-capacity.env index bc98dfd21cc2..8e24f24be61a 100644 --- a/spartan/environments/block-capacity.env +++ b/spartan/environments/block-capacity.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-block-capacity} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a AZTEC_EPOCH_DURATION=8 @@ -23,7 +24,7 @@ OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET VALIDATOR_REPLICAS=1 VALIDATORS_PER_NODE=48 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="prod-hi-tps" +VALIDATOR_RESOURCE_PROFILE="prod" REAL_VERIFIER=false diff --git a/spartan/environments/devnet.env b/spartan/environments/devnet.env index e78d04742203..0741b4751f7e 100644 --- a/spartan/environments/devnet.env +++ b/spartan/environments/devnet.env @@ -1,5 +1,6 @@ GCP_REGION=us-west1-a CLUSTER=aztec-gke-private +RESOURCE_PROFILE=dev NETWORK="devnet" NAMESPACE=${NAMESPACE:-devnet} diff --git a/spartan/environments/five-tps-long-epoch.env b/spartan/environments/five-tps-long-epoch.env deleted file mode 100644 index b8ed75aa4346..000000000000 --- a/spartan/environments/five-tps-long-epoch.env +++ /dev/null @@ -1,75 +0,0 @@ -NAMESPACE=${NAMESPACE:-five-tps} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=32 -AZTEC_SLOT_DURATION=36 -AZTEC_PROOF_SUBMISSION_EPOCHS=2 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -AZTEC_MANA_TARGET=2147483647 - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=64 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=20 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 - -SEQ_MAX_TX_PER_CHECKPOINT=180 -SEQ_MIN_TX_PER_BLOCK=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/five-tps-short-epoch.env b/spartan/environments/five-tps-short-epoch.env deleted file mode 100644 index e78badea2365..000000000000 --- a/spartan/environments/five-tps-short-epoch.env +++ /dev/null @@ -1,75 +0,0 @@ -NAMESPACE=${NAMESPACE:-five-tps} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=8 -AZTEC_SLOT_DURATION=36 -AZTEC_PROOF_SUBMISSION_EPOCHS=10 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -AZTEC_MANA_TARGET=2147483647 - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=64 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=5 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 - -SEQ_MAX_TX_PER_CHECKPOINT=180 -SEQ_MIN_TX_PER_BLOCK=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/kind-minimal.env b/spartan/environments/kind-minimal.env index c70b55aede50..e3d5ab2901fc 100644 --- a/spartan/environments/kind-minimal.env +++ b/spartan/environments/kind-minimal.env @@ -3,6 +3,7 @@ NAMESPACE=${NAMESPACE:-kind} CLUSTER=kind +RESOURCE_PROFILE=dev CREATE_ETH_DEVNET=true CREATE_ROLLUP_CONTRACTS=true CREATE_AZTEC_INFRA=true diff --git a/spartan/environments/kind-provers.env b/spartan/environments/kind-provers.env index f6e0482d7e1a..e74d5a25e0b8 100644 --- a/spartan/environments/kind-provers.env +++ b/spartan/environments/kind-provers.env @@ -3,6 +3,7 @@ NAMESPACE=${NAMESPACE:-kind} CLUSTER=kind +RESOURCE_PROFILE=dev CREATE_ETH_DEVNET=true CREATE_ROLLUP_CONTRACTS=true CREATE_AZTEC_INFRA=true diff --git a/spartan/environments/mainnet.env b/spartan/environments/mainnet.env index 2315e53d29d0..97d6b69748f5 100644 --- a/spartan/environments/mainnet.env +++ b/spartan/environments/mainnet.env @@ -4,6 +4,7 @@ ETHEREUM_CHAIN_ID=${ETHEREUM_CHAIN_ID:-1} GCP_REGION=us-west1-a CLUSTER=aztec-gke-public +RESOURCE_PROFILE=prod NAMESPACE=${NAMESPACE:-mainnet} CREATE_ROLLUP_CONTRACTS=false @@ -24,9 +25,9 @@ FISHERMAN_REPLICAS=1 FISHERMAN_MNEMONIC_START_INDEX=1 PROVER_NODE_DISABLE_PROOF_PUBLISH=true -RPC_RESOURCE_PROFILE=mainnet -BLOB_SINK_RESOURCE_PROFILE=mainnet -PROVER_RESOURCE_PROFILE=mainnet +RPC_RESOURCE_PROFILE=prod +BLOB_SINK_RESOURCE_PROFILE=prod +PROVER_RESOURCE_PROFILE=prod LOG_LEVEL=info FISHERMAN_LOG_LEVEL=info diff --git a/spartan/environments/mbps-net.env b/spartan/environments/mbps-net.env deleted file mode 100644 index 4357bf8fc037..000000000000 --- a/spartan/environments/mbps-net.env +++ /dev/null @@ -1,68 +0,0 @@ -CREATE_ETH_DEVNET=false -GCP_REGION=us-west1-a -CLUSTER=aztec-gke-private -NETWORK=next-net -NAMESPACE=mbps-net -DESTROY_NAMESPACE=true -ETHEREUM_CHAIN_ID=11155111 -ETHEREUM_RPC_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEYS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEY_HEADERS=REPLACE_WITH_GCP_SECRET -FUNDING_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -LABS_INFRA_MNEMONIC=REPLACE_WITH_GCP_SECRET -ROLLUP_DEPLOYMENT_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET -VERIFY_CONTRACTS=false -ETHERSCAN_API_KEY=REPLACE_WITH_GCP_SECRET -DEPLOY_INTERNAL_BOOTNODE=true -STORE_SNAPSHOT_URL= -BLOB_BUCKET_DIRECTORY=${BLOB_BUCKET_DIRECTORY:-next-net/blobs} -R2_ACCESS_KEY_ID=REPLACE_WITH_GCP_SECRET -R2_SECRET_ACCESS_KEY=REPLACE_WITH_GCP_SECRET -PROVER_FAILED_PROOF_STORE=gs://aztec-develop/next-net/failed-proofs -TEST_ACCOUNTS=true -SPONSORED_FPC=true -SEQ_MIN_TX_PER_BLOCK=0 -SEQ_MAX_TX_PER_BLOCK=8 -AZTEC_EPOCH_DURATION=8 -REAL_VERIFIER=false -PROVER_REAL_PROOFS=false - -SEQ_BUILD_CHECKPOINT_IF_EMPTY=true -SEQ_BLOCK_DURATION_MS=6000 -LOG_LEVEL=verbose - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 - -BOT_TRANSFERS_REPLICAS=1 -BOT_TRANSFERS_TX_INTERVAL_SECONDS=4 -BOT_TRANSFERS_FOLLOW_CHAIN=PROPOSED -BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP=proposed - -BOT_SWAPS_REPLICAS=1 -BOT_SWAPS_TX_INTERVAL_SECONDS=4 -BOT_SWAPS_FOLLOW_CHAIN=PROPOSED -BOT_SWAPS_PXE_SYNC_CHAIN_TIP=proposed - -BOT_CROSS_CHAIN_REPLICAS=1 -BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS=8 -BOT_CROSS_CHAIN_FOLLOW_CHAIN=PROPOSED -BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP=proposed - -REDEPLOY_ROLLUP_CONTRACTS=true - -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" - diff --git a/spartan/environments/mbps-pipeline.env b/spartan/environments/mbps-pipeline.env deleted file mode 100644 index fa00ac5c9f88..000000000000 --- a/spartan/environments/mbps-pipeline.env +++ /dev/null @@ -1,69 +0,0 @@ -CREATE_ETH_DEVNET=true -GCP_REGION=us-west1-a -CLUSTER=aztec-gke-private -NETWORK=next-net -NAMESPACE=mbps-pipe -DESTROY_NAMESPACE=true -ETHEREUM_CHAIN_ID=1337 -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -DEPLOY_INTERNAL_BOOTNODE=true -TEST_ACCOUNTS=true -SPONSORED_FPC=true -SEQ_MIN_TX_PER_BLOCK=0 -SEQ_MAX_TX_PER_BLOCK=8 -AZTEC_EPOCH_DURATION=8 -REAL_VERIFIER=false -PROVER_REAL_PROOFS=false - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -SEQ_BUILD_CHECKPOINT_IF_EMPTY=true -SEQ_BLOCK_DURATION_MS=5500 -SEQ_MAX_TX_PER_CHECKPOINT=96 -SEQ_ENABLE_PROPOSER_PIPELINING=true -SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER=1 -LOG_LEVEL=verbose - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -AZTEC_INBOX_LAG=2 - -AZTEC_TARGET_COMMITTEE_SIZE=24 - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 - -BOT_TRANSFERS_REPLICAS=1 -BOT_TRANSFERS_TX_INTERVAL_SECONDS=4 -BOT_TRANSFERS_FOLLOW_CHAIN=PROPOSED -BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP=proposed - -BOT_SWAPS_REPLICAS=1 -BOT_SWAPS_TX_INTERVAL_SECONDS=4 -BOT_SWAPS_FOLLOW_CHAIN=PROPOSED -BOT_SWAPS_PXE_SYNC_CHAIN_TIP=proposed - -BOT_CROSS_CHAIN_REPLICAS=1 -BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS=8 -BOT_CROSS_CHAIN_FOLLOW_CHAIN=PROPOSED -BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP=proposed - -REDEPLOY_ROLLUP_CONTRACTS=true - -DEBUG_P2P_INSTRUMENT_MESSAGES=true -OTEL_COLLECT_INTERVAL_MS=10000 -OTEL_EXPORT_TIMEOUT_MS=5000 - -VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" - diff --git a/spartan/environments/network-defaults.yml b/spartan/environments/network-defaults.yml index 3bfe0cd37aaa..c918dcddc515 100644 --- a/spartan/environments/network-defaults.yml +++ b/spartan/environments/network-defaults.yml @@ -119,10 +119,10 @@ slasher: &slasher SLASH_MAX_PAYLOAD_SIZE: 80 # Rounds to look back when executing slashes. SLASH_EXECUTE_ROUNDS_LOOK_BACK: 4 - # Penalty for slashing validators of a valid pruned epoch. - SLASH_PRUNE_PENALTY: 10e18 # Penalty for data withholding. SLASH_DATA_WITHHOLDING_PENALTY: 10e18 + # Number of full L2 slots to wait after a checkpoint's slot before declaring its txs missing. + SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS: 3 # Missed attestation percentage to trigger inactivity slash (0, 1]. SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9 # Consecutive epochs a validator must be inactive before slashing. @@ -131,8 +131,8 @@ slasher: &slasher SLASH_INACTIVITY_PENALTY: 10e18 # Penalty for proposing invalid attestations. SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 - # Penalty for attesting to a descendant of an invalid block. - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + # Penalty for proposing a checkpoint that builds on an invalid checkpoint. + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 # Penalty for attesting to an invalid checkpoint proposal. SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 # Penalty for proposing two different block or checkpoint proposal for the same position. @@ -143,6 +143,8 @@ slasher: &slasher SLASH_UNKNOWN_PENALTY: 10e18 # Penalty for broadcasting an invalid block. SLASH_INVALID_BLOCK_PENALTY: 10e18 + # Penalty for broadcasting an invalid checkpoint proposal. + SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0 # L2 slots grace period before considering an offense expired. SLASH_GRACE_PERIOD_L2_SLOTS: 0 @@ -235,7 +237,6 @@ networks: PUBLIC_OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "" PUBLIC_OTEL_COLLECT_FROM: "" # Slasher penalties - SLASH_PRUNE_PENALTY: 10e18 SLASH_DATA_WITHHOLDING_PENALTY: 10e18 SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9 SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 1 @@ -243,10 +244,11 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 SLASH_UNKNOWN_PENALTY: 10e18 SLASH_INVALID_BLOCK_PENALTY: 10e18 + SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0 SLASH_GRACE_PERIOD_L2_SLOTS: 0 ENABLE_VERSION_CHECK: true @@ -281,7 +283,6 @@ networks: P2P_MAX_PENDING_TX_COUNT: 1000 P2P_TX_POOL_DELETE_TXS_AFTER_REORG: true # Slasher penalties - SLASH_PRUNE_PENALTY: 10e18 SLASH_DATA_WITHHOLDING_PENALTY: 10e18 SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9 SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 1 @@ -289,10 +290,11 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 SLASH_UNKNOWN_PENALTY: 10e18 SLASH_INVALID_BLOCK_PENALTY: 10e18 + SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0 SLASH_GRACE_PERIOD_L2_SLOTS: 64 ENABLE_VERSION_CHECK: true @@ -341,7 +343,6 @@ networks: PUBLIC_OTEL_COLLECT_FROM: "" ENABLE_VERSION_CHECK: false # Slasher penalties - more lenient initially - SLASH_PRUNE_PENALTY: 0 SLASH_DATA_WITHHOLDING_PENALTY: 0 SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.8 SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 2 @@ -349,8 +350,9 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 2000e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 2000e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 2000e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 2000e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 2000e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 2000e18 SLASH_UNKNOWN_PENALTY: 2000e18 SLASH_INVALID_BLOCK_PENALTY: 2000e18 + SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0 SLASH_GRACE_PERIOD_L2_SLOTS: 1200 diff --git a/spartan/environments/next-net-clone.env b/spartan/environments/next-net-clone.env deleted file mode 100644 index b159feccf9c1..000000000000 --- a/spartan/environments/next-net-clone.env +++ /dev/null @@ -1,79 +0,0 @@ -CREATE_ETH_DEVNET=false -GCP_REGION=us-west1-a -CLUSTER=aztec-gke-private -NETWORK=next-net -NAMESPACE=${NAMESPACE:-next-net-clone} -DESTROY_NAMESPACE=true -ETHEREUM_CHAIN_ID=11155111 -ETHEREUM_RPC_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEYS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEY_HEADERS=REPLACE_WITH_GCP_SECRET -FUNDING_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -LABS_INFRA_MNEMONIC=REPLACE_WITH_GCP_SECRET -ROLLUP_DEPLOYMENT_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET -VERIFY_CONTRACTS=false -ETHERSCAN_API_KEY=REPLACE_WITH_GCP_SECRET -DEPLOY_INTERNAL_BOOTNODE=true -STORE_SNAPSHOT_URL= -#BLOB_BUCKET_DIRECTORY=${BLOB_BUCKET_DIRECTORY:-next-net/blobs} -#BLOB_FILE_STORE_URLS="," -#TX_FILE_STORE_ENABLED=true -#TX_FILE_STORE_BUCKET_DIRECTORY=${TX_FILE_STORE_BUCKET_DIRECTORY:-next-net/txs} -#TX_COLLECTION_FILE_STORE_URLS="https://aztec-labs-snapshots.com/${TX_FILE_STORE_BUCKET_DIRECTORY}" -R2_ACCESS_KEY_ID=REPLACE_WITH_GCP_SECRET -R2_SECRET_ACCESS_KEY=REPLACE_WITH_GCP_SECRET -#PROVER_FAILED_PROOF_STORE=gs://aztec-develop/next-net/failed-proofs -#L1_TX_FAILED_STORE=gs://aztec-develop/next-net/failed-l1-txs -TEST_ACCOUNTS=true -SPONSORED_FPC=true - -SEQ_ENABLE_PROPOSER_PIPELINING=true -SEQ_MIN_TX_PER_BLOCK=1 -SEQ_MAX_TX_PER_CHECKPOINT=12 - -# Build checkpoint even if block is empty. -SEQ_BUILD_CHECKPOINT_IF_EMPTY=true -SEQ_BLOCK_DURATION_MS=5500 - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -AZTEC_INBOX_LAG=2 - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 - -BOT_TRANSFERS_REPLICAS=1 -BOT_TRANSFERS_TX_INTERVAL_SECONDS=250 -BOT_TRANSFERS_FOLLOW_CHAIN=PENDING - -BOT_SWAPS_REPLICAS=1 -BOT_SWAPS_FOLLOW_CHAIN=PENDING -BOT_SWAPS_TX_INTERVAL_SECONDS=350 - -CREATE_ROLLUP_CONTRACTS=true - -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -RPC_INGRESS_ENABLED=false -#RPC_INGRESS_HOSTS='["nextnet.aztec-labs.com"]' -#RPC_INGRESS_STATIC_IP_NAME=nextnet-rpc-ip -#RPC_INGRESS_SSL_CERT_NAMES='["nextnet-rpc-cert"]' - -VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" - -REAL_VERIFIER=true -AZTEC_SLOT_DURATION=72 -AZTEC_EPOCH_DURATION=32 -AZTEC_TARGET_COMMITTEE_SIZE=48 -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -AZTEC_PROOF_SUBMISSION_EPOCHS=1 - diff --git a/spartan/environments/next-net.env b/spartan/environments/next-net.env index 7ecf1b28b7e6..f8541c8b5229 100644 --- a/spartan/environments/next-net.env +++ b/spartan/environments/next-net.env @@ -1,6 +1,7 @@ CREATE_ETH_DEVNET=false GCP_REGION=us-west1-a CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod NETWORK=next-net NAMESPACE=${NAMESPACE:-next-net} DESTROY_NAMESPACE=true @@ -29,7 +30,7 @@ L1_TX_FAILED_STORE=gs://aztec-develop/next-net/failed-l1-txs TEST_ACCOUNTS=true SPONSORED_FPC=true -LOG_LEVEL=debug +LOG_LEVEL="debug; info: json-rpc, simulator" SEQ_ENABLE_PROPOSER_PIPELINING=true SEQ_MIN_TX_PER_BLOCK=1 @@ -69,7 +70,7 @@ RPC_INGRESS_STATIC_IP_NAME=nextnet-rpc-ip RPC_INGRESS_SSL_CERT_NAMES='["nextnet-rpc-cert"]' VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" REAL_VERIFIER=true AZTEC_SLOT_DURATION=72 diff --git a/spartan/environments/next-scenario.env b/spartan/environments/next-scenario.env index e11caa65025e..efc9f2dd15bf 100644 --- a/spartan/environments/next-scenario.env +++ b/spartan/environments/next-scenario.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-scenario} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a DESTROY_NAMESPACE=true DESTROY_ETH_DEVNET=true @@ -52,4 +53,4 @@ PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 SEQ_MIN_TX_PER_BLOCK=0 VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" diff --git a/spartan/environments/prove-n-tps-fake.env b/spartan/environments/prove-n-tps-fake.env index 553ab562dac7..9aa4fc5f6359 100644 --- a/spartan/environments/prove-n-tps-fake.env +++ b/spartan/environments/prove-n-tps-fake.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-prove-n-tps-fake} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a AZTEC_EPOCH_DURATION=32 @@ -32,7 +33,7 @@ RPC_REPLICAS=1 RPC_INGRESS_ENABLED=false PROVER_REPLICAS=10 -PROVER_RESOURCE_PROFILE="hi-tps" +PROVER_RESOURCE_PROFILE="dev-hi-tps" PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 PROVER_AGENT_POLL_INTERVAL_MS=10000 PUBLISHERS_PER_PROVER=1 diff --git a/spartan/environments/prove-n-tps-real.env b/spartan/environments/prove-n-tps-real.env index 41357530292a..16e0548e91e9 100644 --- a/spartan/environments/prove-n-tps-real.env +++ b/spartan/environments/prove-n-tps-real.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-prove-n-tps-real} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a AZTEC_EPOCH_DURATION=32 diff --git a/spartan/environments/scenario.local.env b/spartan/environments/scenario.local.env index 8fcc338a7183..5059489633de 100644 --- a/spartan/environments/scenario.local.env +++ b/spartan/environments/scenario.local.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-scenario} CLUSTER=kind +RESOURCE_PROFILE=dev CREATE_ETH_DEVNET=true LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" L1_ACCOUNT_MNEMONIC="test test test test test test test test test test test junk" diff --git a/spartan/environments/staging-ignition.env b/spartan/environments/staging-ignition.env deleted file mode 100644 index f1d267365995..000000000000 --- a/spartan/environments/staging-ignition.env +++ /dev/null @@ -1,42 +0,0 @@ -CREATE_ETH_DEVNET=false -GCP_REGION=us-west1-a -CLUSTER=aztec-gke-private -NAMESPACE=${NAMESPACE:-staging-ignition} -TRANSACTIONS_DISABLED=true -TEST_ACCOUNTS=false -SPONSORED_FPC=false -SEQ_MIN_TX_PER_BLOCK=0 -SEQ_MAX_TX_PER_BLOCK=0 -NETWORK=staging-ignition - -ETHEREUM_CHAIN_ID=11155111 -ETHEREUM_RPC_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEYS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEY_HEADERS=REPLACE_WITH_GCP_SECRET -FUNDING_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -LABS_INFRA_MNEMONIC=REPLACE_WITH_GCP_SECRET -LABS_INFRA_MNEMONIC_SECRET_NAME=sepolia-labs-staging-ignition-mnemonic -ROLLUP_DEPLOYMENT_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET -VERIFY_CONTRACTS=true -ETHERSCAN_API_KEY=REPLACE_WITH_GCP_SECRET -SNAPSHOT_BUCKET_DIRECTORY=${SNAPSHOT_BUCKET_DIRECTORY:-staging-ignition} -BLOB_BUCKET_DIRECTORY=${BLOB_BUCKET_DIRECTORY:-staging-ignition/blobs} -BLOB_FILE_STORE_URLS="," -R2_ACCESS_KEY_ID=REPLACE_WITH_GCP_SECRET -R2_SECRET_ACCESS_KEY=REPLACE_WITH_GCP_SECRET -BOT_TRANSFERS_REPLICAS=0 -BOT_SWAPS_REPLICAS=0 -DEPLOY_INTERNAL_BOOTNODE=false - -CREATE_ROLLUP_CONTRACTS=${CREATE_ROLLUP_CONTRACTS:-false} - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -USE_NETWORK_CONFIG=true diff --git a/spartan/environments/staging-public.env b/spartan/environments/staging-public.env index cbc41af5d589..b3f8b318c4a4 100644 --- a/spartan/environments/staging-public.env +++ b/spartan/environments/staging-public.env @@ -1,6 +1,7 @@ CREATE_ETH_DEVNET=false GCP_REGION=us-west1-a CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod NETWORK=staging-public NAMESPACE=${NAMESPACE:-staging-public} ETHEREUM_CHAIN_ID=11155111 @@ -51,7 +52,7 @@ VALIDATOR_PUBLISHERS_PER_REPLICA=4 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 VALIDATOR_HA_REPLICAS=1 VALIDATOR_HA_REPLICA_COUNT=4 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" PROVER_FAILED_PROOF_STORE=gs://aztec-develop/staging-public/failed-proofs L1_TX_FAILED_STORE=gs://aztec-develop/staging-public/failed-l1-txs diff --git a/spartan/environments/staging.local.env b/spartan/environments/staging.local.env deleted file mode 100644 index 99054b7b87b1..000000000000 --- a/spartan/environments/staging.local.env +++ /dev/null @@ -1,21 +0,0 @@ -NAMESPACE=${NAMESPACE:-staging} -CLUSTER=kind -CREATE_ETH_DEVNET=false -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - -# The following need to be set manually -# AZTEC_DOCKER_IMAGE=aztecprotocol/aztec:whatever -# ETHEREUM_RPC_URLS='[""]' -# ETHEREUM_CONSENSUS_HOST_URLS='[""]' -# ETHEREUM_CONSENSUS_HOST_API_KEYS='[""]' -# ETHEREUM_CONSENSUS_HOST_API_KEY_HEADERS='[""]' - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 diff --git a/spartan/environments/ten-tps-long-epoch.env b/spartan/environments/ten-tps-long-epoch.env deleted file mode 100644 index 297e2cd55f96..000000000000 --- a/spartan/environments/ten-tps-long-epoch.env +++ /dev/null @@ -1,76 +0,0 @@ -NAMESPACE=${NAMESPACE:-ten-tps} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=32 -AZTEC_SLOT_DURATION=36 -AZTEC_PROOF_SUBMISSION_EPOCHS=2 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -AZTEC_MANA_TARGET=2147483647 - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 -SPONSORED_FPC=true - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=128 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=20 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 - -SEQ_MAX_TX_PER_CHECKPOINT=360 -SEQ_MIN_TX_PER_BLOCK=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/ten-tps-short-epoch.env b/spartan/environments/ten-tps-short-epoch.env deleted file mode 100644 index 56518164d2ab..000000000000 --- a/spartan/environments/ten-tps-short-epoch.env +++ /dev/null @@ -1,76 +0,0 @@ -NAMESPACE=${NAMESPACE:-ten-tps} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=8 -AZTEC_SLOT_DURATION=36 -AZTEC_PROOF_SUBMISSION_EPOCHS=2 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -AZTEC_MANA_TARGET=2147483647 - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 -SPONSORED_FPC=true - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=128 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=5 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 - -SEQ_MAX_TX_PER_CHECKPOINT=360 -SEQ_MIN_TX_PER_BLOCK=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/testnet.env b/spartan/environments/testnet.env index 2a88fb1e1826..10cf468f1341 100644 --- a/spartan/environments/testnet.env +++ b/spartan/environments/testnet.env @@ -1,6 +1,7 @@ CREATE_ETH_DEVNET=false GCP_REGION=us-west1-a CLUSTER=aztec-gke-public +RESOURCE_PROFILE=prod NAMESPACE=${NAMESPACE:-testnet} NETWORK=testnet @@ -80,7 +81,7 @@ VALIDATORS_PER_NODE=64 VALIDATOR_PUBLISHERS_PER_REPLICA=8 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" PUBLISHERS_PER_PROVER=2 PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 diff --git a/spartan/environments/tps-scenario.env b/spartan/environments/tps-scenario.env index fc3893282c6c..4a1f08e156e2 100644 --- a/spartan/environments/tps-scenario.env +++ b/spartan/environments/tps-scenario.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-tps-scenario} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a AZTEC_EPOCH_DURATION=8 @@ -37,7 +38,7 @@ VALIDATOR_REPLICAS=12 VALIDATORS_PER_NODE=4 VALIDATOR_PUBLISHERS_PER_REPLICA=4 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" +VALIDATOR_RESOURCE_PROFILE="prod" REAL_VERIFIER=false @@ -45,12 +46,12 @@ RPC_REPLICAS=10 RPC_INGRESS_ENABLED=false FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" +FULL_NODE_RESOURCE_PROFILE="prod" PUBLISHERS_PER_PROVER=2 PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 PROVER_REPLICAS=20 -PROVER_RESOURCE_PROFILE="hi-tps" +PROVER_RESOURCE_PROFILE="dev-hi-tps" PROVER_AGENT_POLL_INTERVAL_MS=10000 WAIT_FOR_PROVER_DEPLOY=false diff --git a/spartan/metrics/grafana/alerts/policies.yaml b/spartan/metrics/grafana/alerts/policies.yaml index 1de335ec919e..de2ca357a81e 100644 --- a/spartan/metrics/grafana/alerts/policies.yaml +++ b/spartan/metrics/grafana/alerts/policies.yaml @@ -19,18 +19,6 @@ policies: - =~ - $STAGING_PUBLIC_REGEX - # Staging Ignition - by namespace - - receiver: "Slack #alerts-staging-ignition by namespace" - object_matchers: - - - k8s_namespace_name - - =~ - - $STAGING_IGNITION_REGEX - # Staging Ignition - by network label - - receiver: "Slack #alerts-staging-ignition by network" - object_matchers: - - - network - - =~ - - $STAGING_IGNITION_REGEX # Next Scenario - by namespace - receiver: "Slack #alerts-next-scenario by namespace" diff --git a/spartan/metrics/grafana/dashboards/aztec_network.json b/spartan/metrics/grafana/dashboards/aztec_network.json index e6fae556a5e7..ebc2b85ea31d 100644 --- a/spartan/metrics/grafana/dashboards/aztec_network.json +++ b/spartan/metrics/grafana/dashboards/aztec_network.json @@ -248,11 +248,11 @@ { "datasource": { "type": "prometheus", - "uid": "prometheus" + "uid": "${data_source}" }, "editorMode": "code", "exemplar": false, - "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"\"}, \"aztec_status\", \"Pending chain\", \"aztec_status\", \"^$\"))", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"proposed\"}, \"aztec_status\", \"Proposed chain\", \"aztec_status\", \"^proposed$\")) or max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"\"}, \"aztec_status\", \"Proposed chain\", \"aztec_status\", \"^$\"))", "instant": true, "legendFormat": "{{aztec_status}}", "range": false, @@ -261,16 +261,16 @@ { "datasource": { "type": "prometheus", - "uid": "prometheus" + "uid": "${data_source}" }, "editorMode": "code", "exemplar": false, - "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"proven\"}, \"aztec_status\", \"Proven chain\", \"aztec_status\", \"^proven$\"))", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"checkpointed\"}, \"aztec_status\", \"Checkpointed chain\", \"aztec_status\", \"^checkpointed$\")) or max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"\"}, \"aztec_status\", \"Checkpointed chain\", \"aztec_status\", \"^$\"))", "hide": false, "instant": true, "legendFormat": "{{aztec_status}}", "range": false, - "refId": "E" + "refId": "B" }, { "datasource": { @@ -279,38 +279,12 @@ }, "editorMode": "code", "exemplar": false, - "expr": "max by (aztec_status) (label_replace(aztec_archiver_l1_block_height{k8s_namespace_name=\"$namespace\"}, \"aztec_status\", \"l1\", \"aztec_status\", \"^$\"))", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"proven\"}, \"aztec_status\", \"Proven chain\", \"aztec_status\", \"^proven$\"))", "hide": false, "instant": true, - "legendFormat": "L1", + "legendFormat": "{{aztec_status}}", "range": false, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${data_source}" - }, - "editorMode": "code", - "expr": "max(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\", aztec_status=\"\"}) - max(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\", aztec_status=\"proven\"})", - "hide": false, - "instant": false, - "legendFormat": "Pending chain depth", - "range": true, "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${data_source}" - }, - "editorMode": "code", - "expr": "max(aztec_archiver_prune_count{k8s_namespace_name=\"$namespace\"}) or vector(0)", - "hide": false, - "instant": false, - "legendFormat": "Total re-orgs", - "range": true, - "refId": "D" } ], "title": "Current Block Heights", @@ -2592,15 +2566,47 @@ "uid": "${data_source}" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "max by(service_name, aztec_status) (aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=~\"proposed|proven\"})", + "editorMode": "code", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"proposed\"}, \"aztec_status\", \"Proposed chain\", \"aztec_status\", \"^proposed$\")) or max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"\"}, \"aztec_status\", \"Proposed chain\", \"aztec_status\", \"^$\"))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "__auto", + "legendFormat": "{{aztec_status}}", "range": true, "refId": "A", "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"checkpointed\"}, \"aztec_status\", \"Checkpointed chain\", \"aztec_status\", \"^checkpointed$\")) or max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"\"}, \"aztec_status\", \"Checkpointed chain\", \"aztec_status\", \"^$\"))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{aztec_status}}", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"proven\"}, \"aztec_status\", \"Proven chain\", \"aztec_status\", \"^proven$\"))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{aztec_status}}", + "range": true, + "refId": "C", + "useBackend": false } ], "title": "Block height", @@ -2669,8 +2675,8 @@ "gridPos": { "h": 8, "w": 12, - "x": 12, - "y": 75 + "x": 0, + "y": 83 }, "id": 11, "options": { @@ -2774,7 +2780,7 @@ "gridPos": { "h": 8, "w": 12, - "x": 0, + "x": 12, "y": 83 }, "id": 24, @@ -2814,6 +2820,107 @@ ], "title": "Archiver Sync Duration (P95)", "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "${data_source}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 8, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 75 + }, + "id": 41, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "editorMode": "code", + "expr": "max by(k8s_pod_name) (aztec_archiver_block_height{k8s_namespace_name=\"$namespace\", aztec_status=\"proposed\"}) or max by(k8s_pod_name) (aztec_archiver_block_height{k8s_namespace_name=\"$namespace\", aztec_status=\"\"})", + "instant": false, + "legendFormat": "{{k8s_pod_name}}", + "range": true, + "refId": "A" + } + ], + "title": "Proposed Chains by Pod", + "type": "timeseries" } ], "preload": false, diff --git a/spartan/metrics/grafana/dashboards/bootnodes.json b/spartan/metrics/grafana/dashboards/bootnodes.json index 296ded8850ea..dbccf99dc15f 100644 --- a/spartan/metrics/grafana/dashboards/bootnodes.json +++ b/spartan/metrics/grafana/dashboards/bootnodes.json @@ -554,8 +554,8 @@ { "current": { "selected": false, - "text": "staging-ignition", - "value": "staging-ignition" + "text": "staging-public", + "value": "staging-public" }, "datasource": { "type": "prometheus", diff --git a/spartan/metrics/irm-monitor/alerting/alert-rules.yml b/spartan/metrics/irm-monitor/alerting/alert-rules.yml index 82983b498810..a6a08f77633e 100644 --- a/spartan/metrics/irm-monitor/alerting/alert-rules.yml +++ b/spartan/metrics/irm-monitor/alerting/alert-rules.yml @@ -16,7 +16,7 @@ groups: datasourceUid: grafanacloud-prom model: editorMode: code - expr: changes(rollup_pending_block_number{network!="staging-ignition"}[40m]) + expr: changes(rollup_pending_block_number[40m]) instant: true intervalMs: 1000 legendFormat: __auto @@ -33,7 +33,7 @@ groups: type: prometheus uid: grafanacloud-prom editorMode: code - expr: rollup_pending_block_number{network!="staging-ignition"} + expr: rollup_pending_block_number instant: true intervalMs: 1000 legendFormat: __auto diff --git a/spartan/metrics/values.yaml b/spartan/metrics/values.yaml index 5919fc8c34b9..18ffe1d86c77 100644 --- a/spartan/metrics/values.yaml +++ b/spartan/metrics/values.yaml @@ -119,9 +119,8 @@ grafana: server: domain: env: - PRODUCTION_NAMESPACES_REGEX: "v2-testnet|staging-public|staging-ignition" + PRODUCTION_NAMESPACES_REGEX: "v2-testnet|staging-public" STAGING_PUBLIC_REGEX: "staging-public" - STAGING_IGNITION_REGEX: "staging-ignition|ignition-fisherman-sepolia" NEXT_SCENARIO_REGEX: "v[0-9]+-scenario|next-scenario" NEXT_NET_REGEX: "next-net" TESTNET_NAMESPACES_REGEX: "testnet|v[0-9]+-testnet" diff --git a/spartan/scripts/bench_10tps/bench_output.schema.json b/spartan/scripts/bench_10tps/bench_output.schema.json index a6c57437fd06..3685c72960d8 100644 --- a/spartan/scripts/bench_10tps/bench_output.schema.json +++ b/spartan/scripts/bench_10tps/bench_output.schema.json @@ -19,7 +19,9 @@ "const": "3", "description": "Bump when breaking the schema. Old JSONs keep their previous version so the dashboard can render them side-by-side. v3: timeSeries entries carry `series: [{labels, points}]` instead of bare `points` to support per-pod / per-label data." }, - "run": { "$ref": "#/$defs/runMeta" }, + "run": { + "$ref": "#/$defs/runMeta" + }, "summary": { "$ref": "#/$defs/summary", "description": "Scalar reductions — one number per run. Shown on the dashboard trend page and duplicated into index.json so the index can render headline numbers without fetching every run." @@ -31,30 +33,42 @@ "blocks": { "type": "array", "description": "Per-block records parsed from structured logs (each block emits one `Processed N successful txs and M failed txs ...` info line). Authoritative for per-block facts — Prometheus histograms cannot recover per-block samples.", - "items": { "$ref": "#/$defs/blockRecord" } + "items": { + "$ref": "#/$defs/blockRecord" + } }, "events": { "type": "array", "description": "Discrete occurrences during the run (currently just chain prunes). Typically rendered as annotations on charts.", - "items": { "$ref": "#/$defs/event" } + "items": { + "$ref": "#/$defs/event" + } }, "sequencerStateSlots": { "type": "array", "description": "Per-slot sequencer state time budget reconstructed from structured state-transition logs. Optional for older runs and empty when sequencer debug logs were not enabled.", - "items": { "$ref": "#/$defs/sequencerStateSlot" } + "items": { + "$ref": "#/$defs/sequencerStateSlot" + } }, "notes": { "type": "array", - "items": { "type": "string" }, + "items": { + "type": "string" + }, "description": "Free-form operator notes (e.g. 'ran with doubled prover agents'). Optional." } }, - "$defs": { "runMeta": { "type": "object", "additionalProperties": false, - "required": ["runId", "startedAt", "endedAt", "namespace"], + "required": [ + "runId", + "startedAt", + "endedAt", + "namespace" + ], "properties": { "runId": { "type": "string", @@ -80,7 +94,12 @@ "format": "date-time", "description": "Wall-clock time the scraper began querying Prometheus. Typically endedAt + ~90s to let the OTel batch push (60s default) and one Prom scrape (15s) settle." }, - "namespace": { "type": "string", "examples": ["bench-10tps"] }, + "namespace": { + "type": "string", + "examples": [ + "bench-10tps" + ] + }, "gcpProject": { "type": "string", "description": "GCP project containing the GKE container logs." @@ -97,12 +116,25 @@ "type": "string", "description": "Aztec image tag or digest the validators ran." }, - "targetTps": { "type": "number", "minimum": 0 }, - "testDurationSeconds": { "type": "integer", "minimum": 0 }, - "workload": { "type": "string", "examples": ["sha256_hash_1024"] }, + "targetTps": { + "type": "number", + "minimum": 0 + }, + "testDurationSeconds": { + "type": "integer", + "minimum": 0 + }, + "workload": { + "type": "string", + "examples": [ + "sha256_hash_1024" + ] + }, "aztecConfig": { "type": "object", - "additionalProperties": { "type": "string" }, + "additionalProperties": { + "type": "string" + }, "description": "Curated subset of Aztec config env vars captured from a running validator pod. Keys include SEQ_MAX_TX_PER_BLOCK, P2P_MAX_PENDING_TX_COUNT, AZTEC_MANA_TARGET, etc. Lets the dashboard show 'pool=20k vs pool=1000' alongside compared runs." }, "infrastructure": { @@ -118,12 +150,16 @@ "properties": { "instanceTypes": { "type": "array", - "items": { "type": "string" }, + "items": { + "type": "string" + }, "description": "Distinct Kubernetes node instance types used by this role." }, "nodePools": { "type": "array", - "items": { "type": "string" }, + "items": { + "type": "string" + }, "description": "Distinct node pools used by this role, when exposed as node labels." }, "nodes": { @@ -131,13 +167,27 @@ "items": { "type": "object", "additionalProperties": false, - "required": ["role", "podName", "nodeName"], + "required": [ + "role", + "podName", + "nodeName" + ], "properties": { - "role": { "type": "string" }, - "podName": { "type": "string" }, - "nodeName": { "type": "string" }, - "instanceType": { "type": "string" }, - "nodePool": { "type": "string" } + "role": { + "type": "string" + }, + "podName": { + "type": "string" + }, + "nodeName": { + "type": "string" + }, + "instanceType": { + "type": "string" + }, + "nodePool": { + "type": "string" + } } } } @@ -150,10 +200,14 @@ "type": "object", "additionalProperties": false, "properties": { - "enabled": { "type": "boolean" }, + "enabled": { + "type": "boolean" + }, "profile": { "type": "string", - "examples": ["network-requirements"] + "examples": [ + "network-requirements" + ] } } }, @@ -172,7 +226,9 @@ "minimum": 1, "description": "PromQL range-query step." }, - "promUrl": { "type": "string" }, + "promUrl": { + "type": "string" + }, "waitForPendingZero": { "type": "boolean", "description": "Whether live scraping waited for validator pending TxPool depth to reach zero before querying." @@ -183,18 +239,42 @@ "description": "Maximum time the scraper was allowed to wait for validator pending TxPool depth to reach zero." }, "pendingAtScrape": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "minimum": 0, "description": "Validator pending TxPool depth observed when scraping started, or null when the pending drain gate was disabled." }, "pendingByRoleAtScrape": { - "type": ["object", "null"], + "type": [ + "object", + "null" + ], "description": "Pending TxPool depth by pod role at scrape start. RPC/full-node pending can remain non-zero after validators drain, which indicates load that did not propagate to proposers before expiry.", "additionalProperties": false, "properties": { - "rpc": { "type": ["number", "null"], "minimum": 0 }, - "validator": { "type": ["number", "null"], "minimum": 0 }, - "fullNode": { "type": ["number", "null"], "minimum": 0 } + "rpc": { + "type": [ + "number", + "null" + ], + "minimum": 0 + }, + "validator": { + "type": [ + "number", + "null" + ], + "minimum": 0 + }, + "fullNode": { + "type": [ + "number", + "null" + ], + "minimum": 0 + } } }, "pendingWaitTimedOut": { @@ -205,103 +285,239 @@ } } }, - "summary": { "type": "object", "additionalProperties": false, - "required": ["headlineKpi", "inclusionTpsMean", "targetTps"], + "required": [ + "headlineKpi", + "inclusionTpsMean", + "targetTps" + ], "properties": { "headlineKpi": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "description": "inclusionTpsMean / targetTps. The single number on the dashboard top strip." }, - "targetTps": { "type": "number" }, + "targetTps": { + "type": "number" + }, "inclusionTpsMean": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "description": "Inclusion throughput over the observed inclusion window. Uses exact block-log throughput when block records are available, otherwise falls back to the Prometheus inclusionTps mean." }, "inclusionTpsPeak": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "description": "Peak sampled Prometheus rolling inclusion rate over the observed scrape window." }, - "inclusionLatencyP50Ms": { "type": ["number", "null"] }, - "inclusionLatencyP95Ms": { "type": ["number", "null"] }, - "inclusionLatencyP99Ms": { "type": ["number", "null"] }, - "blockBuildDurationP50Ms": { "type": ["number", "null"] }, - "blockBuildDurationP95Ms": { "type": ["number", "null"] }, - "publicProcessorTxDurationP50Ms": { "type": ["number", "null"] }, - "publicProcessorTxDurationP95Ms": { "type": ["number", "null"] }, + "inclusionLatencyP50Ms": { + "type": [ + "number", + "null" + ] + }, + "inclusionLatencyP95Ms": { + "type": [ + "number", + "null" + ] + }, + "inclusionLatencyP99Ms": { + "type": [ + "number", + "null" + ] + }, + "blockBuildDurationP50Ms": { + "type": [ + "number", + "null" + ] + }, + "blockBuildDurationP95Ms": { + "type": [ + "number", + "null" + ] + }, + "publicProcessorTxDurationP50Ms": { + "type": [ + "number", + "null" + ] + }, + "publicProcessorTxDurationP95Ms": { + "type": [ + "number", + "null" + ] + }, "totalTxsMined": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Exact sum from per-block logs. Null when block logs were unavailable and inclusionTpsMean came from Prometheus." }, "totalTxsFailed": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Exact sum from per-block logs. Null when block logs were unavailable." }, "totalSilentSkipCount": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Sum of per-block silentlySkippedCount. > 0 means the post-process blob-field revert path fired during the run." }, "totalSilentSkipDurationMs": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Sum of per-block silentlySkippedDurationMs. Wall-clock 'wasted' on silently-skipped txs across the run." }, "reorgCount": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Count of `Chain pruned` events during the run." }, "deepestReorgBlocks": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Max (fromBlock - toBlock) across reorg events. 0 if no reorgs." } } }, - "timeSeriesSection": { "type": "object", "description": "Key = stable slug (used by the dashboard to look up series); value = a series. Slugs decouple the display name from Prometheus metric names (which may be renamed across Aztec versions).", - "additionalProperties": { "$ref": "#/$defs/timeSeries" }, + "additionalProperties": { + "$ref": "#/$defs/timeSeries" + }, "properties": { - "inclusionTps": { "$ref": "#/$defs/timeSeries" }, - "ingressTps": { "$ref": "#/$defs/timeSeries" }, - "mempoolSizeRpc": { "$ref": "#/$defs/timeSeries" }, - "mempoolSizeValidator": { "$ref": "#/$defs/timeSeries" }, - "mempoolSizeFullNode": { "$ref": "#/$defs/timeSeries" }, - "mempoolMinedMax": { "$ref": "#/$defs/timeSeries" }, - "mempoolEvictedByReasonRate": { "$ref": "#/$defs/timeSeries" }, - "mempoolRejectedByReasonRate": { "$ref": "#/$defs/timeSeries" }, - "blockBuildDurationP95": { "$ref": "#/$defs/timeSeries" }, - "blockBuildDurationP50": { "$ref": "#/$defs/timeSeries" }, - "publicProcessorTxDurationP95": { "$ref": "#/$defs/timeSeries" }, - "publicProcessorTxDurationP50": { "$ref": "#/$defs/timeSeries" }, - "publicProcessorGasRate": { "$ref": "#/$defs/timeSeries" }, - "checkpointLastBlockToBroadcastP95": { "$ref": "#/$defs/timeSeries" }, - "checkpointBlockCountMean": { "$ref": "#/$defs/timeSeries" }, - "checkpointTxCountMean": { "$ref": "#/$defs/timeSeries" }, - "l1InclusionDelayP95": { "$ref": "#/$defs/timeSeries" }, - "gossipLatencyP95": { "$ref": "#/$defs/timeSeries" }, + "inclusionTps": { + "$ref": "#/$defs/timeSeries" + }, + "ingressTps": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolSizeRpc": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolSizeValidator": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolSizeFullNode": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolMinedMax": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolEvictedByReasonRate": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolRejectedByReasonRate": { + "$ref": "#/$defs/timeSeries" + }, + "blockBuildDurationP95": { + "$ref": "#/$defs/timeSeries" + }, + "blockBuildDurationP50": { + "$ref": "#/$defs/timeSeries" + }, + "publicProcessorTxDurationP95": { + "$ref": "#/$defs/timeSeries" + }, + "publicProcessorTxDurationP50": { + "$ref": "#/$defs/timeSeries" + }, + "txMinedDelayP50": { + "$ref": "#/$defs/timeSeries" + }, + "txMinedDelayP95": { + "$ref": "#/$defs/timeSeries" + }, + "txMinedDelayP99": { + "$ref": "#/$defs/timeSeries" + }, + "publicProcessorGasRate": { + "$ref": "#/$defs/timeSeries" + }, + "checkpointLastBlockToBroadcastP95": { + "$ref": "#/$defs/timeSeries" + }, + "checkpointBlockCountMean": { + "$ref": "#/$defs/timeSeries" + }, + "checkpointTxCountMean": { + "$ref": "#/$defs/timeSeries" + }, + "l1InclusionDelayP95": { + "$ref": "#/$defs/timeSeries" + }, + "gossipLatencyP95": { + "$ref": "#/$defs/timeSeries" + }, "peerCountMean": { "$ref": "#/$defs/timeSeries", "description": "Legacy aggregate peer-count series kept for older run JSONs." }, - "peerCountByRole": { "$ref": "#/$defs/timeSeries" }, - "peerCountByValidator": { "$ref": "#/$defs/timeSeries" }, - "attestationsCollectDurationMean": { "$ref": "#/$defs/timeSeries" }, - "attestationsCollectAllowanceMean": { "$ref": "#/$defs/timeSeries" }, - "txCollectorTxsFromMempoolRate": { "$ref": "#/$defs/timeSeries" }, - "txCollectorTxsFromP2pRate": { "$ref": "#/$defs/timeSeries" }, - "txCollectorMissingRate": { "$ref": "#/$defs/timeSeries" }, - "txCollectorRequestedFractionMean": { "$ref": "#/$defs/timeSeries" }, - "txCollectorRequestDelayP95": { "$ref": "#/$defs/timeSeries" }, - "sequencerStateDurationP95": { "$ref": "#/$defs/timeSeries" } + "peerCountByRole": { + "$ref": "#/$defs/timeSeries" + }, + "peerCountByValidator": { + "$ref": "#/$defs/timeSeries" + }, + "attestationsCollectDurationMean": { + "$ref": "#/$defs/timeSeries" + }, + "attestationsCollectAllowanceMean": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorTxsFromMempoolRate": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorTxsFromP2pRate": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorMissingRate": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorRequestedFractionMean": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorRequestDelayP95": { + "$ref": "#/$defs/timeSeries" + }, + "sequencerStateDurationP95": { + "$ref": "#/$defs/timeSeries" + } } }, - "timeSeries": { "type": "object", "additionalProperties": false, - "required": ["metric", "source", "series"], + "required": [ + "metric", + "source", + "series" + ], "properties": { "metric": { "type": "string", @@ -309,73 +525,112 @@ }, "unit": { "type": "string", - "examples": ["ms", "tps", "mana/s", "count"] + "examples": [ + "ms", + "tps", + "mana/s", + "count" + ] }, "source": { "type": "string", - "const": "promql", - "description": "Future-proofing: other series sources may exist (e.g. 'log-aggregated') with different provenance semantics." + "enum": [ + "promql", + "client_observed" + ], + "description": "Provenance: 'promql' = scraped via PromQL from cluster Prometheus; 'client_observed' = computed in this scraper from per-tx records emitted by n_tps.test.ts (e.g. headline tx_mined_delay)." }, "query": { "type": "string", - "description": "Exact PromQL used. Kept for audit: if a value looks wrong, the query is the first thing to check." + "description": "For source=promql: exact PromQL used. For source=client_observed: a human-readable description of the computation. Kept for audit: if a value looks wrong, the query is the first thing to check." + }, + "stepSeconds": { + "type": "integer", + "minimum": 1 }, - "stepSeconds": { "type": "integer", "minimum": 1 }, "series": { "type": "array", "description": "One entry per Prometheus series returned by the query. Single-series queries (e.g. inclusionTps) emit one entry with empty labels. Multi-series queries (per-pod, per-topic, per-rejection-reason, etc.) emit one entry per label combination.", - "items": { "$ref": "#/$defs/seriesEntry" } + "items": { + "$ref": "#/$defs/seriesEntry" + } } } }, - "seriesEntry": { "type": "object", "additionalProperties": false, - "required": ["labels", "points"], + "required": [ + "labels", + "points" + ], "properties": { "labels": { "type": "object", - "additionalProperties": { "type": "string" }, + "additionalProperties": { + "type": "string" + }, "description": "Prometheus labels that disambiguate this series. Empty {} for single-series queries. Common keys: k8s_pod_name, aztec_gossip_topic_name, rejection_reason, aztec_sequencer_state." }, "points": { "type": "array", "description": "Samples ordered by unixEpoch ascending. Missing samples (Prom didn't scrape in that window) are omitted rather than interpolated — consumers decide how to handle gaps.", - "items": { "$ref": "#/$defs/tsPoint" } + "items": { + "$ref": "#/$defs/tsPoint" + } } } }, - "tsPoint": { "type": "object", "additionalProperties": false, - "required": ["unixEpoch", "value"], + "required": [ + "unixEpoch", + "value" + ], "properties": { "unixEpoch": { "type": "integer", "description": "Seconds since unix epoch for this sample. Dashboards normalise to time-within-run via unixEpoch - run.startedAt at render time." }, "value": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "description": "Metric value. null if Prom returned NaN / no data for this step." } } }, - "blockRecord": { "type": "object", "additionalProperties": false, - "required": ["blockNumber", "blockNumberInTest", "minedAt"], + "required": [ + "blockNumber", + "blockNumberInTest", + "minedAt" + ], "properties": { - "blockNumber": { "type": "integer", "minimum": 0 }, + "blockNumber": { + "type": "integer", + "minimum": 0 + }, "blockNumberInTest": { "type": "integer", "description": "blockNumber - firstBlockInTest. First block mined after run.startedAt is 0." }, - "minedAt": { "type": "string", "format": "date-time" }, - "successfulCount": { "type": "integer", "minimum": 0 }, - "failedCount": { "type": "integer", "minimum": 0 }, + "minedAt": { + "type": "string", + "format": "date-time" + }, + "successfulCount": { + "type": "integer", + "minimum": 0 + }, + "failedCount": { + "type": "integer", + "minimum": 0 + }, "silentlySkippedCount": { "type": "integer", "minimum": 0, @@ -386,16 +641,26 @@ "minimum": 0, "description": "Wall-clock time spent on silently-skipped txs in this block. Added 2026-04-22." }, - "buildDurationSeconds": { "type": "number", "minimum": 0 }, + "buildDurationSeconds": { + "type": "number", + "minimum": 0 + }, "totalPublicGas": { "type": "object", "additionalProperties": false, "properties": { - "daGas": { "type": "integer" }, - "l2Gas": { "type": "integer" } + "daGas": { + "type": "integer" + }, + "l2Gas": { + "type": "integer" + } } }, - "totalSizeInBytes": { "type": "integer", "minimum": 0 }, + "totalSizeInBytes": { + "type": "integer", + "minimum": 0 + }, "source": { "type": "string", "const": "log", @@ -403,15 +668,29 @@ } } }, - "event": { "type": "object", "additionalProperties": false, - "required": ["at", "type"], + "required": [ + "at", + "type" + ], "properties": { - "at": { "type": "string", "format": "date-time" }, - "type": { "type": "string", "enum": ["chainPruned", "slotSummary"] }, - "source": { "type": "string", "const": "log" }, + "at": { + "type": "string", + "format": "date-time" + }, + "type": { + "type": "string", + "enum": [ + "chainPruned", + "slotSummary" + ] + }, + "source": { + "type": "string", + "const": "log" + }, "fromBlock": { "type": "integer", "description": "For chainPruned: the pre-prune tip." @@ -428,20 +707,40 @@ "type": "integer", "description": "For slotSummary: wall-clock slot in which the checkpoint was built." }, - "checkpointNumber": { "type": "integer" }, - "sourcePod": { "type": "string" }, + "checkpointNumber": { + "type": "integer" + }, + "sourcePod": { + "type": "string" + }, "proposer": { "type": "string", "description": "Validator/proposer address selected for this slot." }, - "attestorAddress": { "type": "string" }, - "publisherAddress": { "type": "string" }, - "blocksBuilt": { "type": "number", "minimum": 0 }, - "txCount": { "type": "number", "minimum": 0 }, - "totalMana": { "type": "number", "minimum": 0 }, + "attestorAddress": { + "type": "string" + }, + "publisherAddress": { + "type": "string" + }, + "blocksBuilt": { + "type": "number", + "minimum": 0 + }, + "txCount": { + "type": "number", + "minimum": 0 + }, + "totalMana": { + "type": "number", + "minimum": 0 + }, "blockBuildFailures": { "type": "array", - "items": { "type": "object", "additionalProperties": true } + "items": { + "type": "object", + "additionalProperties": true + } }, "checkpointBuildFailure": { "type": "object", @@ -459,11 +758,16 @@ } } }, - "sequencerStateSlot": { "type": "object", "additionalProperties": false, - "required": ["slotNumber", "startedAt", "endedAt", "totalMs", "states"], + "required": [ + "slotNumber", + "startedAt", + "endedAt", + "totalMs", + "states" + ], "properties": { "slotNumber": { "type": "integer", @@ -490,10 +794,13 @@ }, "states": { "type": "object", - "additionalProperties": { "type": "number", "minimum": 0 }, + "additionalProperties": { + "type": "number", + "minimum": 0 + }, "description": "Map from SequencerState name to total milliseconds spent in that state during this slot." } } } } -} +} \ No newline at end of file diff --git a/spartan/scripts/bench_10tps/bench_scrape.ts b/spartan/scripts/bench_10tps/bench_scrape.ts index 3f819585bcfd..f2bfdc301a39 100755 --- a/spartan/scripts/bench_10tps/bench_scrape.ts +++ b/spartan/scripts/bench_10tps/bench_scrape.ts @@ -53,6 +53,7 @@ type Args = { targetTps: number; workload: string; output: string | undefined; + inclusionRecords: string | undefined; waitForPendingZero: boolean; maxPendingWaitSeconds: number; }; @@ -78,6 +79,10 @@ function parseArgs(): Args { argv.indexOf("--output") === -1 ? undefined : argv[argv.indexOf("--output") + 1], + inclusionRecords: + argv.indexOf("--inclusion-records") === -1 + ? undefined + : argv[argv.indexOf("--inclusion-records") + 1], waitForPendingZero: !argv.includes("--no-wait-for-pending-zero") && (argv.includes("--wait-for-pending-zero") || @@ -134,6 +139,128 @@ type SeriesEntry = { points: TsPoint[]; }; +// --- Inclusion records (client-observed per-tx timing from n_tps.test.ts) --- + +// Subset of TxInclusionData (yarn-project/.../tx_metrics.ts) that we care +// about. Records are emitted into /tmp/n_tps_timing_data.json under the +// `inclusionRecords` key, filtered to the high-value group, so this is the +// authoritative client-observed inclusion-latency dataset for the run. +type InclusionRecord = { + txHash: string; + sentAtMs: number; + minedAtMs: number; + blocknumber: number; +}; + +async function loadInclusionRecords( + path: string | undefined, +): Promise { + if (!path) return []; + try { + const raw = await readFile(path, "utf8"); + const parsed = JSON.parse(raw) as { + inclusionRecords?: InclusionRecord[]; + }; + const records = parsed.inclusionRecords ?? []; + log(`Loaded ${records.length} inclusion records`, { path }); + return records; + } catch (err) { + log("inclusion records load failed", { + path, + err: err instanceof Error ? err.message : String(err), + }); + return []; + } +} + +// Nearest-rank quantile. Returns null on empty input. +function quantile(sorted: number[], p: number): number | null { + if (sorted.length === 0) return null; + const idx = Math.min(sorted.length - 1, Math.floor(p * sorted.length)); + return sorted[idx]; +} + +function deltasMs(records: InclusionRecord[]): number[] { + const out: number[] = []; + for (const r of records) { + if (r.sentAtMs > 0 && r.minedAtMs > 0) { + const d = r.minedAtMs - r.sentAtMs; + if (d > 0) out.push(d); + } + } + return out; +} + +function inclusionLatencyScalarMs( + records: InclusionRecord[], + p: number, +): number | null { + const sorted = deltasMs(records).sort((a, b) => a - b); + return quantile(sorted, p); +} + +// Bin records by sentAt minute, compute per-bin quantile. Matches the +// `[1m]` window semantics the old Prom-based tx_mined_delay queries used. +function inclusionLatencyTimeSeriesPoints( + records: InclusionRecord[], + startedAtEpoch: number, + endedAtEpoch: number, + p: number, + bucketSec = 60, +): TsPoint[] { + const bins = new Map(); + for (const r of records) { + if (r.sentAtMs <= 0 || r.minedAtMs <= 0) continue; + const sentSec = Math.floor(r.sentAtMs / 1000); + if (sentSec < startedAtEpoch || sentSec > endedAtEpoch) continue; + const d = r.minedAtMs - r.sentAtMs; + if (d <= 0) continue; + const bin = Math.floor(sentSec / bucketSec) * bucketSec; + const arr = bins.get(bin) ?? []; + arr.push(d); + bins.set(bin, arr); + } + const points: TsPoint[] = []; + for (const bin of [...bins.keys()].sort((a, b) => a - b)) { + const arr = bins.get(bin)!.sort((a, b) => a - b); + points.push({ unixEpoch: bin, value: quantile(arr, p) }); + } + return points; +} + +function buildInclusionLatencyTimeSeries( + records: InclusionRecord[], + startedAtEpoch: number, + endedAtEpoch: number, + p: number, +): { + metric: string; + unit: string; + source: string; + query: string; + stepSeconds: number; + series: SeriesEntry[]; +} { + return { + metric: "n_tps_test.tx_inclusion_time", + unit: "ms", + source: "client_observed", + query: `n_tps.test.ts inclusionRecords (group=tx_inclusion_time), quantile=${p}, 60s bins by sentAtMs`, + stepSeconds: 60, + series: [ + { + labels: {}, + points: inclusionLatencyTimeSeriesPoints( + records, + startedAtEpoch, + endedAtEpoch, + p, + ), + }, + ], + }; +} + const parseValue = (v: string | undefined): number | null => v === undefined || v === "NaN" ? null : Number(v); @@ -1408,6 +1535,7 @@ type SummaryArgs = { timeSeries: Record; blocks: BlockRecord[]; events: Event[]; + inclusionRecords: InclusionRecord[]; }; async function buildSummary(a: SummaryArgs): Promise> { @@ -1463,24 +1591,17 @@ async function buildSummary(a: SummaryArgs): Promise> { const oneShotQuantile = (q: number, bucket: string) => `histogram_quantile(${q}, sum by (le)(rate(${bucket}${NS}[${windowSpec}])))`; - const [ - inclLatP50, - inclLatP95, - inclLatP99, - buildP50, - buildP95, - ppTxP50, - ppTxP95, - ] = await Promise.all([ - safeInstant( - oneShotQuantile(0.5, "aztec_mempool_tx_mined_delay_milliseconds_bucket"), - ), - safeInstant( - oneShotQuantile(0.95, "aztec_mempool_tx_mined_delay_milliseconds_bucket"), - ), - safeInstant( - oneShotQuantile(0.99, "aztec_mempool_tx_mined_delay_milliseconds_bucket"), - ), + // Inclusion-latency quantiles are now computed from per-tx client-observed + // records emitted by n_tps.test.ts (high-value group only). The other + // histogram-based scalars below still come from Prometheus. + const inclLatP50 = inclusionLatencyScalarMs(a.inclusionRecords, 0.5); + const inclLatP95 = inclusionLatencyScalarMs(a.inclusionRecords, 0.95); + const inclLatP99 = inclusionLatencyScalarMs(a.inclusionRecords, 0.99); + if (a.inclusionRecords.length === 0) { + log("No inclusion records loaded; summary.inclusionLatencyP* will be null"); + } + + const [buildP50, buildP95, ppTxP50, ppTxP95] = await Promise.all([ safeInstant( oneShotQuantile( 0.5, @@ -1794,6 +1915,34 @@ async function main(): Promise { log("Scraping Prometheus time-series"); const timeSeries = await scrapeTimeSeries(startedAtEpoch, promEndEpoch); + log("Loading client-observed inclusion records"); + const inclusionRecords = await loadInclusionRecords(args.inclusionRecords); + // Compute the headline inclusion-latency time series from per-tx records + // and inject under the same slugs the dashboard reads. No Prometheus + // dependency for these — they reflect the true client → block-visible + // wall-clock latency for high-value txs only. + (timeSeries as Record).txMinedDelayP50 = + buildInclusionLatencyTimeSeries( + inclusionRecords, + startedAtEpoch, + promEndEpoch, + 0.5, + ); + (timeSeries as Record).txMinedDelayP95 = + buildInclusionLatencyTimeSeries( + inclusionRecords, + startedAtEpoch, + promEndEpoch, + 0.95, + ); + (timeSeries as Record).txMinedDelayP99 = + buildInclusionLatencyTimeSeries( + inclusionRecords, + startedAtEpoch, + promEndEpoch, + 0.99, + ); + log("Scraping per-block logs from gcloud"); // Extend the log window by the drain buffer too — some blocks near endedAt // arrive in gcloud after the test stops sending. @@ -1848,6 +1997,7 @@ async function main(): Promise { timeSeries: timeSeries as Record, blocks, events, + inclusionRecords, }); const payload = { diff --git a/spartan/scripts/check_env_vars.sh b/spartan/scripts/check_env_vars.sh index 4622a51757f1..7976030a21f3 100755 --- a/spartan/scripts/check_env_vars.sh +++ b/spartan/scripts/check_env_vars.sh @@ -157,7 +157,6 @@ EXCLUDED_VARS_ARRAY=( "SERVICE" "SLACK_WEBHOOK_SECRET_NAME" "SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME" - "SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME" "SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME" "SLACK_WEBHOOK_NEXT_NET_SECRET_NAME" "SLACK_WEBHOOK_TESTNET_SECRET_NAME" diff --git a/spartan/scripts/deploy_network.sh b/spartan/scripts/deploy_network.sh index edd3526eb4b8..9ef173dfdacd 100755 --- a/spartan/scripts/deploy_network.sh +++ b/spartan/scripts/deploy_network.sh @@ -43,7 +43,7 @@ declare -A STAGE_TIMINGS ######################## NAMESPACE=${NAMESPACE} # required CLUSTER=${CLUSTER:-kind} -RESOURCE_PROFILE=${RESOURCE_PROFILE:-$([[ "${CLUSTER}" == "kind" ]] && echo "dev" || echo "prod")} +RESOURCE_PROFILE=${RESOURCE_PROFILE:?RESOURCE_PROFILE must be set by the environment} BASE_STATE_PATH="${CLUSTER}/${NAMESPACE}" # Don't try and retrieve contract addresses, instead allow deployed infra to read from network config @@ -586,15 +586,16 @@ PROVER_PUBLISHERS_PER_PROVER = ${PUBLISHERS_PER_PROVER} SENTINEL_ENABLED = ${SENTINEL_ENABLED:-null} SLASH_INACTIVITY_TARGET_PERCENTAGE = ${SLASH_INACTIVITY_TARGET_PERCENTAGE:-null} SLASH_INACTIVITY_PENALTY = ${SLASH_INACTIVITY_PENALTY:-null} -SLASH_PRUNE_PENALTY = ${SLASH_PRUNE_PENALTY:-null} SLASH_DATA_WITHHOLDING_PENALTY = ${SLASH_DATA_WITHHOLDING_PENALTY:-null} +SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS = ${SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS:-null} SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY = ${SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY:-null} SLASH_DUPLICATE_PROPOSAL_PENALTY = ${SLASH_DUPLICATE_PROPOSAL_PENALTY:-null} SLASH_DUPLICATE_ATTESTATION_PENALTY = ${SLASH_DUPLICATE_ATTESTATION_PENALTY:-null} -SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY = ${SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY:-null} +SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY = ${SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY:-null} SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY = ${SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY:-null} SLASH_UNKNOWN_PENALTY = ${SLASH_UNKNOWN_PENALTY:-null} SLASH_INVALID_BLOCK_PENALTY = ${SLASH_INVALID_BLOCK_PENALTY:-null} +SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY = ${SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY:-null} SLASH_OFFENSE_EXPIRATION_ROUNDS = ${SLASH_OFFENSE_EXPIRATION_ROUNDS:-null} SLASH_MAX_PAYLOAD_SIZE = ${SLASH_MAX_PAYLOAD_SIZE:-null} OTEL_COLLECTOR_ENDPOINT = "${OTEL_COLLECTOR_ENDPOINT}" diff --git a/spartan/scripts/network_pause.sh b/spartan/scripts/network_pause.sh index 706b9553b911..8cf0b2f02fd7 100755 --- a/spartan/scripts/network_pause.sh +++ b/spartan/scripts/network_pause.sh @@ -44,7 +44,7 @@ if kubectl get cronjob "$SNAPSHOT_CRONJOB" -n "$NAMESPACE" &>/dev/null; then log "Snapshotting $NAMESPACE" $scripts_dir/manual_snapshot.sh $NAMESPACE log "Waiting for snapshot upload" - sleep 60 # staging-ignition takes 28s + sleep 60 else log "Snapshot cronjob not found ($SNAPSHOT_CRONJOB), skipping snapshot" fi diff --git a/spartan/scripts/wait_for_l2_block.sh b/spartan/scripts/wait_for_l2_block.sh index f3b9278c4177..19f238234111 100755 --- a/spartan/scripts/wait_for_l2_block.sh +++ b/spartan/scripts/wait_for_l2_block.sh @@ -6,6 +6,7 @@ # AZTEC_SLOT_DURATION - seconds per L2 slot # AZTEC_EPOCH_DURATION - slots per epoch # AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET - epochs to wait for validator set +# AZTEC_LAG_IN_EPOCHS_FOR_RANDAO - epochs to wait for RANDAO seed set -euo pipefail @@ -13,25 +14,36 @@ namespace="${1:?namespace is required}" slot_duration="${AZTEC_SLOT_DURATION:?AZTEC_SLOT_DURATION must be set}" epoch_duration="${AZTEC_EPOCH_DURATION:?AZTEC_EPOCH_DURATION must be set}" -lag_epochs="${AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET:?AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET must be set}" +validator_lag_epochs="${AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET:?AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET must be set}" +randao_lag_epochs="${AZTEC_LAG_IN_EPOCHS_FOR_RANDAO:-$validator_lag_epochs}" -# Time to first block = lag_epochs * epoch_duration * slot_duration + buffer -# Add 2x buffer for deployment overhead, validator registration, etc. -expected_wait=$((lag_epochs * epoch_duration * slot_duration)) -max_wait=$((expected_wait * 2 + 120)) # 2x expected + 2min buffer +if [ "$validator_lag_epochs" -gt "$randao_lag_epochs" ]; then + lag_epochs="$validator_lag_epochs" +else + lag_epochs="$randao_lag_epochs" +fi + +# A fresh rollup needs lag + 1 complete epochs before the first committee-backed +# block can be proposed. Add half an epoch plus 5m for deployment and RPC jitter. +warmup_epochs=$((lag_epochs + 1)) +expected_wait=$((warmup_epochs * epoch_duration * slot_duration)) +buffer=$((epoch_duration * slot_duration / 2 + 300)) +max_wait="${L2_BLOCK_WAIT_TIMEOUT_SECONDS:-$((expected_wait + buffer))}" poll_interval=10 -echo "Waiting for L2 blocks (slot=${slot_duration}s, epoch=${epoch_duration} slots, lag=${lag_epochs} epochs)" -echo "Expected first block in ~${expected_wait}s, max wait ${max_wait}s" +echo "Waiting for L2 blocks (slot=${slot_duration}s, epoch=${epoch_duration} slots, validator_lag=${validator_lag_epochs}, randao_lag=${randao_lag_epochs})" +echo "Expected first block after ~${expected_wait}s from genesis, max wait ${max_wait}s from now" rpc_pod="${namespace}-rpc-aztec-node-0" +block_number_request="{\"jsonrpc\":\"2.0\",\"method\":\"node_getBlockNumber\",\"params\":[],\"id\":1}" elapsed=0 while [ $elapsed -lt $max_wait ]; do - block_number=$(kubectl exec -n "$namespace" "$rpc_pod" -- \ - curl -s -X POST http://localhost:8080 \ - -H "Content-Type: application/json" \ - -d '{"jsonrpc":"2.0","method":"node_getBlockNumber","params":[],"id":1}' 2>/dev/null \ - | grep -o '"result":[0-9]*' | grep -o '[0-9]*' || echo "0") + block_number=$(kubectl --request-timeout=10s exec -n "$namespace" "$rpc_pod" -- \ + sh -c "curl --max-time 5 -s -X POST http://localhost:8080 \ + -H \"Content-Type: application/json\" \ + -d \"\$1\" \ + | jq -r \".result // 0\"" \ + sh "$block_number_request" 2>/dev/null || echo "0") if [ "$block_number" -ge 1 ] 2>/dev/null; then echo "L2 block $block_number mined after ${elapsed}s" @@ -39,8 +51,16 @@ while [ $elapsed -lt $max_wait ]; do fi echo "Waiting for L2 blocks... (${elapsed}s/${max_wait}s, block: ${block_number:-0})" - sleep $poll_interval - elapsed=$((elapsed + poll_interval)) + sleep_for=$poll_interval + remaining=$((max_wait - elapsed)) + if [ "$remaining" -lt "$sleep_for" ]; then + sleep_for=$remaining + fi + if [ "$sleep_for" -le 0 ]; then + break + fi + sleep "$sleep_for" + elapsed=$((elapsed + sleep_for)) done echo "Warning: No L2 blocks mined after ${max_wait}s" diff --git a/spartan/terraform/deploy-aztec-infra/main.tf b/spartan/terraform/deploy-aztec-infra/main.tf index 13ea3870380f..46583be5f6fc 100644 --- a/spartan/terraform/deploy-aztec-infra/main.tf +++ b/spartan/terraform/deploy-aztec-infra/main.tf @@ -157,11 +157,11 @@ locals { validator_base_config = { chart = "aztec-validator" timeout = 1800 - values = [ + values = concat([ "common.yaml", "validator.yaml", "validator-resources-${var.VALIDATOR_RESOURCE_PROFILE}.yaml" - ] + ], var.VALIDATOR_HA_REPLICAS > 0 ? ["validator-resources-spot.yaml", "validator-resources-ha.yaml"] : []) inline_values = [yamlencode({ validator = { service = { @@ -170,18 +170,6 @@ locals { node = { logLevel = var.LOG_LEVEL } - # spread validator pods to different nodes to avoid having two validators with the same attester keys on the same physical node - topologySpreadConstraints = [{ - maxSkew = 1 - topologyKey = "kubernetes.io/hostname" - whenUnsatisfiable = "ScheduleAnyway" # soft constraint - labelSelector = { - matchLabels = { - "app.kubernetes.io/component" = "sequencer-node" - } - } - matchLabelKeys = ["apps.kubernetes.io/pod-index"] - }] } })] boot_node_host_path = "validator.node.env.BOOT_NODE_HOST" @@ -200,15 +188,16 @@ locals { "validator.sentinel.enabled" = var.SENTINEL_ENABLED "validator.slash.inactivityTargetPercentage" = var.SLASH_INACTIVITY_TARGET_PERCENTAGE "validator.slash.inactivityPenalty" = var.SLASH_INACTIVITY_PENALTY - "validator.slash.prunePenalty" = var.SLASH_PRUNE_PENALTY "validator.slash.dataWithholdingPenalty" = var.SLASH_DATA_WITHHOLDING_PENALTY + "validator.slash.dataWithholdingToleranceSlots" = var.SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS "validator.slash.proposeInvalidAttestationsPenalty" = var.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY "validator.slash.duplicateProposalPenalty" = var.SLASH_DUPLICATE_PROPOSAL_PENALTY "validator.slash.duplicateAttestationPenalty" = var.SLASH_DUPLICATE_ATTESTATION_PENALTY - "validator.slash.attestDescendantOfInvalidPenalty" = var.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY + "validator.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty" = var.SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY "validator.slash.attestInvalidCheckpointProposalPenalty" = var.SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY "validator.slash.unknownPenalty" = var.SLASH_UNKNOWN_PENALTY "validator.slash.invalidBlockPenalty" = var.SLASH_INVALID_BLOCK_PENALTY + "validator.slash.invalidCheckpointProposalPenalty" = var.SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY "validator.slash.offenseExpirationRounds" = var.SLASH_OFFENSE_EXPIRATION_ROUNDS "validator.slash.maxPayloadSize" = var.SLASH_MAX_PAYLOAD_SIZE "validator.node.env.TRANSACTIONS_DISABLED" = var.TRANSACTIONS_DISABLED diff --git a/spartan/terraform/deploy-aztec-infra/values/blob-sink-resources-mainnet.yaml b/spartan/terraform/deploy-aztec-infra/values/blob-sink-resources-mainnet.yaml deleted file mode 100644 index 17a98678a4b3..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/blob-sink-resources-mainnet.yaml +++ /dev/null @@ -1,41 +0,0 @@ -nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "4" - -replicaCount: 1 - -node: - nodeJsOptions: - - "--max-old-space-size=12288" - resources: - requests: - cpu: "2" - memory: "8Gi" - limits: - cpu: "3.5" - memory: "14Gi" - -persistence: - enabled: true - -statefulSet: - enabled: true - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi - -service: - type: ClusterIP - p2p: - enabled: true - nodePortEnabled: false - admin: - enabled: false - headless: - enabled: false diff --git a/spartan/terraform/deploy-aztec-infra/values/bot-resources-dev.yaml b/spartan/terraform/deploy-aztec-infra/values/bot-resources-dev.yaml index 435afd48a65d..8f555ff021e4 100644 --- a/spartan/terraform/deploy-aztec-infra/values/bot-resources-dev.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/bot-resources-dev.yaml @@ -1,4 +1,24 @@ bot: + nodeSelector: + local-ssd: "false" + node-type: "network" + cores: "2" + pool: "spot" + + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-spot + operator: Exists + + tolerations: + - key: "cloud.google.com/gke-spot" + operator: "Equal" + value: "true" + effect: "NoSchedule" + node: resources: requests: @@ -7,4 +27,3 @@ bot: limits: cpu: "0.5" memory: "2Gi" - diff --git a/spartan/terraform/deploy-aztec-infra/values/bot-resources-prod.yaml b/spartan/terraform/deploy-aztec-infra/values/bot-resources-prod.yaml index 6feb5f1183cf..66da7f06194a 100644 --- a/spartan/terraform/deploy-aztec-infra/values/bot-resources-prod.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/bot-resources-prod.yaml @@ -2,7 +2,8 @@ bot: nodeSelector: local-ssd: "false" node-type: "network" - cores: "8" + cores: "2" + pool: "spot" affinity: nodeAffinity: @@ -21,5 +22,8 @@ bot: node: resources: requests: - cpu: "7" - memory: "16Gi" + cpu: "0.5" + memory: "1Gi" + limits: + cpu: "2" + memory: "4Gi" diff --git a/spartan/terraform/deploy-aztec-infra/values/full-node-resources-2-core-spot.yaml b/spartan/terraform/deploy-aztec-infra/values/full-node-resources-2-core-spot.yaml deleted file mode 100644 index 63577f7db2c9..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/full-node-resources-2-core-spot.yaml +++ /dev/null @@ -1,52 +0,0 @@ -nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "2" - pool: "spot" - -affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: cloud.google.com/gke-spot - operator: Exists - -tolerations: - - key: "cloud.google.com/gke-spot" - operator: "Equal" - value: "true" - effect: "NoSchedule" - -replicaCount: 1 - -node: - resources: - requests: - cpu: "0.5" - memory: "2Gi" - limits: - cpu: "1.5" - memory: "6Gi" -persistence: - enabled: true - -statefulSet: - enabled: true - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 10Gi - -service: - p2p: - enabled: true - nodePortEnabled: false - admin: - enabled: true - headless: - enabled: false diff --git a/spartan/terraform/deploy-aztec-infra/values/full-node-resources-prod.yaml b/spartan/terraform/deploy-aztec-infra/values/full-node-resources-prod.yaml index f98197846110..841620706871 100644 --- a/spartan/terraform/deploy-aztec-infra/values/full-node-resources-prod.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/full-node-resources-prod.yaml @@ -2,19 +2,6 @@ nodeSelector: local-ssd: "false" node-type: "network" cores: "2" - -affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - node - topologyKey: "kubernetes.io/hostname" - namespaceSelector: {} - replicaCount: 1 node: diff --git a/spartan/terraform/deploy-aztec-infra/values/prover-resources-hi-tps.yaml b/spartan/terraform/deploy-aztec-infra/values/prover-resources-dev-hi-tps.yaml similarity index 82% rename from spartan/terraform/deploy-aztec-infra/values/prover-resources-hi-tps.yaml rename to spartan/terraform/deploy-aztec-infra/values/prover-resources-dev-hi-tps.yaml index 586e22a37d7b..dfb893b64230 100644 --- a/spartan/terraform/deploy-aztec-infra/values/prover-resources-hi-tps.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/prover-resources-dev-hi-tps.yaml @@ -14,18 +14,6 @@ node: cores: "8" hi-mem: "true" - affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - node - topologyKey: "kubernetes.io/hostname" - namespaceSelector: {} - persistence: enabled: true statefulSet: @@ -64,7 +52,6 @@ broker: - "--max-old-space-size=65536" resources: requests: - # should land on a 8-core node cpu: "5" memory: "54Gi" diff --git a/spartan/terraform/deploy-aztec-infra/values/prover-resources-mainnet.yaml b/spartan/terraform/deploy-aztec-infra/values/prover-resources-mainnet.yaml deleted file mode 100644 index d1f078b792a4..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/prover-resources-mainnet.yaml +++ /dev/null @@ -1,83 +0,0 @@ -node: - node: - nodeJsOptions: - - "--max-old-space-size=12288" - resources: - requests: - cpu: "2" - memory: "8Gi" - limits: - cpu: "3.5" - memory: "14Gi" - - nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "4" - - persistence: - enabled: true - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi - -broker: - replicaCount: 1 - - nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "4" - - persistence: - enabled: true - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 8Gi - node: - nodeJsOptions: - - "--max-old-space-size=12288" - resources: - requests: - cpu: "2" - memory: "8Gi" - limits: - cpu: "3.5" - memory: "14Gi" - -agent: - replicaCount: 4 - - node: - env: - HARDWARE_CONCURRENCY: "32" - resources: - requests: - memory: "115Gi" - cpu: "31" - - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: cloud.google.com/gke-spot - operator: Exists - - tolerations: - - key: "cloud.google.com/gke-spot" - operator: "Equal" - value: "true" - effect: "NoSchedule" diff --git a/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod-hi-tps.yaml b/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod-hi-tps.yaml index ffd0347086cc..0c8afe9bf385 100644 --- a/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod-hi-tps.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod-hi-tps.yaml @@ -1,12 +1,12 @@ node: node: + enableInspector: true + nodeJsOptions: + - "--max-old-space-size=65536" resources: requests: - cpu: "7.5" - memory: "55Gi" - - nodeJsOptions: - - "--max-old-space-size=61440" + cpu: "6" + memory: "54Gi" nodeSelector: local-ssd: "false" @@ -29,15 +29,6 @@ node: broker: replicaCount: 1 - node: - resources: - requests: - cpu: "7.5" - memory: "55Gi" - - nodeJsOptions: - - "--max-old-space-size=61440" - nodeSelector: local-ssd: "false" node-type: "network" @@ -54,18 +45,32 @@ broker: accessModes: [ReadWriteOnce] resources: requests: - storage: 64Gi + storage: 32Gi + node: + enableInspector: true + nodeJsOptions: + - "--max-old-space-size=65536" + resources: + requests: + cpu: "5" + memory: "54Gi" + agent: replicaCount: 4 node: env: - # the pod will be scheduled on a 32-core VM - HARDWARE_CONCURRENCY: "32" + HARDWARE_CONCURRENCY: "16" resources: requests: - memory: "115Gi" - cpu: "31" + cpu: "4" + memory: "16Gi" + limits: + cpu: "16" + memory: "64Gi" + + nodeSelector: + pool: "spot" affinity: nodeAffinity: diff --git a/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod.yaml b/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod.yaml index b1175d43bae1..91710c0e321c 100644 --- a/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod.yaml @@ -58,12 +58,17 @@ agent: node: env: - # the pod will be scheduled on a 32-core VM - HARDWARE_CONCURRENCY: "32" + HARDWARE_CONCURRENCY: "16" resources: requests: - memory: "115Gi" - cpu: "31" + cpu: "4" + memory: "16Gi" + limits: + cpu: "16" + memory: "64Gi" + + nodeSelector: + pool: "spot" affinity: nodeAffinity: diff --git a/spartan/terraform/deploy-aztec-infra/values/rpc-resources-mainnet.yaml b/spartan/terraform/deploy-aztec-infra/values/rpc-resources-mainnet.yaml deleted file mode 100644 index 0a421fae62c4..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/rpc-resources-mainnet.yaml +++ /dev/null @@ -1,39 +0,0 @@ -nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "4" - -replicaCount: 1 - -node: - nodeJsOptions: - - "--max-old-space-size=12288" - resources: - requests: - cpu: "2" - memory: "8Gi" - limits: - cpu: "3.5" - memory: "14Gi" -persistence: - enabled: true - -statefulSet: - enabled: true - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi - -service: - p2p: - enabled: true - nodePortEnabled: false - admin: - enabled: true - headless: - enabled: false diff --git a/spartan/terraform/deploy-aztec-infra/values/validator-resources-2-core-dedicated.yaml b/spartan/terraform/deploy-aztec-infra/values/validator-resources-2-core-dedicated.yaml deleted file mode 100644 index 52b309cb781a..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/validator-resources-2-core-dedicated.yaml +++ /dev/null @@ -1,22 +0,0 @@ -validator: - nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "2" - node: - resources: - requests: - cpu: "1.5" - memory: "4Gi" - limits: - cpu: "1.5" - memory: "6Gi" - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi diff --git a/spartan/terraform/deploy-aztec-infra/values/validator-resources-ha.yaml b/spartan/terraform/deploy-aztec-infra/values/validator-resources-ha.yaml new file mode 100644 index 000000000000..738996c3c859 --- /dev/null +++ b/spartan/terraform/deploy-aztec-infra/values/validator-resources-ha.yaml @@ -0,0 +1,10 @@ +validator: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + matchLabelKeys: + - apps.kubernetes.io/pod-index + labelSelector: + matchLabels: + app.kubernetes.io/component: sequencer-node diff --git a/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-hi-tps.yaml b/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-hi-tps.yaml deleted file mode 100644 index ea5ef92f5b67..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-hi-tps.yaml +++ /dev/null @@ -1,23 +0,0 @@ -validator: - nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "8" - hi-mem: "true" - node: - resources: - requests: - cpu: "7.5" - memory: "55Gi" - - nodeJsOptions: - - "--max-old-space-size=61440" - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi diff --git a/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-spot.yaml b/spartan/terraform/deploy-aztec-infra/values/validator-resources-spot.yaml similarity index 57% rename from spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-spot.yaml rename to spartan/terraform/deploy-aztec-infra/values/validator-resources-spot.yaml index 0c573f3ff06f..2699f98765f9 100644 --- a/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-spot.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/validator-resources-spot.yaml @@ -18,22 +18,3 @@ validator: operator: "Equal" value: "true" effect: "NoSchedule" - - node: - resources: - requests: - cpu: "0.5" - memory: "2Gi" - limits: - cpu: "1.5" - memory: "6Gi" - - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi diff --git a/spartan/terraform/deploy-aztec-infra/variables.tf b/spartan/terraform/deploy-aztec-infra/variables.tf index 538f37fd0b23..189ec5309838 100644 --- a/spartan/terraform/deploy-aztec-infra/variables.tf +++ b/spartan/terraform/deploy-aztec-infra/variables.tf @@ -24,49 +24,41 @@ variable "GCP_REGION" { variable "FULL_NODE_RESOURCE_PROFILE" { description = "Resource profile to use for the full node" type = string - default = "prod" } variable "P2P_BOOTSTRAP_RESOURCE_PROFILE" { description = "Resource profile to use for the p2p bootstrap" type = string - default = "prod" } variable "VALIDATOR_RESOURCE_PROFILE" { description = "Resource profile to use for the validator" type = string - default = "prod" } variable "PROVER_RESOURCE_PROFILE" { description = "Resource profile to use for the prover" type = string - default = "prod" } variable "RPC_RESOURCE_PROFILE" { description = "Resource profile to use for the rpc" type = string - default = "prod" } variable "BOT_RESOURCE_PROFILE" { description = "Resource profile to use for the bots" type = string - default = "prod" } variable "ARCHIVE_RESOURCE_PROFILE" { description = "Resource profile to use for the archive node" type = string - default = "prod" } variable "BLOB_SINK_RESOURCE_PROFILE" { description = "Resource profile to use for the blob sink" type = string - default = "prod" } variable "DEBUG_P2P_INSTRUMENT_MESSAGES" { @@ -466,14 +458,14 @@ variable "SLASH_INACTIVITY_PENALTY" { nullable = true } -variable "SLASH_PRUNE_PENALTY" { - description = "The slash prune penalty" +variable "SLASH_DATA_WITHHOLDING_PENALTY" { + description = "The slash data withholding penalty" type = string nullable = true } -variable "SLASH_DATA_WITHHOLDING_PENALTY" { - description = "The slash data withholding penalty" +variable "SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS" { + description = "L2 slots to wait after a checkpoint slot before slashing for data withholding" type = string nullable = true } @@ -496,8 +488,8 @@ variable "SLASH_DUPLICATE_ATTESTATION_PENALTY" { nullable = true } -variable "SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY" { - description = "The slash attest descendant of invalid penalty" +variable "SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY" { + description = "The slash propose descendant of invalid penalty" type = string nullable = true } @@ -520,6 +512,12 @@ variable "SLASH_INVALID_BLOCK_PENALTY" { nullable = true } +variable "SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY" { + description = "The slash invalid checkpoint proposal penalty" + type = string + nullable = true +} + variable "SLASH_OFFENSE_EXPIRATION_ROUNDS" { description = "The slash offense expiration rounds" type = string diff --git a/spartan/terraform/deploy-metrics/main.tf b/spartan/terraform/deploy-metrics/main.tf index 57467ee59855..bf30ce3d59ac 100644 --- a/spartan/terraform/deploy-metrics/main.tf +++ b/spartan/terraform/deploy-metrics/main.tf @@ -181,7 +181,6 @@ resource "helm_release" "aztec-gke-cluster" { data = [ { secretKey = "SLACK_WEBHOOK_URL", remoteRef = { key = var.SLACK_WEBHOOK_SECRET_NAME } }, { secretKey = "SLACK_WEBHOOK_STAGING_PUBLIC_URL", remoteRef = { key = var.SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME } }, - { secretKey = "SLACK_WEBHOOK_STAGING_IGNITION_URL", remoteRef = { key = var.SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME } }, { secretKey = "SLACK_WEBHOOK_NEXT_SCENARIO_URL", remoteRef = { key = var.SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME } }, { secretKey = "SLACK_WEBHOOK_NEXT_NET_URL", remoteRef = { key = var.SLACK_WEBHOOK_NEXT_NET_SECRET_NAME } }, { secretKey = "SLACK_WEBHOOK_DEVNET_URL", remoteRef = { key = var.SLACK_WEBHOOK_DEVNET_SECRET_NAME } }, diff --git a/spartan/terraform/deploy-metrics/variables.tf b/spartan/terraform/deploy-metrics/variables.tf index f7327e84877e..0745367539a5 100644 --- a/spartan/terraform/deploy-metrics/variables.tf +++ b/spartan/terraform/deploy-metrics/variables.tf @@ -34,12 +34,6 @@ variable "SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME" { default = "slack-webhook-staging-public-url" } -variable "SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME" { - description = "Webhook for staging-ignition alerts" - type = string - default = "slack-webhook-staging-ignition-url" -} - variable "SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME" { description = "Webhook for next-scenario alerts" type = string diff --git a/spartan/testnet-runbook.md b/spartan/testnet-runbook.md index 44eb1f265e59..dbd68a76d6d7 100644 --- a/spartan/testnet-runbook.md +++ b/spartan/testnet-runbook.md @@ -39,7 +39,7 @@ After cutting a release, deploy a public testnet using the new Docker containers Verbose logging on Aztec nodes should be enabled by default using the following `ENV VARS`: - `LOG_JSON=1` -- `LOG_LEVEL=debug` +- `LOG_LEVEL="debug; info: json-rpc, simulator"` Deployments are initiated from CI by manually running the (_name pending_) workflow. diff --git a/yarn-project/BRANCHING.md b/yarn-project/BRANCHING.md index 371c44da4a22..b5b414b1f398 100644 --- a/yarn-project/BRANCHING.md +++ b/yarn-project/BRANCHING.md @@ -58,13 +58,12 @@ Functionally, it is `v1`. It deploys the following networks: - staging-public, which is used to test changes before releasing to testnet -- staging-ignition, which is use to test changes before releasing to mainnet Release-please has been configured on `v2`. When the release-please PR is merged, it creates a clean tag at the next minor version. For example, at the time of writing, we are at `v2.0.3-rc.4`. When the release please PR is merged, it will create a tag `v2.0.4`. -This will cause ci3.yml to run a release, and then deploy-staging-networks.yml to run and deploy the two networks mentioned above as well as `testnet`. +This will cause ci3.yml to run a release, and then deploy-staging-networks.yml to run and deploy the staging network mentioned above as well as `testnet`. #### hotfixes diff --git a/yarn-project/CLAUDE.md b/yarn-project/CLAUDE.md index 070a5398537a..d83eb0b1dc68 100644 --- a/yarn-project/CLAUDE.md +++ b/yarn-project/CLAUDE.md @@ -118,7 +118,7 @@ yarn workspace @aztec/ test --runInBand ```bash LOG_LEVEL=verbose yarn workspace @aztec/ test src/file.test.ts # Recommended -LOG_LEVEL=debug yarn workspace @aztec/ test src/file.test.ts # More detail +LOG_LEVEL="debug; info: json-rpc, simulator" yarn workspace @aztec/ test src/file.test.ts # More detail # Available levels: trace, debug, verbose, info, warn # Module-specific logging @@ -131,7 +131,7 @@ LOG_LEVEL='info; debug:sequencer,archiver' yarn workspace @aztec/ ### Style -- **Line width**: 120 characters (`printWidth: 120` in `.prettierrc.json`). Wrap comments and code at 120, not 80. +- **Line width**: 120 characters (`printWidth: 120` in `.prettierrc.json`). Wrap **everything** at 120 — code, inline comments, and JSDoc/block comments alike. Do not wrap at 80, 90, or 100 out of habit. Prettier does not reflow comment bodies, so an under-wrapped JSDoc paragraph will sit at ~90 chars forever unless you wrote it at 120 to begin with. ### Format diff --git a/yarn-project/archiver/src/index.ts b/yarn-project/archiver/src/index.ts index 78587150a24b..d5a4868892af 100644 --- a/yarn-project/archiver/src/index.ts +++ b/yarn-project/archiver/src/index.ts @@ -4,6 +4,7 @@ export * from './archiver.js'; export * from './modules/data_source_base.js'; export * from './modules/data_store_updater.js'; export * from './config.js'; +export * from './errors.js'; export { type L1PublishedData } from './structs/published.js'; export { diff --git a/yarn-project/archiver/src/modules/data_store_updater.test.ts b/yarn-project/archiver/src/modules/data_store_updater.test.ts index 6316a16d5198..fa3a8ec9be60 100644 --- a/yarn-project/archiver/src/modules/data_store_updater.test.ts +++ b/yarn-project/archiver/src/modules/data_store_updater.test.ts @@ -6,6 +6,7 @@ import { ContractInstancePublishedEvent } from '@aztec/protocol-contracts/instan import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { L2Block } from '@aztec/stdlib/block'; import { ContractClassLog, PrivateLog } from '@aztec/stdlib/logs'; +import { CheckpointHeader } from '@aztec/stdlib/rollup'; import '@aztec/stdlib/testing/jest'; import { BlockHeader } from '@aztec/stdlib/tx'; @@ -122,6 +123,134 @@ describe('ArchiverDataStoreUpdater', () => { expect(await store.contractInstances.getContractInstance(instanceAddress, timestamp)).toBeUndefined(); }); + it('reconciles a local proposed block with an L1 checkpoint at the same block number but different slot', async () => { + // Regression for issue fixed at https://github.com/AztecProtocol/aztec-packages/pull/23461 + // Local proposed block 1 at slot 125, containing a deployed contract instance. + const localBlock = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(125), + }); + localBlock.body.txEffects[0].contractClassLogs = [contractClassLog]; + localBlock.body.txEffects[0].privateLogs = [ + PrivateLog.fromBuffer(getSampleContractInstancePublishedEventPayload()), + ]; + await updater.addProposedBlock(localBlock); + + const timestamp = localBlock.header.globalVariables.timestamp + 1n; + expect(await store.contractInstances.getContractInstance(instanceAddress, timestamp)).toBeDefined(); + + // L1 confirmed a different block 1 at slot 124, containing the SAME deployed contract instance + // (the same user tx ended up on chain, just signed by a different proposer at a different slot). + // Without the fix the prune step misses the conflict because the slot does not match, and + // re-applying the L1 block's contract data throws "Contract instance ... already exists". + const l1Block = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(124), + }); + l1Block.body.txEffects[0].contractClassLogs = [contractClassLog]; + l1Block.body.txEffects[0].privateLogs = [PrivateLog.fromBuffer(getSampleContractInstancePublishedEventPayload())]; + expect(l1Block.archive.root.equals(localBlock.archive.root)).toBe(false); + + const published = makePublishedCheckpoint(makeCheckpoint([l1Block]), 10); + + await expect(updater.addCheckpoints([published])).resolves.not.toThrow(); + + // The L1 block must end up persisted, with its contract instance reachable. + const storedBlock = await store.blocks.getBlock({ number: BlockNumber(1) }); + expect(storedBlock?.archive.root.equals(l1Block.archive.root)).toBe(true); + expect(await store.contractInstances.getContractInstance(instanceAddress, timestamp)).toBeDefined(); + }); + + it('evicts higher-numbered proposed checkpoints that chain off pruned blocks on conflict', async () => { + // Local builds: block 1 (slot 125, checkpoint 1) → proposed checkpoint 1 + // block 2 (slot 126, checkpoint 2) → proposed checkpoint 2 + // block_store.addCheckpoints already deletes the proposed entry at the same number it stores, + // so the eviction code matters specifically for higher-numbered proposed checkpoints whose + // referenced blocks were pruned by the conflict. + const localBlock1 = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(125), + }); + await updater.addProposedBlock(localBlock1); + await store.blocks.addProposedCheckpoint({ + checkpointNumber: CheckpointNumber(1), + header: CheckpointHeader.empty(), + startBlock: BlockNumber(1), + blockCount: 1, + totalManaUsed: 0n, + feeAssetPriceModifier: 0n, + }); + + const localBlock2 = await L2Block.random(BlockNumber(2), { + checkpointNumber: CheckpointNumber(2), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(126), + lastArchive: localBlock1.archive, + }); + await updater.addProposedBlock(localBlock2); + await store.blocks.addProposedCheckpoint({ + checkpointNumber: CheckpointNumber(2), + header: CheckpointHeader.empty(), + startBlock: BlockNumber(2), + blockCount: 1, + totalManaUsed: 0n, + feeAssetPriceModifier: 0n, + }); + + expect(await store.blocks.getProposedCheckpointNumber()).toBe(2); + + // L1 publishes a conflicting block 1. Pruning takes out both local blocks; both proposed + // checkpoints must be evicted (proposed 1 by block_store.addCheckpoints, proposed 2 by us). + const l1Block = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(124), + }); + expect(l1Block.archive.root.equals(localBlock1.archive.root)).toBe(false); + + await updater.addCheckpoints([makePublishedCheckpoint(makeCheckpoint([l1Block]), 10)]); + + expect(await store.blocks.getLastProposedCheckpoint()).toBeUndefined(); + }); + + it('preserves a speculative local block at a later slot when L1 confirms the matching previous block', async () => { + // Local proposes block 1 at slot 100 and a speculative block 2 at slot 101 built atop it. + // Pipelining: block 2 is the start of proposed checkpoint 2 and must not be pruned just + // because L1 confirmed a checkpoint that only contains block 1. + const localBlock1 = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(100), + }); + await updater.addProposedBlock(localBlock1); + + await store.blocks.addProposedCheckpoint({ + checkpointNumber: CheckpointNumber(1), + header: CheckpointHeader.empty(), + startBlock: BlockNumber(1), + blockCount: 1, + totalManaUsed: 0n, + feeAssetPriceModifier: 0n, + }); + + const localBlock2 = await L2Block.random(BlockNumber(2), { + checkpointNumber: CheckpointNumber(2), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(101), + lastArchive: localBlock1.archive, + }); + await updater.addProposedBlock(localBlock2); + + // L1 confirms checkpoint 1 with the same block 1 as local. Speculative block 2 must survive. + await updater.addCheckpoints([makePublishedCheckpoint(makeCheckpoint([localBlock1]), 10)]); + + const storedBlock2 = await store.blocks.getBlock({ number: BlockNumber(2) }); + expect(storedBlock2?.archive.root.equals(localBlock2.archive.root)).toBe(true); + }); + it('removes contract data when checkpoints are unwound', async () => { // Create block with contract data and add it as a checkpoint const block = await L2Block.random(BlockNumber(1), { diff --git a/yarn-project/archiver/src/modules/data_store_updater.ts b/yarn-project/archiver/src/modules/data_store_updater.ts index 2fb394c497a4..56a1369201f9 100644 --- a/yarn-project/archiver/src/modules/data_store_updater.ts +++ b/yarn-project/archiver/src/modules/data_store_updater.ts @@ -160,9 +160,17 @@ export class ArchiverDataStoreUpdater { /** * Checks for local proposed blocks that do not match the ones to be checkpointed and prunes them. - * This method handles multiple checkpoints but returns after pruning the first conflict found. - * This is correct because pruning from the first conflict point removes all subsequent blocks, - * and when checkpoints are added afterward, they include all the correct blocks. + * Conflict detection is keyed on `blockNumber`: when a local proposed block and an L1 + * checkpointed block share a block number but live at different slots (e.g. a different proposer + * mined the same block number one slot earlier), we still treat them as a conflict and prune. + * The trailing per-checkpoint prune that handles "local has extra trailing blocks within the + * same slot as the published checkpoint" remains scoped by slot to preserve pipelining: local + * blocks that live at a later slot than the checkpoint being processed represent speculation + * atop the just-confirmed tip (and may be referenced by a pending proposed checkpoint), so we + * leave them in place. This method handles multiple checkpoints but returns after pruning the + * first conflict found. This is correct because pruning from the first conflict point removes + * all subsequent blocks, and when checkpoints are added afterward, they include all the correct + * blocks. */ private async pruneMismatchingLocalBlocks(checkpoints: PublishedCheckpoint[]): Promise { const [lastCheckpointedBlockNumber, lastBlockNumber] = await Promise.all([ @@ -176,7 +184,7 @@ export class ArchiverDataStoreUpdater { } // Get all uncheckpointed local blocks - const uncheckpointedLocalBlocks = await this.stores.blocks.getBlocks({ + const uncheckpointedLocalBlocks = await this.stores.blocks.getBlocksData({ from: BlockNumber.add(lastCheckpointedBlockNumber, 1), limit: lastBlockNumber - lastCheckpointedBlockNumber, }); @@ -186,19 +194,19 @@ export class ArchiverDataStoreUpdater { for (const publishedCheckpoint of checkpoints) { const checkpointBlocks = publishedCheckpoint.checkpoint.blocks; const slot = publishedCheckpoint.checkpoint.slot; - const localBlocksInSlot = uncheckpointedLocalBlocks.filter(b => b.slot === slot); if (checkpointBlocks.length === 0) { this.log.warn(`Checkpoint ${publishedCheckpoint.checkpoint.number} for slot ${slot} has no blocks`); continue; } - // Find the first checkpoint block that conflicts with an existing local block and prune local afterwards + // Find the first checkpoint block that conflicts with an existing local block and prune local afterwards. + // Conflict detection joins on block number only — same block number at a different slot is still a conflict. for (const checkpointBlock of checkpointBlocks) { const blockNumber = checkpointBlock.number; - const existingBlock = localBlocksInSlot.find(b => b.number === blockNumber); + const existingBlock = uncheckpointedLocalBlocks.find(b => b.header.getBlockNumber() === blockNumber); const blockInfos = { - existingBlock: existingBlock?.toBlockInfo(), + existingBlock: existingBlock?.header.toInspect(), checkpointBlock: checkpointBlock.toBlockInfo(), }; @@ -210,20 +218,24 @@ export class ArchiverDataStoreUpdater { } else { this.log.info(`Conflict detected at block ${blockNumber} between checkpointed and local block`, blockInfos); const prunedBlocks = await this.removeBlocksAfter(BlockNumber(blockNumber - 1)); + await this.evictProposedCheckpointsForPrunedBlocks(prunedBlocks); return { prunedBlocks, lastAlreadyInsertedBlockNumber }; } } - // If local has more blocks than the checkpoint (e.g., local has [2,3,4] but checkpoint has [2,3]), - // we need to prune the extra local blocks so they match what was checkpointed + // If the sequencer locally proposed extra blocks within this checkpoint's slot (e.g. local has + // [N, N+1] but L1 confirmed just [N]), prune the extras. Scoped to the checkpoint's slot so we + // do not throw away speculative blocks at later slots that belong to a pending proposed checkpoint. const lastCheckpointBlockNumber = checkpointBlocks.at(-1)!.number; - const lastLocalBlockNumber = localBlocksInSlot.at(-1)?.number; + const localBlocksInSlot = uncheckpointedLocalBlocks.filter(b => b.header.getSlot() === slot); + const lastLocalBlockNumber = localBlocksInSlot.at(-1)?.header.getBlockNumber(); if (lastLocalBlockNumber !== undefined && lastLocalBlockNumber > lastCheckpointBlockNumber) { this.log.warn( `Local chain for slot ${slot} ends at block ${lastLocalBlockNumber} but checkpoint ends at ${lastCheckpointBlockNumber}. Pruning blocks after block ${lastCheckpointBlockNumber}.`, ); const prunedBlocks = await this.removeBlocksAfter(lastCheckpointBlockNumber); + await this.evictProposedCheckpointsForPrunedBlocks(prunedBlocks); return { prunedBlocks, lastAlreadyInsertedBlockNumber }; } } @@ -261,6 +273,19 @@ export class ArchiverDataStoreUpdater { return result; } + /** + * Evicts pending proposed checkpoints that referenced any of the just-pruned blocks. Pruned + * blocks invalidate all proposed checkpoints from the lowest pruned block's checkpoint number + * onwards: those checkpoints either reference the pruned blocks directly or chain off them. + */ + private async evictProposedCheckpointsForPrunedBlocks(prunedBlocks: L2Block[]): Promise { + if (prunedBlocks.length === 0) { + return; + } + const fromCheckpointNumber = prunedBlocks[0].checkpointNumber; + await this.stores.blocks.evictProposedCheckpointsFrom(fromCheckpointNumber); + } + /** * Removes all blocks strictly after the given block number along with any logs and contract data. * Does not remove their checkpoints. diff --git a/yarn-project/archiver/src/modules/l1_synchronizer.ts b/yarn-project/archiver/src/modules/l1_synchronizer.ts index fe0f07a812bc..a0daa21d7c83 100644 --- a/yarn-project/archiver/src/modules/l1_synchronizer.ts +++ b/yarn-project/archiver/src/modules/l1_synchronizer.ts @@ -1076,6 +1076,19 @@ export class ArchiverL1Synchronizer implements Traceable { calldataArchiveRoot: calldataCheckpoint.archiveRoot.toString(), }, ); + // Both the locally-proposed checkpoint and the L1-confirmed one are signed by the + // slot proposer; emit a divergence event so the slasher can attribute equivocation. + // Only emit when the slots match — uncheckpointed entries are pruned above so this + // should always hold, but guard defensively to avoid mis-attributing a slash. + if (proposed.header.slotNumber === calldataCheckpoint.header.slotNumber) { + this.events.emit(L2BlockSourceEvents.CheckpointEquivocationDetected, { + type: L2BlockSourceEvents.CheckpointEquivocationDetected, + slotNumber: calldataCheckpoint.header.slotNumber, + checkpointNumber: calldataCheckpoint.checkpointNumber, + l1ArchiveRoot: calldataCheckpoint.archiveRoot, + proposedArchiveRoot: proposed.archive.root, + }); + } // Return a divergence signal so the caller can evict pending >= this number return { diverged: true, fromCheckpointNumber: proposed.checkpointNumber }; } diff --git a/yarn-project/archiver/src/store/block_store.ts b/yarn-project/archiver/src/store/block_store.ts index 46490f35bd77..6e68cd2e41c8 100644 --- a/yarn-project/archiver/src/store/block_store.ts +++ b/yarn-project/archiver/src/store/block_store.ts @@ -13,7 +13,10 @@ import { BlockHash, Body, CommitteeAttestation, + GENESIS_CHECKPOINT_HEADER_HASH, L2Block, + type L2TipId, + type L2Tips, type ValidateCheckpointResult, deserializeValidateCheckpointResult, serializeValidateCheckpointResult, @@ -1129,6 +1132,174 @@ export class BlockStore { return typeof lastBlockNumber === 'number' ? BlockNumber(lastBlockNumber) : BlockNumber(INITIAL_L2_BLOCK_NUM - 1); } + /** + * Resolves all five L2 chain tips (proposed, proposedCheckpoint, checkpointed, proven, finalized) + * in a single read-only transaction so the snapshot is internally consistent. Each underlying + * record is read at most once: latest block, latest confirmed checkpoint, and latest pending + * checkpoint are each loaded directly (no separate "find the number, then look up data" hop), + * the proven/finalized checkpoint singletons are read once and their storage entries are + * reused if they coincide with the latest checkpoint, and per-tip block hashes are deduped + * when two tips land on the same block (e.g. finalized == proven, or proposedCheckpoint falls + * back to checkpointed when no pending checkpoint exists). + * + * The result is guaranteed to satisfy `finalized <= proven <= checkpointed <= proposed` (by + * block number). Genesis is represented by `(INITIAL_L2_BLOCK_NUM - 1)` and the supplied + * `genesisBlockHash`, paired with the synthetic genesis checkpoint id. + * + * @param genesisBlockHash - Block hash to report for the synthetic pre-initial block (used when + * a tip is still at genesis). + */ + async getL2TipsData(genesisBlockHash: BlockHash): Promise { + return await this.db.transactionAsync(async () => { + // Define genesis tips + const genesisBlockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1); + const genesisCheckpointNumber = CheckpointNumber(INITIAL_CHECKPOINT_NUMBER - 1); + const genesisBlockId = { number: genesisBlockNumber, hash: genesisBlockHash.toString() }; + const genesisCheckpointId = { + number: genesisCheckpointNumber, + hash: GENESIS_CHECKPOINT_HEADER_HASH.toString(), + }; + const genesisTip: L2TipId = { block: genesisBlockId, checkpoint: genesisCheckpointId }; + + // Load latest block and checkpoint entries + const [latestBlockEntry] = await toArray(this.#blocks.entriesAsync({ reverse: true, limit: 1 })); + const [proposedCheckpointEntry] = await toArray( + this.#proposedCheckpoints.entriesAsync({ reverse: true, limit: 1 }), + ); + const [latestCheckpointEntry] = await toArray(this.#checkpoints.entriesAsync({ reverse: true, limit: 1 })); + const latestCheckpointNumber = latestCheckpointEntry + ? CheckpointNumber(latestCheckpointEntry[0]) + : genesisCheckpointNumber; + + // Load proven and finalized checkpoint number pointers + const [provenRaw, finalizedRaw] = await Promise.all([ + this.#lastProvenCheckpoint.getAsync(), + this.#lastFinalizedCheckpoint.getAsync(), + ]); + + // Clamp to enforce finalized <= proven <= checkpointed. + const provenCheckpointNumber = CheckpointNumber(Math.min(provenRaw ?? 0, latestCheckpointNumber)); + const finalizedCheckpointNumber = CheckpointNumber(Math.min(finalizedRaw ?? 0, provenCheckpointNumber)); + + // Avoid loading the same checkpoint more than once + const checkpointStorageCache = new Map(); + if (latestCheckpointEntry) { + checkpointStorageCache.set(CheckpointNumber(latestCheckpointEntry[0]), latestCheckpointEntry[1]); + } + const loadCheckpointStorage = async (n: CheckpointNumber): Promise => { + if (n === 0) { + return undefined; + } + if (!checkpointStorageCache.has(n)) { + const checkpointStorage = await this.#checkpoints.getAsync(n); + if (!checkpointStorage) { + throw new CheckpointNotFoundError(n); + } + checkpointStorageCache.set(n, checkpointStorage); + } + return checkpointStorageCache.get(n)!; + }; + + // Load proven and finalized checkpoint storage entries + const provenCheckpoint = await loadCheckpointStorage(provenCheckpointNumber); + const finalizedCheckpoint = await loadCheckpointStorage(finalizedCheckpointNumber); + + // Avoid loading the same block hash multiple times when tips land on the same block + const blockHashCache = new Map(); + blockHashCache.set(genesisBlockNumber, genesisBlockHash.toString()); + if (latestBlockEntry) { + blockHashCache.set(latestBlockEntry[0], BlockHash.fromBuffer(latestBlockEntry[1].blockHash).toString()); + } + const loadBlockHash = async (n: BlockNumber): Promise => { + if (!blockHashCache.has(n)) { + const blockStorage = await this.#blocks.getAsync(n); + if (!blockStorage) { + throw new BlockNotFoundError(n); + } + const blockHash = BlockHash.fromBuffer(blockStorage.blockHash).toString(); + blockHashCache.set(n, blockHash); + } + return blockHashCache.get(n)!; + }; + + // Build proposed chain tip (this one has block only, no checkpoint) + const proposedBlockId = + latestBlockEntry === undefined + ? genesisBlockId + : { + number: BlockNumber(latestBlockEntry[0]), + hash: BlockHash.fromBuffer(latestBlockEntry[1].blockHash).toString(), + }; + + // Build other tips from checkpoint data, reading corresponding block data from the cache + const buildTipFromCheckpoint = async ( + stored: ProposedCheckpointStorage | CheckpointStorage | undefined, + ): Promise => { + if (!stored) { + return genesisTip; + } + const blockNumber = BlockNumber(stored.startBlock + stored.blockCount - 1); + const blockHash = await loadBlockHash(blockNumber); + const header = CheckpointHeader.fromBuffer(stored.header); + return { + block: { number: blockNumber, hash: blockHash }, + checkpoint: { number: CheckpointNumber(stored.checkpointNumber), hash: header.hash().toString() }, + }; + }; + + const checkpointedTip = await buildTipFromCheckpoint(latestCheckpointEntry?.[1]); + const provenTip = await buildTipFromCheckpoint(provenCheckpoint); + const finalizedTip = await buildTipFromCheckpoint(finalizedCheckpoint); + + // Proposed checkpoint falls back to the checkpoint tip if it's not set. And if local storage is + // inconsistent and the proposed checkpoint is behind the checkpointed tip, we patch that and + // report the checkpointed tip as the proposed checkpoint to maintain the invariant. + const proposedCheckpointTip = + proposedCheckpointEntry === undefined || proposedCheckpointEntry[0] <= latestCheckpointNumber + ? checkpointedTip + : await buildTipFromCheckpoint(proposedCheckpointEntry[1]); + + // A checkpointed block past the latest stored block would mean a checkpoint + // references blocks that aren't in blocks. + if (proposedBlockId.number < checkpointedTip.block.number) { + throw new Error( + `Inconsistent block store: latest block ${proposedBlockId.number} is behind checkpointed block ${checkpointedTip.block.number}`, + ); + } + + // Assert that checkpoint numbers are increasing + if ( + finalizedTip.checkpoint.number > provenTip.checkpoint.number || + provenTip.checkpoint.number > checkpointedTip.checkpoint.number || + checkpointedTip.checkpoint.number > proposedCheckpointTip.checkpoint.number + ) { + throw new Error( + `Inconsistent checkpoint numbers in chain tips: finalized=${finalizedTip.checkpoint.number} proven=${provenTip.checkpoint.number} checkpointed=${checkpointedTip.checkpoint.number} proposed=${proposedCheckpointTip.checkpoint.number}`, + ); + } + + // Assert block numbers are increasing + if ( + finalizedTip.block.number > provenTip.block.number || + provenTip.block.number > checkpointedTip.block.number || + checkpointedTip.block.number > proposedCheckpointTip.block.number || + proposedCheckpointTip.block.number > proposedBlockId.number + ) { + throw new Error( + `Inconsistent block numbers in chain tips: finalized=${finalizedTip.block.number} proven=${provenTip.block.number} checkpointed=${checkpointedTip.block.number} proposedCheckpoint=${proposedCheckpointTip.block.number} proposed=${proposedBlockId.number}`, + ); + } + + return { + proposed: proposedBlockId, + proposedCheckpoint: proposedCheckpointTip, + checkpointed: checkpointedTip, + proven: provenTip, + finalized: finalizedTip, + }; + }); + } + /** * Gets the most recent L1 block processed. * @returns The L1 block that published the latest L2 block @@ -1188,13 +1359,15 @@ export class BlockStore { } async getProvenCheckpointNumber(): Promise { - const [latestCheckpointNumber, provenCheckpointNumber] = await Promise.all([ - this.getLatestCheckpointNumber(), - this.#lastProvenCheckpoint.getAsync(), - ]); - return (provenCheckpointNumber ?? 0) > latestCheckpointNumber - ? latestCheckpointNumber - : CheckpointNumber(provenCheckpointNumber ?? 0); + return await this.db.transactionAsync(async () => { + const [latestCheckpointNumber, provenCheckpointNumber] = await Promise.all([ + this.getLatestCheckpointNumber(), + this.#lastProvenCheckpoint.getAsync(), + ]); + return (provenCheckpointNumber ?? 0) > latestCheckpointNumber + ? latestCheckpointNumber + : CheckpointNumber(provenCheckpointNumber ?? 0); + }); } async setProvenCheckpointNumber(checkpointNumber: CheckpointNumber) { @@ -1203,13 +1376,15 @@ export class BlockStore { } async getFinalizedCheckpointNumber(): Promise { - const [latestCheckpointNumber, finalizedCheckpointNumber] = await Promise.all([ - this.getLatestCheckpointNumber(), - this.#lastFinalizedCheckpoint.getAsync(), - ]); - return (finalizedCheckpointNumber ?? 0) > latestCheckpointNumber - ? latestCheckpointNumber - : CheckpointNumber(finalizedCheckpointNumber ?? 0); + return await this.db.transactionAsync(async () => { + const [provenCheckpointNumber, finalizedCheckpointNumber] = await Promise.all([ + this.getProvenCheckpointNumber(), + this.#lastFinalizedCheckpoint.getAsync(), + ]); + return (finalizedCheckpointNumber ?? 0) > provenCheckpointNumber + ? provenCheckpointNumber + : CheckpointNumber(finalizedCheckpointNumber ?? 0); + }); } setFinalizedCheckpointNumber(checkpointNumber: CheckpointNumber) { diff --git a/yarn-project/archiver/src/store/l2_tips_cache.ts b/yarn-project/archiver/src/store/l2_tips_cache.ts index bc69983fc722..68fa309a005b 100644 --- a/yarn-project/archiver/src/store/l2_tips_cache.ts +++ b/yarn-project/archiver/src/store/l2_tips_cache.ts @@ -1,12 +1,4 @@ -import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants'; -import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; -import { - type BlockData, - type BlockHash, - type CheckpointId, - GENESIS_CHECKPOINT_HEADER_HASH, - type L2Tips, -} from '@aztec/stdlib/block'; +import type { BlockHash, L2Tips } from '@aztec/stdlib/block'; import type { BlockStore } from './block_store.js'; @@ -20,10 +12,10 @@ export class L2TipsCache { #tipsPromise: Promise | undefined; /** - * Asymmetric by design: the genesis block hash is dynamic — derived from the injected initial header, - * which depends on `genesisTimestamp` and any prefilled state. The genesis checkpoint hash is static — - * checkpoint 0 is fully synthetic (no real checkpoint header exists at 0), so it stays at the protocol - * constant `GENESIS_CHECKPOINT_HEADER_HASH`. + * The genesis block hash is dynamic — derived from the injected initial header, which depends on + * `genesisTimestamp` and any prefilled state — so it is supplied here rather than read from store. + * The genesis checkpoint hash, by contrast, is the static protocol constant and is resolved + * inside the block store. */ constructor( private blockStore: BlockStore, @@ -32,115 +24,12 @@ export class L2TipsCache { /** Returns the cached L2 tips. Loads from the block store on first call. */ public getL2Tips(): Promise { - return (this.#tipsPromise ??= this.loadFromStore()); + return (this.#tipsPromise ??= this.blockStore.getL2TipsData(this.initialBlockHash)); } /** Reloads the L2 tips from the block store. Should be called after the writer transaction has committed. */ public async refresh(): Promise { - this.#tipsPromise = this.loadFromStore(); + this.#tipsPromise = this.blockStore.getL2TipsData(this.initialBlockHash); await this.#tipsPromise; } - - private async loadFromStore(): Promise { - const [ - latestBlockNumber, - provenBlockNumber, - proposedCheckpointBlockNumber, - checkpointedBlockNumber, - finalizedBlockNumber, - ] = await Promise.all([ - this.blockStore.getLatestL2BlockNumber(), - this.blockStore.getProvenBlockNumber(), - this.blockStore.getProposedCheckpointL2BlockNumber(), - this.blockStore.getCheckpointedL2BlockNumber(), - this.blockStore.getFinalizedL2BlockNumber(), - ]); - - const genesisBlockHeader = { - blockHash: this.initialBlockHash, - checkpointNumber: CheckpointNumber.ZERO, - } as const; - const beforeInitialBlockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1); - - const getBlockData = (blockNumber: BlockNumber) => - blockNumber > beforeInitialBlockNumber - ? this.blockStore.getBlockData({ number: blockNumber }) - : genesisBlockHeader; - - const [latestBlockData, provenBlockData, proposedCheckpointBlockData, checkpointedBlockData, finalizedBlockData] = - await Promise.all( - [ - latestBlockNumber, - provenBlockNumber, - proposedCheckpointBlockNumber, - checkpointedBlockNumber, - finalizedBlockNumber, - ].map(getBlockData), - ); - - if ( - !latestBlockData || - !provenBlockData || - !finalizedBlockData || - !checkpointedBlockData || - !proposedCheckpointBlockData - ) { - throw new Error('Failed to load block data for L2 tips'); - } - - const [provenCheckpointId, finalizedCheckpointId, proposedCheckpointId, checkpointedCheckpointId] = - await Promise.all([ - this.getCheckpointIdForBlock(provenBlockData), - this.getCheckpointIdForBlock(finalizedBlockData), - this.getCheckpointIdForProposedCheckpoint(checkpointedBlockData), - this.getCheckpointIdForBlock(checkpointedBlockData), - ]); - - return { - proposed: { number: latestBlockNumber, hash: latestBlockData.blockHash.toString() }, - proven: { - block: { number: provenBlockNumber, hash: provenBlockData.blockHash.toString() }, - checkpoint: provenCheckpointId, - }, - proposedCheckpoint: { - block: { number: proposedCheckpointBlockNumber, hash: proposedCheckpointBlockData.blockHash.toString() }, - checkpoint: proposedCheckpointId, - }, - finalized: { - block: { number: finalizedBlockNumber, hash: finalizedBlockData.blockHash.toString() }, - checkpoint: finalizedCheckpointId, - }, - checkpointed: { - block: { number: checkpointedBlockNumber, hash: checkpointedBlockData.blockHash.toString() }, - checkpoint: checkpointedCheckpointId, - }, - }; - } - - private async getCheckpointIdForProposedCheckpoint( - checkpointedBlockData: Pick, - ): Promise { - const checkpointData = await this.blockStore.getLastProposedCheckpoint(); - if (!checkpointData) { - return this.getCheckpointIdForBlock(checkpointedBlockData); - } - return { - number: checkpointData.checkpointNumber, - hash: checkpointData.header.hash().toString(), - }; - } - - private async getCheckpointIdForBlock(blockData: Pick): Promise { - const checkpointData = await this.blockStore.getCheckpointData(blockData.checkpointNumber); - if (!checkpointData) { - return { - number: CheckpointNumber.ZERO, - hash: GENESIS_CHECKPOINT_HEADER_HASH.toString(), - }; - } - return { - number: checkpointData.checkpointNumber, - hash: checkpointData.header.hash().toString(), - }; - } } diff --git a/yarn-project/aztec-node/src/aztec-node/config.ts b/yarn-project/aztec-node/src/aztec-node/config.ts index e279494485dc..9d59920335ac 100644 --- a/yarn-project/aztec-node/src/aztec-node/config.ts +++ b/yarn-project/aztec-node/src/aztec-node/config.ts @@ -60,6 +60,12 @@ export type AztecNodeConfig = ArchiverConfig & debugForceTxProofVerification: boolean; /** Whether to enable the prover node as a subsystem. */ enableProverNode: boolean; + /** + * Test-only: use the deterministic AutomineSequencer instead of the production Sequencer. + * Requires `aztecTargetCommitteeSize === 0` on the deployed rollup and anvil-backed L1. + * See `AUTOMINE_E2E_OPTS` in `end-to-end/src/fixtures/fixtures.ts`. + */ + useAutomineSequencer?: boolean; }; export const aztecNodeConfigMappings: ConfigMappingsType = { @@ -98,6 +104,11 @@ export const aztecNodeConfigMappings: ConfigMappingsType = { description: 'Whether to enable the prover node as a subsystem.', ...booleanConfigHelper(false), }, + useAutomineSequencer: { + env: 'USE_AUTOMINE_SEQUENCER', + description: 'Test-only: use AutomineSequencer instead of the production Sequencer.', + ...booleanConfigHelper(false), + }, }; /** diff --git a/yarn-project/aztec-node/src/aztec-node/server.test.ts b/yarn-project/aztec-node/src/aztec-node/server.test.ts index b4ca0084accd..462fa2cba60e 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.test.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.test.ts @@ -1031,6 +1031,81 @@ describe('aztec node', () => { }); }); + describe('pauseSequencer + setConfig', () => { + const INITIAL_MIN_TXS_PER_BLOCK = 2; + + let sequencerClient: MockProxy; + let nodeWithSequencer: AztecNodeService; + + beforeEach(() => { + const sequencer = mock(); + sequencer.getConfig.mockReturnValue({ minTxsPerBlock: INITIAL_MIN_TXS_PER_BLOCK } as any); + + sequencerClient = mock(); + sequencerClient.getSequencer.mockReturnValue(sequencer); + + nodeWithSequencer = new AztecNodeService( + nodeConfig, + p2p, + l2BlockSource, + mock(), + mock(), + mock(), + worldState, + sequencerClient, + undefined, + undefined, + undefined, + undefined, + undefined, + 12345, + rollupVersion.toNumber(), + globalVariablesBuilder, + mock(), + epochCache, + getPackageVersion(), + new TestCircuitVerifier(), + new TestCircuitVerifier(), + ); + }); + + it('keeps the sequencer frozen when setConfig updates minTxsPerBlock while paused', async () => { + await nodeWithSequencer.pauseSequencer(); + sequencerClient.updateConfig.mockClear(); + + await nodeWithSequencer.setConfig({ minTxsPerBlock: 1 }); + + // The sequencer must not receive the new minTxsPerBlock while paused; the freeze stays in place. + const updateCalls = sequencerClient.updateConfig.mock.calls; + const minTxsUpdates = updateCalls.filter(([cfg]) => 'minTxsPerBlock' in cfg); + expect(minTxsUpdates).toEqual([]); + }); + + it('resumeSequencer applies the value set via setConfig during pause (not the pre-pause value)', async () => { + await nodeWithSequencer.pauseSequencer(); + await nodeWithSequencer.setConfig({ minTxsPerBlock: 5 }); + sequencerClient.updateConfig.mockClear(); + + await nodeWithSequencer.resumeSequencer(); + + // Resume must use the test-supplied value (5), not the pre-pause snapshot (INITIAL_MIN_TXS_PER_BLOCK). + expect(sequencerClient.updateConfig).toHaveBeenCalledWith({ minTxsPerBlock: 5 }); + }); + + it('still forwards non-minTxsPerBlock config changes while paused', async () => { + await nodeWithSequencer.pauseSequencer(); + sequencerClient.updateConfig.mockClear(); + + const coinbase = EthAddress.random(); + await nodeWithSequencer.setConfig({ coinbase, minTxsPerBlock: 3 }); + + // coinbase still reaches the sequencer; only minTxsPerBlock is filtered. + const updateCalls = sequencerClient.updateConfig.mock.calls; + expect(updateCalls).toHaveLength(1); + expect(updateCalls[0][0]).toEqual({ coinbase }); + }); + }); + describe('getL2ToL1Messages', () => { const makeBlock = (slotNumber: number, l2ToL1MsgsByTx: Fr[][]): L2Block => { const block = L2Block.empty( diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 817ce3f0bf1d..edba020f1e27 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -1,4 +1,4 @@ -import { Archiver, createArchiver } from '@aztec/archiver'; +import { Archiver, L1ToL2MessagesNotReadyError, createArchiver } from '@aztec/archiver'; import { BBCircuitVerifier, BatchChonkVerifier, QueuedIVCVerifier } from '@aztec/bb-prover'; import { TestCircuitVerifier } from '@aztec/bb-prover/test'; import { type BlobClientInterface, createBlobClientWithFileStores } from '@aztec/blob-client/client'; @@ -20,6 +20,7 @@ import { retryUntil } from '@aztec/foundation/retry'; import { count } from '@aztec/foundation/string'; import { DateProvider, Timer } from '@aztec/foundation/timer'; import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees'; +import { isErrorClass } from '@aztec/foundation/types'; import { type KeyStore, KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore'; import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions'; import { createForwarderL1TxUtilsFromSigners, createL1TxUtilsFromSigners } from '@aztec/node-lib/factories'; @@ -34,15 +35,19 @@ import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { type ProverNode, type ProverNodeDeps, createProverNode } from '@aztec/prover-node'; import { createKeyStoreForProver } from '@aztec/prover-node/config'; import { + AutomineSequencer, FeeProviderImpl, GlobalVariableBuilder, SequencerClient, type SequencerPublisher, + createAutomineSequencer, } from '@aztec/sequencer-client'; import { PublicContractsDB, PublicProcessorFactory } from '@aztec/simulator/server'; import { AttestationsBlockWatcher, - EpochPruneWatcher, + BroadcastedInvalidCheckpointProposalWatcher, + CheckpointEquivocationWatcher, + DataWithholdingWatcher, type SlasherClientInterface, type Watcher, createSlasher, @@ -61,7 +66,12 @@ import { type NormalizedBlockParameter, inspectBlockParameter, } from '@aztec/stdlib/block'; -import { type CheckpointData, L1PublishedData, type PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import { + type CheckpointData, + CheckpointReexecutionTracker, + L1PublishedData, + type PublishedCheckpoint, +} from '@aztec/stdlib/checkpoint'; import type { ContractClassPublic, ContractDataSource, @@ -159,6 +169,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb private metrics: NodeMetrics; // Prevent two snapshot operations to happen simultaneously private isUploadingSnapshot = false; + // Saved minTxsPerBlock used by `pauseSequencer` to restore production-sequencer config on resume. + private sequencerPausedMinTxsPerBlock: number | undefined; public readonly tracer: Tracer; @@ -174,7 +186,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb protected readonly proverNode: ProverNode | undefined, protected readonly slasherClient: SlasherClientInterface | undefined, protected readonly validatorsSentinel: Sentinel | undefined, - protected readonly epochPruneWatcher: EpochPruneWatcher | undefined, + protected readonly dataWithholdingWatcher: DataWithholdingWatcher | undefined, protected readonly attestationsBlockWatcher: AttestationsBlockWatcher | undefined, protected readonly l1ChainId: number, protected readonly version: number, @@ -190,6 +202,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb private validatorClient?: ValidatorClient, private keyStoreManager?: KeystoreManager, private debugLogStore: DebugLogStore = new NullDebugLogStore(), + private readonly automineSequencer?: AutomineSequencer, ) { this.metrics = new NodeMetrics(telemetry, 'AztecNodeService'); this.tracer = telemetry.getTracer('AztecNodeService'); @@ -395,7 +408,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb /** Fetches checkpoint context for a set of blocks, deduplicating shared checkpoints. */ async #getCheckpointContextsForBlocks( blocks: { checkpointNumber: CheckpointNumber }[], - // TODO(palla): CheckpointNumber should be accepted by this lint rule ): Promise> { const unique = Array.from(new Set(blocks.map(b => b.checkpointNumber))); const entries = await Promise.all(unique.map(async n => [n, await this.#getCheckpointContext(n)] as const)); @@ -659,6 +671,9 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb let validatorClient: ValidatorClient | undefined; + // Tracks successful checkpoint re-execution by a checkpoint proposal handler. + const reexecutionTracker = new CheckpointReexecutionTracker(); + if (!config.disableValidator) { // Create validator client if required validatorClient = await createValidatorClient(config, { @@ -672,6 +687,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb l1ToL2MessageSource: archiver, keyStoreManager, blobClient, + reexecutionTracker, slashingProtectionDb: deps.slashingProtectionDb, }); @@ -708,6 +724,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb blobClient, dateProvider, telemetry, + reexecutionTracker, }).register(p2pClient, reexecute, archiver); } @@ -718,29 +735,50 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb await p2pClient.start(); let validatorsSentinel: Awaited> | undefined; - let epochPruneWatcher: EpochPruneWatcher | undefined; + let dataWithholdingWatcher: DataWithholdingWatcher | undefined; let attestationsBlockWatcher: AttestationsBlockWatcher | undefined; + let broadcastedInvalidCheckpointProposalWatcher: BroadcastedInvalidCheckpointProposalWatcher | undefined; + let checkpointEquivocationWatcher: CheckpointEquivocationWatcher | undefined; if (!proverOnly) { - validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, config); + validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, reexecutionTracker, config); if (validatorsSentinel && config.slashInactivityPenalty > 0n) { watchers.push(validatorsSentinel); } - if (config.slashPrunePenalty > 0n || config.slashDataWithholdingPenalty > 0n) { - epochPruneWatcher = new EpochPruneWatcher( + if (config.slashDataWithholdingPenalty > 0n) { + dataWithholdingWatcher = new DataWithholdingWatcher( + epochCache, archiver, + p2pClient.getTxProvider(), + p2pClient, + reexecutionTracker, + { chainId: config.l1ChainId, rollupAddress: config.rollupAddress }, + config, + ); + watchers.push(dataWithholdingWatcher); + } + + if (config.slashBroadcastedInvalidCheckpointProposalPenalty > 0n) { + broadcastedInvalidCheckpointProposalWatcher = new BroadcastedInvalidCheckpointProposalWatcher( + p2pClient, archiver, epochCache, - p2pClient.getTxProvider(), - validatorCheckpointsBuilder, config, ); - watchers.push(epochPruneWatcher); + watchers.push(broadcastedInvalidCheckpointProposalWatcher); + } + + if (config.slashDuplicateProposalPenalty > 0n) { + checkpointEquivocationWatcher = new CheckpointEquivocationWatcher(archiver, epochCache, config); + watchers.push(checkpointEquivocationWatcher); } // We assume we want to slash for invalid attestations unless all max penalties are set to 0 - if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashAttestDescendantOfInvalidPenalty > 0n) { + if ( + config.slashProposeInvalidAttestationsPenalty > 0n || + config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty > 0n + ) { attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config); watchers.push(attestationsBlockWatcher); } @@ -754,20 +792,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb await validatorsSentinel.start(); started.push(validatorsSentinel); } - if (epochPruneWatcher) { - await epochPruneWatcher.start(); - started.push(epochPruneWatcher); + if (dataWithholdingWatcher) { + await dataWithholdingWatcher.start(); + started.push(dataWithholdingWatcher); } if (attestationsBlockWatcher) { await attestationsBlockWatcher.start(); started.push(attestationsBlockWatcher); } + if (broadcastedInvalidCheckpointProposalWatcher) { + await broadcastedInvalidCheckpointProposalWatcher.start(); + started.push(broadcastedInvalidCheckpointProposalWatcher); + } + if (checkpointEquivocationWatcher) { + await checkpointEquivocationWatcher.start(); + started.push(checkpointEquivocationWatcher); + } log.info(`All p2p services started`); }) .catch(err => log.error('Failed to start p2p services after archiver sync', err)); // Validator enabled, create/start relevant service let sequencer: SequencerClient | undefined; + let automineSequencer: AutomineSequencer | undefined; let slasherClient: SlasherClientInterface | undefined; if (!config.disableValidator && validatorClient) { // We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher @@ -827,24 +874,54 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb debugLogStore, ); - sequencer = await SequencerClient.new(config, { - ...deps, - epochCache, - l1TxUtils, - funderL1TxUtils, - validatorClient, - p2pClient, - worldStateSynchronizer, - slasherClient, - checkpointsBuilder, - l2BlockSource: archiver, - l1ToL2MessageSource: archiver, - telemetry, - dateProvider, - blobClient, - nodeKeyStore: keyStoreManager!, - globalVariableBuilder, - }); + if (config.useAutomineSequencer) { + // Test-only path: deterministic, queue-driven sequencer for non-block-building e2e tests. + // See `AUTOMINE_E2E_OPTS` in `end-to-end/src/fixtures/fixtures.ts`. + automineSequencer = await createAutomineSequencer({ + config, + l1TxUtils, + funderL1TxUtils, + publicClient, + rollupContract, + epochCache, + blobClient, + telemetry, + dateProvider, + keyStoreManager: keyStoreManager!, + validatorClient, + checkpointsBuilder, + globalVariableBuilder, + worldStateSynchronizer, + archiver, + p2pClient, + l1Constants: { + l1GenesisTime, + slotDuration: Number(slotDuration), + ethereumSlotDuration: config.ethereumSlotDuration, + rollupManaLimit, + }, + log, + }); + } else { + sequencer = await SequencerClient.new(config, { + ...deps, + epochCache, + l1TxUtils, + funderL1TxUtils, + validatorClient, + p2pClient, + worldStateSynchronizer, + slasherClient, + checkpointsBuilder, + l2BlockSource: archiver, + l1ToL2MessageSource: archiver, + telemetry, + dateProvider, + blobClient, + nodeKeyStore: keyStoreManager!, + globalVariableBuilder, + }); + } } if (!options.dontStartSequencer && sequencer) { @@ -855,6 +932,14 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb log.warn(`Sequencer created but not started`); } + if (!options.dontStartSequencer && automineSequencer) { + await automineSequencer.start(); + started.push({ stop: () => automineSequencer!.stop() }); + log.verbose(`AutomineSequencer started`); + } else if (automineSequencer) { + log.warn(`AutomineSequencer created but not started`); + } + // Create prover node subsystem if enabled let proverNode: ProverNode | undefined; if (config.enableProverNode) { @@ -891,7 +976,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb proverNode, slasherClient, validatorsSentinel, - epochPruneWatcher, + dataWithholdingWatcher, attestationsBlockWatcher, ethereumChain.chainInfo.id, config.rollupVersion, @@ -907,6 +992,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb validatorClient, keyStoreManager, debugLogStore, + automineSequencer, ); return node; @@ -927,6 +1013,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb return this.sequencer; } + /** Test-only: returns the AutomineSequencer when wired via `useAutomineSequencer`. */ + public getAutomineSequencer(): AutomineSequencer | undefined { + return this.automineSequencer; + } + /** Returns the prover node subsystem, if enabled. */ public getProverNode(): ProverNode | undefined { return this.proverNode; @@ -1170,10 +1261,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb this.log.info(`Stopping Aztec Node`); await tryStop(this.attestationsBlockWatcher); await tryStop(this.validatorsSentinel); - await tryStop(this.epochPruneWatcher); + await tryStop(this.dataWithholdingWatcher); await tryStop(this.slasherClient); await Promise.all([tryStop(this.peerProofVerifier), tryStop(this.rpcProofVerifier)]); await tryStop(this.sequencer); + await tryStop(this.automineSequencer); await tryStop(this.proverNode); await tryStop(this.p2pClient); await tryStop(this.worldStateSynchronizer); @@ -1490,11 +1582,24 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb // the world state tree so simulation can take them into account. We detect if the next block would // start a new checkpoint by checking if the proposed checkpoint's block number matches the latest block number, // which means the next block would be the first block of the next checkpoint. + const targetCheckpoint = CheckpointNumber( + (l2Tips.proposedCheckpoint.checkpoint.number ?? CheckpointNumber.ZERO) + 1, + ); const nextCheckpointMessages: Fr[] | undefined = l2Tips.proposedCheckpoint.block.number === l2Tips.proposed.number - ? await this.l1ToL2MessageSource.getL1ToL2Messages( - CheckpointNumber((l2Tips.proposedCheckpoint.checkpoint.number ?? CheckpointNumber.ZERO) + 1), - ) + ? await this.l1ToL2MessageSource.getL1ToL2Messages(targetCheckpoint).catch(err => { + if (isErrorClass(err, L1ToL2MessagesNotReadyError)) { + this.log.warn( + `L1-to-L2 messages for checkpoint ${targetCheckpoint} are not ready yet (simulating without them)`, + ); + } else { + this.log.error( + `Failed to get L1-to-L2 messages for checkpoint ${targetCheckpoint} (simulating without them)`, + err, + ); + } + return undefined; + }) : undefined; // Request a new fork of the world state at the latest block number, and apply any overrides and next checkpoint messages to it before simulation @@ -1590,7 +1695,18 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb public async setConfig(config: Partial): Promise { const newConfig = { ...this.config, ...config }; - this.sequencer?.updateConfig(config); + // If the sequencer is currently paused via pauseSequencer(), record the caller's desired + // minTxsPerBlock as the restore value (so resumeSequencer applies it) and keep the freeze + // (MAX_SAFE_INTEGER) applied to the underlying sequencer. Without this guard, forwarding + // the new minTxsPerBlock to the sequencer would silently unpause block production while + // pauseSequencer() still considers it paused. + const sequencerUpdate = { ...config }; + if (this.sequencerPausedMinTxsPerBlock !== undefined && sequencerUpdate.minTxsPerBlock !== undefined) { + this.sequencerPausedMinTxsPerBlock = sequencerUpdate.minTxsPerBlock; + delete sequencerUpdate.minTxsPerBlock; + } + this.sequencer?.updateConfig(sequencerUpdate); + this.automineSequencer?.updateConfig(sequencerUpdate); this.slasherClient?.updateConfig(config); this.validatorsSentinel?.updateConfig(config); await this.p2pClient.updateP2PConfig(config); @@ -1735,6 +1851,41 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb return Promise.resolve(); } + public pauseSequencer(): Promise { + if (this.automineSequencer) { + this.automineSequencer.pause(); + return Promise.resolve(); + } + if (this.sequencer) { + if (this.sequencerPausedMinTxsPerBlock === undefined) { + this.sequencerPausedMinTxsPerBlock = this.sequencer.getSequencer().getConfig().minTxsPerBlock ?? 0; + this.sequencer.updateConfig({ minTxsPerBlock: Number.MAX_SAFE_INTEGER }); + this.log.info(`Sequencer paused (minTxsPerBlock set to MAX_SAFE_INTEGER)`, { + previousMinTxsPerBlock: this.sequencerPausedMinTxsPerBlock, + }); + } + return Promise.resolve(); + } + throw new BadRequestError('Cannot pause sequencer: no sequencer is running'); + } + + public resumeSequencer(): Promise { + if (this.automineSequencer) { + this.automineSequencer.resume(); + return Promise.resolve(); + } + if (this.sequencer) { + if (this.sequencerPausedMinTxsPerBlock !== undefined) { + const restored = this.sequencerPausedMinTxsPerBlock; + this.sequencerPausedMinTxsPerBlock = undefined; + this.sequencer.updateConfig({ minTxsPerBlock: restored }); + this.log.info(`Sequencer resumed (minTxsPerBlock restored)`, { minTxsPerBlock: restored }); + } + return Promise.resolve(); + } + throw new BadRequestError('Cannot resume sequencer: no sequencer is running'); + } + public getSlashOffenses(round: bigint | 'all' | 'current'): Promise { if (!this.slasherClient) { throw new Error(`Slasher client not enabled`); @@ -1835,6 +1986,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb } public async mineBlock(): Promise { + if (this.automineSequencer) { + await this.automineSequencer.buildEmptyBlock(); + return; + } if (!this.sequencer) { throw new BadRequestError('Cannot mine block: no sequencer is running'); } diff --git a/yarn-project/aztec-node/src/sentinel/README.md b/yarn-project/aztec-node/src/sentinel/README.md new file mode 100644 index 000000000000..5ab68d8d8cff --- /dev/null +++ b/yarn-project/aztec-node/src/sentinel/README.md @@ -0,0 +1,103 @@ +# Sentinel + +The Sentinel watches every committee member's behaviour each L2 slot, aggregates it into per-epoch performance once each epoch is fully observed, and emits inactivity slash payloads to the slasher. + +## Responsibilities + +- Classify per-slot proposer/attestor behaviour from local node observations. +- Persist a sliding window of per-slot history per validator. +- Roll up that history into per-epoch performance after each epoch ends. +- Decide which validators have been inactive for `slashInactivityConsecutiveEpochThreshold` consecutive epochs and emit `WANT_TO_SLASH_EVENT` with `OffenseType.INACTIVITY`. +- Expose validator stats to RPC consumers (`getValidatorStats`, `computeStats`). + +The sentinel is one of several watchers registered with the slasher; it does not vote or publish to L1 itself. + +## Inputs + +| Source | What it provides | +|---|---| +| `EpochCache` | Slot/epoch helpers, committee + proposer for a slot, escape-hatch state | +| `L2BlockSource` (archiver) | Synced slot, `chain-checkpointed` events, block headers | +| `P2PClient` | `getCheckpointAttestationsForSlot(slot, payloadHash)`, `hasBlockProposalsForSlot(slot)` | +| `CheckpointReexecutionTracker` | Local re-execution outcome for the proposal at each slot (`valid` / `invalid` / `unvalidated`) — populated by the validator client's `ProposalHandler` | +| L1-checkpointed events | `chain-checkpointed` populates `slotNumberToCheckpoint` with the canonical attestor set | + +## Two cadences + +`Sentinel.work()` runs every quarter L2 slot and drives two pipelines that operate independently: + +### 1. Per-slot recording (lag = 2 slots) + +`processSlot(currentSlot - 2)` runs once per slot. The 2-slot lag gives P2P attestations time to settle and lets the archiver catch up. It calls `getSlotActivity(slot, epoch, proposer, committee)` and writes per-validator statuses to `SentinelStore.historyMap`. History is a sliding window of `sentinelHistoryLengthInEpochs * epochDuration` slots (default 24 epochs). + +If `EpochCache.getCommittee(slot)` reports `isEscapeHatchOpen`, the slot is recorded as processed without writing any per-validator entries. + +### 2. Per-epoch evaluation (lag = `sentinelEpochEndBufferSlots` past the epoch's last slot) + +`processEpochEnds(currentSlot)` checks whether any epoch is now fully observable and not yet evaluated. An epoch is eligible once both: + +- the buffer has elapsed: `currentSlot − sentinelEpochEndBufferSlots ≥ lastSlotOfEpoch`, and +- per-slot recording has reached the epoch's last slot: `lastProcessedSlot ≥ lastSlotOfEpoch`. + +When eligible, `handleEpochEnd(epoch)` aggregates the slot-level statuses for that epoch into per-validator `{missed, total}`, persists the result to `SentinelStore.epochMap` (default 2000-epoch window), and runs the inactivity check. + +The aggregator catches up if multiple epochs become eligible at once (e.g. after a long backoff). + +## Six-case taxonomy + +For each slot, the proposer is assigned one of six statuses, ranked highest-confidence first: + +| # | Status | Trigger | Inactive party | +|---|---|---|---| +| 6 | `checkpoint-mined` | `slotNumberToCheckpoint.has(slot)` (a checkpoint covering this slot has landed on L1) | Attestors who didn't attest | +| 5 | `checkpoint-valid` | `tracker.getOutcomeForSlot(slot) === 'valid'` | Attestors who didn't attest | +| 4 | `checkpoint-invalid` | `tracker.getOutcomeForSlot(slot) === 'invalid'` (re-executed and rejected) | Proposer | +| 3 | `checkpoint-unvalidated` | `tracker.getOutcomeForSlot(slot) === 'unvalidated'` (validation aborted: missing data, timeout, etc.) | Proposer | +| 2 | `checkpoint-missed` | `p2p.hasBlockProposalsForSlot(slot)` true (blocks seen but no checkpoint proposal observed) | Proposer | +| 1 | `blocks-missed` | None of the above (no block proposals observed) | Proposer | + +Missing-attestor faults are only recorded in cases 5 and 6 — where the local node has positive evidence the checkpoint was valid or canonical. In cases 1–4 the proposer is at fault and no attestor penalty applies. + +Each non-proposer committee member is tagged: + +- `attestation-sent` — attestation seen on P2P (with valid signature) or in the L1 checkpoint's attestor set +- `attestation-missed` — only when proposer status is case 5 or 6 and the validator's attestation was not seen +- none — otherwise + +## Inactivity slashing + +`handleEpochPerformance(epoch, performance)`: + +1. Filter validators where `missed / total ≥ slashInactivityTargetPercentage`. +2. For each, call `checkPastInactivity` to require `slashInactivityConsecutiveEpochThreshold − 1` past epochs (from `SentinelStore.epochMap`) over the same threshold. Epochs where the validator was not on a committee are skipped, not counted against the streak. +3. Emit a single `WANT_TO_SLASH_EVENT` with one `WantToSlashArgs` per qualifying validator. + +`{missed, total}` only counts slots that had something happen (a proposal, an attestation, or a missed proposal opportunity). Slots where the validator was on the committee but no proposal occurred and they were not the proposer don't show up in either count — that prevents an offline validator from appearing as "5/10 missed" simply because half the epoch had no proposals. + +## Storage + +`SentinelStore` is an LMDB-backed KV store with two maps: + +- `historyMap` — validator address → serialized `[(slot, status)]` rolling window +- `epochMap` — validator address → serialized `[{epoch, missed, total}]` rolling window + +`SCHEMA_VERSION` controls on-disk compatibility; bumping it wipes the store on next open. The encoded status numbers live in `SentinelStore.statusToNumber`/`statusFromNumber`. + +## Configuration + +| Key | Env var | Default | Purpose | +|---|---|---|---| +| `sentinelEnabled` | `SENTINEL_ENABLED` | `false` | Master switch | +| `sentinelHistoryLengthInEpochs` | `SENTINEL_HISTORY_LENGTH_IN_EPOCHS` | `24` | Slot-history window, in epochs | +| `sentinelHistoricEpochPerformanceLengthInEpochs` | `SENTINEL_HISTORIC_EPOCH_PERFORMANCE_LENGTH_IN_EPOCHS` | `2000` | Per-epoch performance window | +| `sentinelEpochEndBufferSlots` | `SENTINEL_EPOCH_END_BUFFER_SLOTS` | `2` | Slots to wait past an epoch's last slot before evaluating it | + +The sentinel also reads slashing thresholds and L1 chain identifiers from `SentinelRuntimeConfig` (see `sentinel.ts`). + +## Files + +- `sentinel.ts` — main class +- `store.ts` — KV-backed persistence +- `config.ts` — `SentinelConfig` and env-var mappings +- `factory.ts` — `createSentinel` factory used by `AztecNodeService` +- `sentinel.test.ts` / `store.test.ts` — unit tests diff --git a/yarn-project/aztec-node/src/sentinel/config.ts b/yarn-project/aztec-node/src/sentinel/config.ts index 93fedeb6819e..163bbada989a 100644 --- a/yarn-project/aztec-node/src/sentinel/config.ts +++ b/yarn-project/aztec-node/src/sentinel/config.ts @@ -2,8 +2,9 @@ import { type ConfigMappingsType, booleanConfigHelper, numberConfigHelper } from export type SentinelConfig = { sentinelHistoryLengthInEpochs: number; - sentinelHistoricProvenPerformanceLengthInEpochs: number; + sentinelHistoricEpochPerformanceLengthInEpochs: number; sentinelEnabled: boolean; + sentinelEpochEndBufferSlots: number; }; export const sentinelConfigMappings: ConfigMappingsType = { @@ -13,8 +14,9 @@ export const sentinelConfigMappings: ConfigMappingsType = { ...numberConfigHelper(24), }, /** - * The number of L2 epochs kept of proven performance history for each validator. - * This value must be large enough so that we have proven performance for every validator + * The number of L2 epochs kept of per-epoch performance history for each validator. End-of-epoch + * activity is recorded here and used to decide consecutive-epoch inactivity slashing. + * This value must be large enough so that we have epoch performance for every validator * for at least slashInactivityConsecutiveEpochThreshold. Assuming this value is 3, * and the committee size is 48, and we have 10k validators, then we pick 48 out of 10k each draw. * For any fixed element, per-draw prob = 48/10000 = 0.0048. @@ -24,9 +26,9 @@ export const sentinelConfigMappings: ConfigMappingsType = { * - 95% chance: n = 1310 * - 99% chance: n = 1749 */ - sentinelHistoricProvenPerformanceLengthInEpochs: { - description: 'The number of L2 epochs kept of proven performance history for each validator.', - env: 'SENTINEL_HISTORIC_PROVEN_PERFORMANCE_LENGTH_IN_EPOCHS', + sentinelHistoricEpochPerformanceLengthInEpochs: { + description: 'The number of L2 epochs kept of per-epoch performance history for each validator.', + env: 'SENTINEL_HISTORIC_EPOCH_PERFORMANCE_LENGTH_IN_EPOCHS', ...numberConfigHelper(2000), }, sentinelEnabled: { @@ -34,4 +36,14 @@ export const sentinelConfigMappings: ConfigMappingsType = { env: 'SENTINEL_ENABLED', ...booleanConfigHelper(false), }, + /** + * Number of L2 slots to wait after the end of an epoch before computing the epoch's performance. + * The buffer allows P2P attestations and the local archiver to settle. Higher values reduce the + * risk of misjudging late-arriving activity at the cost of delayed slashing. + */ + sentinelEpochEndBufferSlots: { + description: 'Number of L2 slots after the end of an epoch before the sentinel evaluates it.', + env: 'SENTINEL_EPOCH_END_BUFFER_SLOTS', + ...numberConfigHelper(2), + }, }; diff --git a/yarn-project/aztec-node/src/sentinel/factory.ts b/yarn-project/aztec-node/src/sentinel/factory.ts index 0db6ac82874f..244d54a66a45 100644 --- a/yarn-project/aztec-node/src/sentinel/factory.ts +++ b/yarn-project/aztec-node/src/sentinel/factory.ts @@ -3,6 +3,7 @@ import { createLogger } from '@aztec/foundation/log'; import { createStore } from '@aztec/kv-store/lmdb-v2'; import type { P2PClient } from '@aztec/p2p'; import type { L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { ChainConfig } from '@aztec/stdlib/config'; import type { SlasherConfig } from '@aztec/stdlib/interfaces/server'; import type { DataStoreConfig } from '@aztec/stdlib/kv-store'; @@ -15,6 +16,7 @@ export async function createSentinel( epochCache: EpochCache, archiver: L2BlockSource, p2p: P2PClient, + reexecutionTracker: CheckpointReexecutionTracker, config: SentinelConfig & DataStoreConfig & SlasherConfig & Pick, logger = createLogger('node:sentinel'), ): Promise { @@ -23,10 +25,10 @@ export async function createSentinel( } const kvStore = await createStore('sentinel', SentinelStore.SCHEMA_VERSION, config, logger.getBindings()); const storeHistoryLength = config.sentinelHistoryLengthInEpochs * epochCache.getL1Constants().epochDuration; - const storeHistoricProvenPerformanceLength = config.sentinelHistoricProvenPerformanceLengthInEpochs; + const storeHistoricEpochPerformanceLength = config.sentinelHistoricEpochPerformanceLengthInEpochs; const sentinelStore = new SentinelStore(kvStore, { historyLength: storeHistoryLength, - historicProvenPerformanceLength: storeHistoricProvenPerformanceLength, + historicEpochPerformanceLength: storeHistoricEpochPerformanceLength, }); - return new Sentinel(epochCache, archiver, p2p, sentinelStore, config, logger); + return new Sentinel(epochCache, archiver, p2p, sentinelStore, reexecutionTracker, config, logger); } diff --git a/yarn-project/aztec-node/src/sentinel/sentinel.test.ts b/yarn-project/aztec-node/src/sentinel/sentinel.test.ts index 7bc4d050a71c..d28d49bc81a8 100644 --- a/yarn-project/aztec-node/src/sentinel/sentinel.test.ts +++ b/yarn-project/aztec-node/src/sentinel/sentinel.test.ts @@ -12,11 +12,15 @@ import { L2Block, type L2BlockSource, type L2BlockStream, - type L2BlockStreamEvent, getAttestationInfoFromPublishedCheckpoint, } from '@aztec/stdlib/block'; -import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; -import { type L1RollupConstants, getEpochAtSlot, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers'; +import { + Checkpoint, + CheckpointReexecutionTracker, + L1PublishedData, + PublishedCheckpoint, +} from '@aztec/stdlib/checkpoint'; +import { type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers'; import type { CheckpointAttestation } from '@aztec/stdlib/p2p'; import { TEST_COORDINATION_SIGNATURE_CONTEXT, @@ -41,6 +45,7 @@ describe('sentinel', () => { let archiver: MockProxy; let p2p: MockProxy; let blockStream: MockProxy; + let reexecutionTracker: CheckpointReexecutionTracker; let kvStore: AztecLMDBStoreV2; let store: SentinelStore; @@ -55,6 +60,7 @@ describe('sentinel', () => { slashInactivityPenalty: 100n, slashInactivityTargetPercentage: 0.8, slashInactivityConsecutiveEpochThreshold: 1, + sentinelEpochEndBufferSlots: 2, l1ChainId: TEST_COORDINATION_SIGNATURE_CONTEXT.chainId, rollupAddress: TEST_COORDINATION_SIGNATURE_CONTEXT.rollupAddress, }; @@ -65,9 +71,10 @@ describe('sentinel', () => { archiver.getGenesisBlockHash.mockReturnValue(GENESIS_BLOCK_HEADER_HASH); p2p = mock(); blockStream = mock(); + reexecutionTracker = new CheckpointReexecutionTracker(); kvStore = await openTmpStore('sentinel-test'); - store = new SentinelStore(kvStore, { historyLength: 10, historicProvenPerformanceLength: 5 }); + store = new SentinelStore(kvStore, { historyLength: 10, historicEpochPerformanceLength: 5 }); slot = SlotNumber(10); epoch = EpochNumber(0); @@ -94,13 +101,39 @@ describe('sentinel', () => { epochCache.isProposerPipeliningEnabled.mockReturnValue(false); epochCache.getL1Constants.mockReturnValue(l1Constants); - sentinel = new TestSentinel(epochCache, archiver, p2p, store, config, blockStream); + sentinel = new TestSentinel(epochCache, archiver, p2p, store, reexecutionTracker, config, blockStream); }); afterEach(async () => { await kvStore.close(); }); + describe('init', () => { + beforeEach(() => { + archiver.getBlockNumber.mockResolvedValue(BlockNumber(0)); + }); + + it('floors initialSlot at the archiver synced L2 slot when available', async () => { + const syncedSlot = SlotNumber(7); + epochCache.getSlotNow.mockReturnValue(SlotNumber(20)); + archiver.getSyncedL2SlotNumber.mockResolvedValue(syncedSlot); + + await sentinel.callProductionInit(); + + expect(sentinel.getInitialSlot()).toEqual(syncedSlot); + }); + + it('falls back to the wallclock slot when the archiver is not yet synced', async () => { + const wallclockSlot = SlotNumber(20); + epochCache.getSlotNow.mockReturnValue(wallclockSlot); + archiver.getSyncedL2SlotNumber.mockResolvedValue(undefined); + + await sentinel.callProductionInit(); + + expect(sentinel.getInitialSlot()).toEqual(wallclockSlot); + }); + }); + describe('getSlotActivity', () => { let signers: Secp256k1Signer[]; let validators: EthAddress[]; @@ -130,7 +163,7 @@ describe('sentinel', () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations); }); - it('flags checkpoint as mined', async () => { + it('flags checkpoint as mined when L1 has it (case 6)', async () => { // Create a checkpoint with a block at the target slot and emit chain-checkpointed event const checkpoint = await Checkpoint.random(CheckpointNumber(1), { numBlocks: 1, slotNumber: slot }); await emitCheckpointEvent(checkpoint); @@ -139,26 +172,49 @@ describe('sentinel', () => { expect(activity[proposer.toString()]).toEqual('checkpoint-mined'); }); - it('flags checkpoint as proposed when it is not mined but there are attestations', async () => { - p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations); + it('flags checkpoint as valid when tracker outcome is valid (case 5)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'valid', CheckpointNumber(1)); + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-valid'); + }); + + it('flags checkpoint as invalid when tracker outcome is invalid (case 4)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'invalid', CheckpointNumber(1)); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-invalid'); + }); + + it('flags checkpoint as unvalidated when tracker outcome is unvalidated (case 3)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'unvalidated'); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); - expect(activity[proposer.toString()]).toEqual('checkpoint-proposed'); + expect(activity[proposer.toString()]).toEqual('checkpoint-unvalidated'); }); - it('flags as blocks-missed when there are no attestations and no block proposals', async () => { + it('flags as blocks-missed when there is no tracker outcome and no block proposals (case 1)', async () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); p2p.hasBlockProposalsForSlot.mockResolvedValue(false); const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); expect(activity[proposer.toString()]).toEqual('blocks-missed'); }); - it('flags as checkpoint-missed when there are no attestations but block proposals exist', async () => { + it('flags as checkpoint-missed when block proposals exist but no checkpoint proposal (case 2)', async () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); p2p.hasBlockProposalsForSlot.mockResolvedValue(true); const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); expect(activity[proposer.toString()]).toEqual('checkpoint-missed'); }); + it('prefers L1-mined over tracker outcome', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'invalid', CheckpointNumber(1)); + const checkpoint = await Checkpoint.random(CheckpointNumber(1), { numBlocks: 1, slotNumber: slot }); + await emitCheckpointEvent(checkpoint); + + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-mined'); + }); + it('identifies attestors from p2p and archiver', async () => { // Create a checkpoint with a block at the target slot const checkpoint = await Checkpoint.random(CheckpointNumber(1), { numBlocks: 1, slotNumber: slot }); @@ -255,16 +311,18 @@ describe('sentinel', () => { expect(activity[committee[3].toString()]).toEqual('attestation-missed'); }); - it('identifies missed attestors if block is proposed', async () => { + it('identifies missed attestors when checkpoint proposal was re-executed valid', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'valid', CheckpointNumber(1)); p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations.slice(0, -1)); const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-valid'); expect(activity[committee[1].toString()]).toEqual('attestation-sent'); expect(activity[committee[2].toString()]).toEqual('attestation-sent'); expect(activity[committee[3].toString()]).toEqual('attestation-missed'); }); - it('does not tag attestors as missed if there was no block and no attestations', async () => { + it('does not tag attestors as missed if there was no block and no attestations (case 1)', async () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); p2p.hasBlockProposalsForSlot.mockResolvedValue(false); @@ -275,7 +333,7 @@ describe('sentinel', () => { expect(activity[committee[3].toString()]).not.toBeDefined(); }); - it('does not tag attestors as missed if blocks were proposed but checkpoint was missed', async () => { + it('does not tag attestors as missed if blocks were proposed but checkpoint was missed (case 2)', async () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); p2p.hasBlockProposalsForSlot.mockResolvedValue(true); @@ -285,6 +343,25 @@ describe('sentinel', () => { expect(activity[committee[2].toString()]).not.toBeDefined(); expect(activity[committee[3].toString()]).not.toBeDefined(); }); + + it('does not tag attestors as missed when checkpoint is unvalidated (case 3)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'unvalidated'); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations.slice(0, -1)); + + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-unvalidated'); + // committee[1..3] should not be tagged as missed even though they didn't all attest + expect(activity[committee[3].toString()]).not.toBe('attestation-missed'); + }); + + it('does not tag attestors as missed when checkpoint is invalid (case 4)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'invalid', CheckpointNumber(1)); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations.slice(0, -1)); + + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-invalid'); + expect(activity[committee[3].toString()]).not.toBe('attestation-missed'); + }); }); describe('computeStatsForValidator', () => { @@ -297,7 +374,7 @@ describe('sentinel', () => { it('computes stats correctly', () => { const stats = sentinel.computeStatsForValidator(validator, [ { slot: SlotNumber(1), status: 'checkpoint-mined' }, - { slot: SlotNumber(2), status: 'checkpoint-proposed' }, + { slot: SlotNumber(2), status: 'checkpoint-valid' }, { slot: SlotNumber(3), status: 'checkpoint-missed' }, { slot: SlotNumber(4), status: 'blocks-missed' }, { slot: SlotNumber(5), status: 'attestation-sent' }, @@ -316,6 +393,18 @@ describe('sentinel', () => { expect(stats.lastAttestation?.slot).toEqual(SlotNumber(5)); }); + it('counts checkpoint-invalid and checkpoint-unvalidated as missed proposals', () => { + const stats = sentinel.computeStatsForValidator(validator, [ + { slot: SlotNumber(1), status: 'checkpoint-mined' }, + { slot: SlotNumber(2), status: 'checkpoint-invalid' }, + { slot: SlotNumber(3), status: 'checkpoint-unvalidated' }, + { slot: SlotNumber(4), status: 'checkpoint-missed' }, + { slot: SlotNumber(5), status: 'blocks-missed' }, + ]); + expect(stats.missedProposals.count).toEqual(4); + expect(stats.missedProposals.total).toEqual(5); + }); + it('resets streaks correctly', () => { const stats = sentinel.computeStatsForValidator(validator, [ { slot: SlotNumber(1), status: 'checkpoint-mined' }, @@ -414,7 +503,7 @@ describe('sentinel', () => { ]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockProvenPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockProvenPerformance); jest.spyOn(sentinel, 'computeStatsForValidator').mockReturnValue({ address: validator, totalSlots: 2, @@ -433,7 +522,7 @@ describe('sentinel', () => { missedAttestations: { count: 0, currentStreak: 0, rate: 0, total: 0 }, history: mockHistory, }, - allTimeProvenPerformance: mockProvenPerformance, + allTimeEpochPerformance: mockProvenPerformance, lastProcessedSlot: sentinel.getLastProcessedSlot(), initialSlot: sentinel.getInitialSlot(), slotWindow: 10, @@ -443,7 +532,7 @@ describe('sentinel', () => { it('should call computeStatsForValidator with correct parameters', async () => { const mockHistory: ValidatorStatusHistory = [{ slot: SlotNumber(5), status: 'checkpoint-mined' }]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([]); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([]); const computeStatsSpy = jest.spyOn(sentinel, 'computeStatsForValidator').mockReturnValue({ address: validator, totalSlots: 1, @@ -460,7 +549,7 @@ describe('sentinel', () => { it('should use default slot range when not provided', async () => { const mockHistory: ValidatorStatusHistory = [{ slot: SlotNumber(5), status: 'checkpoint-mined' }]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([]); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([]); const computeStatsSpy = jest.spyOn(sentinel, 'computeStatsForValidator').mockReturnValue({ address: validator, totalSlots: 1, @@ -482,7 +571,7 @@ describe('sentinel', () => { it('should not produce negative slot numbers when historyLength exceeds lastProcessedSlot', async () => { const mockHistory: ValidatorStatusHistory = [{ slot: SlotNumber(2), status: 'checkpoint-mined' }]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([]); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([]); jest.spyOn(store, 'getHistoryLength').mockReturnValue(1000); // Large history length // Set lastProcessedSlot to a small value @@ -515,8 +604,8 @@ describe('sentinel', () => { ]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - const getProvenPerformanceSpy = jest - .spyOn(store, 'getProvenPerformance') + const getEpochPerformanceSpy = jest + .spyOn(store, 'getEpochPerformance') .mockResolvedValue(mockProvenPerformance); jest.spyOn(sentinel, 'computeStatsForValidator').mockReturnValue({ address: validator, @@ -528,8 +617,8 @@ describe('sentinel', () => { const result = await sentinel.getValidatorStats(validator); - expect(getProvenPerformanceSpy).toHaveBeenCalledWith(validator); - expect(result?.allTimeProvenPerformance).toEqual(mockProvenPerformance); + expect(getEpochPerformanceSpy).toHaveBeenCalledWith(validator); + expect(result?.allTimeEpochPerformance).toEqual(mockProvenPerformance); }); }); @@ -587,32 +676,14 @@ describe('sentinel', () => { }); }); - describe('handleChainProven', () => { + describe('handleEpochEnd', () => { it('calls inactivity watcher with performance data', async () => { - const blockNumber = BlockNumber(15); - const blockHash = '0xblockhash'; - const mockBlock = await L2Block.random(blockNumber); - const slot = mockBlock.header.getSlot(); - const epochNumber = getEpochAtSlot(slot, l1Constants); + const epochNumber = EpochNumber(2); const validator1 = EthAddress.random(); const validator2 = EthAddress.random(); const validator3 = EthAddress.random(); const [fromSlot, toSlot] = getSlotRangeForEpoch(epochNumber, l1Constants); - epochCache.getEpochAndSlotNow.mockReturnValue({ - epoch: epochNumber, - slot, - ts, - nowMs: ts * 1000n, - }); - epochCache.getSlotNow.mockReturnValue(slot); - epochCache.getTargetSlot.mockReturnValue(slot); - epochCache.getEpochNow.mockReturnValue(epochNumber); - epochCache.getTargetEpoch.mockReturnValue(epochNumber); - archiver.getBlockData.mockResolvedValue({ header: mockBlock.header } as any); - archiver.getL1Constants.mockResolvedValue(l1Constants); - epochCache.getL1Constants.mockReturnValue(l1Constants); - epochCache.getCommittee.mockResolvedValue({ committee: [validator1, validator2, validator3], seed: 0n, @@ -648,14 +719,14 @@ describe('sentinel', () => { history: [], }, }, - lastProcessedSlot: slot, + lastProcessedSlot: SlotNumber(toSlot), initialSlot: SlotNumber(0), slotWindow: 15, }; const computeStatsSpy = jest.spyOn(sentinel, 'computeStats').mockResolvedValue(statsResult); const emitSpy = jest.spyOn(sentinel, 'emit'); - await sentinel.handleChainProven({ type: 'chain-proven', block: { number: blockNumber, hash: blockHash } }); + await sentinel.handleEpochEnd(epochNumber); expect(computeStatsSpy).toHaveBeenCalledWith({ fromSlot, @@ -723,16 +794,10 @@ describe('sentinel', () => { expect(sentinel.getLastProcessedSlot()).toEqual(slot); }); - it('handleChainProven skips proven performance when escape hatch is open', async () => { - const blockNumber = BlockNumber(15); - const blockHash = '0xblockhash'; - const mockBlock = await L2Block.random(blockNumber); - const blockSlot = mockBlock.header.getSlot(); - const epochNumber = getEpochAtSlot(blockSlot, l1Constants); + it('handleEpochEnd skips epoch performance when escape hatch is open', async () => { + const epochNumber = EpochNumber(2); const validator1 = EthAddress.random(); - archiver.getBlockData.mockResolvedValue({ header: mockBlock.header } as any); - epochCache.getCommittee.mockResolvedValue({ committee: [validator1], seed: 0n, @@ -741,12 +806,12 @@ describe('sentinel', () => { }); const emitSpy = jest.spyOn(sentinel, 'emit'); - const updateProvenSpy = jest.spyOn(store, 'updateProvenPerformance'); + const updateEpochSpy = jest.spyOn(store, 'updateEpochPerformance'); - await sentinel.handleChainProven({ type: 'chain-proven', block: { number: blockNumber, hash: blockHash } }); + await sentinel.handleEpochEnd(epochNumber); // Should have stored empty performance (no offenses during escape hatch) - expect(updateProvenSpy).toHaveBeenCalledWith(epochNumber, {}); + expect(updateEpochSpy).toHaveBeenCalledWith(epochNumber, {}); // Should NOT have emitted any slash events expect(emitSpy).not.toHaveBeenCalled(); }); @@ -771,7 +836,7 @@ describe('sentinel', () => { { epoch: EpochNumber(2), missed: 5, total: 10 }, // 50% missed (active) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -787,7 +852,7 @@ describe('sentinel', () => { { epoch: EpochNumber(2), missed: 5, total: 10 }, // 50% missed (active) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -801,7 +866,7 @@ describe('sentinel', () => { { epoch: EpochNumber(4), missed: 9, total: 10 }, // 90% missed (inactive) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -814,7 +879,7 @@ describe('sentinel', () => { { epoch: EpochNumber(4), missed: 9, total: 10 }, // 90% missed (inactive) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); // We are checking at epoch 4, so no past epochs const result = await sentinel.checkPastInactivity(validator1, EpochNumber(4), 2); @@ -830,7 +895,7 @@ describe('sentinel', () => { { epoch: EpochNumber(2), missed: 8, total: 10 }, // 80% missed (inactive) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -838,7 +903,7 @@ describe('sentinel', () => { }); it('should work with threshold of 0 used when there are no past epochs to inspect', async () => { - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([]); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([]); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 0); expect(result).toBe(true); }); @@ -852,7 +917,7 @@ describe('sentinel', () => { { epoch: EpochNumber(2), missed: 5, total: 10 }, // 50% missed (active) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); // Query on epoch 5, so we only consider past ones and don't get to threshold const result = await sentinel.checkPastInactivity(validator1, EpochNumber(5), 3); @@ -867,7 +932,7 @@ describe('sentinel', () => { { epoch: EpochNumber(3), missed: 8, total: 10 }, // 80% missed (inactive) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -876,13 +941,13 @@ describe('sentinel', () => { }); }); - describe('handleProvenPerformance with consecutive epochs', () => { + describe('handleEpochPerformance with consecutive epochs', () => { it('should slash validators only after consecutive epoch failures', async () => { // Update config to require 2 consecutive epochs sentinel.updateConfig({ slashInactivityConsecutiveEpochThreshold: 2 }); // Mock performance data for two validators - jest.spyOn(store, 'getProvenPerformance').mockImplementation(validator => { + jest.spyOn(store, 'getEpochPerformance').mockImplementation(validator => { if (validator.equals(validator1)) { // Validator1: inactive for 2+ consecutive epochs - should be slashed return Promise.resolve([ @@ -908,7 +973,7 @@ describe('sentinel', () => { [validator2.toString()]: { missed: 8, total: 10 }, // 80% missed }; - await sentinel.handleProvenPerformance(EpochNumber(5), currentEpochPerformance); + await sentinel.handleEpochPerformance(EpochNumber(5), currentEpochPerformance); // Should only slash validator1 (2 consecutive epochs), not validator2 (1 epoch) expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ @@ -926,7 +991,7 @@ describe('sentinel', () => { sentinel.updateConfig({ slashInactivityConsecutiveEpochThreshold: 3 }); // Mock performance data: validators only inactive for 2 epochs - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([ + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([ { epoch: EpochNumber(5), missed: 8, total: 10 }, // 80% missed (inactive) { epoch: EpochNumber(4), missed: 9, total: 10 }, // 90% missed (inactive) { epoch: EpochNumber(3), missed: 5, total: 10 }, // 50% missed (active) @@ -938,7 +1003,7 @@ describe('sentinel', () => { [validator1.toString()]: { missed: 8, total: 10 }, // 80% missed }; - await sentinel.handleProvenPerformance(EpochNumber(5), currentEpochPerformance); + await sentinel.handleEpochPerformance(EpochNumber(5), currentEpochPerformance); // Should not emit any slash events expect(emitSpy).not.toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, expect.anything()); @@ -953,10 +1018,11 @@ class TestSentinel extends Sentinel { archiver: L2BlockSource, p2p: P2PClient, store: SentinelStore, + reexecutionTracker: CheckpointReexecutionTracker, config: SentinelRuntimeConfig, protected override blockStream: L2BlockStream, ) { - super(epochCache, archiver, p2p, store, config); + super(epochCache, archiver, p2p, store, reexecutionTracker, config); } public override init() { @@ -964,6 +1030,11 @@ class TestSentinel extends Sentinel { return Promise.resolve(); } + /** Invokes the production Sentinel.init() so tests can assert its initialSlot logic. */ + public callProductionInit() { + return super.init(); + } + public override getSlotActivity(slot: SlotNumber, epoch: EpochNumber, proposer: EthAddress, committee: EthAddress[]) { return super.getSlotActivity(slot, epoch, proposer, committee); } @@ -977,16 +1048,16 @@ class TestSentinel extends Sentinel { return super.computeStatsForValidator(address, history, fromSlot, toSlot); } - public override handleChainProven(event: L2BlockStreamEvent) { - return super.handleChainProven(event); + public override handleEpochEnd(epoch: EpochNumber) { + return super.handleEpochEnd(epoch); } public override computeStats(opts: { fromSlot?: SlotNumber; toSlot?: SlotNumber }) { return super.computeStats(opts); } - public override handleProvenPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { - return super.handleProvenPerformance(epoch, performance); + public override handleEpochPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { + return super.handleEpochPerformance(epoch, performance); } public override getValidatorStats(validatorAddress: EthAddress, fromSlot?: SlotNumber, toSlot?: SlotNumber) { diff --git a/yarn-project/aztec-node/src/sentinel/sentinel.ts b/yarn-project/aztec-node/src/sentinel/sentinel.ts index e1d4c153169c..53d1dcc70099 100644 --- a/yarn-project/aztec-node/src/sentinel/sentinel.ts +++ b/yarn-project/aztec-node/src/sentinel/sentinel.ts @@ -27,6 +27,7 @@ import { type L2BlockStreamEventHandler, getAttestationInfoFromPublishedCheckpoint, } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { ChainConfig } from '@aztec/stdlib/config'; import { getEpochAtSlot, getSlotRangeForEpoch, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { ConsensusPayload, type CoordinationSignatureContext } from '@aztec/stdlib/p2p'; @@ -42,12 +43,14 @@ import type { import EventEmitter from 'node:events'; +import type { SentinelConfig } from './config.js'; import { SentinelStore } from './store.js'; export type SentinelRuntimeConfig = Pick< SlasherConfig, 'slashInactivityTargetPercentage' | 'slashInactivityPenalty' | 'slashInactivityConsecutiveEpochThreshold' > & + Pick & Pick; /** Maps a validator status to its category: proposer or attestation. */ @@ -61,6 +64,76 @@ function statusToCategory(status: ValidatorStatusInSlot): ValidatorStatusType { } } +/** + * The Sentinel observes validator behaviour every L2 slot, classifies it into a per-slot status, + * aggregates those statuses into per-epoch performance once each epoch is fully observed, and + * emits inactivity slash payloads when a validator has been inactive for the configured number + * of consecutive epochs. + * + * ## Two cadences + * + * The sentinel runs `work()` every quarter L2 slot and drives two independent pipelines: + * + * 1. **Per-slot activity recording.** `processSlot(currentSlot - 2)` runs once per slot, with a + * two-slot lag to let P2P attestations settle and the archiver catch up. It classifies each + * committee member's behaviour for that slot via `getSlotActivity` and persists the result to + * `SentinelStore.historyMap` (sliding window of `sentinelHistoryLengthInEpochs * epochDuration` + * slots, default 24 epochs). + * + * 2. **Per-epoch evaluation.** `processEpochEnds(currentSlot)` runs every tick too. Once + * `sentinelEpochEndBufferSlots` (default 2) has elapsed past an epoch's last slot AND the + * per-slot recorder has covered that last slot, the sentinel calls `handleEpochEnd(epoch)`. + * That aggregates the slot-level statuses for the epoch into per-validator `{missed, total}`, + * persists it to `SentinelStore.epochMap` (default 2000-epoch window), and runs the slashing + * decision. + * + * Triggering per-epoch evaluation off local L2 state — rather than waiting for L1 proof + * publication — decouples slashing from prover availability. + * + * ## Six-case taxonomy in `getSlotActivity` + * + * For each slot, the sentinel assigns the proposer one of six statuses, ranked highest-confidence + * first: + * + * - `checkpoint-mined` — a checkpoint covering this slot has landed on L1 + * (`slotNumberToCheckpoint` populated from `chain-checkpointed`). + * - `checkpoint-valid` — the local node re-executed a checkpoint proposal for this slot + * successfully (consulted via `CheckpointReexecutionTracker`). + * - `checkpoint-invalid` — the local node re-executed a checkpoint proposal for this slot + * and rejected it (e.g. header/archive/out-hash mismatch, limit + * breach). Proposer-fault. + * - `checkpoint-unvalidated` — the local node observed a checkpoint proposal but could not + * validate it (missing blocks/txs, timeouts). Treated as + * proposer-fault for slashing. + * - `checkpoint-missed` — block proposals seen on P2P but no checkpoint proposal at all. + * - `blocks-missed` — no block proposals seen for this slot. + * + * Missing-attestor faults are recorded only in `checkpoint-mined` and `checkpoint-valid`, where + * the local node has positive evidence the checkpoint was canonical or valid. In the other four + * cases the proposer is at fault and no attestor penalty applies. + * + * ## Re-execution tracker + * + * `CheckpointReexecutionTracker` is populated by the validator client's checkpoint proposal + * handler. Every early return in `validateCheckpointProposal` records an outcome + * (`valid` / `invalid` / `unvalidated`) keyed by slot. + * + * ## Inactivity slashing + * + * `handleEpochPerformance` filters the epoch's per-validator stats by + * `slashInactivityTargetPercentage` and then calls `checkPastInactivity` to require + * `slashInactivityConsecutiveEpochThreshold` consecutive past epochs over the same threshold + * (read from `SentinelStore.epochMap`). Only validators meeting both conditions are emitted as + * `WANT_TO_SLASH_EVENT` with `OffenseType.INACTIVITY`. The slot-level counters that feed this — + * `missedProposals` and `missedAttestations` — include the four proposer-fault statuses plus + * `attestation-missed`. + * + * ## Escape hatch + * + * If `epochCache.getCommittee(slot)` reports `isEscapeHatchOpen`, per-slot recording is skipped + * (no history entries for that slot) and per-epoch evaluation writes an empty performance map + * (no slashing). + */ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) implements L2BlockStreamEventHandler, Watcher { protected runningPromise: RunningPromise; protected blockStream!: L2BlockStream; @@ -68,6 +141,8 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme protected initialSlot: SlotNumber | undefined; protected lastProcessedSlot: SlotNumber | undefined; + /** Largest epoch number for which the end-of-epoch aggregator has run. */ + protected lastEvaluatedEpoch: EpochNumber | undefined; protected slotNumberToCheckpoint: Map< SlotNumber, { @@ -84,6 +159,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme protected archiver: L2BlockSource, protected p2p: P2PClient, protected store: SentinelStore, + protected reexecutionTracker: CheckpointReexecutionTracker, protected config: SentinelRuntimeConfig, protected logger = createLogger('node:sentinel'), ) { @@ -109,14 +185,31 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme this.runningPromise.start(); } - /** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */ + /** + * Loads initial slot and initializes blockstream. We will not process anything at or before + * the initial slot. Floors at the archiver's synced L2 slot so the sentinel keeps making + * forward progress when L1 is advancing but L2 has no activity (the synced slot is driven by + * L1 sync, not by L2 blocks). Falls back to the wallclock if the archiver isn't ready yet + * (cold start). + */ protected async init() { - this.initialSlot = this.epochCache.getSlotNow(); + this.initialSlot = await this.getCurrentSlot(); const startingBlock = BlockNumber(await this.archiver.getBlockNumber()); this.logger.info(`Starting validator sentinel with initial slot ${this.initialSlot} and block ${startingBlock}`); this.blockStream = new L2BlockStream(this.archiver, this.l2TipsStore, this, this.logger, { startingBlock }); } + /** + * Returns the L2 slot the sentinel should treat as "current": the archiver's last fully + * synced L2 slot, falling back to the wallclock slot when the archiver isn't ready yet + * (cold start). Anchoring to the synced slot keeps timing arithmetic (initial floor, + * per-slot lag, end-of-epoch buffer, stats-range fallback) from speculating ahead of where + * L1 actually is. + */ + protected async getCurrentSlot(): Promise { + return (await this.archiver.getSyncedL2SlotNumber()) ?? this.epochCache.getSlotNow(); + } + public stop() { return this.runningPromise.stop(); } @@ -125,8 +218,6 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme await this.l2TipsStore.handleBlockStreamEvent(event); if (event.type === 'chain-checkpointed') { this.handleCheckpoint(event); - } else if (event.type === 'chain-proven') { - await this.handleChainProven(event); } } @@ -163,33 +254,25 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme } } - protected async handleChainProven(event: L2BlockStreamEvent) { - if (event.type !== 'chain-proven') { - return; - } - const blockNumber = event.block.number; - const header = (await this.archiver.getBlockData({ number: blockNumber }))?.header; - if (!header) { - this.logger.error(`Failed to get block header ${blockNumber}`); - return; - } - - // TODO(palla/slash): We should only be computing proven performance if this is - // a full proof epoch and not a partial one, otherwise we'll end up with skewed stats. - const epoch = getEpochAtSlot(header.getSlot(), this.epochCache.getL1Constants()); - this.logger.debug(`Computing proven performance for epoch ${epoch}`); - const performance = await this.computeProvenPerformance(epoch); - this.logger.info(`Computed proven performance for epoch ${epoch}`, performance); + /** + * Called once per epoch, after the configured end-of-epoch buffer has elapsed beyond the + * epoch's last slot. Computes per-epoch performance from the slot-level history collected + * by `processSlot` and emits any inactivity slash payloads. + */ + protected async handleEpochEnd(epoch: EpochNumber) { + this.logger.debug(`Computing epoch performance for epoch ${epoch}`); + const performance = await this.computeEpochPerformance(epoch); + this.logger.info(`Computed epoch performance for epoch ${epoch}`, performance); - await this.store.updateProvenPerformance(epoch, performance); - await this.handleProvenPerformance(epoch, performance); + await this.store.updateEpochPerformance(epoch, performance); + await this.handleEpochPerformance(epoch, performance); } - protected async computeProvenPerformance(epoch: EpochNumber): Promise { + protected async computeEpochPerformance(epoch: EpochNumber): Promise { const [fromSlot, toSlot] = getSlotRangeForEpoch(epoch, this.epochCache.getL1Constants()); const { committee, isEscapeHatchOpen } = await this.epochCache.getCommittee(fromSlot); if (isEscapeHatchOpen) { - this.logger.info(`Skipping proven performance for epoch ${epoch} - escape hatch is open`); + this.logger.info(`Skipping epoch performance for epoch ${epoch} - escape hatch is open`); return {}; } if (!committee) { @@ -231,8 +314,8 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme return true; } - // Get all historical performance for this validator - const allPerformance = await this.store.getProvenPerformance(validator); + // Get all historical per-epoch performance for this validator + const allPerformance = await this.store.getEpochPerformance(validator); // Sort by epoch descending to get most recent first, keep only epochs strictly before the current one, and get the first N const pastEpochs = allPerformance.sort((a, b) => Number(b.epoch - a.epoch)).filter(p => p.epoch < currentEpoch); @@ -251,7 +334,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme .every(p => (p.total === 0 ? false : p.missed / p.total >= this.config.slashInactivityTargetPercentage)); } - protected async handleProvenPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { + protected async handleEpochPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { if (this.config.slashInactivityPenalty === 0n) { return; } @@ -291,26 +374,72 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme * Process data for two L2 slots ago. * Note that we do not process historical data, since we rely on p2p data for processing, * and we don't have that data if we were offline during the period. + * + * `currentSlot` is anchored to the archiver's last synced L2 slot rather than the wallclock, + * so the per-slot lag (`isReadyToProcess`) and the end-of-epoch buffer (`processEpochEnds`) + * advance with archiver. */ public async work() { - const currentSlot = this.epochCache.getSlotNow(); + const currentSlot = await this.getCurrentSlot(); try { // Manually sync the block stream to ensure we have the latest data. // Note we never `start` the blockstream, so it loops at the same pace as we do. await this.blockStream.sync(); - // Check if we are ready to process data for two L2 slots ago. + // Per-slot activity recording (lag = 2 slots for P2P attestation settlement). const targetSlot = await this.isReadyToProcess(currentSlot); - - // And process it if we are. if (targetSlot !== false) { await this.processSlot(targetSlot); } + + // End-of-epoch evaluation (lag = sentinelEpochEndBufferSlots beyond the epoch's last slot). + await this.processEpochEnds(currentSlot); } catch (err) { this.logger.error(`Failed to process slot ${currentSlot}`, err); } } + /** + * After the configured buffer has elapsed past an epoch's last slot, runs the end-of-epoch + * aggregator for that epoch. Catches up if multiple epochs become eligible at once. + */ + protected async processEpochEnds(currentSlot: SlotNumber) { + const constants = this.epochCache.getL1Constants(); + const buffer = this.config.sentinelEpochEndBufferSlots; + if (currentSlot < buffer) { + return; + } + if (this.initialSlot === undefined) { + return; + } + + // We can close epoch E iff: + // - the per-slot recorder has covered the epoch's last slot (lastProcessedSlot ≥ toSlot(E)) + // - the buffer has elapsed past the epoch's last slot (currentSlot − buffer ≥ toSlot(E)) + // - the epoch is not in the past relative to when the sentinel started (toSlot(E) > initialSlot) + if (this.lastProcessedSlot === undefined) { + return; + } + const slotForBuffer = SlotNumber(currentSlot - buffer); + + // First eligible epoch to close is the one after lastEvaluatedEpoch, or the epoch containing + // the initial slot if we haven't evaluated any yet (the initialSlot epoch may be partial — we + // don't try to evaluate it, we start from initialSlot's epoch + 1). + const startEpoch = + this.lastEvaluatedEpoch !== undefined + ? EpochNumber(this.lastEvaluatedEpoch + 1) + : EpochNumber(getEpochAtSlot(this.initialSlot, constants) + 1); + + for (let epoch = startEpoch; ; epoch = EpochNumber(epoch + 1)) { + const [, toSlot] = getSlotRangeForEpoch(epoch, constants); + if (toSlot > this.lastProcessedSlot || toSlot > slotForBuffer) { + break; + } + await this.handleEpochEnd(epoch); + this.lastEvaluatedEpoch = epoch; + } + } + /** * Check if we are ready to process data for two L2 slots ago, so we allow plenty of time for p2p to process all in-flight attestations. * We also don't move past the archiver last synced L2 slot, as we don't want to process data that is not yet available. @@ -379,49 +508,68 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme this.lastProcessedSlot = slot; } - /** Computes activity for a given slot. */ + /** + * Computes activity for a given slot using the six-case taxonomy. + * + * Proposer status: + * - case 6 `checkpoint-mined` — a checkpoint covering this slot has landed on L1. + * - case 5 `checkpoint-valid` — the local node re-executed a checkpoint proposal for this + * slot successfully. + * - case 4 `checkpoint-invalid` — the local node re-executed a checkpoint proposal for this + * slot and rejected it. + * - case 3 `checkpoint-unvalidated` — the local node observed a checkpoint proposal for this + * slot but could not validate it (missing data, timeouts). + * - case 2 `checkpoint-missed` — block proposals seen on P2P but no checkpoint proposal. + * - case 1 `blocks-missed` — no block proposals seen for this slot. + * + * Missing-attestor penalties apply only in cases 5 and 6, where the local node has positive + * evidence the checkpoint was valid or has been canonicalised on L1. + */ protected async getSlotActivity(slot: SlotNumber, epoch: EpochNumber, proposer: EthAddress, committee: EthAddress[]) { this.logger.debug(`Computing stats for slot ${slot} at epoch ${epoch}`, { slot, epoch, proposer, committee }); - // Check if there is an L2 block in L1 for this L2 slot - - // Here we get all checkpoint attestations for the checkpoint at the given slot, - // or all checkpoint attestations for all proposals in the slot if no checkpoint was mined. - // We gather from both p2p (contains the ones seen on the p2p layer) and archiver - // (contains the ones synced from mined checkpoints, which we may have missed from p2p). + // Gather attestors from both p2p (live attestations) and the archiver (signers on the + // checkpoint if one has landed on L1). Used regardless of which case applies. const checkpoint = this.slotNumberToCheckpoint.get(slot); const p2pAttested = await this.p2p.getCheckpointAttestationsForSlot(slot, checkpoint?.proposalPayloadHash); - // Filter out attestations with invalid signatures const p2pAttestors = p2pAttested.map(a => a.getSender()).filter((s): s is EthAddress => s !== undefined); const attestors = new Set( [...p2pAttestors.map(a => a.toString()), ...(checkpoint?.attestors.map(a => a.toString()) ?? [])].filter( - addr => proposer.toString() !== addr, // Exclude the proposer from the attestors + addr => proposer.toString() !== addr, ), ); - // We assume that there was a block proposal if at least one of the validators (other than the proposer) attested to it. - // It could be the case that every single validator failed, and we could differentiate it by having - // this node re-execute every block proposal it sees and storing it in the attestation pool. - // But we'll leave that corner case out to reduce pressure on the node. - // TODO(palla/slash): This breaks if a given node has more than one validator in the current committee, - // since they will attest to their own proposal it even if it's not re-executable. - let status: 'checkpoint-mined' | 'checkpoint-proposed' | 'checkpoint-missed' | 'blocks-missed'; + // Determine the proposer status from the six-case taxonomy. + const reexecutionOutcome = this.reexecutionTracker.getOutcomeForSlot(slot); + let status: + | 'checkpoint-mined' + | 'checkpoint-valid' + | 'checkpoint-invalid' + | 'checkpoint-unvalidated' + | 'checkpoint-missed' + | 'blocks-missed'; if (checkpoint) { status = 'checkpoint-mined'; - } else if (attestors.size > 0) { - status = 'checkpoint-proposed'; + } else if (reexecutionOutcome === 'valid') { + status = 'checkpoint-valid'; + } else if (reexecutionOutcome === 'invalid') { + status = 'checkpoint-invalid'; + } else if (reexecutionOutcome === 'unvalidated') { + status = 'checkpoint-unvalidated'; } else { - // No checkpoint on L1 and no checkpoint attestations seen. Check if block proposals were sent for this slot. + // No L1 checkpoint, no local re-execution outcome for this slot. Distinguish "proposer + // sent block proposals but never made a checkpoint" from "proposer sent nothing". const hasBlockProposals = await this.p2p.hasBlockProposalsForSlot(slot); status = hasBlockProposals ? 'checkpoint-missed' : 'blocks-missed'; } this.logger.debug(`Checkpoint status for slot ${slot}: ${status}`, { ...checkpoint, slot }); - // Get attestors that failed their checkpoint attestation duties, but only if there was a checkpoint proposed or mined + // Missing-attestor faults only apply when we have positive evidence the proposal was valid. + const attestorsExpected = status === 'checkpoint-mined' || status === 'checkpoint-valid'; const missedAttestors = new Set( - status === 'blocks-missed' || status === 'checkpoint-missed' - ? [] - : committee.filter(v => !attestors.has(v.toString()) && !proposer.equals(v)).map(v => v.toString()), + attestorsExpected + ? committee.filter(v => !attestors.has(v.toString()) && !proposer.equals(v)).map(v => v.toString()) + : [], ); this.logger.debug(`Retrieved ${attestors.size} attestors out of ${committee.length} for slot ${slot}`, { @@ -465,7 +613,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme ? fromEntries(await Promise.all(validators.map(async v => [v.toString(), await this.store.getHistory(v)]))) : await this.store.getHistories(); - const slotNow = this.epochCache.getSlotNow(); + const slotNow = await this.getCurrentSlot(); fromSlot ??= SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0)); toSlot ??= this.lastProcessedSlot ?? slotNow; @@ -493,7 +641,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme return undefined; } - const slotNow = this.epochCache.getSlotNow(); + const slotNow = await this.getCurrentSlot(); const effectiveFromSlot = fromSlot ?? SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0)); const effectiveToSlot = toSlot ?? this.lastProcessedSlot ?? slotNow; @@ -515,7 +663,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme return { validator, - allTimeProvenPerformance: await this.store.getProvenPerformance(validatorAddress), + allTimeEpochPerformance: await this.store.getEpochPerformance(validatorAddress), lastProcessedSlot: this.lastProcessedSlot, initialSlot: this.initialSlot, slotWindow: this.store.getHistoryLength(), @@ -530,16 +678,19 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme ): ValidatorStats { let history = fromSlot ? allHistory.filter(h => BigInt(h.slot) >= fromSlot) : allHistory; history = toSlot ? history.filter(h => BigInt(h.slot) <= toSlot) : history; - const lastProposal = history - .filter(h => h.status === 'checkpoint-proposed' || h.status === 'checkpoint-mined') - .at(-1); + const lastProposal = history.filter(h => h.status === 'checkpoint-valid' || h.status === 'checkpoint-mined').at(-1); const lastAttestation = history.filter(h => h.status === 'attestation-sent').at(-1); return { address: EthAddress.fromString(address), lastProposal: this.computeFromSlot(lastProposal?.slot), lastAttestation: this.computeFromSlot(lastAttestation?.slot), totalSlots: history.length, - missedProposals: this.computeMissed(history, 'proposer', ['checkpoint-missed', 'blocks-missed']), + missedProposals: this.computeMissed(history, 'proposer', [ + 'checkpoint-missed', + 'blocks-missed', + 'checkpoint-invalid', + 'checkpoint-unvalidated', + ]), missedAttestations: this.computeMissed(history, 'attestation', ['attestation-missed']), history, }; diff --git a/yarn-project/aztec-node/src/sentinel/store.test.ts b/yarn-project/aztec-node/src/sentinel/store.test.ts index 0c7babb7ce99..cd8adf3d352e 100644 --- a/yarn-project/aztec-node/src/sentinel/store.test.ts +++ b/yarn-project/aztec-node/src/sentinel/store.test.ts @@ -13,12 +13,12 @@ describe('sentinel-store', () => { let log: Logger; const historyLength = 4; - const historicProvenPerformanceLength = 3; + const historicEpochPerformanceLength = 3; beforeEach(async () => { log = createLogger('sentinel:store:test'); kvStore = await openTmpStore('sentinel-store-test'); - store = new SentinelStore(kvStore, { historyLength, historicProvenPerformanceLength }); + store = new SentinelStore(kvStore, { historyLength, historicEpochPerformanceLength }); }); afterEach(async () => { @@ -27,10 +27,12 @@ describe('sentinel-store', () => { it('inserts new validators with all statuses', async () => { const slot = SlotNumber(1); - const validators: `0x${string}`[] = times(6, () => EthAddress.random().toString()); + const validators: `0x${string}`[] = times(8, () => EthAddress.random().toString()); const statuses: ValidatorStatusInSlot[] = [ 'checkpoint-mined', - 'checkpoint-proposed', + 'checkpoint-valid', + 'checkpoint-invalid', + 'checkpoint-unvalidated', 'checkpoint-missed', 'blocks-missed', 'attestation-sent', @@ -66,7 +68,7 @@ describe('sentinel-store', () => { await store.updateValidators( SlotNumber(2), Object.fromEntries([ - ...newValidators.map(v => [v, 'checkpoint-proposed'] as const), + ...newValidators.map(v => [v, 'checkpoint-valid'] as const), ...existingValidators.map(v => [v, 'checkpoint-missed'] as const), ]), ); @@ -84,8 +86,8 @@ describe('sentinel-store', () => { { slot: SlotNumber(2), status: 'checkpoint-missed' }, ]); - expect(histories[newValidators[0]]).toEqual([{ slot: SlotNumber(2), status: 'checkpoint-proposed' }]); - expect(histories[newValidators[1]]).toEqual([{ slot: SlotNumber(2), status: 'checkpoint-proposed' }]); + expect(histories[newValidators[0]]).toEqual([{ slot: SlotNumber(2), status: 'checkpoint-valid' }]); + expect(histories[newValidators[1]]).toEqual([{ slot: SlotNumber(2), status: 'checkpoint-valid' }]); }); it('trims history to the specified length', async () => { @@ -106,52 +108,52 @@ describe('sentinel-store', () => { ]); }); - it('updates proven performance', async () => { + it('updates per-epoch performance', async () => { const validator = EthAddress.random(); - await store.updateProvenPerformance(EpochNumber(1), { [validator.toString()]: { missed: 2, total: 10 } }); - const provenPerformance = await store.getProvenPerformance(validator); - expect(provenPerformance).toEqual([{ epoch: EpochNumber(1), missed: 2, total: 10 }]); + await store.updateEpochPerformance(EpochNumber(1), { [validator.toString()]: { missed: 2, total: 10 } }); + const epochPerformance = await store.getEpochPerformance(validator); + expect(epochPerformance).toEqual([{ epoch: EpochNumber(1), missed: 2, total: 10 }]); - await store.updateProvenPerformance(EpochNumber(1), { [validator.toString()]: { missed: 3, total: 10 } }); - const provenPerformance2 = await store.getProvenPerformance(validator); - expect(provenPerformance2).toEqual([{ epoch: EpochNumber(1), missed: 3, total: 10 }]); + await store.updateEpochPerformance(EpochNumber(1), { [validator.toString()]: { missed: 3, total: 10 } }); + const epochPerformance2 = await store.getEpochPerformance(validator); + expect(epochPerformance2).toEqual([{ epoch: EpochNumber(1), missed: 3, total: 10 }]); - await store.updateProvenPerformance(EpochNumber(2), { [validator.toString()]: { missed: 4, total: 10 } }); - const provenPerformance3 = await store.getProvenPerformance(validator); - expect(provenPerformance3).toEqual([ + await store.updateEpochPerformance(EpochNumber(2), { [validator.toString()]: { missed: 4, total: 10 } }); + const epochPerformance3 = await store.getEpochPerformance(validator); + expect(epochPerformance3).toEqual([ { epoch: EpochNumber(1), missed: 3, total: 10 }, { epoch: EpochNumber(2), missed: 4, total: 10 }, ]); }); - it('trims proven performance to the specified historicProvenPerformanceLength', async () => { + it('trims per-epoch performance to the specified historicEpochPerformanceLength', async () => { const validator = EthAddress.random(); - // Add 5 epochs worth of proven performance data (more than historicProvenPerformanceLength = 3) + // Add 5 epochs worth of per-epoch performance data (more than historicEpochPerformanceLength = 3) for (let i = 1; i <= 5; i++) { - await store.updateProvenPerformance(EpochNumber(i), { [validator.toString()]: { missed: i, total: 10 } }); + await store.updateEpochPerformance(EpochNumber(i), { [validator.toString()]: { missed: i, total: 10 } }); } - const provenPerformance = await store.getProvenPerformance(validator); + const epochPerformance = await store.getEpochPerformance(validator); // Should only keep the most recent 3 entries (epochs 3, 4, 5) - expect(provenPerformance).toHaveLength(historicProvenPerformanceLength); - expect(provenPerformance).toEqual([ + expect(epochPerformance).toHaveLength(historicEpochPerformanceLength); + expect(epochPerformance).toEqual([ { epoch: EpochNumber(3), missed: 3, total: 10 }, { epoch: EpochNumber(4), missed: 4, total: 10 }, { epoch: EpochNumber(5), missed: 5, total: 10 }, ]); }); - it('getHistoricProvenPerformanceLength returns the correct value', () => { - expect(store.getHistoricProvenPerformanceLength()).toBe(historicProvenPerformanceLength); + it('getHistoricEpochPerformanceLength returns the correct value', () => { + expect(store.getHistoricEpochPerformanceLength()).toBe(historicEpochPerformanceLength); }); - it('proven performance with 2k entries', async () => { + it('per-epoch performance with 2k entries', async () => { const validator = EthAddress.random(); const totalEntries = 2000; - log.info(`Starting stress test with ${totalEntries} proven performance entries`); + log.info(`Starting stress test with ${totalEntries} per-epoch performance entries`); // Track timing for additions const addTimes: number[] = []; @@ -160,7 +162,7 @@ describe('sentinel-store', () => { // Add 2k entries for (let i = 1; i <= totalEntries; i++) { const addStart = Date.now(); - await store.updateProvenPerformance(EpochNumber(i), { + await store.updateEpochPerformance(EpochNumber(i), { [validator.toString()]: { missed: i % 10, total: 10 }, }); const addEnd = Date.now(); @@ -186,15 +188,15 @@ describe('sentinel-store', () => { for (let i = 0; i < numRetrievals; i++) { const retrievalStart = Date.now(); - const performance = await store.getProvenPerformance(validator); + const performance = await store.getEpochPerformance(validator); const retrievalEnd = Date.now(); retrievalTimes.push(retrievalEnd - retrievalStart); // Verify we only keep the configured number of entries - expect(performance).toHaveLength(historicProvenPerformanceLength); + expect(performance).toHaveLength(historicEpochPerformanceLength); // Verify we kept the most recent entries - const expectedStartEpoch = totalEntries - historicProvenPerformanceLength + 1; + const expectedStartEpoch = totalEntries - historicEpochPerformanceLength + 1; expect(performance[0].epoch).toBe(EpochNumber(expectedStartEpoch)); expect(performance[performance.length - 1].epoch).toBe(EpochNumber(totalEntries)); } @@ -206,7 +208,7 @@ describe('sentinel-store', () => { it('does not allow insertion of invalid validator addresses', async () => { const validator = '0x123'; await expect( - store.updateProvenPerformance(EpochNumber(1), { [validator]: { missed: 2, total: 10 } }), + store.updateEpochPerformance(EpochNumber(1), { [validator]: { missed: 2, total: 10 } }), ).rejects.toThrow(); await expect(store.updateValidators(SlotNumber(1), { [validator]: 'checkpoint-mined' })).rejects.toThrow(); }); diff --git a/yarn-project/aztec-node/src/sentinel/store.ts b/yarn-project/aztec-node/src/sentinel/store.ts index c06be27cb179..6f74c8c50a76 100644 --- a/yarn-project/aztec-node/src/sentinel/store.ts +++ b/yarn-project/aztec-node/src/sentinel/store.ts @@ -9,45 +9,45 @@ import type { } from '@aztec/stdlib/validators'; export class SentinelStore { - public static readonly SCHEMA_VERSION = 3; + public static readonly SCHEMA_VERSION = 4; // a map from validator address to their ValidatorStatusHistory private readonly historyMap: AztecAsyncMap<`0x${string}`, Buffer>; - // a map from validator address to their historical proven epoch performance + // a map from validator address to their historical epoch performance, evaluated at end-of-epoch. // e.g. { validator: [{ epoch: 1, missed: 1, total: 10 }, { epoch: 2, missed: 3, total: 7 }, ...] } - private readonly provenMap: AztecAsyncMap<`0x${string}`, Buffer>; + private readonly epochMap: AztecAsyncMap<`0x${string}`, Buffer>; constructor( private store: AztecAsyncKVStore, - private config: { historyLength: number; historicProvenPerformanceLength: number }, + private config: { historyLength: number; historicEpochPerformanceLength: number }, ) { this.historyMap = store.openMap('sentinel-validator-status'); - this.provenMap = store.openMap('sentinel-validator-proven'); + this.epochMap = store.openMap('sentinel-validator-epoch'); } public getHistoryLength() { return this.config.historyLength; } - public getHistoricProvenPerformanceLength() { - return this.config.historicProvenPerformanceLength; + public getHistoricEpochPerformanceLength() { + return this.config.historicEpochPerformanceLength; } - public async updateProvenPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { + public async updateEpochPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { await this.store.transactionAsync(async () => { for (const [who, { missed, total }] of Object.entries(performance)) { - await this.pushValidatorProvenPerformanceForEpoch({ who: EthAddress.fromString(who), missed, total, epoch }); + await this.pushValidatorEpochPerformance({ who: EthAddress.fromString(who), missed, total, epoch }); } }); } - public async getProvenPerformance(who: EthAddress): Promise<{ missed: number; total: number; epoch: EpochNumber }[]> { - const currentPerformanceBuffer = await this.provenMap.getAsync(who.toString()); + public async getEpochPerformance(who: EthAddress): Promise<{ missed: number; total: number; epoch: EpochNumber }[]> { + const currentPerformanceBuffer = await this.epochMap.getAsync(who.toString()); return currentPerformanceBuffer ? this.deserializePerformance(currentPerformanceBuffer) : []; } - private async pushValidatorProvenPerformanceForEpoch({ + private async pushValidatorEpochPerformance({ who, missed, total, @@ -58,7 +58,7 @@ export class SentinelStore { total: number; epoch: EpochNumber; }) { - const currentPerformance = await this.getProvenPerformance(who); + const currentPerformance = await this.getEpochPerformance(who); const existingIndex = currentPerformance.findIndex(p => p.epoch === epoch); if (existingIndex !== -1) { currentPerformance[existingIndex] = { missed, total, epoch }; @@ -70,10 +70,10 @@ export class SentinelStore { // Since we keep the size small, this is not a big deal. currentPerformance.sort((a, b) => Number(a.epoch - b.epoch)); - // keep the most recent `historicProvenPerformanceLength` entries. - const performanceToKeep = currentPerformance.slice(-this.config.historicProvenPerformanceLength); + // keep the most recent `historicEpochPerformanceLength` entries. + const performanceToKeep = currentPerformance.slice(-this.config.historicEpochPerformanceLength); - await this.provenMap.set(who.toString(), this.serializePerformance(performanceToKeep)); + await this.epochMap.set(who.toString(), this.serializePerformance(performanceToKeep)); } public async updateValidators(slot: SlotNumber, statuses: Record<`0x${string}`, ValidatorStatusInSlot | undefined>) { @@ -147,7 +147,7 @@ export class SentinelStore { switch (status) { case 'checkpoint-mined': return 1; - case 'checkpoint-proposed': + case 'checkpoint-valid': return 2; case 'checkpoint-missed': return 3; @@ -157,6 +157,10 @@ export class SentinelStore { return 5; case 'blocks-missed': return 6; + case 'checkpoint-invalid': + return 7; + case 'checkpoint-unvalidated': + return 8; default: { const _exhaustive: never = status; throw new Error(`Unknown status: ${status}`); @@ -169,7 +173,7 @@ export class SentinelStore { case 1: return 'checkpoint-mined'; case 2: - return 'checkpoint-proposed'; + return 'checkpoint-valid'; case 3: return 'checkpoint-missed'; case 4: @@ -178,6 +182,10 @@ export class SentinelStore { return 'attestation-missed'; case 6: return 'blocks-missed'; + case 7: + return 'checkpoint-invalid'; + case 8: + return 'checkpoint-unvalidated'; default: throw new Error(`Unknown status: ${status}`); } diff --git a/yarn-project/aztec-node/src/test/index.ts b/yarn-project/aztec-node/src/test/index.ts index be390476ef21..22e12a224cef 100644 --- a/yarn-project/aztec-node/src/test/index.ts +++ b/yarn-project/aztec-node/src/test/index.ts @@ -1,7 +1,7 @@ import type { EpochCacheInterface } from '@aztec/epoch-cache'; import type { P2P } from '@aztec/p2p'; import { SequencerClient } from '@aztec/sequencer-client'; -import { EpochPruneWatcher, type SlasherClientInterface } from '@aztec/slasher'; +import { DataWithholdingWatcher, type SlasherClientInterface } from '@aztec/slasher'; import type { L2BlockSource } from '@aztec/stdlib/block'; import type { ContractDataSource } from '@aztec/stdlib/contract'; import type { L2LogsSource, Service, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; @@ -23,7 +23,7 @@ export declare class TestAztecNodeService extends AztecNodeService { declare public sequencer: SequencerClient | undefined; declare public slasherClient: SlasherClientInterface | undefined; declare public validatorsSentinel: Sentinel | undefined; - declare public epochPruneWatcher: EpochPruneWatcher | undefined; + declare public dataWithholdingWatcher: DataWithholdingWatcher | undefined; declare public l1ChainId: number; declare public version: number; declare public globalVariableBuilder: GlobalVariableBuilderInterface; diff --git a/yarn-project/aztec.js/src/deployment/publish_instance.ts b/yarn-project/aztec.js/src/deployment/publish_instance.ts index bb6db197f49c..69801363ed91 100644 --- a/yarn-project/aztec.js/src/deployment/publish_instance.ts +++ b/yarn-project/aztec.js/src/deployment/publish_instance.ts @@ -17,6 +17,7 @@ export function publishInstance(wallet: Wallet, instance: ContractInstanceWithAd salt, contractClassId, instance.initializationHash, + instance.immutablesHash, publicKeys, isUniversalDeploy, ); diff --git a/yarn-project/aztec.js/src/utils/node.test.ts b/yarn-project/aztec.js/src/utils/node.test.ts index 2bdfc8cc3699..7ae9528aae00 100644 --- a/yarn-project/aztec.js/src/utils/node.test.ts +++ b/yarn-project/aztec.js/src/utils/node.test.ts @@ -42,7 +42,7 @@ describe('waitForTx', () => { const revertedReceipt = new TxReceipt( txHash, TxStatus.CHECKPOINTED, - TxExecutionResult.APP_LOGIC_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, @@ -56,7 +56,7 @@ describe('waitForTx', () => { const revertedReceipt = new TxReceipt( txHash, TxStatus.CHECKPOINTED, - TxExecutionResult.APP_LOGIC_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, diff --git a/yarn-project/aztec.js/src/wallet/wallet.test.ts b/yarn-project/aztec.js/src/wallet/wallet.test.ts index cf96c2231cc2..344747a28a29 100644 --- a/yarn-project/aztec.js/src/wallet/wallet.test.ts +++ b/yarn-project/aztec.js/src/wallet/wallet.test.ts @@ -136,12 +136,13 @@ describe('WalletSchema', () => { }; const mockInstance: ContractInstanceWithAddress = { address: await AztecAddress.random(), - version: 1, + version: 2, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: PublicKeys.default(), }; const result = await context.client.registerContract(mockInstance, mockArtifact, Fr.random()); @@ -150,10 +151,11 @@ describe('WalletSchema', () => { currentContractClassId: expect.any(Fr), deployer: expect.any(AztecAddress), initializationHash: expect.any(Fr), + immutablesHash: expect.any(Fr), originalContractClassId: expect.any(Fr), publicKeys: expect.any(PublicKeys), salt: expect.any(Fr), - version: 1, + version: 2, }); }); @@ -335,12 +337,13 @@ describe('WalletSchema', () => { const mockInstance: ContractInstanceWithAddress = { address: address2, - version: 1, + version: 2, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: PublicKeys.default(), }; @@ -470,11 +473,12 @@ class MockWallet implements Wallet { async registerContract(_instanceData: any, _artifact?: any, _secretKey?: Fr): Promise { return { - version: 1, + version: 2, address: await AztecAddress.random(), currentContractClassId: Fr.random(), deployer: await AztecAddress.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), originalContractClassId: Fr.random(), publicKeys: await PublicKeys.random(), salt: Fr.random(), diff --git a/yarn-project/aztec/src/cli/aztec_start_action.ts b/yarn-project/aztec/src/cli/aztec_start_action.ts index 856ea28b4aaf..d41010e5f360 100644 --- a/yarn-project/aztec/src/cli/aztec_start_action.ts +++ b/yarn-project/aztec/src/cli/aztec_start_action.ts @@ -10,7 +10,7 @@ import type { ChainConfig } from '@aztec/stdlib/config'; import { AztecNodeAdminApiSchema, AztecNodeApiSchema, AztecNodeDebugApiSchema } from '@aztec/stdlib/interfaces/client'; import { getPackageVersion } from '@aztec/stdlib/update-checker'; import { getVersioningMiddleware } from '@aztec/stdlib/versioning'; -import { getOtelJsonRpcPropagationMiddleware } from '@aztec/telemetry-client'; +import { getOtelJsonRpcDiagnosticsMiddleware, getOtelJsonRpcPropagationMiddleware } from '@aztec/telemetry-client'; import { createLocalNetwork } from '../local-network/index.js'; import { github, splash } from '../splash.js'; @@ -95,6 +95,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg // Start the main JSON-RPC server if (Object.entries(services).length > 0) { const rpcServer = createNamespacedSafeJsonRpcServer(services, { + diagnostic: getOtelJsonRpcDiagnosticsMiddleware(), http200OnError: false, log: debugLogger, middlewares: [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions, versioningOpts)], @@ -126,6 +127,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg } const rpcServer = createNamespacedSafeJsonRpcServer(adminServices, { + diagnostic: getOtelJsonRpcDiagnosticsMiddleware(), http200OnError: false, log: debugLogger, middlewares: adminMiddlewares, diff --git a/yarn-project/aztec/src/cli/util.ts b/yarn-project/aztec/src/cli/util.ts index 06d91a711ae2..d0cff613a517 100644 --- a/yarn-project/aztec/src/cli/util.ts +++ b/yarn-project/aztec/src/cli/util.ts @@ -82,18 +82,12 @@ export async function createAccountLogs(accountManagers: AccountManager[], walle accountLogStrings.push(` Address: ${completeAddress.address.toString()}\n`); accountLogStrings.push(` Partial Address: ${completeAddress.partialAddress.toString()}\n`); accountLogStrings.push(` Secret Key: ${account.getSecretKey().toString()}\n`); + accountLogStrings.push(` Master nullifier public key hash: ${completeAddress.publicKeys.npkMHash.toString()}\n`); + accountLogStrings.push(` Master incoming viewing public key: ${completeAddress.publicKeys.ivpkM.toString()}\n\n`); accountLogStrings.push( - ` Master nullifier public key: ${completeAddress.publicKeys.masterNullifierPublicKey.toString()}\n`, - ); - accountLogStrings.push( - ` Master incoming viewing public key: ${completeAddress.publicKeys.masterIncomingViewingPublicKey.toString()}\n\n`, - ); - accountLogStrings.push( - ` Master outgoing viewing public key: ${completeAddress.publicKeys.masterOutgoingViewingPublicKey.toString()}\n\n`, - ); - accountLogStrings.push( - ` Master tagging public key: ${completeAddress.publicKeys.masterTaggingPublicKey.toString()}\n\n`, + ` Master outgoing viewing public key hash: ${completeAddress.publicKeys.ovpkMHash.toString()}\n\n`, ); + accountLogStrings.push(` Master tagging public key hash: ${completeAddress.publicKeys.tpkMHash.toString()}\n\n`); } } return accountLogStrings; diff --git a/yarn-project/aztec/src/local-network/local-network.ts b/yarn-project/aztec/src/local-network/local-network.ts index 6293df2653c5..a771e611b09c 100644 --- a/yarn-project/aztec/src/local-network/local-network.ts +++ b/yarn-project/aztec/src/local-network/local-network.ts @@ -206,6 +206,21 @@ export async function createLocalNetwork(config: Partial = { SequencerState.SYNCHRONIZING, ]); watcher?.setIsSequencerBuilding(() => !idleStates.has(sequencer.getState())); + // Under proposer pipelining the L1 publish for slot N happens during wall-clock slot N, + // but the proposer for slot N has already built the checkpoint during slot N-1 and is + // waiting for L1 to advance. We need to fast-forward L1 to wake that wait — and the wait + // we have to break first is `waitForValidParentCheckpointOnL1`, which blocks the + // checkpoint_proposal_job's background submission task until the archiver has synced past + // the build slot. That wait happens *before* `PUBLISHING_CHECKPOINT` is set, so a hook on + // that state transition would be circular (L1 has to advance before the state we'd use to + // advance L1 fires). The earliest pre-wait signal is `block-proposed`, which the sequencer + // emits once each block is built. In sandbox single-block-per-slot mode this is + // effectively "checkpoint built", and the watcher warp is harmless if a subsequent + // assembly/validation/parent-wait step aborts: L1 just sits one slot ahead, which the + // cascade absorbs. + if (watcher) { + sequencer.on('block-proposed', ({ slot }) => watcher!.setProposedTargetSlot(Number(slot))); + } } let epochTestSettler: EpochTestSettler | undefined; diff --git a/yarn-project/aztec/src/testing/anvil_test_watcher.ts b/yarn-project/aztec/src/testing/anvil_test_watcher.ts index e2f9c8ed2cbb..81505d5296fa 100644 --- a/yarn-project/aztec/src/testing/anvil_test_watcher.ts +++ b/yarn-project/aztec/src/testing/anvil_test_watcher.ts @@ -44,6 +44,12 @@ export class AnvilTestWatcher { // Tracks when we first observed the current unfilled slot with pending txs (real wall time). private unfilledSlotFirstSeen?: { slot: number; realTime: number }; + // Latest target slot for which the proposer has built a block destined for L1 but which has + // not yet been committed. Set by the proposer-pipelining hook from `block-proposed` events so + // the watcher can advance L1 (and the injected date provider) to the target slot ahead of the + // publisher's `sendRequestsAt` sleep, instead of waiting a full wall-clock slot. + private proposedTargetSlot?: number; + constructor( private cheatcodes: EthCheatCodes, rollupAddress: EthAddress, @@ -86,6 +92,18 @@ export class AnvilTestWatcher { this.isSequencerBuilding = fn; } + /** + * Records the target slot for which the proposer has built a block destined for L1. Used by + * the local-network watcher to fast-forward L1 (and the injected date provider) ahead of the + * pipelined publisher's `sendRequestsAt` sleep so it ends promptly instead of waiting a full + * wall-clock slot. Only ratchets up — late warps for stale slots are no-ops. + */ + setProposedTargetSlot(slot: number) { + if (this.proposedTargetSlot === undefined || slot > this.proposedTargetSlot) { + this.proposedTargetSlot = slot; + } + } + async start() { if (this.filledRunningPromise) { throw new Error('Watcher already watching for filled slot'); @@ -177,6 +195,20 @@ export class AnvilTestWatcher { return; } + // Pipelined-publish shortcut: if the proposer has built a block destined for a slot + // beyond the current L1 slot, fast-forward L1 to that slot's timestamp so the publisher's + // `sendRequestsAt(targetSlot)` sleep ends and the multicall mines inside the target slot. + // Without this, the publisher waits up to a full real-time slot for wall clock to catch up. + if (this.proposedTargetSlot !== undefined && this.proposedTargetSlot > currentSlot) { + const targetSlotTimestamp = Number( + await this.rollup.read.getTimestampForSlot([BigInt(this.proposedTargetSlot)]), + ); + if (await this.warpToTimestamp(targetSlotTimestamp)) { + this.logger.info(`Warped L1 to target slot ${this.proposedTargetSlot} for pipelined publish`); + } + return; + } + // If there are pending txs and the sequencer missed them, warp quickly (after a 2s real-time debounce) so the // sequencer can retry in the next slot. Without this, we'd have to wait a full real-time slot duration (~36s) for // the dateProvider to catch up to the next slot timestamp. We skip the warp if the sequencer is actively building diff --git a/yarn-project/aztec/src/testing/cheat_codes.ts b/yarn-project/aztec/src/testing/cheat_codes.ts index 7890b7f561f8..a78137eb3a1a 100644 --- a/yarn-project/aztec/src/testing/cheat_codes.ts +++ b/yarn-project/aztec/src/testing/cheat_codes.ts @@ -2,6 +2,7 @@ import { EthCheatCodes, RollupCheatCodes } from '@aztec/ethereum/test'; import { SlotNumber } from '@aztec/foundation/branded-types'; import { createLogger } from '@aztec/foundation/log'; import type { DateProvider } from '@aztec/foundation/timer'; +import type { AutomineSequencer } from '@aztec/sequencer-client'; import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; /** @@ -18,15 +19,22 @@ export class CheatCodes { public eth: EthCheatCodes, /** Cheat codes for the Aztec Rollup contract on L1. */ public rollup: RollupCheatCodes, + /** When wired, redirects time-warps through the AutomineSequencer queue (test-only). */ + private automine?: AutomineSequencer, ) {} - static async create(rpcUrls: string[], node: AztecNode, dateProvider: DateProvider): Promise { + static async create( + rpcUrls: string[], + node: AztecNode, + dateProvider: DateProvider, + automine?: AutomineSequencer, + ): Promise { const ethCheatCodes = new EthCheatCodes(rpcUrls, dateProvider); const rollupCheatCodes = new RollupCheatCodes( ethCheatCodes, await node.getNodeInfo().then(n => n.l1ContractAddresses), ); - return new CheatCodes(ethCheatCodes, rollupCheatCodes); + return new CheatCodes(ethCheatCodes, rollupCheatCodes, automine); } /** @@ -46,6 +54,15 @@ export class CheatCodes { ); } + // AutomineSequencer owns time control through its serial queue — delegate to keep warps atomic + // with respect to any in-flight build, and avoid the mineBlock-loop hack below. + // `warpTo` internally builds an empty L2 checkpoint, which auto-mines exactly one L1 block at + // the target slot boundary, so no separate `node.mineBlock()` is needed here. + if (this.automine) { + await this.automine.warpTo(Number(targetBigInt)); + return; + } + const currentSlot = await this.rollup.getSlot(); const targetSlot = await this.rollup.getSlotAt(targetBigInt); diff --git a/yarn-project/bootstrap.sh b/yarn-project/bootstrap.sh index 140dd2c6ca78..46c0c712bdac 100755 --- a/yarn-project/bootstrap.sh +++ b/yarn-project/bootstrap.sh @@ -203,9 +203,9 @@ function test_cmds { # Add debug logging for tests that require a bit more info if [[ "$test" == p2p/src/client/p2p_client.test.ts || "$test" == p2p/src/services/discv5/discv5_service.test.ts || "$test" == p2p/src/client/p2p_client.integration.test.ts ]]; then - cmd_env+=" LOG_LEVEL=debug" + cmd_env+=" LOG_LEVEL=\"debug; info: json-rpc, simulator\"" elif [[ "$test" =~ rollup_ivc_integration || "$test" =~ avm_integration ]]; then - cmd_env+=" LOG_LEVEL=debug BB_VERBOSE=1 " + cmd_env+=" LOG_LEVEL=\"debug; info: json-rpc, simulator\" BB_VERBOSE=1 " elif [[ "$test" =~ e2e_p2p ]]; then cmd_env+=" LOG_LEVEL='verbose; debug:p2p'" fi @@ -247,7 +247,7 @@ function bench_cmds { echo "$hash BENCH_OUTPUT=bench-out/kv_store.bench.json yarn-project/scripts/run_test.sh kv-store/src/bench/map_bench.test.ts" echo "$hash BENCH_OUTPUT=bench-out/tx_pool_v2.bench.json yarn-project/scripts/run_test.sh p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_bench.test.ts" echo "$hash BENCH_OUTPUT=bench-out/tx_validator.bench.json yarn-project/scripts/run_test.sh p2p/src/msg_validators/tx_validator/tx_validator_bench.test.ts" - echo "$hash:ISOLATE=1:CPUS=16:MEM=32g:TIMEOUT=1800 BENCH_OUTPUT=bench-out/p2p_client_proposal_tx_collector.bench.json yarn-project/scripts/run_test.sh p2p/src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts" + echo "$hash:ISOLATE=1:CPUS=16:MEM=32g:TIMEOUT=1800 BENCH_OUTPUT=bench-out/p2p_client_batch_tx_requester.bench.json yarn-project/scripts/run_test.sh p2p/src/client/test/p2p_client.batch_tx_requester.bench.test.ts" echo "$hash BENCH_OUTPUT=bench-out/tx.bench.json yarn-project/scripts/run_test.sh stdlib/src/tx/tx_bench.test.ts" echo "$hash:ISOLATE=1:CPUS=10:MEM=16g:LOG_LEVEL=silent BENCH_OUTPUT=bench-out/proving_broker.bench.json yarn-project/scripts/run_test.sh prover-client/src/test/proving_broker_testbench.test.ts" echo "$hash:ISOLATE=1:CPUS=16:MEM=16g BENCH_OUTPUT=bench-out/avm_bulk_test.bench.json yarn-project/scripts/run_test.sh bb-prover/src/avm_proving_tests/avm_bulk.test.ts" diff --git a/yarn-project/cli-wallet/package.json b/yarn-project/cli-wallet/package.json index f8046b3d1711..11f8ab5d5b45 100644 --- a/yarn-project/cli-wallet/package.json +++ b/yarn-project/cli-wallet/package.json @@ -19,7 +19,7 @@ "scripts": { "start": "node --no-warnings ./dest/bin", "start:debug": "node --inspect=0.0.0.0:9221 --no-warnings ./dest/bin", - "dev": "LOG_LEVEL=debug && node ./dest/bin", + "dev": "LOG_LEVEL=\"debug; info: json-rpc, simulator\" node ./dest/bin", "build": "yarn clean && ../scripts/tsc.sh", "build:dev": "../scripts/tsc.sh --watch", "clean": "rm -rf ./dest .tsbuildinfo", diff --git a/yarn-project/constants/src/constants.gen.ts b/yarn-project/constants/src/constants.gen.ts index 65028bb96a5e..ae24ee193e19 100644 --- a/yarn-project/constants/src/constants.gen.ts +++ b/yarn-project/constants/src/constants.gen.ts @@ -136,12 +136,15 @@ export const DEFAULT_OVPK_M_X = 122127877196173055705879288602884754543280089552 export const DEFAULT_OVPK_M_Y = 3646747884782549389807830220601404629716007431341772952958971658285958854707n; export const DEFAULT_TPK_M_X = 728059161893070741164607238299536939695876538801885465230641192969135857403n; export const DEFAULT_TPK_M_Y = 14575718736702206050102425029229426215631664471161015518982549597389390371695n; +export const DEFAULT_NPK_M_HASH = 9490941203163884203266873379528043162885952552009707050511473783876867365414n; +export const DEFAULT_OVPK_M_HASH = 6503635668323258394266152634006889881423098283582185344306514598322956522059n; +export const DEFAULT_TPK_M_HASH = 3696996950890211715833095099359687729113787313245035143274671977290400579312n; export const AZTEC_ADDRESS_LENGTH = 1; export const GAS_FEES_LENGTH = 2; export const GAS_LENGTH = 2; export const GAS_SETTINGS_LENGTH = 8; export const CALL_CONTEXT_LENGTH = 4; -export const CONTRACT_INSTANCE_LENGTH = 16; +export const CONTRACT_INSTANCE_LENGTH = 10; export const CONTRACT_STORAGE_READ_LENGTH = 3; export const CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH = 3; export const ETH_ADDRESS_LENGTH = 1; @@ -163,9 +166,9 @@ export const L2_TO_L1_MESSAGE_LENGTH = 2; export const COUNTED_L2_TO_L1_MESSAGE_LENGTH = 3; export const SCOPED_L2_TO_L1_MESSAGE_LENGTH = 3; export const SCOPED_COUNTED_L2_TO_L1_MESSAGE_LENGTH = 4; -export const KEY_VALIDATION_REQUEST_LENGTH = 4; -export const KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH = 5; -export const SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH = 6; +export const KEY_VALIDATION_REQUEST_LENGTH = 2; +export const KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH = 3; +export const SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH = 4; export const PARTIAL_STATE_REFERENCE_LENGTH = 6; export const TREE_LEAF_READ_REQUEST_LENGTH = 2; export const PRIVATE_LOG_SIZE_IN_FIELDS = 16; @@ -204,19 +207,19 @@ export const BLOCK_HEADER_LENGTH = 22; export const CHECKPOINT_HEADER_LENGTH = 12; export const CHECKPOINT_HEADER_SIZE_IN_BYTES = 316; export const SCOPED_READ_REQUEST_LEN = 3; -export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 870; +export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 838; export const PRIVATE_CONTEXT_INPUTS_LENGTH = 37; export const FEE_RECIPIENT_LENGTH = 2; export const HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE = 28; export const PAIRING_POINTS_SIZE = 8; export const IPA_CLAIM_SIZE = 6; export const PUBLIC_DATA_READ_LENGTH = 3; -export const PRIVATE_VALIDATION_REQUESTS_LENGTH = 771; +export const PRIVATE_VALIDATION_REQUESTS_LENGTH = 643; export const PRIVATE_TO_ROLLUP_ACCUMULATED_DATA_LENGTH = 1243; export const TX_CONSTANT_DATA_LENGTH = 34; export const COMBINED_CONSTANT_DATA_LENGTH = 43; export const PRIVATE_ACCUMULATED_DATA_LENGTH = 2059; -export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2873; +export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2745; export const PRIVATE_TO_PUBLIC_ACCUMULATED_DATA_LENGTH = 1371; export const PRIVATE_TO_AVM_ACCUMULATED_DATA_LENGTH = 152; export const NUM_PRIVATE_TO_AVM_ACCUMULATED_DATA_ARRAYS = 3; @@ -460,7 +463,7 @@ export const AVM_DEBUGLOG_BASE_L2_GAS = 9; export const AVM_POSEIDON2_BASE_L2_GAS = 360; export const AVM_SHA256COMPRESSION_BASE_L2_GAS = 12288; export const AVM_KECCAKF1600_BASE_L2_GAS = 58176; -export const AVM_ECADD_BASE_L2_GAS = 270; +export const AVM_ECADD_BASE_L2_GAS = 180; export const AVM_TORADIXBE_BASE_L2_GAS = 24; export const AVM_CALLDATACOPY_DYN_L2_GAS = 3; export const AVM_RETURNDATACOPY_DYN_L2_GAS = 3; @@ -536,8 +539,9 @@ export enum DomainSeparator { OVSK_M = 4272201051, TSK_M = 1546190975, PUBLIC_KEYS_HASH = 777457226, + SINGLE_PUBLIC_KEY_HASH = 3452068255, PARTIAL_ADDRESS = 2103633018, - CONTRACT_ADDRESS_V1 = 1788365517, + CONTRACT_ADDRESS_V2 = 4099338721, BLOCK_HEADER_HASH = 4195546849, TX_REQUEST = 3763737512, PUBLIC_TX_HASH = 1630108851, diff --git a/yarn-project/constants/src/scripts/constants.in.ts b/yarn-project/constants/src/scripts/constants.in.ts index 88d1c5fd6534..a864d6a2d2e3 100644 --- a/yarn-project/constants/src/scripts/constants.in.ts +++ b/yarn-project/constants/src/scripts/constants.in.ts @@ -122,9 +122,10 @@ const CPP_GENERATORS: string[] = [ 'BLOCK_HEADER_HASH', 'SALTED_INITIALIZATION_HASH', 'PARTIAL_ADDRESS', - 'CONTRACT_ADDRESS_V1', + 'CONTRACT_ADDRESS_V2', 'CONTRACT_CLASS_ID', 'PUBLIC_KEYS_HASH', + 'SINGLE_PUBLIC_KEY_HASH', 'NOTE_HASH_NONCE', 'UNIQUE_NOTE_HASH', 'SILOED_NOTE_HASH', @@ -316,9 +317,10 @@ const PIL_CONSTANTS = [ const PIL_GENERATORS: string[] = [ 'SALTED_INITIALIZATION_HASH', 'PARTIAL_ADDRESS', - 'CONTRACT_ADDRESS_V1', + 'CONTRACT_ADDRESS_V2', 'CONTRACT_CLASS_ID', 'PUBLIC_KEYS_HASH', + 'SINGLE_PUBLIC_KEY_HASH', 'NOTE_HASH_NONCE', 'UNIQUE_NOTE_HASH', 'SILOED_NOTE_HASH', diff --git a/yarn-project/end-to-end/bootstrap.sh b/yarn-project/end-to-end/bootstrap.sh index e0ec4356830e..a40cd127f22f 100755 --- a/yarn-project/end-to-end/bootstrap.sh +++ b/yarn-project/end-to-end/bootstrap.sh @@ -25,20 +25,23 @@ function set_dump_avm { function test_cmds { local run_test_script="yarn-project/end-to-end/scripts/run_test.sh" - local prefix="$hash:ISOLATE=1" + local prefix="$hash:ISOLATE=1:TIMEOUT=20m" if [ "$CI_FULL" -eq 1 ]; then echo "$prefix:TIMEOUT=20m:CPUS=16:MEM=96g:NAME=e2e_prover_full_real $run_test_script simple e2e_prover/full" else echo "$prefix:NAME=e2e_prover_full_fake FAKE_PROOFS=1 $run_test_script simple e2e_prover/full" fi - echo "$prefix:TIMEOUT=15m:NAME=e2e_block_building $(set_dump_avm e2e_block_building) $run_test_script simple e2e_block_building" + echo "$prefix:TIMEOUT=25m:NAME=e2e_block_building $(set_dump_avm e2e_block_building) $run_test_script simple e2e_block_building" + echo "$prefix:TIMEOUT=30m:NAME=e2e_avm_simulator $(set_dump_avm e2e_avm_simulator) $run_test_script simple src/e2e_avm_simulator.test.ts" + + local tests=( # List all standalone and nested tests, except for the ones listed above. src/e2e_!(prover)/*.test.ts src/e2e_p2p/reqresp/*.test.ts - src/e2e_!(block_building).test.ts + src/e2e_!(block_building|avm_simulator).test.ts ) for test in "${tests[@]}"; do local name=${test#*e2e_} @@ -50,6 +53,9 @@ function test_cmds { e2e_p2p/add_rollup) test_prefix="$prefix:TIMEOUT=20m" ;; + e2e_cross_chain_messaging/l1_to_l2) + test_prefix="$prefix:TIMEOUT=20m" + ;; esac # Check if this is a .parallel.test.ts file @@ -74,7 +80,7 @@ function test_cmds { ) for test in "${tests[@]}"; do # We must set ONLY_TERM_PARENT=1 to allow the script to fully control cleanup process. - echo "$hash:ONLY_TERM_PARENT=1 $run_test_script compose $test" + echo "$hash:ONLY_TERM_PARENT=1:TIMEOUT=20m $run_test_script compose $test" done tests=( @@ -82,7 +88,7 @@ function test_cmds { ) for test in "${tests[@]}"; do # We must set ONLY_TERM_PARENT=1 to allow the script to fully control cleanup process. - echo "$hash:ONLY_TERM_PARENT=1 $run_test_script web3signer $test" + echo "$hash:ONLY_TERM_PARENT=1:TIMEOUT=20m $run_test_script web3signer $test" done tests=( @@ -90,7 +96,7 @@ function test_cmds { ) for test in "${tests[@]}"; do # We must set ONLY_TERM_PARENT=1 to allow the script to fully control cleanup process. - echo "$hash:ONLY_TERM_PARENT=1 $run_test_script ha $test" + echo "$hash:ONLY_TERM_PARENT=1:TIMEOUT=30m $run_test_script ha $test" done #echo "$hash:ONLY_TERM_PARENT=1 $run_test_script simple src/e2e_multi_validator/e2e_multi_validator_node.test.ts" diff --git a/yarn-project/end-to-end/scripts/docker-compose.yml b/yarn-project/end-to-end/scripts/docker-compose.yml index 528efb33a286..e394e2610220 100644 --- a/yarn-project/end-to-end/scripts/docker-compose.yml +++ b/yarn-project/end-to-end/scripts/docker-compose.yml @@ -28,6 +28,7 @@ services: WS_BLOCK_CHECK_INTERVAL_MS: 500 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 P2P_MIN_TX_POOL_AGE_MS: 0 + SEQ_ENABLE_PROPOSER_PIPELINING: 'true' HARDWARE_CONCURRENCY: ${HARDWARE_CONCURRENCY:-} end-to-end: diff --git a/yarn-project/end-to-end/scripts/test_simple.sh b/yarn-project/end-to-end/scripts/test_simple.sh index ea2089cef1c6..4d878e805922 100755 --- a/yarn-project/end-to-end/scripts/test_simple.sh +++ b/yarn-project/end-to-end/scripts/test_simple.sh @@ -33,7 +33,7 @@ else [ -n "${test_name:-}" ] && test_name_arg=(--testNamePattern="$test_name") node --experimental-vm-modules ../node_modules/.bin/jest \ - --testTimeout=300000 \ + --testTimeout=600000 \ --no-cache \ "${cache_dir_arg[@]}" \ "${test_name_arg[@]}" \ diff --git a/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts b/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts index 56cdad9aba68..1d58f3a3e40e 100644 --- a/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts +++ b/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts @@ -24,7 +24,7 @@ import type { TestWallet } from '../test-wallet/test_wallet.js'; import { proveInteraction } from '../test-wallet/utils.js'; // Set a 3 minute timeout. -const TIMEOUT = 180_000; +const TIMEOUT = 300_000; describe('transaction benchmarks', () => { const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS); diff --git a/yarn-project/end-to-end/src/composed/e2e_cheat_codes.test.ts b/yarn-project/end-to-end/src/composed/e2e_cheat_codes.test.ts index 956a5f8c9b81..6febfdf40ca8 100644 --- a/yarn-project/end-to-end/src/composed/e2e_cheat_codes.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_cheat_codes.test.ts @@ -71,14 +71,30 @@ describe('e2e_cheat_codes', () => { it('warpL2TimeAtLeastTo with target in current slot auto-adjusts to next slot', async () => { // Target is 1 second ahead of L1 time — still in the current slot, so auto-adjust should kick in. - const currentL1Timestamp = Number(await cheatCodes.eth.lastBlockTimestamp()); - const targetTimestamp = currentL1Timestamp + 1; - await cheatCodes.warpL2TimeAtLeastTo(nodeDebug, targetTimestamp); - - const blockNumber = await aztecNode.getBlockNumber(); - const block = await aztecNode.getBlock(blockNumber); - expect(block).toBeDefined(); - expect(Number(block!.header.globalVariables.timestamp)).toBeGreaterThanOrEqual(targetTimestamp); + // The sequencer running in this composed test advances L1 by a full slot when it proposes a block, + // and that warp can land between our `lastBlockTimestamp()` read and the cheat code's internal + // re-read, racing `currentL1 + 1` into the past. Retry on that specific race with a fresh target; + // a subsequent slot-jump within the retry window is improbable enough that a small cap suffices. + const maxAttempts = 5; + let lastError: unknown; + for (let attempt = 1; attempt <= maxAttempts; attempt++) { + const currentL1Timestamp = Number(await cheatCodes.eth.lastBlockTimestamp()); + const targetTimestamp = currentL1Timestamp + 1; + try { + await cheatCodes.warpL2TimeAtLeastTo(nodeDebug, targetTimestamp); + const blockNumber = await aztecNode.getBlockNumber(); + const block = await aztecNode.getBlock(blockNumber); + expect(block).toBeDefined(); + expect(Number(block!.header.globalVariables.timestamp)).toBeGreaterThanOrEqual(targetTimestamp); + return; + } catch (err) { + lastError = err; + if (!(err instanceof Error) || !err.message.includes('is not in the future')) { + throw err; + } + } + } + throw lastError; }); it('warpL2TimeAtLeastTo with past timestamp throws', async () => { diff --git a/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts b/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts index 2f01949e3c21..be5c43d80cb4 100644 --- a/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts @@ -114,7 +114,7 @@ describe('e2e_local_network_example', () => { expect(aliceBalance).toBe(initialSupply - transferQuantity); expect(bobBalance).toBe(transferQuantity + mintQuantity); - }); + }, 900_000); it('can create accounts on the local network', async () => { const logger = createLogger('e2e:token'); @@ -222,5 +222,5 @@ describe('e2e_local_network_example', () => { expect(bobNewBalance).toEqual(bobBalance - amountTransferToAlice); expect(await getFeeJuiceBalance(sponsoredFPC, node)).toEqual(initialFPCFeeJuice - receiptForBob.transactionFee!); - }); + }, 900_000); }); diff --git a/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts b/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts index 31b9667d0190..0853af29b175 100644 --- a/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts @@ -16,10 +16,11 @@ import { tmpdir } from 'os'; import { join } from 'path'; import { BlacklistTokenContractTest, Role } from '../e2e_blacklist_token_contract/blacklist_token_contract_test.js'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { type EndToEndContext, setup } from '../fixtures/utils.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; -jest.setTimeout(60_000); +jest.setTimeout(15 * 60 * 1000); describe('Aztec persistence', () => { /** @@ -60,7 +61,11 @@ describe('Aztec persistence', () => { beforeAll(async () => { dataDirectory = await mkdtemp(join(tmpdir(), 'aztec-node-')); - const initialContext = await setup(1, { dataDirectory, numberOfInitialFundedAccounts: 3 }, { dataDirectory }); + const initialContext = await setup( + 1, + { ...PIPELINING_SETUP_OPTS, dataDirectory, numberOfInitialFundedAccounts: 3 }, + { dataDirectory }, + ); aztecNode = initialContext.aztecNode; deployL1ContractsValues = initialContext.deployL1ContractsValues; initialFundedAccounts = initialContext.initialFundedAccounts; @@ -101,7 +106,7 @@ describe('Aztec persistence', () => { await progressBlocksPastDelay(contract); await initialContext.teardown(); - }, 180_000); + }, 600_000); const progressBlocksPastDelay = async (contract: TokenBlacklistContract) => { for (let i = 0; i < BlacklistTokenContractTest.CHANGE_ROLES_DELAY; ++i) { @@ -113,14 +118,19 @@ describe('Aztec persistence', () => { [ // ie we were shutdown and now starting back up. Initial sync should be ~instant 'when starting Node and PXE with existing databases', - () => setup(0, { dataDirectory, deployL1ContractsValues, initialFundedAccounts }, { dataDirectory }), - 1000, + () => + setup( + 0, + { ...PIPELINING_SETUP_OPTS, dataDirectory, deployL1ContractsValues, initialFundedAccounts }, + { dataDirectory }, + ), + 60_000, ], [ // ie our PXE was restarted, data kept intact and now connects to a "new" Node. Initial synch will synch from scratch 'when starting a PXE with an existing database, connected to a Node with database synched from scratch', - () => setup(0, { deployL1ContractsValues, initialFundedAccounts }, { dataDirectory }), - 10_000, + () => setup(0, { ...PIPELINING_SETUP_OPTS, deployL1ContractsValues, initialFundedAccounts }, { dataDirectory }), + 120_000, ], ])('%s', (_, contextSetup, timeout) => { let contract: TokenBlacklistContract; @@ -207,14 +217,14 @@ describe('Aztec persistence', () => { [ // ie. I'm setting up a new full node, sync from scratch and restore wallets/notes 'when starting the Node and PXE with empty databases', - () => setup(0, { deployL1ContractsValues, initialFundedAccounts }, {}), - 10_000, + () => setup(0, { ...PIPELINING_SETUP_OPTS, deployL1ContractsValues, initialFundedAccounts }, {}), + 120_000, ], [ // ie. I'm setting up a new PXE, restore wallets/notes from a Node 'when starting a PXE with an empty database connected to a Node with an existing database', - () => setup(0, { dataDirectory, deployL1ContractsValues, initialFundedAccounts }, {}), - 10_000, + () => setup(0, { ...PIPELINING_SETUP_OPTS, dataDirectory, deployL1ContractsValues, initialFundedAccounts }, {}), + 120_000, ], ])('%s', (_, contextSetup, timeout) => { beforeEach(async () => { @@ -285,7 +295,7 @@ describe('Aztec persistence', () => { // Then shutdown the temporary components and restart the original components // They should sync up from where they left off and be able to see the actions performed by the temporary node & PXE. beforeAll(async () => { - const temporaryContext = await setup(0, { deployL1ContractsValues }, {}); + const temporaryContext = await setup(0, { ...PIPELINING_SETUP_OPTS, deployL1ContractsValues }, {}); await temporaryContext.wallet.registerContract(contractInstance, TokenBlacklistContract.artifact); @@ -313,11 +323,11 @@ describe('Aztec persistence', () => { let contract: TokenBlacklistContract; beforeEach(async () => { - context = await setup(0, { dataDirectory, deployL1ContractsValues }, { dataDirectory }); + context = await setup(0, { ...PIPELINING_SETUP_OPTS, dataDirectory, deployL1ContractsValues }, { dataDirectory }); const account = initialFundedAccounts[0]; await context.wallet.createSchnorrAccount(account.secret, account.salt); contract = TokenBlacklistContract.at(contractAddress, context.wallet); - }); + }, 120_000); afterEach(async () => { await context.teardown(); diff --git a/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts b/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts index 532d25ee5832..b20a3d70274e 100644 --- a/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts @@ -211,5 +211,5 @@ describe('e2e_cross_chain_messaging token_bridge_tutorial_test', () => { const newL1Balance = await l1TokenManager.getL1TokenBalance(ownerEthAddress); logger.info(`New L1 balance of ${ownerEthAddress} is ${newL1Balance}`); expect(newL1Balance).toBe(withdrawAmount); - }, 300_000); + }, 900_000); }); diff --git a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts index 9a228508423b..443adbe3a2e0 100644 --- a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts +++ b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts @@ -27,6 +27,8 @@ import { GovernanceProposerAbi } from '@aztec/l1-artifacts/GovernanceProposerAbi import { StatefulTestContractArtifact } from '@aztec/noir-test-contracts.js/StatefulTest'; import { type AttestationInfo, getAttestationInfoFromPublishedCheckpoint } from '@aztec/stdlib/block'; import { Checkpoint } from '@aztec/stdlib/checkpoint'; +import { OffenseType } from '@aztec/stdlib/slashing'; +import { TxStatus } from '@aztec/stdlib/tx'; import type { GenesisData } from '@aztec/stdlib/world-state'; import type { ValidatorClient } from '@aztec/validator-client'; import { PostgresSlashingProtectionDatabase } from '@aztec/validator-ha-signer/db'; @@ -38,6 +40,7 @@ import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { Pool } from 'pg'; +import { PIPELINING_SETUP_OPTS } from '../../fixtures/fixtures.js'; import { type HADatabaseConfig, cleanupHADatabase, @@ -152,26 +155,30 @@ describe('HA Full Setup', () => { dateProvider, deployL1ContractsValues, genesis, - } = await setup(1, { - initialValidators, - sequencerPublisherPrivateKeys: [new SecretValue(publisherPrivateKeys[0])], - aztecTargetCommitteeSize: COMMITTEE_SIZE, - minTxsPerBlock: 1, - archiverPollingIntervalMS: 200, - sequencerPollingIntervalMS: 200, - worldStateBlockCheckIntervalMS: 200, - blockCheckIntervalMS: 200, - startProverNode: true, - // Disable validation on this node - disableValidator: true, - skipAccountDeployment: true, - // Enable P2P for transaction gossip - p2pEnabled: true, - // Enable slashing for testing governance + slashing vote coordination - slasherEnabled: true, - slashingRoundSizeInEpochs: 1, // 32 slots (1 epoch) - slashingQuorum: 17, // >50% of 32 slots for tally quorum, - })); + } = await setup( + 1, + { + ...PIPELINING_SETUP_OPTS, + initialValidators, + sequencerPublisherPrivateKeys: [new SecretValue(publisherPrivateKeys[0])], + aztecTargetCommitteeSize: COMMITTEE_SIZE, + archiverPollingIntervalMS: 200, + sequencerPollingIntervalMS: 200, + worldStateBlockCheckIntervalMS: 200, + blockCheckIntervalMS: 200, + startProverNode: true, + // Disable validation on this node + disableValidator: true, + skipAccountDeployment: true, + // Enable P2P for transaction gossip + p2pEnabled: true, + // Enable slashing for testing governance + slashing vote coordination + slasherEnabled: true, + slashingRoundSizeInEpochs: 1, // 32 slots (1 epoch) + slashingQuorum: 17, // >50% of 32 slots for tally quorum, + }, + { syncChainTip: 'proven' }, + )); if (!dateProvider) { throw new Error('dateProvider must be provided by setup for HA tests'); @@ -266,22 +273,30 @@ describe('HA Full Setup', () => { accountData.signingKey, ); const deployMethod = await accountManager.getDeployMethod(); - await deployMethod.send({ from: NO_FROM }); + await deployMethod.send({ from: NO_FROM, wait: { waitForStatus: TxStatus.CHECKPOINTED } }); ownerAddress = accountManager.address; logger.info(`Test account deployed at ${ownerAddress}`); }); afterAll(async () => { - // Cleanup all HA peer nodes + // Stop all HA peer nodes in parallel with a per-node deadline. A single stuck node can otherwise + // block the serial loop long enough to blow the jest hook timeout — e.g. a sequencer.stop() that + // awaits an L1 publish whose tx-timeout was computed on a test-warped clock and never fires. if (haNodeServices) { - for (let i = 0; i < haNodeServices.length; i++) { - try { + const STOP_DEADLINE_MS = 30_000; + await Promise.allSettled( + haNodeServices.map((service, i) => { logger.info(`Stopping HA peer node ${i}`); - await haNodeServices[i].stop(); - } catch (error) { - logger.error(`Failed to stop HA peer node ${i}: ${error}`); - } - } + return Promise.race([ + service.stop().catch(error => { + logger.error(`Failed to stop HA peer node ${i}: ${error}`); + }), + sleep(STOP_DEADLINE_MS).then(() => { + logger.error(`HA peer node ${i} stop did not return within ${STOP_DEADLINE_MS}ms; abandoning`); + }), + ]); + }), + ); } // Cleanup HA keystore temp directories @@ -333,6 +348,7 @@ describe('HA Full Setup', () => { logger.info(`Deploying contract from ${ownerAddress}`); const { receipt } = await deployer.deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }).send({ from: ownerAddress, + wait: { waitForStatus: TxStatus.CHECKPOINTED }, }); await waitForProven(aztecNode, receipt, { @@ -455,6 +471,7 @@ describe('HA Full Setup', () => { const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); const { receipt } = await deployer.deploy([ownerAddress, 42], { salt: Fr.random() }).send({ from: ownerAddress, + wait: { waitForStatus: TxStatus.CHECKPOINTED }, }); expect(receipt.blockNumber).toBeDefined(); logger.info(`Transaction mined in block ${receipt.blockNumber}`); @@ -476,15 +493,28 @@ describe('HA Full Setup', () => { const round = await governanceProposer.computeRound(blockSlot); logger.info(`Block slot ${blockSlot}, governance round ${round}`); - // Poll until L1 vote count converges with the DB duties. - // The DB records a duty as "signed" when the crypto signature is produced, but before the L1 tx mines. - // We need to wait for all in-flight L1 txs to land before comparing. - logger.info('Polling L1 for governance votes and waiting for DB convergence...'); + // Wait for at least one on-chain governance signal for our payload to land, then assert on + // the round *outcome* (payload-with-most-signals) rather than on a strict per-node duty + // count equality. + // + // Why not assert `l1VoteCount === uniqueSlots.size` like the previous version did? HA + // signing intentionally suppresses duplicate signatures across nodes for the same + // `(slot, validator)` duty: only one of the N HA peers actually emits the L1 tx for each + // scheduled slot. Under pipelining there is an additional build-slot-vs-target-slot offset + // where a vote signed in build slot N targets slot N+1, so at any measurement time the DB + // can have a duty row for slot S whose L1 tx hasn't mined yet. The old strict equality + // pinned the test to behavior that doesn't hold under either of those. + // + // What we actually care about: the HA cluster coordinated well enough that at least one + // successful governance signal landed for our payload, the round-winner converges on the + // payload we configured, no duty was double-signed for the same `(slot, validator)`, and + // every recorded duty ended in SIGNED state. + logger.info('Polling L1 for governance signals to confirm HA cluster coordination...'); const rollupAddr = deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString() as `0x${string}`; const govProposerAddr = deployL1ContractsValues.l1ContractAddresses.governanceProposerAddress.toString() as `0x${string}`; - const { l1VoteCount, governanceVoteDuties } = await retryUntil( + const { l1VoteCount, lastSignalSlot, payloadWithMostSignals } = await retryUntil( async () => { const snapshotBlock = await deployL1ContractsValues.l1Client.getBlockNumber(); const [roundData, l1VoteCountBig] = await Promise.all([ @@ -505,56 +535,68 @@ describe('HA Full Setup', () => { ]); const lastSignalSlot = Number(roundData.lastSignalSlot); const l1VoteCount = Number(l1VoteCountBig); - if (l1VoteCount === 0) { - return undefined; - } - - const dbResult = await mainPool.query( - `SELECT * FROM validator_duties WHERE slot::numeric <= $1 AND duty_type = 'GOVERNANCE_VOTE' ORDER BY slot, started_at`, - [lastSignalSlot.toString()], - ); - const governanceVoteDuties = dbResult.rows; - const uniqueSlots = new Set(governanceVoteDuties.map(row => row.slot)); - logger.info( `L1 round ${round}: lastSignalSlot=${lastSignalSlot}, l1VoteCount=${l1VoteCount}, ` + - `DB duties=${governanceVoteDuties.length}, uniqueSlots=${uniqueSlots.size} ` + + `payloadWithMostSignals=${roundData.payloadWithMostSignals} ` + `(snapshot at L1 block ${snapshotBlock})`, ); - - if (l1VoteCount < uniqueSlots.size) { + if (l1VoteCount === 0) { return undefined; } - return { l1VoteCount, governanceVoteDuties }; + return { + l1VoteCount, + lastSignalSlot, + payloadWithMostSignals: roundData.payloadWithMostSignals, + }; }, - 'L1 vote count to match DB duties', - 10, - 0.2, + `L1 governance round to land >= 1 signal`, + 120, + 0.5, ); + // Outcome 1: the round leader payload is the one we configured all HA nodes to vote for. + // This is the strongest "governance state advanced toward our payload" assertion the + // contract exposes per-round short of executing the proposal (which needs QUORUM_SIZE + // signals -- defaults to ~151 and takes many minutes to reach, way beyond a unit-test + // budget). expect(l1VoteCount).toBeGreaterThan(0); + expect(payloadWithMostSignals.toLowerCase()).toBe(mockGovernancePayload.toString().toLowerCase()); + logger.info( + `Governance round ${round} coordinated on payload ${payloadWithMostSignals}: ${l1VoteCount} signals on L1`, + ); - if (governanceVoteDuties.length > 0) { - const dutyKeys = governanceVoteDuties.map(row => `${row.slot}-${row.validator_address}`); - const uniqueDutyKeys = new Set(dutyKeys); - expect(uniqueDutyKeys.size).toBe(governanceVoteDuties.length); + // Outcome 2: every duty the HA cluster recorded for this round is in a healthy state, and + // no (slot, validator) pair was signed twice — i.e. HA dedup actually suppressed duplicates. + // We tolerate `uniqueDutySlots > l1VoteCount` (in-flight L1 txs that haven't mined yet) and + // `uniqueDutySlots < l1VoteCount` (duties that completed too recently to be visible at the + // snapshot read) — the only invariant we hold is "no two HA nodes both signed the same + // (slot, validator)". + const dbResult = await mainPool.query( + `SELECT * FROM validator_duties WHERE slot::numeric <= $1 AND duty_type = 'GOVERNANCE_VOTE' ORDER BY slot, started_at`, + [lastSignalSlot.toString()], + ); + const governanceVoteDuties = dbResult.rows; - for (const duty of governanceVoteDuties) { - logger.info( - ` Governance vote duty: slot ${duty.slot}, validator ${duty.validator_address}, node ${duty.node_id}, status ${duty.status}`, - ); - expect(duty.status).toBe(DutyStatus.SIGNED); - expect(duty.completed_at).toBeDefined(); - } + expect(governanceVoteDuties.length).toBeGreaterThan(0); + + const dutyKeys = governanceVoteDuties.map(row => `${row.slot}-${row.validator_address}`); + const uniqueDutyKeys = new Set(dutyKeys); + expect(uniqueDutyKeys.size).toBe(governanceVoteDuties.length); - const uniqueSlots = new Set(governanceVoteDuties.map(row => row.slot)); + for (const duty of governanceVoteDuties) { logger.info( - `L1 vote count: ${l1VoteCount}, unique slots in DB with governance votes: ${uniqueSlots.size} (slots: ${[...uniqueSlots].join(', ')})`, + ` Governance vote duty: slot ${duty.slot}, validator ${duty.validator_address}, node ${duty.node_id}, status ${duty.status}`, ); - expect(l1VoteCount).toBe(uniqueSlots.size); - logger.info(`Verified L1 votes (${l1VoteCount}) === unique slots with votes (${uniqueSlots.size})`); + expect(duty.status).toBe(DutyStatus.SIGNED); + expect(duty.completed_at).toBeDefined(); } + const uniqueSlots = new Set(governanceVoteDuties.map(row => row.slot)); + logger.info( + `L1 vote count: ${l1VoteCount}, governance vote duties: ${governanceVoteDuties.length}, ` + + `unique slots with votes: ${uniqueSlots.size} (slots: ${[...uniqueSlots].join(', ')})`, + ); + logger.info('Governance voting with HA coordination and L1 verification complete'); }); @@ -616,6 +658,7 @@ describe('HA Full Setup', () => { const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); const receipt = await deployer.deploy([ownerAddress, 201], { salt: new Fr(201) }).send({ from: ownerAddress, + wait: { waitForStatus: TxStatus.CHECKPOINTED }, }); expect(receipt.receipt.blockNumber).toBeDefined(); const [block] = await aztecNode.getBlocks(receipt.receipt.blockNumber!, 1, { @@ -662,6 +705,7 @@ describe('HA Full Setup', () => { const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); const { receipt } = await deployer.deploy([ownerAddress, i + 100], { salt: new Fr(BigInt(i + 100)) }).send({ from: ownerAddress, + wait: { waitForStatus: TxStatus.CHECKPOINTED }, }); expect(receipt.blockNumber).toBeDefined(); @@ -765,45 +809,6 @@ describe('HA Full Setup', () => { `Block ${receipt.blockNumber}: Database shows ${dutiesByValidator.size} unique validators attested (quorum: ${quorum}), no double-signing detected in DB`, ); - // P2P LAYER CHECK: Verify only one attestation per validator was sent over P2P - // Find first active node for P2P check - let p2pNodeIndex = 0; - for (let idx = 0; idx < haNodeServices.length; idx++) { - if (!killedNodes.includes(idx)) { - p2pNodeIndex = idx; - break; - } - } - - const p2pNode = haNodeServices[p2pNodeIndex]; - const p2p = p2pNode.getP2P(); - const slot = SlotNumber(Number(slotNumber)); - - // Get all attestations from P2P pool for this slot (before deduplication) - const p2pAttestations = await p2p.getCheckpointAttestationsForSlot(slot); - const p2pAttestationsWithSignatures = p2pAttestations.filter(a => !a.signature.isEmpty()); - expect(p2pAttestationsWithSignatures.length).toBeGreaterThan(0); - - // Extract validator addresses from P2P attestations using getSender() - const p2pValidatorAddresses = new Map(); - for (const attestation of p2pAttestationsWithSignatures) { - const sender = attestation.getSender(); - if (sender) { - const addr = sender.toString(); - p2pValidatorAddresses.set(addr, (p2pValidatorAddresses.get(addr) || 0) + 1); - } - } - - // Verify no validator sent multiple attestations over P2P - // Each validator should have sent exactly one attestation - for (const [_, count] of p2pValidatorAddresses.entries()) { - expect(count).toBe(1); - } - - logger.info( - `Block ${receipt.blockNumber}: P2P layer shows ${p2pValidatorAddresses.size} unique validators sent attestations, no duplicates detected`, - ); - // SECONDARY CHECK: Verify checkpoint attestations match database records const [publishedCheckpoint] = await aztecNode.getCheckpoints(block.checkpointNumber, 1, { includeAttestations: true, @@ -837,6 +842,19 @@ describe('HA Full Setup', () => { expect(dutiesByValidator.has(validatorAddress)).toBe(true); } } + + // GOSSIP-LAYER CHECK: each HA node's libp2p service detects when a signer attests to two + // distinct payloads at the same slot and fires `duplicateAttestationCallback` -> validator + // client emits WANT_TO_SLASH_EVENT -> SlashOffensesCollector persists a DUPLICATE_ATTESTATION + // offense. We assert no such offense (or DUPLICATE_PROPOSAL) was collected on any surviving + // HA node. Killed nodes are unreachable, but the surviving node — which has been alive the + // whole test — has observed all gossiped attestations and proposals across every slot. + const aliveNodes = haNodeServices.filter((_, idx) => !killedNodes.includes(idx)); + const allOffenses = (await Promise.all(aliveNodes.map(n => n.getSlashOffenses('all')))).flat(); + const equivocationOffenses = allOffenses.filter( + o => o.offenseType === OffenseType.DUPLICATE_ATTESTATION || o.offenseType === OffenseType.DUPLICATE_PROPOSAL, + ); + expect(equivocationOffenses).toEqual([]); }); describe('Clock Skew and Timezone Safety', () => { diff --git a/yarn-project/end-to-end/src/composed/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/end-to-end/src/composed/uniswap_trade_on_l1_from_l2.test.ts index a614516846dd..a85c1b4988b9 100644 --- a/yarn-project/end-to-end/src/composed/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/end-to-end/src/composed/uniswap_trade_on_l1_from_l2.test.ts @@ -1,3 +1,4 @@ +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { setup as e2eSetup } from '../fixtures/utils.js'; import { uniswapL1L2TestSuite } from '../shared/uniswap_l1_l2.js'; @@ -10,7 +11,7 @@ const EXPECTED_FORKED_BLOCK = 0; //17514288; let teardown: () => Promise; const testSetup = async () => { - const context = await e2eSetup(2, { stateLoad: dumpedState, startProverNode: true }); + const context = await e2eSetup(2, { ...PIPELINING_SETUP_OPTS, stateLoad: dumpedState, startProverNode: true }); teardown = context.teardown; diff --git a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts index 6d1f29501e2e..018c4a8e2f15 100644 --- a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts +++ b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts @@ -35,7 +35,7 @@ import { createKeyFile5, createKeyFile6, } from '../../e2e_multi_validator/utils.js'; -import { MNEMONIC } from '../../fixtures/fixtures.js'; +import { MNEMONIC, PIPELINING_SETUP_OPTS } from '../../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../../fixtures/utils.js'; import { createWeb3SignerKeystore, @@ -154,6 +154,8 @@ function verifyKeyStore(directory: string) { expect(validatorAdapter.getAttesterAddresses()).toHaveLength(VALIDATOR_COUNT); } +jest.setTimeout(10 * 60 * 1000); + describe('e2e_multi_validator_node', () => { let initialValidatorPrivateKeys: `0x${string}`[]; let validatorAddresses: `0x${string}`[]; @@ -283,6 +285,7 @@ describe('e2e_multi_validator_node', () => { aztecNode, sequencer: sequencerClient, } = await setup(1, { + ...PIPELINING_SETUP_OPTS, initialValidators, aztecTargetCommitteeSize: COMMITTEE_SIZE, keyStoreDirectory, @@ -293,6 +296,8 @@ describe('e2e_multi_validator_node', () => { worldStateBlockCheckIntervalMS: 200, blockCheckIntervalMS: 200, startProverNode: true, + aztecEpochDuration: 8, + aztecProofSubmissionEpochs: 4, })); sequencer = (sequencerClient! as TestSequencerClient).getSequencer(); diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index b9e15d0378cc..22274e82c59f 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -9,6 +9,7 @@ import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { expect, jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, expectTokenBalance, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup, setupPXEAndGetWallet } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; @@ -52,7 +53,7 @@ describe('e2e_2_pxes', () => { accounts: [accountAAddress], logger, teardown: teardownA, - } = await setup(1, { numberOfInitialFundedAccounts: 3 })); + } = await setup(1, { ...AUTOMINE_E2E_OPTS, numberOfInitialFundedAccounts: 3 })); ({ wallet: walletB, diff --git a/yarn-project/end-to-end/src/e2e_abi_types.test.ts b/yarn-project/end-to-end/src/e2e_abi_types.test.ts index 0244327b214a..81ca7f63667f 100644 --- a/yarn-project/end-to-end/src/e2e_abi_types.test.ts +++ b/yarn-project/end-to-end/src/e2e_abi_types.test.ts @@ -7,9 +7,10 @@ import { AbiTypesContract } from '@aztec/noir-test-contracts.js/AbiTypes'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; const U64_MAX = 2n ** 64n - 1n; const I64_MAX = 2n ** 63n - 1n; @@ -30,7 +31,7 @@ describe('AbiTypes', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: abiTypesContract } = await AbiTypesContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index d48af0ff7fe3..74a85e77875c 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -17,6 +17,7 @@ import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { createPXE, getPXEConfig } from '@aztec/pxe/server'; import { deriveSigningKey } from '@aztec/stdlib/keys'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; import { AztecNodeProxy } from './test-wallet/utils.js'; @@ -60,7 +61,10 @@ const itShouldBehaveLikeAnAccountContract = ( address, }; - ({ logger, teardown, aztecNode } = await setup(0, { initialFundedAccounts: [accountData] })); + ({ logger, teardown, aztecNode } = await setup(0, { + ...AUTOMINE_E2E_OPTS, + initialFundedAccounts: [accountData], + })); wallet = await TestWalletInternals.create(aztecNode); const accountManager = await wallet.createAccount({ secret, contract, salt }); diff --git a/yarn-project/end-to-end/src/e2e_amm.test.ts b/yarn-project/end-to-end/src/e2e_amm.test.ts index 1df2829bdc0a..2fb58fad62ae 100644 --- a/yarn-project/end-to-end/src/e2e_amm.test.ts +++ b/yarn-project/end-to-end/src/e2e_amm.test.ts @@ -6,11 +6,12 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 900_000; // TODO(F-560): Consider whether it makes sense to drop this // https://linear.app/aztec-labs/issue/F-560/add-more-tests-to-forward-compatibility-testing @@ -40,12 +41,17 @@ describe('AMM', () => { const INITIAL_TOKEN_BALANCE = 1_000_000_000n; beforeAll(async () => { + // Anchor the PXE to the checkpointed tip rather than the proposed tip. Under pipelining the + // proposed tip can be pruned when a slot ends without a checkpoint landing on L1 (e.g. when a + // time warp races `Sequencer.work`'s two epoch-cache reads and the wait-for-parent gate ends up + // pointing at the wrong slot). The checkpointed tip is L1-confirmed and cannot be pruned, so + // inflight setup txs survive the race. ({ teardown, wallet, accounts: [adminAddress, liquidityProviderAddress, otherLiquidityProviderAddress, swapperAddress], logger, - } = await setup(4)); + } = await setup(4, { ...AUTOMINE_E2E_OPTS }, { syncChainTip: 'checkpointed' })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_authwit.test.ts b/yarn-project/end-to-end/src/e2e_authwit.test.ts index a2e470e4d876..efe9c18b1408 100644 --- a/yarn-project/end-to-end/src/e2e_authwit.test.ts +++ b/yarn-project/end-to-end/src/e2e_authwit.test.ts @@ -9,11 +9,11 @@ import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { jest } from '@jest/globals'; import { sendThroughAuthwitProxy } from './fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from './fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from './fixtures/fixtures.js'; import { type EndToEndContext, ensureAccountContractsPublished, setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; -const TIMEOUT = 150_000; +const TIMEOUT = 300_000; describe('e2e_authwit_tests', () => { jest.setTimeout(TIMEOUT); @@ -31,7 +31,7 @@ describe('e2e_authwit_tests', () => { teardown, wallet, accounts: [account1Address, account2Address], - } = await setup(2)); + } = await setup(2, { ...AUTOMINE_E2E_OPTS })); await ensureAccountContractsPublished(wallet, [account1Address, account2Address]); ({ contract: auth } = await AuthWitTestContract.deploy(wallet).send({ from: account1Address })); diff --git a/yarn-project/end-to-end/src/e2e_automine_smoke.test.ts b/yarn-project/end-to-end/src/e2e_automine_smoke.test.ts new file mode 100644 index 000000000000..01c5eac6464b --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_automine_smoke.test.ts @@ -0,0 +1,137 @@ +import type { AztecNodeService } from '@aztec/aztec-node'; +import { AztecAddress } from '@aztec/aztec.js/addresses'; +import type { Wallet } from '@aztec/aztec.js/wallet'; +import type { CheatCodes } from '@aztec/aztec/testing'; +import { range } from '@aztec/foundation/array'; +import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; + +import { jest } from '@jest/globals'; +import 'jest-extended'; + +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; +import { setup } from './fixtures/utils.js'; + +describe('e2e_automine_smoke', () => { + jest.setTimeout(10 * 60 * 1000); + + let teardown: () => Promise; + let aztecNode: AztecNode & AztecNodeDebug; + let aztecNodeService: AztecNodeService; + let wallet: Wallet; + let owner: AztecAddress; + let cheatCodes: CheatCodes; + let contract: TestContract; + + beforeAll(async () => { + ({ + teardown, + aztecNode, + aztecNodeService, + wallet, + accounts: [owner], + cheatCodes, + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); + + ({ contract } = await TestContract.deploy(wallet).send({ from: owner })); + }); + + afterAll(() => teardown()); + + it('mines sequential dependent txs back-to-back', async () => { + const startBlock = await aztecNode.getBlockNumber(); + const blockNumbers: number[] = []; + for (let i = 0; i < 5; i++) { + const { receipt } = await contract.methods.emit_nullifier_public(BigInt(i + 1000)).send({ from: owner }); + blockNumbers.push(receipt.blockNumber!); + } + + // Each .send is sequential, so each tx lands in its own block. + expect(blockNumbers[0]).toBeGreaterThan(startBlock); + expect(blockNumbers).toEqual(range(5, startBlock + 1)); + }); + + it('parallel sends all land', async () => { + const startBlock = await aztecNode.getBlockNumber(); + + const results = await Promise.all( + [...Array(5).keys()].map(i => contract.methods.emit_nullifier_public(BigInt(i + 2000)).send({ from: owner })), + ); + + for (const r of results) { + expect(r.receipt.blockNumber).toBeGreaterThan(startBlock); + } + }); + + it('warp advances L1 timestamp and the next tx lands at a fresh slot', async () => { + const before = await cheatCodes.eth.lastBlockTimestamp(); + const warpBy = 24; + await cheatCodes.warpL2TimeAtLeastBy(aztecNode, warpBy); + const after = await cheatCodes.eth.lastBlockTimestamp(); + expect(after - before).toBeGreaterThanOrEqual(warpBy); + + const { receipt } = await contract.methods.emit_nullifier_public(BigInt(9999)).send({ from: owner }); + expect(receipt.blockNumber).toBeGreaterThan(0); + }); + + it('mineBlock produces an empty checkpoint', async () => { + const before = await aztecNode.getChainTips(); + await aztecNode.mineBlock(); + const after = await aztecNode.getChainTips(); + expect(after.checkpointed.checkpoint.number).toBeGreaterThan(before.checkpointed.checkpoint.number); + expect(after.checkpointed.block.number).toBeGreaterThan(before.checkpointed.block.number); + }); + + it('revertToCheckpoint rolls back L1+L2 state', async () => { + // Land a tx and record the checkpoint it landed at. + await contract.methods.emit_nullifier_public(BigInt(5000)).send({ from: owner }); + const checkpointBefore = (await aztecNode.getChainTips()).checkpointed.checkpoint.number; + + // Land another tx so we advance to a later checkpoint. + await contract.methods.emit_nullifier_public(BigInt(5001)).send({ from: owner }); + const checkpointAfter = (await aztecNode.getChainTips()).checkpointed.checkpoint.number; + expect(checkpointAfter).toBeGreaterThan(checkpointBefore); + + // Revert to the first checkpoint. + const automine = aztecNodeService.getAutomineSequencer()!; + await automine.revertToCheckpoint(checkpointBefore); + + // Archiver tip should be back at checkpointBefore. + const checkpointReverted = (await aztecNode.getChainTips()).checkpointed.checkpoint.number; + expect(checkpointReverted).toBe(checkpointBefore); + + // After reverting, a new tx should land cleanly. + const { receipt: r3 } = await contract.methods.emit_nullifier_public(BigInt(5002)).send({ from: owner }); + expect(r3.blockNumber).toBeGreaterThan(0); + }); + + it('interleaved txs and warps all land successfully', async () => { + const startBlock = await aztecNode.getBlockNumber(); + const startL1Ts = await cheatCodes.eth.lastBlockTimestamp(); + + // Fire off N sends without awaiting; intermix warps between them. + const pending: Array> = []; + const NUM_TXS = 6; + for (let i = 0; i < NUM_TXS; i++) { + pending.push(contract.methods.emit_nullifier_public(BigInt(i + 7000)).send({ from: owner })); + // Warp between every couple of sends without awaiting the sends. + if (i % 2 === 1) { + await cheatCodes.warpL2TimeAtLeastBy(aztecNode, 24); // 2 slots + } + } + + // All txs must eventually land. + const results = await Promise.all(pending); + for (const r of results) { + expect(r.receipt.blockNumber).toBeGreaterThan(startBlock); + } + + // L1 should have advanced by at least the warps we issued. + const endL1Ts = await cheatCodes.eth.lastBlockTimestamp(); + expect(endL1Ts - startL1Ts).toBeGreaterThanOrEqual(24 * Math.floor(NUM_TXS / 2)); + + // All NUM_TXS receipts must have valid block numbers above startBlock. + const blockNumbers = results.map(r => r.receipt.blockNumber!); + expect(blockNumbers.every(n => n > startBlock)).toBe(true); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts index 7e82f7eb9b68..9b344c1a424b 100644 --- a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts +++ b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts @@ -9,9 +9,10 @@ import { AvmTestContract } from '@aztec/noir-test-contracts.js/AvmTest'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; -const TIMEOUT = 100_000; +const TIMEOUT = 600_000; describe('e2e_avm_simulator', () => { jest.setTimeout(TIMEOUT); @@ -27,229 +28,252 @@ describe('e2e_avm_simulator', () => { wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); await ensureAccountContractsPublished(wallet, [defaultAccountAddress]); }); afterAll(() => teardown()); describe('AvmTestContract', () => { - let avmContract: AvmTestContract; - let avmContractInstance: ContractInstanceWithAddress; - let secondAvmContract: AvmTestContract; - - beforeEach(async () => { - ({ contract: avmContract, instance: avmContractInstance } = await AvmTestContract.deploy(wallet).send({ - from: defaultAccountAddress, - })); - ({ contract: secondAvmContract } = await AvmTestContract.deploy(wallet).send({ from: defaultAccountAddress })); - }); + // Read-only / non-mutating tests share a single deployment to keep slot-paced deploy txs + // out of the per-test critical path under proposer pipelining. + describe('with shared deployment', () => { + let avmContract: AvmTestContract; + let avmContractInstance: ContractInstanceWithAddress; + + beforeAll(async () => { + ({ contract: avmContract, instance: avmContractInstance } = await AvmTestContract.deploy(wallet).send({ + from: defaultAccountAddress, + })); + }); - describe('Assertions & error enriching', () => { - /** - * Expect an error like: - * Assertion failed: This assertion should fail! 'assert(not_true == true, "This assertion should fail!")' - * ... - * at assert(not_true == true, "This assertion should fail!") (../../../../../../../home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr:223:5) - * at inner_helper_with_failed_assertion() (../../../../../../../home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr:228:9) - * at quote { $self } (../std/meta/expr.nr:269:9) - * at function.name(); - * let call = quote { $name($args) (/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/macros/dispatch.nr:59:20) - * at AvmTest.0xc3515746 - */ - describe('Not nested', () => { - it('PXE processes user code assertions and recovers message (properly enriched)', async () => { - await expect( - avmContract.methods.assertion_failure().simulate({ from: defaultAccountAddress }), - ).rejects.toThrow( - expect.objectContaining({ - message: expect.stringMatching( - /Assertion failed: This assertion should fail! 'assert\(not_true == true, "This assertion should fail!"\)'/, - ), - stack: expect.stringMatching(/at inner_helper_with_failed_assertion[\s\S]*at AvmTest\..*/), - }), - ); - }); - it('PXE processes user code assertions and recovers message (complex)', async () => { - await expect( - avmContract.methods.assert_nullifier_exists(123).simulate({ from: defaultAccountAddress }), - ).rejects.toThrow("Assertion failed: Nullifier doesn't exist!"); + describe('Assertions & error enriching', () => { + /** + * Expect an error like: + * Assertion failed: This assertion should fail! 'assert(not_true == true, "This assertion should fail!")' + * ... + * at assert(not_true == true, "This assertion should fail!") (../../../../../../../home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr:223:5) + * at inner_helper_with_failed_assertion() (../../../../../../../home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr:228:9) + * at quote { $self } (../std/meta/expr.nr:269:9) + * at function.name(); + * let call = quote { $name($args) (/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/macros/dispatch.nr:59:20) + * at AvmTest.0xc3515746 + */ + describe('Not nested', () => { + it('PXE processes user code assertions and recovers message (properly enriched)', async () => { + await expect( + avmContract.methods.assertion_failure().simulate({ from: defaultAccountAddress }), + ).rejects.toThrow( + expect.objectContaining({ + message: expect.stringMatching( + /Assertion failed: This assertion should fail! 'assert\(not_true == true, "This assertion should fail!"\)'/, + ), + stack: expect.stringMatching(/at inner_helper_with_failed_assertion[\s\S]*at AvmTest\..*/), + }), + ); + }); + it('PXE processes user code assertions and recovers message (complex)', async () => { + await expect( + avmContract.methods.assert_nullifier_exists(123).simulate({ from: defaultAccountAddress }), + ).rejects.toThrow("Assertion failed: Nullifier doesn't exist!"); + }); + it('PXE processes intrinsic assertions and recovers message', async () => { + await expect( + avmContract.methods.divide_by_zero(0).simulate({ from: defaultAccountAddress }), + ).rejects.toThrow('Division by zero'); + }); }); - it('PXE processes intrinsic assertions and recovers message', async () => { - await expect(avmContract.methods.divide_by_zero(0).simulate({ from: defaultAccountAddress })).rejects.toThrow( - 'Division by zero', - ); + describe('Nested', () => { + it('PXE processes user code assertions and recovers message', async () => { + await expect( + avmContract.methods.external_call_to_assertion_failure().simulate({ from: defaultAccountAddress }), + ).rejects.toThrow('Assertion failed: This assertion should fail!'); + }); + it('PXE processes intrinsic assertions and recovers message', async () => { + await expect( + avmContract.methods.external_call_to_divide_by_zero().simulate({ from: defaultAccountAddress }), + ).rejects.toThrow('Division by zero'); + }); }); }); - describe('Nested', () => { - it('PXE processes user code assertions and recovers message', async () => { - await expect( - avmContract.methods.external_call_to_assertion_failure().simulate({ from: defaultAccountAddress }), - ).rejects.toThrow('Assertion failed: This assertion should fail!'); - }); - it('PXE processes intrinsic assertions and recovers message', async () => { - await expect( - avmContract.methods.external_call_to_divide_by_zero().simulate({ from: defaultAccountAddress }), - ).rejects.toThrow('Division by zero'); + + describe('From private', () => { + it('Should enqueue a public function correctly', async () => { + const request = await avmContract.methods.enqueue_public_from_private().request(); + const simulation = await wallet.simulateTx(request, { from: defaultAccountAddress }); + expect(simulation.publicOutput!.revertReason).toBeUndefined(); }); }); - }); - describe('From private', () => { - it('Should enqueue a public function correctly', async () => { - const request = await avmContract.methods.enqueue_public_from_private().request(); - const simulation = await wallet.simulateTx(request, { from: defaultAccountAddress }); - expect(simulation.publicOutput!.revertReason).toBeUndefined(); + describe('Gas metering', () => { + it('Tracks L2 gas usage on simulation', async () => { + const request = await avmContract.methods.add_args_return(20n, 30n).request(); + const simulation = await wallet.simulateTx(request, { from: defaultAccountAddress }); + // Subtract the teardown gas from the total gas to figure out the gas used by the contract logic. + const l2TeardownGas = simulation.publicOutput!.gasUsed.teardownGas.l2Gas; + const l2GasUsed = simulation.publicOutput!.gasUsed.totalGas.l2Gas - l2TeardownGas; + // L2 gas used will vary a lot depending on codegen and other factors, + // so we just set a wide range for it, and check it's not a suspiciously round number. + expect(l2GasUsed).toBeGreaterThan(150); + expect(l2GasUsed).toBeLessThan(1e6); + expect(l2GasUsed! % 1000).not.toEqual(0); + }); }); - }); - describe('Gas metering', () => { - it('Tracks L2 gas usage on simulation', async () => { - const request = await avmContract.methods.add_args_return(20n, 30n).request(); - const simulation = await wallet.simulateTx(request, { from: defaultAccountAddress }); - // Subtract the teardown gas from the total gas to figure out the gas used by the contract logic. - const l2TeardownGas = simulation.publicOutput!.gasUsed.teardownGas.l2Gas; - const l2GasUsed = simulation.publicOutput!.gasUsed.totalGas.l2Gas - l2TeardownGas; - // L2 gas used will vary a lot depending on codegen and other factors, - // so we just set a wide range for it, and check it's not a suspiciously round number. - expect(l2GasUsed).toBeGreaterThan(150); - expect(l2GasUsed).toBeLessThan(1e6); - expect(l2GasUsed! % 1000).not.toEqual(0); + describe('Contract instance', () => { + it('Works', async () => { + const { receipt: tx } = await avmContract.methods + .test_get_contract_instance_matches( + avmContract.address, + avmContractInstance.deployer, + avmContractInstance.currentContractClassId, + avmContractInstance.initializationHash, + avmContractInstance.immutablesHash, + ) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); }); - }); - describe('Storage', () => { - it('Modifies storage (Field)', async () => { - await avmContract.methods.set_storage_single(20n).send({ from: defaultAccountAddress }); - expect( - (await avmContract.methods.read_storage_single().simulate({ from: defaultAccountAddress })).result, - ).toEqual(20n); + describe('L2 to L1 messages', () => { + it('Should fail if emitting to an invalid ethereum address', async () => { + const recipient = Fr.MAX_FIELD_VALUE; + await expect( + avmContract.methods + .raw_l2_to_l1_msg({ address: recipient }, new Fr(1)) + .send({ from: defaultAccountAddress }), + ).rejects.toThrow(); + }); }); - it('Modifies storage (Map)', async () => { - const address = AztecAddress.fromBigInt(9090n); - await avmContract.methods.set_storage_map(address, 100).send({ from: defaultAccountAddress }); - await avmContract.methods.add_storage_map(address, 100).send({ from: defaultAccountAddress }); - expect( - (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, - ).toEqual(200n); - }); + describe('Nested calls', () => { + it('Nested call to non-existent contract reverts & rethrows by default', async () => { + // The nested call reverts and by default caller rethrows + await expect( + avmContract.methods.nested_call_to_nothing().simulate({ from: defaultAccountAddress }), + ).rejects.toThrow(/not deployed/); + }); - it('Preserves storage across enqueued public calls', async () => { - const address = AztecAddress.fromBigInt(9090n); - // This will create 1 tx with 2 public calls in it. - await new BatchCall(wallet, [ - avmContract.methods.set_storage_map(address, 100), - avmContract.methods.add_storage_map(address, 100), - ]).send({ from: defaultAccountAddress }); - // On a separate tx, we check the result. - expect( - (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, - ).toEqual(200n); + it('Nested CALL instruction to non-existent contract returns failure, but caller can recover', async () => { + // The nested call reverts (returns failure), but the caller doesn't HAVE to rethrow. + const { receipt: tx } = await avmContract.methods + .nested_call_to_nothing_recovers() + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); + it('Should NOT be able to emit the same unsiloed nullifier from the same contract', async () => { + const nullifier = new Fr(1); + await expect( + avmContract.methods + .create_same_nullifier_in_nested_call(avmContract.address, nullifier) + .send({ from: defaultAccountAddress }), + ).rejects.toThrow(); + }); }); }); - describe('Contract instance', () => { - it('Works', async () => { - const { receipt: tx } = await avmContract.methods - .test_get_contract_instance_matches( - avmContract.address, - avmContractInstance.deployer, - avmContractInstance.currentContractClassId, - avmContractInstance.initializationHash, - ) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + // State-mutating tests get a fresh deployment per test to avoid cross-test leakage of + // storage writes or persisted nullifiers. + describe('with fresh deployment per test', () => { + let avmContract: AvmTestContract; + let secondAvmContract: AvmTestContract; + + beforeEach(async () => { + ({ contract: avmContract } = await AvmTestContract.deploy(wallet).send({ + from: defaultAccountAddress, + })); + ({ contract: secondAvmContract } = await AvmTestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); - }); - describe('Nullifiers', () => { - // Nullifier will not yet be siloed by the kernel. - it('Emit and check in the same tx', async () => { - const { receipt: tx } = await avmContract.methods - .emit_nullifier_and_check(123456) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - }); + describe('Storage', () => { + it('Modifies storage (Field)', async () => { + await avmContract.methods.set_storage_single(20n).send({ from: defaultAccountAddress }); + expect( + (await avmContract.methods.read_storage_single().simulate({ from: defaultAccountAddress })).result, + ).toEqual(20n); + }); - // Nullifier will have been siloed by the kernel, but we check against the unsiloed one. - it('Emit and check in separate tx', async () => { - const nullifier = new Fr(123456); - let { receipt: tx } = await avmContract.methods.new_nullifier(nullifier).send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + it('Modifies storage (Map)', async () => { + const address = AztecAddress.fromBigInt(9090n); + await avmContract.methods.set_storage_map(address, 100).send({ from: defaultAccountAddress }); + await avmContract.methods.add_storage_map(address, 100).send({ from: defaultAccountAddress }); + expect( + (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, + ).toEqual(200n); + }); - ({ receipt: tx } = await avmContract.methods - .assert_nullifier_exists(nullifier) - .send({ from: defaultAccountAddress })); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + it('Preserves storage across enqueued public calls', async () => { + const address = AztecAddress.fromBigInt(9090n); + // This will create 1 tx with 2 public calls in it. + await new BatchCall(wallet, [ + avmContract.methods.set_storage_map(address, 100), + avmContract.methods.add_storage_map(address, 100), + ]).send({ from: defaultAccountAddress }); + // On a separate tx, we check the result. + expect( + (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, + ).toEqual(200n); + }); }); - it('Emit and check in separate enqueued calls but same tx', async () => { - const nullifier = new Fr(123456); - - // This will create 1 tx with 2 public calls in it. - await new BatchCall(wallet, [ - avmContract.methods.new_nullifier(nullifier), - avmContract.methods.assert_nullifier_exists(nullifier), - ]).send({ from: defaultAccountAddress }); - }); - }); + describe('Nullifiers', () => { + // Nullifier will not yet be siloed by the kernel. + it('Emit and check in the same tx', async () => { + const { receipt: tx } = await avmContract.methods + .emit_nullifier_and_check(123456) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); - describe('L2 to L1 messages', () => { - it('Should fail if emitting to an invalid ethereum address', async () => { - const recipient = Fr.MAX_FIELD_VALUE; - await expect( - avmContract.methods.raw_l2_to_l1_msg({ address: recipient }, new Fr(1)).send({ from: defaultAccountAddress }), - ).rejects.toThrow(); - }); - }); + // Nullifier will have been siloed by the kernel, but we check against the unsiloed one. + it('Emit and check in separate tx', async () => { + const nullifier = new Fr(123456); + let { receipt: tx } = await avmContract.methods + .new_nullifier(nullifier) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + + ({ receipt: tx } = await avmContract.methods + .assert_nullifier_exists(nullifier) + .send({ from: defaultAccountAddress })); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); - describe('Nested calls', () => { - it('Nested call to non-existent contract reverts & rethrows by default', async () => { - // The nested call reverts and by default caller rethrows - await expect( - avmContract.methods.nested_call_to_nothing().simulate({ from: defaultAccountAddress }), - ).rejects.toThrow(/not deployed/); - }); + it('Emit and check in separate enqueued calls but same tx', async () => { + const nullifier = new Fr(123456); - it('Nested CALL instruction to non-existent contract returns failure, but caller can recover', async () => { - // The nested call reverts (returns failure), but the caller doesn't HAVE to rethrow. - const { receipt: tx } = await avmContract.methods - .nested_call_to_nothing_recovers() - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - }); - it('Should NOT be able to emit the same unsiloed nullifier from the same contract', async () => { - const nullifier = new Fr(1); - await expect( - avmContract.methods - .create_same_nullifier_in_nested_call(avmContract.address, nullifier) - .send({ from: defaultAccountAddress }), - ).rejects.toThrow(); + // This will create 1 tx with 2 public calls in it. + await new BatchCall(wallet, [ + avmContract.methods.new_nullifier(nullifier), + avmContract.methods.assert_nullifier_exists(nullifier), + ]).send({ from: defaultAccountAddress }); + }); }); - it('Should be able to emit different unsiloed nullifiers from the same contract', async () => { - const nullifier = new Fr(1); - const { receipt: tx } = await avmContract.methods - .create_different_nullifier_in_nested_call(avmContract.address, nullifier) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - }); + describe('Nested calls', () => { + it('Should be able to emit different unsiloed nullifiers from the same contract', async () => { + const nullifier = new Fr(1); + const { receipt: tx } = await avmContract.methods + .create_different_nullifier_in_nested_call(avmContract.address, nullifier) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); - it('Should be able to emit the same unsiloed nullifier from two different contracts', async () => { - const nullifier = new Fr(1); - const { receipt: tx } = await avmContract.methods - .create_same_nullifier_in_nested_call(secondAvmContract.address, nullifier) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - }); + it('Should be able to emit the same unsiloed nullifier from two different contracts', async () => { + const nullifier = new Fr(1); + const { receipt: tx } = await avmContract.methods + .create_same_nullifier_in_nested_call(secondAvmContract.address, nullifier) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); - it('Should be able to emit different unsiloed nullifiers from two different contracts', async () => { - const nullifier = new Fr(1); - const { receipt: tx } = await avmContract.methods - .create_different_nullifier_in_nested_call(secondAvmContract.address, nullifier) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + it('Should be able to emit different unsiloed nullifiers from two different contracts', async () => { + const nullifier = new Fr(1); + const { receipt: tx } = await avmContract.methods + .create_different_nullifier_in_nested_call(secondAvmContract.address, nullifier) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts index 76f015066d44..15c51b48c84f 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts @@ -1,12 +1,13 @@ import { AztecAddress } from '@aztec/aztec.js/addresses'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { BlacklistTokenContractTest, Role } from './blacklist_token_contract_test.js'; describe('e2e_blacklist_token_contract access control', () => { const t = new BlacklistTokenContractTest('access_control'); beforeAll(async () => { - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts index a8db3a6f3704..99b57844219f 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts @@ -14,7 +14,14 @@ import type { AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; -import { type EndToEndContext, deployAccounts, publicDeployAccounts, setup, teardown } from '../fixtures/setup.js'; +import { + type EndToEndContext, + type SetupOptions, + deployAccounts, + publicDeployAccounts, + setup, + teardown, +} from '../fixtures/setup.js'; import { TokenSimulator } from '../simulators/token_simulator.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; @@ -69,6 +76,12 @@ export class BlacklistTokenContractTest { } async crossTimestampOfChange() { + // Under AUTOMINE_E2E_OPTS, the 86400s warp crosses many epochs without any proofs being + // submitted. Mark current pending checkpoints as proven first so the rollup contract's + // pruning window doesn't reset the chain tip to genesis (which would make the warp's + // own empty-checkpoint propose fail with Rollup__InvalidArchive). See the AutomineSequencer + // README "Epoch proving caveat" and the equivalent pattern in lending_simulator.progressSlots. + await this.cheatCodes.rollup.markAsProven(); await this.cheatCodes.warpL2TimeAtLeastBy(this.aztecNode, BlacklistTokenContractTest.CHANGE_ROLES_DELAY); } @@ -78,8 +91,9 @@ export class BlacklistTokenContractTest { * 2. Publicly deploy accounts, deploy token contract and a "bad account". */ async applyBaseSetup() { - // Adding a timeout of 2 minutes in here such that it is propagated to the underlying tests - jest.setTimeout(120_000); + // Bumped from 2 min: pipelined cadence (~24s/dependent-tx) makes the 3-account deploy plus token/bad-account/ + // proxy deploys exceed the original window. + jest.setTimeout(600_000); this.logger.info('Deploying 3 accounts'); const { deployedAccounts } = await deployAccounts( @@ -139,9 +153,10 @@ export class BlacklistTokenContractTest { ).toEqual(new Role().withAdmin().toNoirStruct()); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up fresh context'); this.context = await setup(0, { + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, }); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts index 9b8b28204e15..f0d50c5eebcb 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts @@ -2,6 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { DUPLICATE_NULLIFIER_ERROR, U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; @@ -10,7 +11,10 @@ describe('e2e_blacklist_token_contract burn', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the wallet as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts index 579a1cc42132..77666a652533 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts @@ -2,6 +2,7 @@ import { computeSecretHash } from '@aztec/aztec.js/crypto'; import { Fr } from '@aztec/aztec.js/fields'; import type { TxHash } from '@aztec/aztec.js/tx'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { U128_OVERFLOW_ERROR } from '../fixtures/index.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; @@ -10,7 +11,10 @@ describe('e2e_blacklist_token_contract mint', () => { let { asset, tokenSim, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the admin as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts index 7ac49c276345..55e22ac57043 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts @@ -1,6 +1,7 @@ import { computeSecretHash } from '@aztec/aztec.js/crypto'; import { Fr } from '@aztec/aztec.js/fields'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; @@ -9,7 +10,10 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); await t.applyMint(); // Beware that we are adding the admin as minter here // Have to destructure again to ensure we have latest refs. ({ asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts index 88bbbf428fd5..1bc2e45f53e7 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; describe('e2e_blacklist_token_contract transfer private', () => { @@ -10,7 +10,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the admin as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts index 2862a3c735e7..2c5ff43cae93 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts @@ -1,5 +1,6 @@ import { Fr } from '@aztec/aztec.js/fields'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; @@ -8,7 +9,10 @@ describe('e2e_blacklist_token_contract transfer public', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the admin as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts index 9547b5b992dd..1f78751a2d7e 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; describe('e2e_blacklist_token_contract unshielding', () => { @@ -10,7 +10,10 @@ describe('e2e_blacklist_token_contract unshielding', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the admin as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index a89b49c30949..b5b2645777e0 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -27,7 +27,7 @@ import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; import { jest } from '@jest/globals'; import 'jest-extended'; -import { DUPLICATE_NULLIFIER_ERROR } from './fixtures/fixtures.js'; +import { DUPLICATE_NULLIFIER_ERROR, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -43,7 +43,7 @@ describe('e2e_block_building', () => { let aztecNode: AztecNode; let aztecNodeAdmin: AztecNodeAdmin; - let sequencer: TestSequencerClient; + let _sequencer: TestSequencerClient; let watcher: AnvilTestWatcher; let teardown: () => Promise; @@ -63,12 +63,13 @@ describe('e2e_block_building', () => { accounts: [ownerAddress, minterAddress], sequencer: sequencerClient, } = await setup(2, { + ...PIPELINING_SETUP_OPTS, archiverPollingIntervalMS: 200, sequencerPollingIntervalMS: 200, worldStateBlockCheckIntervalMS: 200, blockCheckIntervalMS: 200, })); - sequencer = sequencerClient! as TestSequencerClient; + _sequencer = sequencerClient! as TestSequencerClient; }); beforeEach(async () => { @@ -81,6 +82,7 @@ describe('e2e_block_building', () => { minTxsPerBlock: 1, maxTxsPerBlock: undefined, // reset to default enforceTimeTable: false, // reset to false (as it is in setup()) + blockDurationMs: undefined, // reset to single-block-per-slot mode }); // Clean up any mocks jest.restoreAllMocks(); @@ -88,44 +90,42 @@ describe('e2e_block_building', () => { afterAll(() => teardown()); + // Under pipelining, the proposer divides each slot into fixed sub-slots of length `blockDurationMs`. + // Each sub-slot owns the budget for exactly one L2 block; the block builder enforces the sub-slot + // deadline as a hard cap on tx execution. The invariant this test protects: if there are far more txs + // than fit in one sub-slot, the proposer must cut the block off at the deadline and roll the excess + // txs into the next sub-slot (and the next checkpoint when the slot ends). It must NOT pack everything + // into a single block and burn the whole slot on it. it('processes txs until hitting timetable', async () => { - const DEADLINE_S = 0.5; // half a second of building per block - const DEADLINE_MS = DEADLINE_S * 1000; - const MAX_TXS_FIT_IN_DEADLINE = 5; // via deadline and fake delay, we force this maximum to be true - const FAKE_DELAY_PER_TX_MS = DEADLINE_MS / MAX_TXS_FIT_IN_DEADLINE; // e.g. 100ms if 5 txs per 0.5s - - // the minimum number of blocks we want to see - const EXPECTED_BLOCKS = 3; - // choose a tx count should ensure that we use EXPECTED_BLOCKS or more - // Note that we don't need to ensure that last block is _full_ - const TX_COUNT = MAX_TXS_FIT_IN_DEADLINE * (EXPECTED_BLOCKS - 1) + 1; - - // print out the test parameters - logger.info(`multi-block timetable test parameters:`); - logger.info(` Deadline per block: ${DEADLINE_MS} ms`); - logger.info(` Fake delay per tx: ${FAKE_DELAY_PER_TX_MS} ms`); - logger.info(` Max txs that should fit in deadline: ${MAX_TXS_FIT_IN_DEADLINE}`); - logger.info(` Total txs to send: ${TX_COUNT}`); - logger.info(` Expected minimum blocks: ${EXPECTED_BLOCKS}`); + // Fixture defaults under pipelining: aztecSlotDuration=12s, ethereumSlotDuration=4s. With + // ethereumSlotDuration<8 the timing model uses checkpointInitializationTime=0.5s, + // checkpointAssembleTime=0.5s, p2pPropagationTime=0, minExecutionTime=1s. Picking a 2s sub-slot + // gives floor((12 - 0.5 - (0.5 + 2)) / 2) = 4 sub-slots per slot. + const BLOCK_DURATION_MS = 2000; + // Fake delay per tx, sized so ~3 txs fit in a 2s sub-slot before the builder cuts at the deadline. + const FAKE_DELAY_PER_TX_MS = 500; + // Send substantially more than fits in one sub-slot so the proposer must span multiple blocks. + const TX_COUNT = 10; + + logger.info(`multi-block timetable test parameters:`, { + blockDurationMs: BLOCK_DURATION_MS, + fakeDelayPerTxMs: FAKE_DELAY_PER_TX_MS, + txCount: TX_COUNT, + }); const { contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); logger.info(`Deployed stateful test contract at ${contract.address}`); - // Configure sequencer with a small delay per tx and enforce timetable + // Configure sequencer for multi-block-per-slot mode with a per-tx delay long enough that the + // builder must cut blocks off at each sub-slot deadline. await aztecNodeAdmin.setConfig({ - fakeProcessingDelayPerTxMs: FAKE_DELAY_PER_TX_MS, // ensure that each tx takes at least this long + fakeProcessingDelayPerTxMs: FAKE_DELAY_PER_TX_MS, minTxsPerBlock: 1, - maxTxsPerBlock: TX_COUNT, // intentionally large because we want to flex deadline, not this max + maxTxsPerBlock: TX_COUNT, // intentionally large; we want to flex the sub-slot deadline, not this cap enforceTimeTable: true, + blockDurationMs: BLOCK_DURATION_MS, }); - // Mock the timetable to limit time for block building. - jest.spyOn(sequencer.sequencer.timetable, 'canStartNextBlock').mockImplementation((secondsIntoSlot: number) => ({ - canStart: true, - deadline: secondsIntoSlot + DEADLINE_S, // limit block-building time - isLastBlock: true, - })); - // Flood the mempool with TX_COUNT simultaneous txs const methods = times(TX_COUNT, i => contract.methods.increment_public_value(ownerAddress, i)); const provenTxs = await asyncMap(methods, method => proveInteraction(wallet, method, { from: ownerAddress })); @@ -139,13 +139,23 @@ describe('e2e_block_building', () => { const receipts = await Promise.all(txHashes.map(txHash => waitForTx(aztecNode, txHash))); const blockNumbers = receipts.map(r => r.blockNumber!).sort((a, b) => a - b); logger.info(`Txs mined on blocks: ${unique(blockNumbers)}`); - expect(blockNumbers.at(-1)! - blockNumbers[0]).toBeGreaterThanOrEqual(EXPECTED_BLOCKS - 1); + // Spread must be at least 1 — i.e. txs are split across at least 2 distinct blocks. This fails + // (and the test catches a regression) if the proposer reverts to single-block-per-slot behavior + // or if sub-slot deadlines stop being enforced. + expect(blockNumbers.at(-1)! - blockNumbers[0]).toBeGreaterThanOrEqual(1); + expect(unique(blockNumbers).length).toBeGreaterThanOrEqual(2); }); it('assembles a block with multiple txs', async () => { // Assemble N contract deployment txs // We need to create them sequentially since we cannot have parallel calls to a circuit const TX_COUNT = 8; + + // Publish the contract class up front so that the N deploys below do not each include a + // ContractClassRegistry.publish call. Without this, every parallel deploy shares the same + // class-publication nullifier and only the first one is admitted to the mempool. + await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); + await aztecNodeAdmin.setConfig({ minTxsPerBlock: TX_COUNT }); // Need to have value > 0, so adding + 1 @@ -160,7 +170,7 @@ describe('e2e_block_building', () => { const provenTxs = []; const addresses = []; for (let i = 0; i < TX_COUNT; i++) { - const options: DeployOptions = { from: ownerAddress }; + const options: DeployOptions = { from: ownerAddress, skipClassPublication: true }; const instance = await methods[i].getInstance(); addresses.push(instance.address); provenTxs.push(await proveInteraction(wallet, methods[i], options)); @@ -297,7 +307,7 @@ describe('e2e_block_building', () => { logger, wallet, accounts: [ownerAddress], - } = await setup(1)); + } = await setup(1, { ...PIPELINING_SETUP_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: ownerAddress })); logger.info(`Test contract deployed at ${contract.address}`); }); @@ -423,11 +433,11 @@ describe('e2e_block_building', () => { logger, wallet, accounts: [ownerAddress], - } = await setup(1)); + } = await setup(1, { ...PIPELINING_SETUP_OPTS })); logger.info(`Deploying test contract`); ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: ownerAddress })); - }, 60_000); + }, 300_000); afterAll(() => teardown()); @@ -492,18 +502,19 @@ describe('e2e_block_building', () => { // Regression for https://github.com/AztecProtocol/aztec-packages/issues/7918 it('publishes two empty blocks', async () => { ({ teardown, wallet, logger, aztecNode } = await setup(0, { + ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 0, + buildCheckpointIfEmpty: true, })); - await retryUntil(async () => (await aztecNode.getBlockNumber()) >= 3, 'wait-block', 10, 1); + // Under pipelining, with `aztecSlotDuration=12s`, each empty checkpoint contains one empty + // block and lands roughly every 12s. Allow up to 60s for three empty blocks to appear. + await retryUntil(async () => (await aztecNode.getBlockNumber()) >= 3, 'wait-block', 60, 1); }); // Regression for https://github.com/AztecProtocol/aztec-packages/issues/7537 it('sends a tx on the first block', async () => { - const context = await setup(0, { - minTxsPerBlock: 0, - numberOfInitialFundedAccounts: 1, - }); + const context = await setup(0, { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 0, numberOfInitialFundedAccounts: 1 }); ({ teardown, logger, aztecNode, wallet } = context); await sleep(1000); @@ -524,9 +535,7 @@ describe('e2e_block_building', () => { wallet, aztecNodeAdmin, accounts: [ownerAddress], - } = await setup(1, { - minTxsPerBlock: 1, - })); + } = await setup(1, { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 1 })); logger.info('Deploying token contract'); const { contract: token } = await TokenContract.deploy(wallet, ownerAddress, 'TokenName', 'TokenSymbol', 18).send( @@ -554,10 +563,7 @@ describe('e2e_block_building', () => { // which translates in an incorrect end state for world state. We can easily detect this by checking whether the nullifier // tree next available leaf index is a multiple of 64. it('clears up all nullifiers if tx processing fails', async () => { - const context = await setup(1, { - minTxsPerBlock: 1, - numberOfInitialFundedAccounts: 1, - }); + const context = await setup(1, { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 1, numberOfInitialFundedAccounts: 1 }); ({ teardown, logger, @@ -588,14 +594,23 @@ describe('e2e_block_building', () => { const txHashResults = await Promise.all(batches.map(batch => batch.send({ from: ownerAddress, wait: NO_WAIT }))); const txHashes = txHashResults.map(({ txHash }) => txHash); logger.warn(`Sent two txs to test contract`, { txs: txHashes.map(hash => hash.toString()) }); - await Promise.race(txHashes.map(txHash => waitForTx(aztecNode, txHash, { timeout: 60 }))); + // Use Promise.any (not Promise.race): exactly one of the two txs will be dropped (the one that hits + // the fake AVM error in tx processing), so the dropped-tx rejection would settle Promise.race first. + // We want the first *successful* mine. + const minedTxHash = await Promise.any( + txHashes.map(async txHash => { + await waitForTx(aztecNode, txHash, { timeout: 60 }); + return txHash; + }), + ); - logger.warn(`At least one tx has been mined`); - const lastBlock = (await context.aztecNode.getBlockData('latest'))?.header; - expect(lastBlock).toBeDefined(); + logger.warn(`At least one tx has been mined`, { minedTxHash: minedTxHash.toString() }); + const minedReceipt = await aztecNode.getTxReceipt(minedTxHash); + const block = await context.aztecNode.getBlock(minedReceipt.blockNumber!); + expect(block).toBeDefined(); - logger.warn(`Latest block is ${lastBlock!.getBlockNumber()}`, { state: lastBlock?.state.partial }); - const nextNullifierIndex = lastBlock!.state.partial.nullifierTree.nextAvailableLeafIndex; + logger.warn(`Mined block is ${block!.header.getBlockNumber()}`, { state: block!.header.state.partial }); + const nextNullifierIndex = block!.header.state.partial.nullifierTree.nextAvailableLeafIndex; expect(nextNullifierIndex % 64).toEqual(0); }); }); @@ -616,7 +631,7 @@ describe('e2e_block_building', () => { cheatCodes, watcher, accounts: [ownerAddress], - } = await setup(1)); + } = await setup(1, { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 1 })); ({ contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress })); initialBlockNumber = await aztecNode.getBlockNumber(); @@ -624,10 +639,12 @@ describe('e2e_block_building', () => { await cheatCodes.rollup.advanceToNextEpoch(); + // Mark all blocks up to the current pending tip as proven so the contract-deployment block + // is anchored against a proven checkpoint. The e2e fixture's AnvilTestWatcher does NOT + // auto-prove under interval mining (only under automining), so we must drive proven manually. + await cheatCodes.rollup.markAsProven(); const bn = await aztecNode.getBlockNumber(); - while ((await aztecNode.getBlockNumber('proven')) < bn) { - await sleep(1000); - } + await retryUntil(async () => (await aztecNode.getBlockNumber('proven')) >= bn, 'wait-proven', 60, 1); watcher.setIsMarkingAsProven(false); }); diff --git a/yarn-project/end-to-end/src/e2e_bot.test.ts b/yarn-project/end-to-end/src/e2e_bot.test.ts index 381a22dfd889..6ff803dd388e 100644 --- a/yarn-project/end-to-end/src/e2e_bot.test.ts +++ b/yarn-project/end-to-end/src/e2e_bot.test.ts @@ -23,6 +23,7 @@ import { EmbeddedWallet } from '@aztec/wallets/embedded'; import { jest } from '@jest/globals'; +import { PIPELINED_FEE_PADDING, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from './fixtures/utils.js'; describe('e2e_bot', () => { @@ -36,7 +37,11 @@ describe('e2e_bot', () => { beforeAll(async () => { const [botAccount] = await getInitialTestAccountsData(); - const setupResult = await setup(0, { initialFundedAccounts: [botAccount] }); + const setupResult = await setup(0, { + ...PIPELINING_SETUP_OPTS, + aztecProofSubmissionEpochs: 640, + initialFundedAccounts: [botAccount], + }); ({ teardown, aztecNode, @@ -62,6 +67,7 @@ describe('e2e_bot', () => { ...getBotDefaultConfig(), followChain: 'CHECKPOINTED', botMode: 'transfer', + minFeePadding: PIPELINED_FEE_PADDING, }; bot = await Bot.create(config, wallet, aztecNode, undefined, new BotStore(await openTmpStore('bot'))); }); @@ -252,7 +258,7 @@ describe('e2e_bot', () => { // See 'can consume L1 to L2 message in %s after inbox drifts away from the rollup' // in end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts for context on this test. it('creates bot after inbox drift', async () => { - await cheatCodes.rollup.advanceInboxInProgress(10); + await cheatCodes.rollup.advanceInboxInProgress(4); await Bot.create(config, wallet, aztecNode, aztecNodeAdmin, new BotStore(await openTmpStore('bot'))); }, 300_000); }); @@ -292,13 +298,13 @@ describe('e2e_bot', () => { expect(block).toBeDefined(); const l2ToL1Msgs = block!.body.txEffects.flatMap(e => e.l2ToL1Msgs).filter(m => !m.isZero()); expect(l2ToL1Msgs.length).toBeGreaterThanOrEqual(1); - }, 120_000); + }, 300_000); it('replenishes the seeding pipeline across ticks', async () => { // Tick 2: the first tick consumed one message. This tick should seed a // replacement and still have a ready message to consume. const result = await bot.run(); expect(result).toBeDefined(); - }, 120_000); + }, 300_000); }); }); diff --git a/yarn-project/end-to-end/src/e2e_card_game.test.ts b/yarn-project/end-to-end/src/e2e_card_game.test.ts index 6f387d27e51c..5c6741a707b5 100644 --- a/yarn-project/end-to-end/src/e2e_card_game.test.ts +++ b/yarn-project/end-to-end/src/e2e_card_game.test.ts @@ -9,6 +9,7 @@ import { CardGameContract } from '@aztec/noir-contracts.js/CardGame'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; /* eslint-disable camelcase */ @@ -86,7 +87,7 @@ describe('e2e_card_game', () => { }; beforeAll(async () => { - const context = await setup(3); + const context = await setup(3, { ...AUTOMINE_E2E_OPTS }); ({ logger, teardown, wallet } = context); [firstPlayer, secondPlayer, thirdPlayer] = context.accounts; diff --git a/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts b/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts index 8b7a36f30576..e806f61dfe0c 100644 --- a/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts +++ b/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts @@ -3,6 +3,7 @@ import { MAX_APPS_PER_KERNEL } from '@aztec/constants'; import fs from 'fs/promises'; import path from 'path'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; /** @@ -16,7 +17,7 @@ describe('Circuit Recorder', () => { process.env.CIRCUIT_RECORD_DIR = RECORD_DIR; // Run setup which deploys an account contract and runs kernels - const { teardown } = await setup(1); + const { teardown } = await setup(1, { ...AUTOMINE_E2E_OPTS }); // Check recording directory exists const dirExists = await fs.stat(RECORD_DIR).then( @@ -81,5 +82,5 @@ describe('Circuit Recorder', () => { await fs.rm(RECORD_DIR, { recursive: true, force: true }); delete process.env.CIRCUIT_RECORD_DIR; await teardown(); - }, 60_000); + }, 120_000); }); diff --git a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts index 1e5bfd82bbf8..ab2aa16ac1ee 100644 --- a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts +++ b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts @@ -6,7 +6,6 @@ import type { AztecNode } from '@aztec/aztec.js/node'; import type { Wallet } from '@aztec/aztec.js/wallet'; import type { CheatCodes } from '@aztec/aztec/testing'; import { MINIMUM_UPDATE_DELAY, UPDATED_CLASS_IDS_SLOT } from '@aztec/constants'; -import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config'; import { UpdatableContract } from '@aztec/noir-test-contracts.js/Updatable'; import { UpdatedContract, UpdatedContractArtifact } from '@aztec/noir-test-contracts.js/Updated'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; @@ -22,11 +21,14 @@ import type { AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import { deriveSigningKey } from '@aztec/stdlib/keys'; import { PublicDataTreeLeaf } from '@aztec/stdlib/trees'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -// Set the update delay in genesis data so it's feasible to test in an e2e test -const { aztecSlotDuration } = getL1ContractsConfigEnvVars(); -const DEFAULT_TEST_UPDATE_DELAY = BigInt(aztecSlotDuration) * 10n; +// Set the update delay in genesis data so it's feasible to test in an e2e test. +// The protocol enforces `MINIMUM_UPDATE_DELAY` (600 seconds, see constants.gen.ts), so we use that +// as the test delay: it's the smallest the chain will accept, which keeps `warpL2TimeAtLeastBy` +// times reasonable while still exercising the same code path. +const DEFAULT_TEST_UPDATE_DELAY = BigInt(MINIMUM_UPDATE_DELAY); const INITIAL_UPDATABLE_CONTRACT_VALUE = 1n; // Constant copied over from Updated contract @@ -97,6 +99,7 @@ describe('e2e_contract_updates', () => { accounts: [defaultAccountAddress], cheatCodes, } = await setup(1, { + ...AUTOMINE_E2E_OPTS, genesisPublicData, initialFundedAccounts, })); @@ -122,7 +125,9 @@ describe('e2e_contract_updates', () => { INITIAL_UPDATABLE_CONTRACT_VALUE, ); await contract.methods.update_to(updatedContractClassId).send({ from: defaultAccountAddress }); - // Warp time to get past the timestamp of change where the update takes effect + // Warp time to get past the timestamp of change where the update takes effect so the latest + // header's timestamp (which the PXE uses to read the current class id) is past the update's + // timestampOfChange. await cheatCodes.warpL2TimeAtLeastBy(aztecNode, DEFAULT_TEST_UPDATE_DELAY); // Should be updated now await wallet.registerContract(instance, UpdatedContract.artifact); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts index 4f9fbc5ba363..7303a23f5fec 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts @@ -4,7 +4,7 @@ import { waitForProven } from '@aztec/aztec.js/contracts'; import { type Logger, createLogger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; import type { TxReceipt } from '@aztec/aztec.js/tx'; -import { CheatCodes } from '@aztec/aztec/testing'; +import { CheatCodes, EpochTestSettler } from '@aztec/aztec/testing'; import { createExtendedL1Client } from '@aztec/ethereum/client'; import { InboxContract, OutboxContract, RollupContract } from '@aztec/ethereum/contracts'; import type { @@ -19,6 +19,7 @@ import { sleep } from '@aztec/foundation/sleep'; import { TestERC20Abi, TestERC20Bytecode } from '@aztec/l1-artifacts'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge'; +import type { PXEConfig } from '@aztec/pxe/server'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { MNEMONIC } from '../fixtures/fixtures.js'; @@ -37,6 +38,7 @@ export class CrossChainMessagingTest { private requireEpochProven: boolean; private setupOptions: SetupOptions; private deployL1ContractsArgs: Partial; + private pxeOpts: Partial; logger: Logger; context!: EndToEndContext; aztecNode!: AztecNode; @@ -59,12 +61,23 @@ export class CrossChainMessagingTest { outbox!: OutboxContract; cheatCodes!: CheatCodes; + /** + * Background loop that marks each completed epoch as proven on L1. Started in `applyBaseSetup` + * when the test runs without a real prover node, because the e2e fixture uses L1 interval mining + * and the AnvilTestWatcher's auto-prove loop only runs under L1 automine. Without this, L1's + * `aztecProofSubmissionEpochs` window expires mid-test and triggers a chain prune that drops + * in-flight wallet txs. Tests that intentionally pause proving (e.g. inbox drift tests) can + * stop it via `await t.epochTestSettler?.stop()`. + */ + epochTestSettler?: EpochTestSettler; + deployL1ContractsValues!: DeployAztecL1ContractsReturnType; constructor( testName: string, opts: SetupOptions = {}, deployL1ContractsArgs: Partial = {}, + pxeOpts: Partial = {}, ) { this.logger = createLogger(`e2e:e2e_cross_chain_messaging:${testName}`); this.setupOptions = opts; @@ -72,17 +85,25 @@ export class CrossChainMessagingTest { initialValidators: [], ...deployL1ContractsArgs, }; + this.pxeOpts = pxeOpts; this.requireEpochProven = opts.startProverNode ?? false; } - async setup() { + async setup(opts: Partial = {}, pxeOpts: Partial = {}) { this.logger.info('Setting up cross chain messaging test'); - this.context = await setup(0, { - ...this.setupOptions, - fundSponsoredFPC: true, - skipAccountDeployment: true, - l1ContractsArgs: this.deployL1ContractsArgs, - }); + // Recompute requireEpochProven from the merged options so per-call startProverNode is honored. + this.requireEpochProven = opts.startProverNode ?? this.setupOptions.startProverNode ?? false; + this.context = await setup( + 0, + { + ...this.setupOptions, + ...opts, + fundSponsoredFPC: true, + skipAccountDeployment: true, + l1ContractsArgs: { ...this.deployL1ContractsArgs, ...opts.l1ContractsArgs }, + }, + { ...this.pxeOpts, ...pxeOpts }, + ); await this.applyBaseSetup(); } @@ -105,6 +126,7 @@ export class CrossChainMessagingTest { } async teardown() { + await this.epochTestSettler?.stop(); await teardown(this.context); } @@ -120,6 +142,19 @@ export class CrossChainMessagingTest { if (this.requireEpochProven) { // Turn off the watcher to prevent it from keep marking blocks as proven. this.context.watcher.setIsMarkingAsProven(false); + } else { + // When no real prover is running, the L1 proof window (aztecProofSubmissionEpochs) would + // otherwise expire mid-test and trigger a chain prune. The AnvilTestWatcher's auto-prove + // loop is dormant under L1 interval mining (it gates on `isAutoMining`), so start an + // EpochTestSettler to mark each completed epoch as proven on L1. + this.epochTestSettler = new EpochTestSettler( + this.context.ethCheatCodes, + this.context.deployL1ContractsValues.l1ContractAddresses.rollupAddress, + this.context.aztecNodeService.getBlockSource(), + this.logger.createChild('epoch-settler'), + { pollingIntervalMs: 500 }, + ); + await this.epochTestSettler.start(); } // Deploy 3 accounts diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.parallel.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.parallel.test.ts new file mode 100644 index 000000000000..7a182f2d4c6d --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.parallel.test.ts @@ -0,0 +1,324 @@ +import { AztecAddress } from '@aztec/aztec.js/addresses'; +import { generateClaimSecret } from '@aztec/aztec.js/ethereum'; +import { Fr } from '@aztec/aztec.js/fields'; +import type { Logger } from '@aztec/aztec.js/log'; +import { isL1ToL2MessageReady } from '@aztec/aztec.js/messaging'; +import type { AztecNode } from '@aztec/aztec.js/node'; +import { TxExecutionResult } from '@aztec/aztec.js/tx'; +import type { Wallet } from '@aztec/aztec.js/wallet'; +import { BlockNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; +import { timesAsync } from '@aztec/foundation/collection'; +import { retryUntil } from '@aztec/foundation/retry'; +import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { ExecutionPayload } from '@aztec/stdlib/tx'; + +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; +import { sendL1ToL2Message } from '../fixtures/l1_to_l2_messaging.js'; +import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; +import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; + +jest.setTimeout(300_000); + +describe('e2e_cross_chain_messaging l1_to_l2', () => { + let t: CrossChainMessagingTest; + let log: Logger; + let crossChainTestHarness: CrossChainTestHarness; + let aztecNode: AztecNode; + let wallet: Wallet; + let user1Address: AztecAddress; + let testContract: TestContract; + + beforeEach(async () => { + t = new CrossChainMessagingTest( + 'l1_to_l2', + // PIPELINING_SETUP_OPTS sets minTxsPerBlock=0; this test needs minTxsPerBlock=1 because it + // manually mines blocks one tx at a time via advanceBlock() and counts checkpoints, so empty + // pipelined checkpoints interleaving between txs would break the exact block-number assertions. + { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 1 }, + { aztecProofSubmissionEpochs: 2, aztecEpochDuration: 4 }, + // Anchor PXE to the checkpointed chain so that a proposed-chain invalidation cascade + // (e.g. a missed checkpoint publish that prunes the pipelined proposed chain) doesn't + // drop the wallet's in-flight tx via handlePrunedBlocks. + { syncChainTip: 'checkpointed' }, + ); + await t.setup(); + + ({ logger: log, crossChainTestHarness, wallet, user1Address, aztecNode } = t); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: user1Address })); + }, 300_000); + + afterEach(async () => { + await t.teardown(); + }); + + const getConsumeMethod = (scope: 'private' | 'public') => + scope === 'private' + ? testContract.methods.consume_message_from_arbitrary_sender_private + : testContract.methods.consume_message_from_arbitrary_sender_public; + + // Sends a tx to L2 to advance the block number by 1 + const advanceBlock = async () => { + const block = await aztecNode.getBlockNumber(); + log.warn(`Sending noop tx at block ${block}`); + await wallet.sendTx(ExecutionPayload.empty(), { from: user1Address }); + const newBlock = await aztecNode.getBlockNumber(); + log.warn(`Advanced to block ${newBlock}`); + if (newBlock === block) { + throw new Error(`Failed to advance block ${block}`); + } + // Under interval mining `AnvilTestWatcher.markAsProven` does not auto-fire; without an explicit + // prove call here, L1's `aztecProofSubmissionEpochs=2` window (96s with pipelined 12s slots) + // expires mid-test and triggers a chain prune that drops in-flight wallet txs. + await t.context.watcher.markAsProven(); + return newBlock; + }; + + const waitForBlockToCheckpoint = async (blockNumber: BlockNumber) => { + return await retryUntil( + async () => { + const checkpointedBlockNumber = await aztecNode.getBlockNumber('checkpointed'); + const isCheckpointed = checkpointedBlockNumber >= blockNumber; + if (!isCheckpointed) { + return undefined; + } + const [checkpointedBlock] = await aztecNode.getBlocks(blockNumber, 1, { + includeL1PublishInfo: true, + includeAttestations: true, + onlyCheckpointed: true, + }); + return checkpointedBlock.checkpointNumber; + }, + 'wait for block to checkpoint', + 60, + ); + }; + + const advanceCheckpoint = async () => { + let checkpoint = await aztecNode.getCheckpointNumber(); + const originalCheckpoint = checkpoint; + log.warn(`Original checkpoint ${originalCheckpoint}`); + do { + const newBlock = await advanceBlock(); + checkpoint = await waitForBlockToCheckpoint(newBlock); + } while (checkpoint <= originalCheckpoint); + log.warn(`At checkpoint ${checkpoint}`); + }; + + // Same as above but ignores errors. Useful if we expect a prune. + const tryAdvanceBlock = async () => { + try { + await advanceBlock(); + } catch (err) { + log.warn(`Failed to advance block: ${(err as Error).message}`); + } + }; + + // Waits until the message is fetched by the archiver of the node and returns the msg target checkpoint + const waitForMessageFetched = async (msgHash: Fr) => { + log.warn(`Waiting until the message is fetched by the node`); + return await retryUntil( + async () => { + const checkpoint = await aztecNode.getL1ToL2MessageCheckpoint(msgHash); + if (checkpoint !== undefined) { + return checkpoint; + } + await advanceBlock(); + return undefined; + }, + 'get msg checkpoint', + 60, + ); + }; + + // Waits until the message is ready to be consumed on L2 as it's been added to the world state + const waitForMessageReady = async ( + msgHash: Fr, + scope: 'private' | 'public', + onNotReady?: (blockNumber: BlockNumber) => Promise, + ) => { + const msgCheckpoint = await waitForMessageFetched(msgHash); + log.warn( + `Waiting until L2 reaches the first block of msg checkpoint ${msgCheckpoint} (current is ${await aztecNode.getCheckpointNumber()})`, + ); + await retryUntil( + async () => { + const [blockNumber, checkpointNumber] = await Promise.all([ + aztecNode.getBlockNumber(), + aztecNode.getCheckpointNumber(), + ]); + const witness = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash); + const isReady = await isL1ToL2MessageReady(aztecNode, msgHash); + log.info( + `Block is ${blockNumber}, checkpoint is ${checkpointNumber}. Message checkpoint is ${msgCheckpoint}. Witness ${!!witness}. Ready ${isReady}.`, + ); + if (!isReady) { + await (onNotReady ? onNotReady(blockNumber) : advanceBlock()); + } + return isReady; + }, + `wait for rollup to reach msg checkpoint ${msgCheckpoint}`, + 240, + ); + }; + + // We register one portal address when deploying contract but that address is no-longer the only address + // allowed to send messages to the given contract. In the following test we'll test that it's really the case. + // We'll also test that we can send the same message content across the bridge multiple times. + const canSendMessageFromNonRegisteredPortal = async (scope: 'private' | 'public') => { + // Generate and send the message to the L1 contract + const [secret, secretHash] = await generateClaimSecret(); + const message = { recipient: testContract.address, content: Fr.random(), secretHash }; + const { msgHash: message1Hash, globalLeafIndex: actualMessage1Index } = await sendL1ToL2Message( + message, + crossChainTestHarness, + ); + + await waitForMessageReady(message1Hash, scope); + + const [message1Index] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message1Hash))!; + expect(actualMessage1Index.toBigInt()).toBe(message1Index); + + const sendConsumeMsgTx = async (index: Fr) => { + const call = getConsumeMethod(scope)(message.content, secret, crossChainTestHarness.ethAccount, index); + if (scope === 'public') { + await call.simulate({ from: user1Address }); + } + await call.send({ from: user1Address }); + }; + + // We consume the L1 to L2 message using the test contract either from private or public + await sendConsumeMsgTx(actualMessage1Index); + + // We send and consume the exact same message the second time to test that oracles correctly return the new + // non-nullified message + const { msgHash: message2Hash, globalLeafIndex: actualMessage2Index } = await sendL1ToL2Message( + message, + crossChainTestHarness, + ); + + // We check that the duplicate message was correctly inserted by checking that its message index is defined + await waitForMessageReady(message2Hash, scope); + + const [message2Index] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message2Hash))!; + expect(message2Index).toBeDefined(); + expect(message2Index).toBeGreaterThan(actualMessage1Index.toBigInt()); + expect(actualMessage2Index.toBigInt()).toBe(message2Index); + + // Now we consume the message again. Everything should pass because oracle should return the duplicate message + // which is not nullified + await sendConsumeMsgTx(actualMessage2Index); + }; + + it('can send an L1 to L2 message from a non-registered portal address consumed from private repeatedly', async () => { + await canSendMessageFromNonRegisteredPortal('private'); + }); + + it('can send an L1 to L2 message from a non-registered portal address consumed from public repeatedly', async () => { + await canSendMessageFromNonRegisteredPortal('public'); + }); + + // Inbox checkpoint number can drift on two scenarios: if the rollup reorgs and rolls back its own + // checkpoint number, or if the inbox receives too many messages and they are inserted faster than + // they are consumed. In this test, we mine several checkpoints without marking them as proven until + // we can trigger a reorg, and then wait until the message can be processed to consume it. + const canConsumeMessageAfterInboxDrift = async (scope: 'private' | 'public') => { + // Stop the background epoch test settler so the drift scenario below can proceed without + // an auto-prover racing it. + await t.epochTestSettler?.stop(); + + // Reset the L1 proof window by marking the current pending tip as proven. The e2e fixture + // runs L1 on interval mining, so the watcher's auto-prove loop never starts (it gates on + // `isAutoMining`). That means L1's prune deadline has been anchored to chain genesis the + // whole setup, and would otherwise fire mid-test before we finish mining the 4 drift + // checkpoints below. + await t.context.watcher.markAsProven(); + + // Stop proving + const lastProven = await aztecNode.getBlockNumber(); + const [checkpointedProvenBlock] = await aztecNode.getBlocks(lastProven, 1, { + includeL1PublishInfo: true, + includeAttestations: true, + onlyCheckpointed: true, + }); + log.warn(`Stopping proof submission at checkpoint ${checkpointedProvenBlock.checkpointNumber} to allow drift`); + t.context.watcher.setIsMarkingAsProven(false); + + // Mine several checkpoints to ensure drift + log.warn(`Mining blocks to allow drift`); + await timesAsync(4, advanceCheckpoint); + + // Generate and send the message to the L1 contract + log.warn(`Sending L1 to L2 message`); + const [secret, secretHash] = await generateClaimSecret(); + const message = { recipient: testContract.address, content: Fr.random(), secretHash }; + const { msgHash, globalLeafIndex } = await sendL1ToL2Message(message, crossChainTestHarness); + + // Wait until the Aztec node has synced it + const msgCheckpointNumber = await waitForMessageFetched(msgHash); + log.warn(`Message synced for checkpoint ${msgCheckpointNumber}`); + expect(checkpointedProvenBlock.checkpointNumber + 4).toBeLessThan(msgCheckpointNumber); + + // And keep mining until we prune back to the original block number. Now the "waiting for two blocks" + // strategy for the message to be ready to use shouldn't work, since the lastProven block is more than + // two blocks behind the message block. This is the scenario we want to test. + log.warn(`Waiting until we prune back to ${lastProven}`); + await retryUntil( + async () => + (await aztecNode.getBlockNumber().then(b => b === lastProven || b === lastProven + 1)) || + (await tryAdvanceBlock()), + 'wait for prune', + 180, + ); + + // Check that there is no witness yet + expect(await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash)).toBeUndefined(); + + // Define L2 function to consume the message + const consume = () => + getConsumeMethod(scope)(message.content, secret, crossChainTestHarness.ethAccount, globalLeafIndex); + + // Wait until the message is ready to be consumed, checking that it cannot be consumed beforehand + await waitForMessageReady(msgHash, scope, async () => { + if (scope === 'private') { + // On private, we simulate the tx locally and check that we get a missing message error, then we advance to the next block + await expect(() => consume().simulate({ from: user1Address })).rejects.toThrow(/No L1 to L2 message found/); + await tryAdvanceBlock(); + } else { + // In public it is harder to determine when a message becomes consumable. + // We send a transaction, this advances the chain and the message MIGHT be consumed in the new block. + // If it does get consumed then we check that the block contains the message. + // If it fails we check that the block doesn't contain the message + const { receipt } = await consume().send({ from: user1Address, wait: { dontThrowOnRevert: true } }); + if (receipt.executionResult === TxExecutionResult.SUCCESS) { + // The block the transaction included should be for the message checkpoint number + // and be the first block in the checkpoint + const block = await aztecNode.getBlock(receipt.blockNumber!); + expect(block).toBeDefined(); + expect(block!.checkpointNumber).toEqual(msgCheckpointNumber); + expect(block!.indexWithinCheckpoint).toEqual(IndexWithinCheckpoint.ZERO); + } else { + expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); + } + } + await t.context.watcher.markAsProven(); + }); + + // Verify the membership witness is available for creating the tx (private-land only) + if (scope === 'private') { + const [messageIndex] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash))!; + expect(messageIndex).toEqual(globalLeafIndex.toBigInt()); + // And consume the message for private, public was already consumed. + await consume().send({ from: user1Address }); + } + }; + + it('can consume L1 to L2 message in private after inbox drifts away from the rollup', async () => { + await canConsumeMessageAfterInboxDrift('private'); + }); + + it('can consume L1 to L2 message in public after inbox drifts away from the rollup', async () => { + await canConsumeMessageAfterInboxDrift('public'); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts deleted file mode 100644 index 294069db6b86..000000000000 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts +++ /dev/null @@ -1,288 +0,0 @@ -import { AztecAddress } from '@aztec/aztec.js/addresses'; -import { generateClaimSecret } from '@aztec/aztec.js/ethereum'; -import { Fr } from '@aztec/aztec.js/fields'; -import type { Logger } from '@aztec/aztec.js/log'; -import { isL1ToL2MessageReady } from '@aztec/aztec.js/messaging'; -import type { AztecNode } from '@aztec/aztec.js/node'; -import { TxExecutionResult } from '@aztec/aztec.js/tx'; -import type { Wallet } from '@aztec/aztec.js/wallet'; -import { BlockNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; -import { timesAsync } from '@aztec/foundation/collection'; -import { retryUntil } from '@aztec/foundation/retry'; -import { TestContract } from '@aztec/noir-test-contracts.js/Test'; -import { ExecutionPayload } from '@aztec/stdlib/tx'; - -import { sendL1ToL2Message } from '../fixtures/l1_to_l2_messaging.js'; -import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; -import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; - -describe('e2e_cross_chain_messaging l1_to_l2', () => { - let t: CrossChainMessagingTest; - let log: Logger; - let crossChainTestHarness: CrossChainTestHarness; - let aztecNode: AztecNode; - let wallet: Wallet; - let user1Address: AztecAddress; - let testContract: TestContract; - - beforeEach(async () => { - t = new CrossChainMessagingTest( - 'l1_to_l2', - { minTxsPerBlock: 1 }, - { aztecProofSubmissionEpochs: 2, aztecEpochDuration: 4, inboxLag: 2 }, - ); - await t.setup(); - - ({ logger: log, crossChainTestHarness, wallet, user1Address, aztecNode } = t); - ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: user1Address })); - }, 300_000); - - afterEach(async () => { - await t.teardown(); - }); - - const getConsumeMethod = (scope: 'private' | 'public') => - scope === 'private' - ? testContract.methods.consume_message_from_arbitrary_sender_private - : testContract.methods.consume_message_from_arbitrary_sender_public; - - // Sends a tx to L2 to advance the block number by 1 - const advanceBlock = async () => { - const block = await aztecNode.getBlockNumber(); - log.warn(`Sending noop tx at block ${block}`); - await wallet.sendTx(ExecutionPayload.empty(), { from: user1Address }); - const newBlock = await aztecNode.getBlockNumber(); - log.warn(`Advanced to block ${newBlock}`); - if (newBlock === block) { - throw new Error(`Failed to advance block ${block}`); - } - return newBlock; - }; - - const waitForBlockToCheckpoint = async (blockNumber: BlockNumber) => { - return await retryUntil( - async () => { - const checkpointedBlockNumber = await aztecNode.getBlockNumber('checkpointed'); - const isCheckpointed = checkpointedBlockNumber >= blockNumber; - if (!isCheckpointed) { - return undefined; - } - const [checkpointedBlock] = await aztecNode.getBlocks(blockNumber, 1, { - includeL1PublishInfo: true, - includeAttestations: true, - onlyCheckpointed: true, - }); - return checkpointedBlock.checkpointNumber; - }, - 'wait for block to checkpoint', - 60, - ); - }; - - const advanceCheckpoint = async () => { - let checkpoint = await aztecNode.getCheckpointNumber(); - const originalCheckpoint = checkpoint; - log.warn(`Original checkpoint ${originalCheckpoint}`); - do { - const newBlock = await advanceBlock(); - checkpoint = await waitForBlockToCheckpoint(newBlock); - } while (checkpoint <= originalCheckpoint); - log.warn(`At checkpoint ${checkpoint}`); - }; - - // Same as above but ignores errors. Useful if we expect a prune. - const tryAdvanceBlock = async () => { - try { - await advanceBlock(); - } catch (err) { - log.warn(`Failed to advance block: ${(err as Error).message}`); - } - }; - - // Waits until the message is fetched by the archiver of the node and returns the msg target checkpoint - const waitForMessageFetched = async (msgHash: Fr) => { - log.warn(`Waiting until the message is fetched by the node`); - return await retryUntil( - async () => { - const checkpoint = await aztecNode.getL1ToL2MessageCheckpoint(msgHash); - if (checkpoint !== undefined) { - return checkpoint; - } - await advanceBlock(); - return undefined; - }, - 'get msg checkpoint', - 60, - ); - }; - - // Waits until the message is ready to be consumed on L2 as it's been added to the world state - const waitForMessageReady = async ( - msgHash: Fr, - scope: 'private' | 'public', - onNotReady?: (blockNumber: BlockNumber) => Promise, - ) => { - const msgCheckpoint = await waitForMessageFetched(msgHash); - log.warn( - `Waiting until L2 reaches the first block of msg checkpoint ${msgCheckpoint} (current is ${await aztecNode.getCheckpointNumber()})`, - ); - await retryUntil( - async () => { - const [blockNumber, checkpointNumber] = await Promise.all([ - aztecNode.getBlockNumber(), - aztecNode.getCheckpointNumber(), - ]); - const witness = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash); - const isReady = await isL1ToL2MessageReady(aztecNode, msgHash); - log.info( - `Block is ${blockNumber}, checkpoint is ${checkpointNumber}. Message checkpoint is ${msgCheckpoint}. Witness ${!!witness}. Ready ${isReady}.`, - ); - if (!isReady) { - await (onNotReady ? onNotReady(blockNumber) : advanceBlock()); - } - return isReady; - }, - `wait for rollup to reach msg checkpoint ${msgCheckpoint}`, - 120, - ); - }; - - // We register one portal address when deploying contract but that address is no-longer the only address - // allowed to send messages to the given contract. In the following test we'll test that it's really the case. - // We'll also test that we can send the same message content across the bridge multiple times. - it.each(['private', 'public'] as const)( - 'can send an L1 to L2 message from a non-registered portal address consumed from %s repeatedly', - async (scope: 'private' | 'public') => { - // Generate and send the message to the L1 contract - const [secret, secretHash] = await generateClaimSecret(); - const message = { recipient: testContract.address, content: Fr.random(), secretHash }; - const { msgHash: message1Hash, globalLeafIndex: actualMessage1Index } = await sendL1ToL2Message( - message, - crossChainTestHarness, - ); - - await waitForMessageReady(message1Hash, scope); - - const [message1Index] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message1Hash))!; - expect(actualMessage1Index.toBigInt()).toBe(message1Index); - - const sendConsumeMsgTx = async (index: Fr) => { - const call = getConsumeMethod(scope)(message.content, secret, crossChainTestHarness.ethAccount, index); - if (scope === 'public') { - await call.simulate({ from: user1Address }); - } - await call.send({ from: user1Address }); - }; - - // We consume the L1 to L2 message using the test contract either from private or public - await sendConsumeMsgTx(actualMessage1Index); - - // We send and consume the exact same message the second time to test that oracles correctly return the new - // non-nullified message - const { msgHash: message2Hash, globalLeafIndex: actualMessage2Index } = await sendL1ToL2Message( - message, - crossChainTestHarness, - ); - - // We check that the duplicate message was correctly inserted by checking that its message index is defined - await waitForMessageReady(message2Hash, scope); - - const [message2Index] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message2Hash))!; - expect(message2Index).toBeDefined(); - expect(message2Index).toBeGreaterThan(actualMessage1Index.toBigInt()); - expect(actualMessage2Index.toBigInt()).toBe(message2Index); - - // Now we consume the message again. Everything should pass because oracle should return the duplicate message - // which is not nullified - await sendConsumeMsgTx(actualMessage2Index); - }, - 120_000, - ); - - // Inbox checkpoint number can drift on two scenarios: if the rollup reorgs and rolls back its own - // checkpoint number, or if the inbox receives too many messages and they are inserted faster than - // they are consumed. In this test, we mine several checkpoints without marking them as proven until - // we can trigger a reorg, and then wait until the message can be processed to consume it. - it.each(['private', 'public'] as const)( - 'can consume L1 to L2 message in %s after inbox drifts away from the rollup', - async (scope: 'private' | 'public') => { - // Stop proving - const lastProven = await aztecNode.getBlockNumber(); - const [checkpointedProvenBlock] = await aztecNode.getBlocks(lastProven, 1, { - includeL1PublishInfo: true, - includeAttestations: true, - onlyCheckpointed: true, - }); - log.warn(`Stopping proof submission at checkpoint ${checkpointedProvenBlock.checkpointNumber} to allow drift`); - t.context.watcher.setIsMarkingAsProven(false); - - // Mine several checkpoints to ensure drift - log.warn(`Mining blocks to allow drift`); - await timesAsync(4, advanceCheckpoint); - - // Generate and send the message to the L1 contract - log.warn(`Sending L1 to L2 message`); - const [secret, secretHash] = await generateClaimSecret(); - const message = { recipient: testContract.address, content: Fr.random(), secretHash }; - const { msgHash, globalLeafIndex } = await sendL1ToL2Message(message, crossChainTestHarness); - - // Wait until the Aztec node has synced it - const msgCheckpointNumber = await waitForMessageFetched(msgHash); - log.warn(`Message synced for checkpoint ${msgCheckpointNumber}`); - expect(checkpointedProvenBlock.checkpointNumber + 4).toBeLessThan(msgCheckpointNumber); - - // And keep mining until we prune back to the original block number. Now the "waiting for two blocks" - // strategy for the message to be ready to use shouldn't work, since the lastProven block is more than - // two blocks behind the message block. This is the scenario we want to test. - log.warn(`Waiting until we prune back to ${lastProven}`); - await retryUntil( - async () => - (await aztecNode.getBlockNumber().then(b => b === lastProven || b === lastProven + 1)) || - (await tryAdvanceBlock()), - 'wait for prune', - 40, - ); - - // Check that there is no witness yet - expect(await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash)).toBeUndefined(); - - // Define L2 function to consume the message - const consume = () => - getConsumeMethod(scope)(message.content, secret, crossChainTestHarness.ethAccount, globalLeafIndex); - - // Wait until the message is ready to be consumed, checking that it cannot be consumed beforehand - await waitForMessageReady(msgHash, scope, async () => { - if (scope === 'private') { - // On private, we simulate the tx locally and check that we get a missing message error, then we advance to the next block - await expect(() => consume().simulate({ from: user1Address })).rejects.toThrow(/No L1 to L2 message found/); - await tryAdvanceBlock(); - } else { - // In public it is harder to determine when a message becomes consumable. - // We send a transaction, this advances the chain and the message MIGHT be consumed in the new block. - // If it does get consumed then we check that the block contains the message. - // If it fails we check that the block doesn't contain the message - const { receipt } = await consume().send({ from: user1Address, wait: { dontThrowOnRevert: true } }); - if (receipt.executionResult === TxExecutionResult.SUCCESS) { - // The block the transaction included should be for the message checkpoint number - // and be the first block in the checkpoint - const block = await aztecNode.getBlock(receipt.blockNumber!); - expect(block).toBeDefined(); - expect(block!.checkpointNumber).toEqual(msgCheckpointNumber); - expect(block!.indexWithinCheckpoint).toEqual(IndexWithinCheckpoint.ZERO); - } else { - expect(receipt.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); - } - } - await t.context.watcher.markAsProven(); - }); - - // Verify the membership witness is available for creating the tx (private-land only) - if (scope === 'private') { - const [messageIndex] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash))!; - expect(messageIndex).toEqual(globalLeafIndex.toBigInt()); - // And consume the message for private, public was already consumed. - await consume().send({ from: user1Address }); - } - }, - ); -}); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts index 6c123772337b..34b29d165450 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts @@ -5,6 +5,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { OutboxContract, RollupContract, type ViemL2ToL1Msg } from '@aztec/ethereum/contracts'; import { OutboxAbi } from '@aztec/l1-artifacts'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { type Sequencer, type SequencerEvents, SequencerState } from '@aztec/sequencer-client'; import { computeL2ToL1MessageHash } from '@aztec/stdlib/hash'; import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { @@ -14,12 +15,43 @@ import { } from '@aztec/stdlib/messaging'; import type { TxHash } from '@aztec/stdlib/tx'; +import { jest } from '@jest/globals'; import { type Hex, decodeEventLog } from 'viem'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; +/** + * Waits for the sequencer to reach IDLE state so that subsequent setConfig() calls take effect on + * the next checkpoint job rather than racing with an in-flight one. Mirrors the helper in + * `e2e_fees/gas_estimation.test.ts`. + */ +function waitForSequencerIdle(sequencer: Sequencer, timeout = 30000): Promise { + if (sequencer.status().state === SequencerState.IDLE) { + return Promise.resolve(); + } + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + sequencer.off('state-changed', handler); + reject(new Error('Timeout waiting for sequencer IDLE state')); + }, timeout); + const handler = (args: Parameters[0]) => { + if (args.newState === SequencerState.IDLE) { + clearTimeout(timer); + sequencer.off('state-changed', handler); + resolve(); + } + }; + sequencer.on('state-changed', handler); + }); +} + describe('e2e_cross_chain_messaging l2_to_l1', () => { + // Pipelining slows wall-clock chain progress (12s slots); advanceToEpochProven plus the per-test + // multi-tx flows exceed the default 300s per-test budget. + jest.setTimeout(15 * 60 * 1000); + const t = new CrossChainMessagingTest('l2_to_l1', { startProverNode: true }); let crossChainTestHarness: CrossChainTestHarness; @@ -35,7 +67,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { let contract: TestContract; beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); ({ crossChainTestHarness, aztecNode, aztecNodeAdmin, wallet, user1Address, rollup, outbox } = t); @@ -59,6 +91,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { // Configure the node to be able to rollup only 1 tx. await aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); + await waitForSequencerIdle(t.context.sequencer!.getSequencer()); const { receipt: txReceipt } = await new BatchCall(wallet, [ contract.methods.create_l2_to_l1_message_arbitrary_recipient_private(contents[0], recipient), @@ -90,6 +123,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { // Configure the node to include the 2 txs in the same block. await aztecNodeAdmin.setConfig({ minTxsPerBlock: 2 }); + await waitForSequencerIdle(t.context.sequencer!.getSequencer()); // Send the 2 txs. const [{ receipt: noMessageReceipt }, { receipt: withMessageReceipt }] = await Promise.all([ @@ -112,6 +146,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { it('2 txs (balanced), one with 3 messages (unbalanced), one with 4 messages (balanced)', async () => { // Force txs to be in the same block. await aztecNodeAdmin!.setConfig({ minTxsPerBlock: 2 }); + await waitForSequencerIdle(t.context.sequencer!.getSequencer()); const tx0 = generateMessages(3); const tx1 = generateMessages(4); @@ -164,6 +199,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { it('3 txs (unbalanced), one with 3 messages (unbalanced), one with 1 message (the subtree root), one with 2 messages (balanced)', async () => { // Force txs to be in the same block. await aztecNodeAdmin!.setConfig({ minTxsPerBlock: 3 }); + await waitForSequencerIdle(t.context.sequencer!.getSequencer()); const tx0 = generateMessages(3); const tx1 = generateMessages(1); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_failure_cases.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_failure_cases.test.ts index d864b328ceef..13d7837d4133 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_failure_cases.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_failure_cases.test.ts @@ -5,7 +5,7 @@ import { sha256ToField } from '@aztec/foundation/crypto/sha256'; import { toFunctionSelector } from 'viem'; -import { NO_L1_TO_L2_MSG_ERROR } from '../fixtures/fixtures.js'; +import { NO_L1_TO_L2_MSG_ERROR, PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; describe('e2e_cross_chain_messaging token_bridge_failure_cases', () => { @@ -15,7 +15,7 @@ describe('e2e_cross_chain_messaging token_bridge_failure_cases', () => { let { crossChainTestHarness, ethAccount, l2Bridge, ownerAddress, user1Address, user2Address, rollup } = t; beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ crossChainTestHarness, user1Address, user2Address, ownerAddress, rollup } = t); ethAccount = crossChainTestHarness.ethAccount; @@ -40,7 +40,7 @@ describe('e2e_cross_chain_messaging token_bridge_failure_cases', () => { .exit_to_l1_public(ethAccount, withdrawAmount, EthAddress.ZERO, authwitNonce) .simulate({ from: user1Address }), ).rejects.toThrow(/unauthorized/); - }, 60_000); + }, 180_000); it("Can't claim funds privately which were intended for public deposit from the token portal", async () => { const bridgeAmount = 100n; @@ -72,7 +72,7 @@ describe('e2e_cross_chain_messaging token_bridge_failure_cases', () => { .claim_private(ownerAddress, wrongBridgeAmount, claim.claimSecret, claim.messageLeafIndex) .simulate({ from: user2Address }), ).rejects.toThrow(`No L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`); - }, 60_000); + }, 180_000); it("Can't claim funds publicly which were intended for private deposit from the token portal", async () => { // 1. Mint tokens on L1 diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts index 2060c5263a68..70cf8c1b53eb 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts @@ -6,11 +6,18 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import type { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge'; import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; describe('e2e_cross_chain_messaging token_bridge_private', () => { + // Pipelining slows wall-clock chain progress (12s slots); waitForProven via advanceToEpochProven + // needs more than the default 300s per-test budget. + jest.setTimeout(15 * 60 * 1000); + const t = new CrossChainMessagingTest('token_bridge_private', { startProverNode: true }); let crossChainTestHarness: CrossChainTestHarness; @@ -24,7 +31,7 @@ describe('e2e_cross_chain_messaging token_bridge_private', () => { let user2Address: AztecAddress; beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ crossChainTestHarness, ethAccount, aztecNode, logger, ownerAddress, l2Bridge, l2Token, wallet, user2Address } = t); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_public.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_public.test.ts index 4f4e4d34cc12..23894e168172 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_public.test.ts @@ -1,17 +1,23 @@ import { Fr } from '@aztec/aztec.js/fields'; import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; -import { NO_L1_TO_L2_MSG_ERROR } from '../fixtures/fixtures.js'; +import { jest } from '@jest/globals'; + +import { NO_L1_TO_L2_MSG_ERROR, PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; describe('e2e_cross_chain_messaging token_bridge_public', () => { + // Pipelining slows wall-clock chain progress (12s slots); waitForProven via advanceToEpochProven + // needs more than the default 300s per-test budget. + jest.setTimeout(15 * 60 * 1000); + const t = new CrossChainMessagingTest('token_bridge_public', { startProverNode: true }); let { crossChainTestHarness, ethAccount, aztecNode, logger, ownerAddress, l2Bridge, l2Token, wallet, user2Address } = t; beforeEach(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ crossChainTestHarness, wallet, user2Address } = t); @@ -93,7 +99,7 @@ describe('e2e_cross_chain_messaging token_bridge_public', () => { l2ToL1MessageResult.siblingPath, ); expect(await crossChainTestHarness.getL1BalanceOf(ethAccount)).toBe(l1TokenBalance - bridgeAmount + withdrawAmount); - }, 120_000); + }, 900_000); it('Someone else can mint funds to me on my behalf (publicly)', async () => { const l1TokenBalance = 1000000n; diff --git a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts index 1fd23d78063f..5c78970eae43 100644 --- a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts +++ b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts @@ -6,14 +6,16 @@ import { ClaimContract } from '@aztec/noir-contracts.js/Claim'; import { CrowdfundingContract } from '@aztec/noir-contracts.js/Crowdfunding'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; -jest.setTimeout(200_000); +jest.setTimeout(400_000); // Tests crowdfunding via the Crowdfunding contract and claiming the reward token via the Claim contract describe('e2e_crowdfunding_and_claim', () => { @@ -46,6 +48,7 @@ describe('e2e_crowdfunding_and_claim', () => { let crowdfundingSecretKey: Fr; let crowdfundingPublicKeys: PublicKeys; let cheatCodes: CheatCodes; + let _aztecNode: AztecNode & AztecNodeDebug; let deadline: number; // end of crowdfunding period let uintNote!: any; @@ -56,8 +59,9 @@ describe('e2e_crowdfunding_and_claim', () => { teardown, logger, wallet, + aztecNode: _aztecNode, accounts: [operatorAddress, donor1Address, donor2Address], - } = await setup(3)); + } = await setup(3, { ...AUTOMINE_E2E_OPTS })); // We set the deadline to a week from now deadline = (await cheatCodes.eth.lastBlockTimestamp()) + 7 * 24 * 60 * 60; @@ -309,8 +313,12 @@ describe('e2e_crowdfunding_and_claim', () => { ); const witness = await wallet.createAuthWit(donor2Address, { caller: crowdfundingContract.address, action }); - // 2) We set next block timestamp to be after the deadline - await cheatCodes.eth.warp(deadline + 1); + // 2) We warp L1 past the deadline. We don't mine an L2 block here: the deadline is set 7 + // days in the future during setup, and warping that far before mining would cause the + // archiver to predict-reorg every prior checkpoint (their L1 publish blocks fall in a stale + // anvil layout after the warp). The next donate tx is rejected by the contract because the + // next L2 block's timestamp is already past the deadline. + await cheatCodes.eth.warp(Number(deadline + 1), { resetBlockInterval: true }); // 3) We donate to the crowdfunding contract await expect( diff --git a/yarn-project/end-to-end/src/e2e_custom_message.test.ts b/yarn-project/end-to-end/src/e2e_custom_message.test.ts index 0ff387019d2e..34fa17f1c901 100644 --- a/yarn-project/end-to-end/src/e2e_custom_message.test.ts +++ b/yarn-project/end-to-end/src/e2e_custom_message.test.ts @@ -7,9 +7,10 @@ import { CustomMessageContract, type MultiLogEvent } from '@aztec/noir-test-cont import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('CustomMessage - Multi-Log Pattern', () => { let contract: CustomMessageContract; @@ -24,7 +25,7 @@ describe('CustomMessage - Multi-Log Pattern', () => { teardown, wallet, accounts: [account], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); await ensureAccountContractsPublished(wallet, [account]); ({ contract } = await CustomMessageContract.deploy(wallet).send({ from: account })); }); diff --git a/yarn-project/end-to-end/src/e2e_debug_trace.test.ts b/yarn-project/end-to-end/src/e2e_debug_trace.test.ts index 71f950086660..c79e42e6f1cd 100644 --- a/yarn-project/end-to-end/src/e2e_debug_trace.test.ts +++ b/yarn-project/end-to-end/src/e2e_debug_trace.test.ts @@ -52,6 +52,11 @@ describe('e2e_debug_trace_transaction', () => { maxSpeedUpAttempts: 0, // Disable speed ups, so that cancellation txs never make it through minTxsPerBlock: 0, coinbase: coinbase, + enableProposerPipelining: true, + aztecSlotDuration: 12, + ethereumSlotDuration: 4, + aztecProofSubmissionEpochs: 640, + inboxLag: 2, })); sequencer = sequencerClient! as TestSequencerClient; publisherManager = sequencer.publisherManager; @@ -122,7 +127,7 @@ describe('e2e_debug_trace_transaction', () => { // We now want to set the sequencer config to allow blocks with 0 transactions // Wait until we have successfully moved forward by a few blocks - const numBlocksToMine = 3; + const numBlocksToMine = 2; const startBlockNumber = await aztecNode.getBlockNumber(); await aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); const result = await retryUntil( @@ -131,7 +136,7 @@ describe('e2e_debug_trace_transaction', () => { return blockNumber >= startBlockNumber + numBlocksToMine; }, 'block number check', - 30, + 60, 1, ); expect(result).toBeTrue(); @@ -249,7 +254,7 @@ describe('e2e_debug_trace_transaction', () => { return blockNumber >= startBlockNumber + numBlocksToMine; }, 'block number check', - 30, + 60, 1, ); expect(result).toBeTrue(); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts index cb0a5b7cb54b..71344027a78d 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts @@ -12,16 +12,23 @@ import type { Logger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; import { TxExecutionResult, type TxReceipt } from '@aztec/aztec.js/tx'; import type { Wallet } from '@aztec/aztec.js/wallet'; +import type { BlockNumber } from '@aztec/foundation/branded-types'; import { writeTestData } from '@aztec/foundation/testing/files'; import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import type { ContractClassIdPreimage } from '@aztec/stdlib/contract'; import { PublicKeys } from '@aztec/stdlib/keys'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { jest } from '@jest/globals'; + +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { DeployTest, type StatefulContractCtorArgs } from './deploy_test.js'; describe('e2e_deploy_contract contract class registration', () => { + // Pipelined cadence (~24s/dependent-tx) inflates the chained deploy/publish setup beyond the default 5 min + // hook window. Many of the publishInstance helpers serially register multiple contracts/instances per case. + jest.setTimeout(900_000); + const t = new DeployTest('contract class'); let logger: Logger; @@ -34,7 +41,7 @@ describe('e2e_deploy_contract contract class registration', () => { let publicationTxReceipt: TxReceipt; beforeAll(async () => { - ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup()); + ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup({ ...AUTOMINE_E2E_OPTS })); artifact = StatefulTestContract.artifact; publicationTxReceipt = await publishContractClass(wallet, artifact).then(c => c.send({ from: defaultAccountAddress }).then(({ receipt }) => receipt), @@ -72,7 +79,10 @@ describe('e2e_deploy_contract contract class registration', () => { }); }); - const testDeployingAnInstance = (how: string, deployFn: (toDeploy: ContractInstanceWithAddress) => Promise) => + const testDeployingAnInstance = ( + how: string, + deployFn: (toDeploy: ContractInstanceWithAddress) => Promise, + ) => describe(`deploying a contract instance ${how}`, () => { let instance: ContractInstanceWithAddress; let initArgs: StatefulContractCtorArgs; @@ -91,7 +101,7 @@ describe('e2e_deploy_contract contract class registration', () => { }); const { address, currentContractClassId: contractClassId } = instance; logger.info(`Deploying contract instance at ${address.toString()} class id ${contractClassId.toString()}`); - await deployFn(instance); + const publishBlockNumber = await deployFn(instance); // TODO(@spalladino) We should **not** need the whole instance, including initArgs and salt, // in order to interact with a public function for the contract. We may even not need @@ -111,21 +121,25 @@ describe('e2e_deploy_contract contract class registration', () => { }); expect(registered.address).toEqual(instance.address); const contract = StatefulTestContract.at(instance.address, wallet); - return { contract, initArgs, instance, publicKeys }; + return { contract, initArgs, instance, publicKeys, publishBlockNumber }; }; describe('using a private constructor', () => { + let publishBlockNumber: BlockNumber; beforeAll(async () => { - ({ instance, initArgs, contract } = await publishInstance()); + const result = await publishInstance(); + ({ instance, initArgs, contract } = result); + publishBlockNumber = result.publishBlockNumber; }); it('stores contract instance in the aztec node', async () => { - // Contract instance deployed event is emitted via private logs. - const blockNumber = await aztecNode.getBlockNumber(); - - const logs = (await aztecNode.getBlock(blockNumber, { includeTransactions: true }))!.body.txEffects.flatMap( - t => t.privateLogs, - ); + // Contract instance deployed event is emitted via private logs. Read the block carrying + // the publish tx directly — under pipelining the "latest" block at this point may be an + // empty pipelined block, and the publish tx's receipt blockNumber is the authoritative + // anchor. + const logs = (await aztecNode.getBlock(publishBlockNumber, { + includeTransactions: true, + }))!.body.txEffects.flatMap(t => t.privateLogs); expect(logs.length).toBe(1); @@ -142,6 +156,7 @@ describe('e2e_deploy_contract contract class registration', () => { expect(deployed!.address).toEqual(instance.address); expect(deployed!.currentContractClassId).toEqual(contractClass.id); expect(deployed!.initializationHash).toEqual(instance.initializationHash); + expect(deployed!.immutablesHash).toEqual(instance.immutablesHash); expect(deployed!.publicKeys).toEqual(instance.publicKeys); expect(deployed!.salt).toEqual(instance.salt); expect(deployed!.deployer).toEqual(instance.deployer); @@ -161,7 +176,7 @@ describe('e2e_deploy_contract contract class registration', () => { const { receipt } = await contract.methods .increment_public_value(whom, 10) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); - expect(receipt.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); + expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); // Meanwhile we check we didn't increment the value expect( @@ -205,7 +220,7 @@ describe('e2e_deploy_contract contract class registration', () => { const { receipt } = await contract.methods .public_constructor(whom, 43) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); - expect(receipt.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); + expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); expect( (await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress })).result, ).toEqual(0n); @@ -232,7 +247,8 @@ describe('e2e_deploy_contract contract class registration', () => { testDeployingAnInstance('from a wallet', async instance => { // Calls the deployer contract directly from a wallet const deployMethod = publishInstance(wallet, instance); - await deployMethod.send({ from: defaultAccountAddress }); + const { receipt } = await deployMethod.send({ from: defaultAccountAddress }); + return receipt.blockNumber!; }); testDeployingAnInstance('from a contract', async instance => { @@ -240,7 +256,10 @@ describe('e2e_deploy_contract contract class registration', () => { await wallet.registerContract(instance, artifact); // Set up the contract that calls the deployer (which happens to be the TestContract) and call it const { contract: deployer } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); - await deployer.methods.publish_contract_instance(instance.address).send({ from: defaultAccountAddress }); + const { receipt } = await deployer.methods + .publish_contract_instance(instance.address) + .send({ from: defaultAccountAddress }); + return receipt.blockNumber!; }); describe('error scenarios in deployment', () => { @@ -256,7 +275,7 @@ describe('e2e_deploy_contract contract class registration', () => { const { receipt: tx } = await instance.methods .increment_public_value_no_init_check(whom, 10) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); - expect(tx.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); + expect(tx.executionResult).toEqual(TxExecutionResult.REVERTED); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts index 4bdf1e9fc248..e9799ed57b7d 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts @@ -11,6 +11,7 @@ import { NoConstructorContract } from '@aztec/noir-test-contracts.js/NoConstruct import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import { GasFees } from '@aztec/stdlib/gas'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { TestWallet } from '../test-wallet/test_wallet.js'; import { DeployTest } from './deploy_test.js'; @@ -23,7 +24,7 @@ describe('e2e_deploy_contract deploy method', () => { let defaultAccountAddress: AztecAddress; beforeAll(async () => { - ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup()); + ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup({ ...AUTOMINE_E2E_OPTS })); }); afterAll(() => t.teardown()); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts index 79c6ecce5c05..aeaf3da2d6fe 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts @@ -9,7 +9,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import type { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; -import { type EndToEndContext, deployAccounts, setup, teardown } from '../fixtures/setup.js'; +import { type EndToEndContext, type SetupOptions, deployAccounts, setup, teardown } from '../fixtures/setup.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; export class DeployTest { @@ -24,9 +24,10 @@ export class DeployTest { this.logger = createLogger(`e2e:e2e_deploy_contract:${testName}`); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up test environment'); this.context = await setup(0, { + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, }); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts index a4d1c1e0748d..17998c08d374 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts @@ -9,6 +9,7 @@ import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest import { TestContractArtifact } from '@aztec/noir-test-contracts.js/Test'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { DeployTest } from './deploy_test.js'; @@ -20,7 +21,7 @@ describe('e2e_deploy_contract legacy', () => { let defaultAccountAddress: AztecAddress; beforeAll(async () => { - ({ logger, wallet, defaultAccountAddress } = await t.setup()); + ({ logger, wallet, defaultAccountAddress } = await t.setup({ ...AUTOMINE_E2E_OPTS })); }); afterAll(() => t.teardown()); @@ -122,7 +123,7 @@ describe('e2e_deploy_contract legacy', () => { expect(goodTxReceipt!.blockNumber).toEqual(expect.any(Number)); expect(badTxReceipt!.blockNumber).toEqual(expect.any(Number)); - expect(badTxReceipt!.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); + expect(badTxReceipt!.executionResult).toEqual(TxExecutionResult.REVERTED); const badInstance = await badDeploy.getInstance(); // But the bad tx did not deploy the class diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts index 33d63164a9c1..9fbbbbd36598 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts @@ -11,6 +11,7 @@ import { PrivateInitTestContract } from '@aztec/noir-test-contracts.js/PrivateIn import { siloNullifier } from '@aztec/stdlib/hash'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { DeployTest } from './deploy_test.js'; @@ -25,7 +26,7 @@ describe('e2e_deploy_contract private initialization', () => { let aztecNode: AztecNode; beforeAll(async () => { - ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup()); + ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup({ ...AUTOMINE_E2E_OPTS })); await publishContractClass(wallet, InitTestContract.artifact).then(c => c.send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_double_spend.test.ts b/yarn-project/end-to-end/src/e2e_double_spend.test.ts index 3cc69dec717d..94bb2ec72f7d 100644 --- a/yarn-project/end-to-end/src/e2e_double_spend.test.ts +++ b/yarn-project/end-to-end/src/e2e_double_spend.test.ts @@ -5,6 +5,7 @@ import { TxExecutionResult } from '@aztec/aztec.js/tx'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_double_spend', () => { @@ -23,7 +24,7 @@ describe('e2e_double_spend', () => { wallet, accounts: [defaultAccountAddress], logger, - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); @@ -46,7 +47,7 @@ describe('e2e_double_spend', () => { // tx will be included in a block but with app logic reverted await expect( contract.methods.emit_nullifier_public(nullifier).send({ from: defaultAccountAddress }), - ).rejects.toThrow(TxExecutionResult.APP_LOGIC_REVERTED); + ).rejects.toThrow(TxExecutionResult.REVERTED); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_equivocation.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_equivocation.test.ts index a72862c14d1d..080431c3549b 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_equivocation.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_equivocation.test.ts @@ -10,6 +10,7 @@ import { retryUntil } from '@aztec/foundation/retry'; import { bufferToHex } from '@aztec/foundation/string'; import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { tryStop } from '@aztec/stdlib/interfaces/server'; +import { OffenseType } from '@aztec/stdlib/slashing'; import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; @@ -58,6 +59,7 @@ describe('e2e_epochs/epochs_equivocation', () => { // - checkpointFinalization = 0.5s (assemble) + 0 (p2p in test) + 2s (L1 publish) = 2.5s // - finalBlockDuration = 8s (re-execution) // - Total: 0.5 + 24 + 8 + 2.5 = 35s => use 36s + const slashingUnit = BigInt(1e14); test = await EpochsTestContext.setup({ numberOfAccounts: 0, initialValidators: validators, @@ -76,6 +78,28 @@ describe('e2e_epochs/epochs_equivocation', () => { l1PublishingTime: 2, aztecTargetCommitteeSize: 4, skipInitialSequencer: true, + // Enable the slasher so we can assert the equivocating proposer is detected for slashing. + // Round size is aztecEpochDuration * slashingRoundSizeInEpochs = 4 slots; the L1 contract + // requires QUORUM > ROUND_SIZE / 2, so quorum must be at least 3. + slasherEnabled: true, + slashingQuorum: 3, + slashingRoundSizeInEpochs: 1, + slashingOffsetInRounds: 1, + slashAmountSmall: slashingUnit, + slashAmountMedium: slashingUnit * 2n, + slashAmountLarge: slashingUnit * 3n, + slashSelfAllowed: true, + slashDuplicateProposalPenalty: slashingUnit, + // Disable other offense penalties so we only see the equivocation offense. + slashInactivityPenalty: 0n, + slashDataWithholdingPenalty: 0n, + slashBroadcastedInvalidBlockPenalty: 0n, + slashBroadcastedInvalidCheckpointProposalPenalty: 0n, + slashDuplicateAttestationPenalty: 0n, + slashProposeInvalidAttestationsPenalty: 0n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 0n, + slashAttestInvalidCheckpointProposalPenalty: 0n, + slashUnknownPenalty: 0n, }); logger = test.logger; @@ -271,9 +295,26 @@ describe('e2e_epochs/epochs_equivocation', () => { ), ); - // TODO(A-980): assert the equivocating proposer of the first slot is eventually slashed - // for the DUPLICATE_PROPOSAL offense. Slasher is currently disabled in the harness - // (slasherEnabled: false) and enabling it requires plumbing offense submission and - // waiting for the slasher's offense window. + // Every observing validator should have recorded the equivocation offense. A has been stopped + // above and D is a non-validator (no slasher), so we poll only B and C. + logger.warn(`Waiting for DUPLICATE_PROPOSAL offense on every observing node`, { + proposerAttester, + submissionSlot, + }); + const matchesOffense = (o: { offenseType: OffenseType; validator: { toString(): string }; epochOrSlot: bigint }) => + o.offenseType === OffenseType.DUPLICATE_PROPOSAL && + o.validator.toString() === proposerAttester.toString() && + o.epochOrSlot === BigInt(submissionSlot); + await retryUntil( + async () => { + const found = await Promise.all( + [nodeB, nodeC].map(async n => (await n.getSlashOffenses('all')).some(matchesOffense)), + ); + return found.every(Boolean); + }, + `DUPLICATE_PROPOSAL offense on every observing node`, + test.L2_SLOT_DURATION_IN_S * 4, + 0.5, + ); }); }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts index 1f952fd76ef6..431632c757b2 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts @@ -378,12 +378,19 @@ describe('e2e_epochs/epochs_invalidate_block', () => { // Wait for at least one checkpoint to be mined so that any in-progress slot has completed const initialCheckpointNumber = (await nodes[0].getChainTips()).checkpointed.checkpoint.number; await test.waitUntilCheckpointNumber(CheckpointNumber(initialCheckpointNumber + 1), test.L2_SLOT_DURATION_IN_S * 4); + + // Align to the start of an L2 slot before computing the bad slots, so we have a generous + // buffer to push the malicious config to badSlot1's proposer before it snapshots its config + // into a new CheckpointProposalJob. Under proposer pipelining, that job is built during the + // last L1 slot of the previous L2 slot (when getEpochAndSlotInNextL1Slot first returns the + // proposer's target slot), so the practical window is somewhat less than a full L2 slot. + await test.monitor.waitUntilNextL2Slot(); const { l2SlotNumber: currentSlot } = await test.monitor.run(); logger.warn(`First checkpoint mined, current slot is ${currentSlot}`); - // Pick the next two slots after the current one, with a 1-slot gap to account for pipelining - const badSlot1 = SlotNumber.add(currentSlot, 2); - const badSlot2 = SlotNumber.add(currentSlot, 3); + // Pick the next two slots with a 2-slot gap to account for pipelining plus a margin + const badSlot1 = SlotNumber.add(currentSlot, 3); + const badSlot2 = SlotNumber.add(currentSlot, 4); const badSlots = [badSlot1, badSlot2]; const badProposers = await Promise.all(badSlots.map(s => test.epochCache.getProposerAttesterAddressInSlot(s))); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts index a59b47b78071..18af37d8d167 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts @@ -314,7 +314,9 @@ describe('e2e_epochs/epochs_mbps', () => { 0.1, ); - const multiBlockCheckpoint = await assertMultipleBlocksPerSlot(EXPECTED_BLOCKS_PER_CHECKPOINT, logger); + // Mirror the sibling MBPS tests: we may lose one sub-slot to pipelined overhead, so accept >= 2 + // blocks per checkpoint rather than the legacy 3-block expectation. + const multiBlockCheckpoint = await assertMultipleBlocksPerSlot(2, logger); // Verify L2→L1 messages are in the blocks const checkpoints = await archiver.getCheckpoints({ from: CheckpointNumber(1), limit: 50 }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_missed_l1_slot.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_missed_l1_slot.test.ts index 0c32eaab5353..eda99eef06c3 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_missed_l1_slot.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_missed_l1_slot.test.ts @@ -234,9 +234,13 @@ describe('e2e_epochs/epochs_missed_l1_slot', () => { await eth.setIntervalMining(L1_BLOCK_TIME); // Step 5: Wait for the next checkpoint to confirm block production resumed cleanly. + // We allow up to 3 L2 slots because the slot-N+1 propose for this checkpoint is dropped + // pre-send by bundleSimulate (the resumed L1 block lands in slot N, not slot N+1, so + // propose's validateHeader would revert), and the publisher retries one or two slots + // later once L1 timing realigns. const finalCheckpoint = CheckpointNumber(checkpointEvent.checkpointNumber + 1); logger.info(`Waiting for checkpoint ${finalCheckpoint}...`); - await test.waitUntilCheckpointNumber(finalCheckpoint, 60); + await test.waitUntilCheckpointNumber(finalCheckpoint, L2_SLOT_DURATION * 3); await monitor.run(); logger.info(`Checkpoint ${finalCheckpoint} published in slot ${monitor.l2SlotNumber}`); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts index 9ae7af5040f8..eaf403de188c 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts @@ -172,7 +172,8 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { // Tighter happy-path bound: the proof must land BEFORE the boundary slot's pipelined build kicks // off. With pipelining, the boundary slot's build starts at the start of the previous L2 slot // (i.e. boundaryTs - L2_SLOT_DURATION_IN_S). If the proof's L1 block is strictly earlier than - // that, the build at the boundary observes `tips.proven` already advanced and skips the override. + // that, the build at the boundary observes `tips.proven` already advanced so the proven pin is + // defensive only (no prune is due) and the boundary checkpoint publishes on the happy path. const assertProofMinedBeforeBoundaryBuild = async (proofReceipt: { blockNumber: bigint }, boundaryTs: bigint) => { const proofBlock = await test.l1Client.getBlock({ blockNumber: proofReceipt.blockNumber }); expect(proofBlock.timestamp).toBeLessThan(boundaryTs - BigInt(test.L2_SLOT_DURATION_IN_S)); @@ -201,8 +202,8 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { it('proof lands during slot build and checkpoint succeeds at boundary', async () => { // The proof for the unproven epoch lands AFTER the boundary slot's pipelined build starts but - // BEFORE the publisher's preCheck. The proven-override lets the boundary checkpoint build - // before the proof has landed; the preCheck succeeds because the proof arrives in time. + // BEFORE the publisher's preCheck. The proven pin lets the boundary checkpoint build before + // the proof has landed; the preCheck succeeds because the proof arrives in time. await setupTest({ aztecProofSubmissionEpochs: 1 }); const sequencers = nodes.map(node => node.getSequencer()!); @@ -238,17 +239,16 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { expect(boundaryPublished).toBeDefined(); const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); - expect(boundaryPreparing.some(p => p.provenOverride !== undefined)).toBe(true); expect(boundaryPreparing.some(p => p.hadProposedParent)).toBe(true); expect(Number(test.monitor.checkpointNumber)).toBeGreaterThanOrEqual(Number(boundaryPublished!.checkpoint)); logger.warn(`Test passed. Final tip checkpoint=${test.monitor.checkpointNumber}`); }); - it('proof lands well before deadline and checkpoint succeeds without override', async () => { + it('proof lands well before deadline and checkpoint succeeds at boundary', async () => { // Sanity check: the prover runs on its natural schedule, so the proof lands well before the - // boundary epoch. By the time the boundary slot is built `tips.proven` is already advanced, - // `isPruneDueAtSlot` returns false, and the proven-override does not fire. + // boundary epoch. By the time the boundary slot is built `tips.proven` is already advanced + // and the proven pin is defensive only — but the boundary checkpoint must still publish. await setupTest({ aztecProofSubmissionEpochs: 1 }); const sequencers = nodes.map(node => node.getSequencer()!); @@ -272,15 +272,14 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); expect(boundaryPreparing.some(p => p.hadProposedParent)).toBe(true); - expect(boundaryPreparing.every(p => p.provenOverride === undefined)).toBe(true); expect(Number(test.monitor.checkpointNumber)).toBeGreaterThanOrEqual(Number(boundaryPublished!.checkpoint)); }); it('proof never lands so no checkpoint submission is attempted', async () => { - // The boundary slot's build applies the proven-override, but the publisher's preCheck rejects - // the propose tx because the proof never landed. After the prune fires on a later slot, a - // fresh propose advances the chain and a checkpoint is published in the new epoch. + // The boundary slot's build applies the proven pin, but the publisher's preCheck rejects the + // propose tx because the proof never landed. After the prune fires on a later slot, a fresh + // propose advances the chain and a checkpoint is published in the new epoch. await setupTest({ aztecProofSubmissionEpochs: 1 }); const sequencers = nodes.map(node => node.getSequencer()!); @@ -300,7 +299,6 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); expect(boundaryPreparing.some(p => p.hadProposedParent)).toBe(true); - expect(boundaryPreparing.some(p => p.provenOverride !== undefined)).toBe(true); // After the boundary fails, a subsequent slot's propose tx triggers the on-chain prune (since // the proof never landed and the deadline has expired) and resets `tips.pending`. The fresh @@ -314,7 +312,7 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { it('proof lands without a proposed parent and boundary checkpoint succeeds', async () => { // The slot before the boundary is paused so the boundary slot's build does not see a proposed - // parent. The proof still lands well before the deadline, so the proven-override never fires + // parent. The proof still lands well before the deadline, so the proven pin is defensive only // and the boundary checkpoint is published normally. await setupTest({ aztecProofSubmissionEpochs: 1 }); @@ -345,14 +343,13 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); expect(boundaryPreparing.length).toBeGreaterThan(0); expect(boundaryPreparing.every(p => !p.hadProposedParent)).toBe(true); - expect(boundaryPreparing.every(p => p.provenOverride === undefined)).toBe(true); expect(Number(test.monitor.checkpointNumber)).toBeGreaterThanOrEqual(Number(boundaryPublished!.checkpoint)); }); it('proof never lands without a proposed parent so no checkpoint submission is attempted', async () => { - // Same as the no-parent variant above but with the proof never landing. The proven-override - // fires (no parent + prune is due) but the publisher's preCheck rejects the propose, so no + // Same as the no-parent variant above but with the proof never landing. The proven pin fires + // (no parent + prune is due) but the publisher's preCheck rejects the propose, so no // checkpoint is published for the boundary slot. await setupTest({ aztecProofSubmissionEpochs: 1 }); @@ -378,7 +375,6 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); expect(boundaryPreparing.length).toBeGreaterThan(0); expect(boundaryPreparing.every(p => !p.hadProposedParent)).toBe(true); - expect(boundaryPreparing.some(p => p.provenOverride !== undefined)).toBe(true); // See the parent test for the reasoning: a subsequent slot's propose triggers the on-chain // prune in-tx, so the first post-boundary checkpoint lands within a couple of slots. diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts index 0d9b27000373..33743e47394e 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts @@ -98,7 +98,7 @@ describe('e2e_epochs/epochs_proof_public_cross_chain', () => { globalLeafIndex.toBigInt(), ) .send({ from: context.accounts[0], wait: { dontThrowOnRevert: true } }); - expect(failedReceipt.executionResult).toBe(TxExecutionResult.APP_LOGIC_REVERTED); + expect(failedReceipt.executionResult).toBe(TxExecutionResult.REVERTED); logger.info(`Test succeeded`); }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts index d6d6905b6c61..1f2c8e1d4654 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts @@ -517,6 +517,7 @@ export class EpochsTestContext { 'proposer-rollup-check-failed', 'checkpoint-error', 'checkpoint-publish-failed', + 'header-validation-failed', 'pipelined-checkpoint-discarded', ...additionalFailEventKeys, ]; @@ -548,6 +549,13 @@ export class EpochsTestContext { }); failEventsKeys.forEach(eventName => { sequencer.getSequencer().on(eventName, (args: Parameters[0]) => { + // Skip benign block-build-failed events where the builder rejected the block because it + // could not collect enough valid txs. This is the same "not enough txs" case as + // block-tx-count-check-failed (which is already excluded above), just detected after we + // started processing txs rather than before. + if (eventName === 'block-build-failed' && (args as { reason?: string }).reason === 'Insufficient valid txs') { + return; + } const evt = makeEvent(i, eventName, args); failEvents.push(evt); this.logger.error(`Failed event ${eventName} from sequencer ${sequencerIndex}`, undefined, evt); diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index 4763abf825e0..6f6c33012a27 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -7,6 +7,7 @@ import { EscrowContract } from '@aztec/noir-contracts.js/Escrow'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import type { PublicKeys } from '@aztec/stdlib/keys'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { expectTokenBalance, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -32,7 +33,7 @@ describe('e2e_escrow_contract', () => { wallet, accounts: [owner, recipient], logger, - } = await setup(2)); + } = await setup(2, { ...AUTOMINE_E2E_OPTS })); // Generate private key for escrow contract, register key in PXE, and deploy // Note that we need to register it first if we want to emit an encrypted note for it in the constructor diff --git a/yarn-project/end-to-end/src/e2e_event_logs.test.ts b/yarn-project/end-to-end/src/e2e_event_logs.test.ts index 63f083e07d67..eada81d5429d 100644 --- a/yarn-project/end-to-end/src/e2e_event_logs.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_logs.test.ts @@ -17,9 +17,10 @@ import { import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('Logs', () => { let testLogContract: TestLogContract; @@ -41,7 +42,7 @@ describe('Logs', () => { accounts: [account1Address, account2Address], aztecNode, logger: log, - } = await setup(2)); + } = await setup(2, { ...AUTOMINE_E2E_OPTS })); log.warn(`Setup complete, checking account contracts published`); await ensureAccountContractsPublished(wallet, [account1Address, account2Address]); diff --git a/yarn-project/end-to-end/src/e2e_event_only.test.ts b/yarn-project/end-to-end/src/e2e_event_only.test.ts index d2b036f601a0..dda2710f7d06 100644 --- a/yarn-project/end-to-end/src/e2e_event_only.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_only.test.ts @@ -6,9 +6,10 @@ import { EventOnlyContract, type TestEvent } from '@aztec/noir-test-contracts.js import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; /// Tests that a private event can be obtained for a contract that does not work with notes. describe('EventOnly', () => { @@ -24,7 +25,7 @@ describe('EventOnly', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); await ensureAccountContractsPublished(wallet, [defaultAccountAddress]); ({ contract: eventOnlyContract } = await EventOnlyContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts b/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts index 7f8700cd7d5a..69ca90026ab2 100644 --- a/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts +++ b/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts @@ -1,9 +1,11 @@ import { AztecAddress } from '@aztec/aztec.js/addresses'; -import type { AztecNode } from '@aztec/aztec.js/node'; +import type { CheatCodes } from '@aztec/aztec/testing'; import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import { TX_ERROR_INVALID_EXPIRATION_TIMESTAMP } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -11,7 +13,8 @@ import { proveInteraction } from './test-wallet/utils.js'; describe('e2e_expiration_timestamp', () => { let wallet: TestWallet; let defaultAccountAddress: AztecAddress; - let aztecNode: AztecNode; + let aztecNode: AztecNode & AztecNodeDebug; + let cheatCodes: CheatCodes; let teardown: () => Promise; let contract: TestContract; @@ -23,8 +26,9 @@ describe('e2e_expiration_timestamp', () => { teardown, wallet, aztecNode, + cheatCodes, accounts: [defaultAccountAddress], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); @@ -38,8 +42,10 @@ describe('e2e_expiration_timestamp', () => { if (!header) { throw new Error('Block header not found in the setup of e2e_expiration_timestamp.test.ts'); } - // The timestamp of the next slot. - expirationTimestamp = header.globalVariables.timestamp + aztecSlotDuration; + // Two slots ahead of the latest mined block — gives enough headroom that the expiration + // is safely above the next block's timestamp even if there's a brief delay between + // fetching the header and proving the tx. + expirationTimestamp = header.globalVariables.timestamp + aztecSlotDuration * 2n; }); describe('with no enqueued public calls', () => { @@ -91,7 +97,10 @@ describe('e2e_expiration_timestamp', () => { if (!header) { throw new Error('Block header not found in the setup of e2e_expiration_timestamp.test.ts'); } - // 1n lower than the next slot. + // 1n below the start of the next slot (header.timestamp + slotDuration). Under + // AutomineSequencer the next block is always one slot ahead, so an expiration just + // before that boundary is provable (expiration > anchor block timestamp) but rejected + // at submission because nextSlotTimestamp >= expiration. expirationTimestamp = header.globalVariables.timestamp + aztecSlotDuration - 1n; }); @@ -108,11 +117,7 @@ describe('e2e_expiration_timestamp', () => { }); it('invalidates the transaction', async () => { - await expect( - contract.methods - .set_expiration_timestamp(expirationTimestamp, enqueuePublicCall) - .send({ from: defaultAccountAddress }), - ).rejects.toThrow(TX_ERROR_INVALID_EXPIRATION_TIMESTAMP); + await runInvalidatesTest(enqueuePublicCall); }); }); @@ -129,13 +134,46 @@ describe('e2e_expiration_timestamp', () => { }); it('invalidates the transaction', async () => { - await expect( - contract.methods - .set_expiration_timestamp(expirationTimestamp, enqueuePublicCall) - .send({ from: defaultAccountAddress }), - ).rejects.toThrow(TX_ERROR_INVALID_EXPIRATION_TIMESTAMP); + await runInvalidatesTest(enqueuePublicCall); }); }); + + // Prove a tx with an expiration a few slots above the latest mined block's timestamp (so it passes + // the PXE's prove-time check that requires `expirationTimestamp > anchor block timestamp`), then + // warp L1 time past the expiration. Submitting the proven tx must then be rejected by the node + // because the next slot's timestamp (derived from L1 time) is greater than the tx expiration. + async function runInvalidatesTest(enqueuePublicCall: boolean) { + const header = (await aztecNode.getBlockData('latest'))?.header; + if (!header) { + throw new Error('Block header not found in invalidates-the-transaction setup'); + } + const requestedExpiration = header.globalVariables.timestamp + aztecSlotDuration * 5n; + + const provenTx = await proveInteraction( + wallet, + contract.methods.set_expiration_timestamp(requestedExpiration, enqueuePublicCall), + { from: defaultAccountAddress }, + ); + const provedExpiration = provenTx.data.expirationTimestamp; + expect(provedExpiration).toBeGreaterThan(0n); + + // Warp L1 time past the tx expiration. The node's `isValidTx` uses the next L1 slot timestamp + // (via `epochCache.getEpochAndSlotInNextL1Slot()`), so warping L1 alone is enough — we don't + // mine an L2 block here. Warping multiple slots forward and then mining would cause the + // archiver to predict-reorg prior checkpoints (their L1 publish blocks fall in a stale + // anvil layout after the warp). We use the lower-level `cheatCodes.eth.warp` rather than + // the queue-aware `warpL2TimeAtLeastTo` helper, since the latter also forces an L2 block. + // No mempool poller race here — no txs are pending until `provenTx.send()` below. + // If L1 time has already advanced past the expiration (e.g. due to a prior test's warp), skip + // the warp — the tx is already invalid against the current L1 slot. + const currentL1Timestamp = BigInt(await cheatCodes.eth.lastBlockTimestamp()); + const targetTimestamp = provedExpiration + aztecSlotDuration; + if (targetTimestamp > currentL1Timestamp) { + await cheatCodes.eth.warp(Number(targetTimestamp), { resetBlockInterval: true }); + } + + await expect(provenTx.send()).rejects.toThrow(TX_ERROR_INVALID_EXPIRATION_TIMESTAMP); + } }); describe('when requesting expiration timestamp lower than the one of a mined block', () => { diff --git a/yarn-project/end-to-end/src/e2e_fee_asset_price_oracle.test.ts b/yarn-project/end-to-end/src/e2e_fee_asset_price_oracle.test.ts index b898b1f3c5f0..a59840840152 100644 --- a/yarn-project/end-to-end/src/e2e_fee_asset_price_oracle.test.ts +++ b/yarn-project/end-to-end/src/e2e_fee_asset_price_oracle.test.ts @@ -10,12 +10,12 @@ import { jest } from '@jest/globals'; import { mnemonicToAccount } from 'viem/accounts'; import { foundry } from 'viem/chains'; -import { MNEMONIC } from './fixtures/fixtures.js'; +import { MNEMONIC, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { getLogger, setup, startAnvil } from './fixtures/utils.js'; import { MockStateView, diffInBps } from './shared/mock_state_view.js'; describe('FeeAssetPriceOracle E2E', () => { - jest.setTimeout(300_000); + jest.setTimeout(15 * 60 * 1000); let logger: Logger; let teardown: () => Promise; @@ -54,7 +54,7 @@ describe('FeeAssetPriceOracle E2E', () => { await ethCheatCodes.mine(10); await ethCheatCodes.mineEmptyBlock(); - const context = await setup(0, { l1ChainId: chain.id, minTxsPerBlock: 0 }, {}, chain); + const context = await setup(0, { ...PIPELINING_SETUP_OPTS, l1ChainId: chain.id }, {}, chain); teardown = context.teardown; const l1Client = context.deployL1ContractsValues.l1Client; diff --git a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts index 29fc20ddd03a..b05bf4ce0edf 100644 --- a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts @@ -17,17 +17,19 @@ import { GasSettings } from '@aztec/stdlib/gas'; import { jest } from '@jest/globals'; -import { getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; +import { PIPELINING_SETUP_OPTS, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { FeesTest } from './fees_test.js'; -jest.setTimeout(300_000); +// FeesTest.setup + applyFundAliceWithBananas + applyFPCSetup chains many dependent txs which run at the +// ~24s/tx pipelined cadence, exceeding the default 5 min hook window. +jest.setTimeout(15 * 60 * 1000); describe('e2e_fees account_init', () => { const t = new FeesTest('account_init', 1); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applyFundAliceWithBananas(); await t.applyFPCSetup(); ({ aliceAddress, wallet, bananaCoin, bananaFPC, logger, aztecNode } = t); diff --git a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts index 554bb03f16ea..13ddaadf0980 100644 --- a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts @@ -14,11 +14,17 @@ import { FunctionCall, FunctionType } from '@aztec/stdlib/abi'; import { Gas, GasSettings } from '@aztec/stdlib/gas'; import { ExecutionPayload } from '@aztec/stdlib/tx'; -import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { expectMapping } from '../fixtures/utils.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees failures', () => { + // FeesTest.setup + applyFPCSetup chains many dependent txs which run at the + // ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(900_000); + let wallet: Wallet; let aliceAddress: AztecAddress; let sequencerAddress: AztecAddress; @@ -31,7 +37,10 @@ describe('e2e_fees failures', () => { const t = new FeesTest('failures', 3, { coinbase }); beforeAll(async () => { - await t.setup(); + // Shorter epochs (default 32 → 4) speed the per-test `advanceToNextEpoch + waitForProven` + // cycle: the prover-node submits a proof as soon as the epoch is complete, so ~8x shorter + // epochs ≈ ~8x faster proof cadence per cycle. Setup itself stays slot-bound. + await t.setup({ ...PIPELINING_SETUP_OPTS, aztecProofSubmissionEpochs: 640, aztecEpochDuration: 4 }); await t.applyFPCSetup(); ({ wallet, aliceAddress, sequencerAddress, bananaCoin, bananaFPC, gasSettings } = t); aztecNode = t.aztecNode; @@ -87,6 +96,7 @@ describe('e2e_fees failures', () => { await t.catchUpProvenChain(); const currentSequencerRewards = await t.getCoinbaseSequencerRewards(); + const provenCheckpointBefore = await t.rollupContract.getProvenCheckpointNumber(); const { receipt: txReceipt } = await bananaCoin.methods .transfer_in_public(aliceAddress, sequencerAddress, outrageousPublicAmountAliceDoesNotHave, 0) @@ -98,7 +108,7 @@ describe('e2e_fees failures', () => { wait: { dontThrowOnRevert: true }, }); - expect(txReceipt.executionResult).toBe(TxExecutionResult.APP_LOGIC_REVERTED); + expect(txReceipt.executionResult).toBe(TxExecutionResult.REVERTED); const { sequencerBlockRewards } = await t.getBlockRewards(); @@ -106,13 +116,27 @@ describe('e2e_fees failures', () => { // epoch and thereby pays out fees at the same time (when proven). await t.context.watcher.trigger(); await t.cheatCodes.rollup.advanceToNextEpoch(); - await t.catchUpProvenChain(); + const provenTimeout = + (t.context.config.aztecProofSubmissionEpochs + 1) * + t.context.config.aztecEpochDuration * + t.context.config.aztecSlotDuration; + await waitForProven(aztecNode, txReceipt, { provenTimeout }); + + // Under pipelining, multiple empty checkpoints can land and prove between the snapshot and waitForProven; + // each one contributes a block reward to the coinbase, so multiply by the actual proven-checkpoint delta. + const provenCheckpointAfter = await t.rollupContract.getProvenCheckpointNumber(); + const newlyProvenCheckpoints = BigInt(provenCheckpointAfter - provenCheckpointBefore); const feeAmount = txReceipt.transactionFee!; - const expectedProverFee = await t.getProverFee(txReceipt.blockNumber!); + const expectedProverFee = await t.getCommittedProverFee(txReceipt.blockNumber!); + const expectedBurn = await t.getCommittedBurn(txReceipt.blockNumber!); const newSequencerRewards = await t.getCoinbaseSequencerRewards(); expect(newSequencerRewards).toEqual( - currentSequencerRewards + sequencerBlockRewards + feeAmount - expectedProverFee, + currentSequencerRewards + + newlyProvenCheckpoints * sequencerBlockRewards + + feeAmount - + expectedBurn - + expectedProverFee, ); // and thus we paid the fee @@ -201,7 +225,7 @@ describe('e2e_fees failures', () => { wait: { dontThrowOnRevert: true }, }); - expect(txReceipt.executionResult).toBe(TxExecutionResult.APP_LOGIC_REVERTED); + expect(txReceipt.executionResult).toBe(TxExecutionResult.REVERTED); const feeAmount = txReceipt.transactionFee!; // and thus we paid the fee @@ -298,7 +322,7 @@ describe('e2e_fees failures', () => { }, wait: { dontThrowOnRevert: true }, }); - expect(receipt.executionResult).toEqual(TxExecutionResult.TEARDOWN_REVERTED); + expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); expect(receipt.transactionFee).toBeGreaterThan(0n); await expectMapping( @@ -346,7 +370,7 @@ describe('e2e_fees failures', () => { wait: { dontThrowOnRevert: true }, }); - expect(receipt.executionResult).toBe(TxExecutionResult.BOTH_REVERTED); + expect(receipt.executionResult).toBe(TxExecutionResult.REVERTED); expect(receipt.transactionFee).toBeGreaterThan(0n); await t.context.watcher.trigger(); diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts index c8ba437bcdcf..df16714a7ce1 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts @@ -6,10 +6,17 @@ import type { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice'; import type { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token'; import type { GasSettings } from '@aztec/stdlib/gas'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees Fee Juice payments', () => { + // FeesTest.setup + applyFundAliceWithBananas chains many dependent txs which run at the + // ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(15 * 60 * 1000); + let aliceAddress: AztecAddress; let wallet: TestWallet; let bobAddress: AztecAddress; @@ -20,7 +27,7 @@ describe('e2e_fees Fee Juice payments', () => { const t = new FeesTest('fee_juice', 1); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applyFundAliceWithBananas(); ({ feeJuiceContract, aliceAddress, wallet, bananaCoin, gasSettings } = t); diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts index 2c025c2cb526..1ec24f5563dc 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts @@ -1,7 +1,7 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import type { AztecNode } from '@aztec/aztec.js/node'; import { CheatCodes } from '@aztec/aztec/testing'; -import type { BlockNumber } from '@aztec/foundation/branded-types'; +import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; import { retryUntil } from '@aztec/foundation/retry'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; @@ -24,7 +24,27 @@ describe('e2e_fees fee settings', () => { let gasSettings: Partial; let testContract: TestContract; let testContractDeployBlock: BlockNumber; - const t = new FeesTest('fee_juice', 1); + + // Run under proposer pipelining. `manaTarget` is set just above the largest setup tx + // (account deploy ~6.5M mana, so manaLimit = 2 * manaTarget = 8M covers it). `walletMinFeePadding: 30` + // matches PR #23150's pipelining-aware default — under pipelining the proposer's fee evolves up to ~20x + // between PXE snapshot and inclusion for setup txs, so the 5x default is no longer sufficient. + // (Test-body txs explicitly call `wallet.setMinFeePadding(...)` so they don't use the wallet default.) + const AZTEC_SLOT_DURATION = 12; + const t = new FeesTest('fee_juice', 1, { + enableProposerPipelining: true, + inboxLag: 2, + minTxsPerBlock: 0, + aztecSlotDuration: AZTEC_SLOT_DURATION, + ethereumSlotDuration: 4, + aztecProofSubmissionEpochs: 640, + walletMinFeePadding: 30, + manaTarget: 4_000_000n, + }); + + // FeesTest.setup chains many dependent txs which run at the pipelined cadence (one per L2 slot); + // the default 300s jest hook timeout is not enough. + jest.setTimeout(600_000); beforeAll(async () => { await t.setup(); @@ -43,21 +63,77 @@ describe('e2e_fees fee settings', () => { }); describe('setting max fee per gas', () => { - const bumpL2Fees = async () => { - const before = await aztecNode.getCurrentMinFees(); - t.logger.info(`Initial L2 min fees are ${inspect(before)}`, { minFees: before.toInspect() }); - await cheatCodes.rollup.bumpProvingCostPerMana(current => (current * 120n) / 100n); + // Drive an organic L2 fee bump via an L1 base-fee spike. On mainnet, L1 base fees fluctuate + // organically with L1 demand and dominate `feePerL2Gas` (the rollup's L1 gas oracle samples + // L1 base fee into `post` at every successful rotation and the L2 manaMinFee is derived from + // it). We simulate that by setting the next L1 block's base fee to a multiple of the current + // one and forcing an oracle rotation via the cheatcode-callable `Rollup.updateL1GasFeeOracle`. + // Unlike `bumpProvingCostPerMana` (the only-owner governance write previously used here), this + // does NOT mutate `FeeStore.config`, so it does not trigger the `Rollup__InvalidManaMinFee` + // recovery race that pipelined proposers hit when governance config mutates between header + // build and L1 submission. + // + // Congestion via heavy L2 txs was considered: each `emit_nullifier_public` is only ~570k mana, + // and at `manaTarget=4M` the sequencer takes ~3 of those per checkpoint (~1.88M mana — well + // below target), so excessMana stays at zero and the congestion-multiplier channel never + // engages. The L1 base-fee channel is both more reliable here and a closer analogue to + // mainnet behaviour (L1 base fee swings happen routinely; sustained L2 congestion is rarer). + // + // `reference` is the snapshot the caller intends to compare against. The retry waits until the + // post-rotation L2 fee is at least 1.3x of `reference` — an earlier version compared `after` + // against an internal `before` captured at function entry and exited as soon as `after > before`, + // but the natural L2 fee fluctuates between L1 blocks (EIP-1559 decay swings the sample), so a + // 1-wei drift above `before` satisfied that condition without the oracle ever rotating. The + // retry returned ~15s in — well before the LIFETIME-LAG=3 slot (36s) oracle deadband opened — + // and the caller's `> reference * 1.1` assertion failed because the returned value was just + // natural noise. Requiring `after >= reference * 13/10` distinguishes a real rotation (≥1.5x + // rise) from ambient noise (≤±10%). + const inflateL2FeesViaL1BaseFee = async (reference: GasFees) => { + const beforeAtCall = await aztecNode.getCurrentMinFees(); + t.logger.info(`Initial L2 min fees are ${inspect(beforeAtCall)} (reference=${inspect(reference)})`, { + minFees: beforeAtCall.toInspect(), + reference: reference.toInspect(), + }); + + const minRiseTarget = (reference.feePerL2Gas * 13n) / 10n; + + // Bump next L1 block base fee above both the current L1 fee and the L1 fee implied by + // the requested L2 fee rise, with a 0.1 gwei absolute floor. The absolute floor + // matters when anvil's natural EIP-1559 decay has driven `currentL1BaseFee` close to zero — + // multiplying tiny numbers stays tiny, so a target below the previous oracle snapshot can + // *decrease* L2 fees. The reference-derived floor matters after an earlier spike has + // already raised the L2 fee baseline: repeating the same absolute L1 base fee can leave + // the derived L2 fee below the required 1.3x rise. The oracle rotation deadband + // (`LIFETIME - LAG = 3` L2 slots between successful rotations, see FeeLib.sol:170) + // silently no-ops `updateL1GasFeeOracle` until the window opens; we retry every second so + // the *first* call after the deadband opens captures our bumped block. + const latestL1Block = await cheatCodes.eth.publicClient.getBlock(); + const currentL1BaseFee = latestL1Block.baseFeePerGas ?? 1_000_000_000n; + const referenceDerivedL1BaseFee = minRiseTarget / 8_000n; + const targetL1BaseFee = [currentL1BaseFee * 2n, 100_000_000n, referenceDerivedL1BaseFee].reduce((a, b) => + a > b ? a : b, + ); + t.logger.info(`Targeting L1 base fee ${targetL1BaseFee} (current ${currentL1BaseFee})`); + return await retryUntil( async () => { + await cheatCodes.eth.setNextBlockBaseFeePerGas(targetL1BaseFee); + await cheatCodes.eth.mine(); + try { + await cheatCodes.rollup.updateL1GasFeeOracle(); + } catch { + // Rotation deadband closed — try again on the next iteration. + } const after = await aztecNode.getCurrentMinFees(); t.logger.info(`L2 min fees are now ${inspect(after)}`, { - minFeesBefore: before.toInspect(), + minFeesBefore: beforeAtCall.toInspect(), minFeesAfter: after.toInspect(), + minRiseTarget: minRiseTarget.toString(), }); - return after.feePerL2Gas > before.feePerL2Gas ? after : undefined; + return after.feePerL2Gas >= minRiseTarget ? after : undefined; }, - 'L2 min fee increase', - 5, + 'L2 min fee organic increase (L1 base fee bump) above reference', + 90, 1, ); }; @@ -93,7 +169,8 @@ describe('e2e_fees fee settings', () => { }; const prepareTxsWithMockedMinFees = async (noPaddingMinFees: GasFees, defaultPaddingMinFees: GasFees) => { - // Mock getPredictedMinFees (used by the wallet) and getCurrentMinFees (used by bumpL2Fees and other callers). + // Mock getPredictedMinFees (used by the wallet) and getCurrentMinFees (used by inflateL2FeesViaCongestion + // and other callers). const getPredictedMinFeesSpy = jest .spyOn(aztecNode, 'getPredictedMinFees') .mockResolvedValueOnce([noPaddingMinFees]) @@ -124,9 +201,14 @@ describe('e2e_fees fee settings', () => { ), ).toBe(true); - // Now bump the L2 fees before we actually send them - const bumpedMinFees = await bumpL2Fees(); + // Now bump the L2 fees organically (L1 base fee spike) before we actually send them. + // Require the bump to be at least 10% — a "any-positive-rise" check is satisfied by 1 wei + // and doesn't prove a meaningful fee shift was handled. `inflateL2FeesViaL1BaseFee` takes + // `stableMinFees` as the reference so its retry waits until the oracle has actually rotated + // to our bumped L1 fee, rather than returning on the first sub-percent natural fluctuation. + const bumpedMinFees = await inflateL2FeesViaL1BaseFee(stableMinFees); expect(stableMinFees.feePerL2Gas).toBeLessThan(bumpedMinFees.feePerL2Gas); + expect(bumpedMinFees.feePerL2Gas).toBeGreaterThan((stableMinFees.feePerL2Gas * 11n) / 10n); expect(stableMinFees.mul(1 + DEFAULT_MIN_FEE_PADDING).feePerL2Gas).toBeGreaterThan(bumpedMinFees.feePerL2Gas); // And check that the no-padding does not get mined, but the default padding is good enough @@ -137,7 +219,11 @@ describe('e2e_fees fee settings', () => { it('reproduces the stale fee snapshot race deterministically', async () => { const lowerMinFees = await getCurrentMinFeesAfterCheckpoint(testContractDeployBlock); - const higherMinFees = lowerMinFees.mul(2); + // `higherMinFees` is the synthetic "stale" snapshot the wallet supposedly took before the + // real L2 fee bumped — it only needs to stay above the realized `bumpedMinFees` so that + // `txWithNoPadding` is still mineable after the bump. Use `4x` for unambiguous headroom + // while keeping the snapshot below the 6x default-padding cap. + const higherMinFees = lowerMinFees.mul(4); const { txWithNoPadding, txWithDefaultPadding } = await prepareTxsWithMockedMinFees(higherMinFees, lowerMinFees); @@ -148,8 +234,9 @@ describe('e2e_fees fee settings', () => { ), ).toBe(true); - const bumpedMinFees = await bumpL2Fees(); + const bumpedMinFees = await inflateL2FeesViaL1BaseFee(lowerMinFees); expect(lowerMinFees.feePerL2Gas).toBeLessThan(bumpedMinFees.feePerL2Gas); + expect(bumpedMinFees.feePerL2Gas).toBeGreaterThan((lowerMinFees.feePerL2Gas * 11n) / 10n); expect(higherMinFees.feePerL2Gas).toBeGreaterThan(bumpedMinFees.feePerL2Gas); expect(lowerMinFees.mul(1 + DEFAULT_MIN_FEE_PADDING).feePerL2Gas).toBeGreaterThan(bumpedMinFees.feePerL2Gas); @@ -158,5 +245,58 @@ describe('e2e_fees fee settings', () => { await expect(txWithNoPadding.send()).resolves.toBeDefined(); await expect(txWithDefaultPadding.send()).resolves.toBeDefined(); }); + + // Regression test for A-1057. Under pipelining, the proposer for slot N starts building the + // checkpoint header (and bakes `manaMinFee` into `gasFees.feePerL2Gas`) during slot N-1. If + // governance executes `setProvingCostPerMana` or `updateManaTarget` between that build and the + // L1 submission, L1 recomputes `manaMinFee` from the post-mutation `FeeStore.config` and the + // submitted header reverts with `Rollup__InvalidManaMinFee`. The chain should eat the + // in-flight checkpoint and the next pipelined proposer should produce a header that validates, + // resuming normal block production. This test exercises that path end-to-end: bump once, then + // verify the chain advances and a fresh tx still mines. + it('recovers after a governance fee-config bump invalidates a pipelined checkpoint', async () => { + // Take a fresh checkpoint baseline so we measure progress strictly post-bump, and capture + // the slot of `checkpointBefore` so we can assert below that at least one L2 slot was + // skipped between the bump and recovery — that's the positive signal that a pipelined + // header was actually dropped, distinguishing the A-1057 recovery path from a chain that + // silently absorbed the governance write without exercising the failure case. + const checkpointBefore = await aztecNode.getCheckpointNumber('checkpointed'); + const slotBefore = (await aztecNode.getCheckpoint(checkpointBefore))!.header.slotNumber; + + t.logger.info(`Bumping provingCostPerMana at checkpointed=${checkpointBefore} (slot ${slotBefore})`); + await cheatCodes.rollup.bumpProvingCostPerMana(current => (current * 120n) / 100n); + + // At most a couple of pipelined headers were built against the pre-bump config; allow up to + // 6 slot windows before insisting the chain has made forward progress past the bump. With + // pipelining + minTxsPerBlock=0 an idle chain still emits empty checkpoints, so the + // `checkpointed` tip must strictly advance. + const RECOVERY_TARGET = CheckpointNumber.add(checkpointBefore, 3); + const RECOVERY_BUDGET_SECONDS = AZTEC_SLOT_DURATION * 6; + await retryUntil( + async () => (await aztecNode.getCheckpointNumber('checkpointed')) >= RECOVERY_TARGET, + `chain advances at least ${RECOVERY_TARGET - checkpointBefore} checkpoints past governance bump`, + RECOVERY_BUDGET_SECONDS, + 1, + ); + + // Healthy pipelining produces one checkpoint per L2 slot, so an advance of 3 checkpoints + // covers exactly 3 slots. If a pipelined header was invalidated and dropped (the A-1057 + // path), the recovery span will cover at least one extra slot. A passing assertion here + // proves the test exercised the invalidation+recovery flow rather than landing the bump + // outside the vulnerable window. + const slotAfter = (await aztecNode.getCheckpoint(RECOVERY_TARGET))!.header.slotNumber; + const slotSpan = slotAfter - slotBefore; + t.logger.info(`Recovery spanned ${slotSpan} slots for ${RECOVERY_TARGET - checkpointBefore} checkpoints`, { + slotBefore, + slotAfter, + checkpointBefore, + recoveryTarget: RECOVERY_TARGET, + }); + expect(slotSpan).toBeGreaterThan(RECOVERY_TARGET - checkpointBefore); + + // Fresh tx prepared against the post-bump fee snapshot still mines under default padding. + const tx = await proveTx(undefined); + await expect(tx.send()).resolves.toBeDefined(); + }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts index 478687371913..7cdd897b450e 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts @@ -84,6 +84,8 @@ export class FeesTest { public getBananaPublicBalanceFn!: BalancesFn; public getBananaPrivateBalanceFn!: BalancesFn; public getProverFee!: (blockNumber: BlockNumber) => Promise; + public getCommittedProverFee!: (blockNumber: BlockNumber) => Promise; + public getCommittedBurn!: (blockNumber: BlockNumber) => Promise; public readonly ALICE_INITIAL_BANANAS = BigInt(1e22); public readonly SUBSCRIPTION_AMOUNT = BigInt(1e19); @@ -102,13 +104,14 @@ export class FeesTest { this.logger = createLogger(`e2e:e2e_fees:${testName}`); } - async setup() { + async setup(opts: Partial = {}) { this.logger.verbose('Setting up fresh context...'); // Token allowlist entries are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha. const tokenAllowList = await getTokenAllowedSetupFunctions(); this.context = await setup(0, { startProverNode: true, ...this.setupOptions, + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, l1ContractsArgs: { ...this.setupOptions }, @@ -302,6 +305,27 @@ export class FeesTest { const mana = block!.header.totalManaUsed.toBigInt(); return mulDiv(mana * proverCost, 10n ** 12n, price); }; + + /** + * Reads the prover fee that the rollup actually committed for the block's checkpoint, which is what + * RewardLib uses to pay prover rewards. Unlike `getProverFee`, this does not re-derive the value + * from current L1 fees or current eth-per-fee-asset price, so it is robust to pipelined fee-asset-price + * drift between propose-time and reward-payout-time. + */ + this.getCommittedProverFee = async (blockNumber: BlockNumber) => { + const block = await this.aztecNode.getBlock(blockNumber); + const feeHeader = await this.rollupContract.getFeeHeader(BigInt(block!.checkpointNumber)); + return feeHeader.manaUsed * feeHeader.proverCost; + }; + + // RewardLib computes sequencerFee = checkpointFee - burn - proverFee where burn = manaUsed * congestionCost. + // The fixture's typical case keeps congestionCost at zero, but reading it explicitly avoids latent bugs + // when test load changes excess mana. + this.getCommittedBurn = async (blockNumber: BlockNumber) => { + const block = await this.aztecNode.getBlock(blockNumber); + const feeHeader = await this.rollupContract.getFeeHeader(BigInt(block!.checkpointNumber)); + return feeHeader.manaUsed * feeHeader.congestionCost; + }; } public async applySponsoredFPCSetup() { diff --git a/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts b/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts index 53fb5bd0498e..5a629951347b 100644 --- a/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts @@ -16,8 +16,10 @@ import { GasSettings, } from '@aztec/stdlib/gas'; +import { jest } from '@jest/globals'; import { inspect } from 'util'; +import { PIPELINING_SETUP_OPTS, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; import { FeesTest } from './fees_test.js'; /** @@ -49,6 +51,10 @@ function waitForSequencerIdle(sequencer: Sequencer, timeout = 30000): Promise { + // FeesTest.setup + applyFPCSetup + applyFundAliceWithBananas chains many dependent txs which run + // at the pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(900_000); + let wallet: Wallet; let aliceAddress: AztecAddress; let bobAddress: AztecAddress; @@ -61,18 +67,21 @@ describe('e2e_fees gas_estimation', () => { const t = new FeesTest('gas_estimation'); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applyFPCSetup(); await t.applyFundAliceWithBananas(); ({ wallet, aliceAddress, bobAddress, bananaCoin, bananaFPC, gasSettings, logger, aztecNode } = t); }); beforeEach(async () => { - // Load the gas fees at the start of each test, use those exactly as the max fees per gas - const gasFees = await aztecNode.getCurrentMinFees(); + // Pad max fees per gas to absorb pipelined fee-asset price evolution between snapshot and + // submission. The assertions below compare `transactionFee` (manaUsed * block.gasFees) against + // `estimatedGas.gasLimits.computeFee(block.gasFees)`, so they only require `gasLimits == manaUsed` + // (guaranteed by `estimatedGasPadding: 0`); they do not require `maxFeesPerGas == block.gasFees`. + const paddedMaxFees = await getPaddedMaxFeesPerGas(aztecNode); gasSettings = GasSettings.from({ ...gasSettings, - maxFeesPerGas: gasFees, + maxFeesPerGas: paddedMaxFees, maxPriorityFeesPerGas: new GasFees(0, 0), }); }, 10000); diff --git a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts index 9563d02815da..15b37f516b5d 100644 --- a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts @@ -7,12 +7,19 @@ import type { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token import { GasSettings } from '@aztec/stdlib/gas'; import { TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE } from '@aztec/stdlib/tx'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { expectMapping } from '../fixtures/utils.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { proveInteraction } from '../test-wallet/utils.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees private_payment', () => { + // FeesTest.setup + applyFPCSetup + applyFundAliceWithBananas chains many dependent txs which run at the + // ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(900_000); + let wallet: TestWallet; let aliceAddress: AztecAddress; let bobAddress: AztecAddress; @@ -25,7 +32,10 @@ describe('e2e_fees private_payment', () => { const t = new FeesTest('private_payment'); beforeAll(async () => { - await t.setup(); + // Shorter epochs (default 32 → 4) speed the per-test `advanceToNextEpoch + waitForProven` + // cycle: the prover-node submits a proof as soon as the epoch is complete, so ~8x shorter + // epochs ≈ ~8x faster proof cadence per cycle. Setup itself stays slot-bound. + await t.setup({ ...PIPELINING_SETUP_OPTS, aztecProofSubmissionEpochs: 640, aztecEpochDuration: 4 }); await t.applyFPCSetup(); await t.applyFundAliceWithBananas(); ({ wallet, aliceAddress, bobAddress, sequencerAddress, bananaCoin, bananaFPC, gasSettings, aztecNode } = t); @@ -106,17 +116,28 @@ describe('e2e_fees private_payment', () => { const sequencerRewardsBefore = await t.getCoinbaseSequencerRewards(); const { sequencerBlockRewards } = await t.getBlockRewards(); + const provenCheckpointBefore = await t.rollupContract.getProvenCheckpointNumber(); const receipt = await localTx.send({ timeout: 300, interval: 10 }); await t.cheatCodes.rollup.advanceToNextEpoch(); await waitForProven(aztecNode, receipt, { provenTimeout: 300 }); + // Under pipelining, multiple empty checkpoints can land and prove between the snapshot and waitForProven; + // each one contributes a block reward to the coinbase, so multiply by the actual proven-checkpoint delta. + const provenCheckpointAfter = await t.rollupContract.getProvenCheckpointNumber(); + const newlyProvenCheckpoints = BigInt(provenCheckpointAfter - provenCheckpointBefore); + // @note There is a potential race condition here if other tests send transactions that get into the same // epoch and thereby pays out fees at the same time (when proven). - const expectedProverFee = await t.getProverFee(receipt.blockNumber!); + const expectedProverFee = await t.getCommittedProverFee(receipt.blockNumber!); + const expectedBurn = await t.getCommittedBurn(receipt.blockNumber!); await expect(t.getCoinbaseSequencerRewards()).resolves.toEqual( - sequencerRewardsBefore + sequencerBlockRewards + receipt.transactionFee! - expectedProverFee, + sequencerRewardsBefore + + newlyProvenCheckpoints * sequencerBlockRewards + + receipt.transactionFee! - + expectedBurn - + expectedProverFee, ); const feeAmount = receipt.transactionFee!; diff --git a/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts index b059938777db..df4cc32f479a 100644 --- a/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts @@ -6,10 +6,17 @@ import type { FPCContract } from '@aztec/noir-contracts.js/FPC'; import type { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token'; import { GasSettings } from '@aztec/stdlib/gas'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; import { expectMapping } from '../fixtures/utils.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees public_payment', () => { + // FeesTest.setup + applyFPCSetup + applyFundAliceWithBananas chains many dependent txs which run + // at the ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(15 * 60 * 1000); + let aztecNode: AztecNode; let wallet: Wallet; let aliceAddress: AztecAddress; @@ -22,7 +29,7 @@ describe('e2e_fees public_payment', () => { const t = new FeesTest('public_payment'); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applyFPCSetup(); await t.applyFundAliceWithBananas(); ({ wallet, aliceAddress, bobAddress, sequencerAddress, bananaCoin, bananaFPC, gasSettings, aztecNode } = t); @@ -45,7 +52,7 @@ describe('e2e_fees public_payment', () => { beforeEach(async () => { gasSettings = GasSettings.from({ ...gasSettings, - maxFeesPerGas: await aztecNode.getCurrentMinFees(), + maxFeesPerGas: await getPaddedMaxFeesPerGas(aztecNode), }); [ diff --git a/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts index ec9726d9d129..6e1f89dbff21 100644 --- a/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts @@ -5,10 +5,17 @@ import type { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { GasSettings } from '@aztec/stdlib/gas'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; import { expectMapping } from '../fixtures/utils.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees sponsored_public_payment', () => { + // FeesTest.setup + applySponsoredFPCSetup + applyFundAliceWithBananas chains many dependent txs which run + // at the ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(15 * 60 * 1000); + let aztecNode: AztecNode; let aliceAddress: AztecAddress; let bobAddress: AztecAddress; @@ -20,7 +27,7 @@ describe('e2e_fees sponsored_public_payment', () => { const t = new FeesTest('sponsored_payment'); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applySponsoredFPCSetup(); await t.applyFundAliceWithBananas(); ({ aztecNode, aliceAddress, bobAddress, sequencerAddress, sponsoredFPC, bananaCoin, gasSettings } = t); @@ -43,7 +50,7 @@ describe('e2e_fees sponsored_public_payment', () => { beforeEach(async () => { gasSettings = GasSettings.from({ ...gasSettings, - maxFeesPerGas: await aztecNode.getCurrentMinFees(), + maxFeesPerGas: await getPaddedMaxFeesPerGas(aztecNode), }); [[initialAlicePublicBananas, initialBobPublicBananas], [initialAliceGas, initialFPCGas, initialSequencerGas]] = diff --git a/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts b/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts index 06b9e8729eb1..1543890e7c59 100644 --- a/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts +++ b/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts @@ -2,6 +2,7 @@ import { NO_FROM } from '@aztec/aztec.js/account'; import { createLogger } from '@aztec/aztec.js/log'; import { retryUntil } from '@aztec/foundation/retry'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { type EndToEndContext, setup } from './fixtures/utils.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -11,21 +12,11 @@ describe('e2e_genesis_timestamp', () => { const logger = createLogger('e2e:genesis_timestamp'); beforeEach(async () => { - // Skip account deployment and prevent the sequencer from mining empty blocks. - // Configure PXE to sync anchor only to proven blocks so its anchor lags behind proposed blocks - // (tests do not spin up a prover, so nothing will ever be proven and the anchor stays at genesis). - context = await setup( - 0, - { - skipAccountDeployment: true, - minTxsPerBlock: 1, - startProverNode: false, - anvilTestWatcherOpts: { isMarkingAsProven: false }, - }, - { syncChainTip: 'proven' }, - ); - - context.watcher.setIsMarkingAsProven(false); + // Skip account deployment and configure PXE to sync its anchor only to proven blocks so its + // anchor lags behind proposed blocks. Under AUTOMINE_E2E_OPTS the AnvilTestWatcher is disabled + // and the AutomineSequencer never marks blocks as proven on its own, so without a prover node + // the proven tip stays at genesis for the duration of the test. + context = await setup(0, { ...AUTOMINE_E2E_OPTS, skipAccountDeployment: true }, { syncChainTip: 'proven' }); }); afterEach(() => context.teardown()); @@ -56,7 +47,7 @@ describe('e2e_genesis_timestamp', () => { }; it('can include genesis-anchored tx in a block after block 1', async () => { - const { aztecNode, aztecNodeAdmin } = context; + const { aztecNode } = context; // We're at block 0 -- no blocks have been mined yet. expect(await aztecNode.getBlockNumber()).toBe(0); @@ -64,21 +55,19 @@ describe('e2e_genesis_timestamp', () => { // Step 1: Prove the account deploy tx while PXE is still anchored to genesis (block 0). const provenTx = await proveTxAnchoredToGenesis(); - // Step 2: Mine an empty block to advance past genesis. - await aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); + // Step 2: Mine an empty block to advance past genesis. Under AUTOMINE_E2E_OPTS the sequencer + // only mines on tx submission or explicit `mineBlock()`, so we drive it directly here. + await aztecNode.mineBlock(); await awaitBlockCheckpointed(); - // Step 3: Prevent further empty blocks so the next block only mines when our tx arrives. - await aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); - - // Step 4: Send the genesis-anchored proven tx. It should land in a block after block 1. + // Step 3: Send the genesis-anchored proven tx. It should land in a block after block 1. const receipt = await provenTx.send(); logger.info(`Tx mined in block ${receipt.blockNumber}`); // The tx landed after block 1, proving that genesis-anchored transactions // are valid beyond the first block when the genesis has a non-zero timestamp. expect(receipt.blockNumber).toBeGreaterThan(1); - }, 120_000); + }, 300_000); // Regression for an issue where PXE failed to prove txs while anchored to block zero // if there were new blocks mined that modified the public data tree. @@ -113,5 +102,5 @@ describe('e2e_genesis_timestamp', () => { logger.info(`Second genesis-anchored deploy mined in block ${secondReceipt.blockNumber}`); expect(secondReceipt.blockNumber).toBeDefined(); expect(secondReceipt.blockNumber!).toBeGreaterThan(firstReceipt.blockNumber!); - }, 180_000); + }, 400_000); }); diff --git a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts index bc3567df0c7b..e89ac4a3c436 100644 --- a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts +++ b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts @@ -20,6 +20,7 @@ import { MerkleTreeId } from '@aztec/stdlib/trees'; import { jest } from '@jest/globals'; import { simulateThroughAuthwitProxy } from './fixtures/authwit_proxy.js'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -56,7 +57,7 @@ describe('Kernelless simulation', () => { wallet, accounts: [adminAddress, liquidityProviderAddress, swapperAddress], logger, - } = await setup(3)); + } = await setup(3, { ...AUTOMINE_E2E_OPTS })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_keys.test.ts b/yarn-project/end-to-end/src/e2e_keys.test.ts index c566e6ef525f..0890b1c721ed 100644 --- a/yarn-project/end-to-end/src/e2e_keys.test.ts +++ b/yarn-project/end-to-end/src/e2e_keys.test.ts @@ -14,13 +14,15 @@ import { deriveMasterNullifierHidingKey, deriveMasterOutgoingViewingSecretKey, derivePublicKeyFromSecretKey, + hashPublicKey, } from '@aztec/stdlib/keys'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('Keys', () => { jest.setTimeout(TIMEOUT); @@ -42,7 +44,7 @@ describe('Keys', () => { wallet, accounts: [defaultAccountAddress], initialFundedAccounts, - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); @@ -114,9 +116,13 @@ describe('Keys', () => { describe('ovsk_app', () => { it('gets ovsk_app', async () => { - // Derive the ovpk_m_hash from the account secret + // Derive the ovpk_m_hash from the account secret. Use `hashPublicKey` (the + // domain-separated hash over `[x, y]`) rather than `Point.hash()` (which hashes + // `[x, y, is_infinite]` with no separator) -- the PXE's `KeyStore.addAccount` stores + // master-key hashes computed via `hashPublicKey`, so this is what the + // `aztec_utl_getKeyValidationRequest` lookup compares against. const ovskM = deriveMasterOutgoingViewingSecretKey(secret); - const ovpkMHash = await (await derivePublicKeyFromSecretKey(ovskM)).hash(); + const ovpkMHash = await hashPublicKey(await derivePublicKeyFromSecretKey(ovskM)); // Compute the expected ovsk_app const expectedOvskApp = await computeAppSecretKey(ovskM, testContract.address, 'ov'); diff --git a/yarn-project/end-to-end/src/e2e_l1_publisher/e2e_l1_publisher.test.ts b/yarn-project/end-to-end/src/e2e_l1_publisher/e2e_l1_publisher.test.ts index 70503811095d..d9e62b7a5deb 100644 --- a/yarn-project/end-to-end/src/e2e_l1_publisher/e2e_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/e2e_l1_publisher/e2e_l1_publisher.test.ts @@ -175,6 +175,23 @@ describe('L1Publisher integration', () => { } }; + // Warp the chain forward so that the current L2 slot matches `targetSlot`, and resync the + // dateProvider so `epochCache.getSlotNow()` (used by the bundle-level eth_simulateV1 and the + // L1 tx mine timestamp) also lands on `targetSlot`. The rollup contract rejects header slots + // that don't match block.timestamp, so the test must align both the chain and the date + // provider to the header's slot before calling sendRequests. + const progressToSlot = async (targetSlot: bigint) => { + const currentSlot = await rollup.getSlotNumber(); + if (BigInt(targetSlot) > BigInt(currentSlot)) { + await progressTimeBySlot(Number(BigInt(targetSlot) - BigInt(currentSlot))); + } + // Always resync the dateProvider so `epochCache.getSlotNow()` matches L1's block.timestamp. + // `sendRequests` derives its bundle-simulate timestamp from `getCurrentL2Slot()`, so if the + // dateProvider lags the chain the simulate runs at a stale slot and the rollup rejects the + // header with `HeaderLib__InvalidSlotNumber`. + await ethCheatCodes.syncDateProvider(); + }; + let port = 8545; // We increase the port for each test to avoid anvil conflicts const setup = async (deployL1ContractsArgs: Partial = {}) => { ({ rpcUrl, anvil } = await startAnvil({ port: port++ })); @@ -532,6 +549,8 @@ describe('L1Publisher integration', () => { CommitteeAttestationsAndSigners.empty(getSignatureContext()), Signature.empty(), ); + // Align chain time so the bundle simulate and the L1 send both run at the header's slot. + await progressToSlot(BigInt(checkpoint.header.slotNumber)); await publisher.sendRequests(); const logs = await l1Client.getLogs({ @@ -643,6 +662,8 @@ describe('L1Publisher integration', () => { new CommitteeAttestationsAndSigners(attestations, getSignatureContext()), signature, ); + // Align chain time so the bundle simulate and the L1 send both run at the header's slot. + await progressToSlot(BigInt(checkpoint.header.slotNumber)); const result = await publisher.sendRequests(); expect(result!.successfulActions).toEqual(['propose']); expect(result!.failedActions).toEqual([]); @@ -680,9 +701,23 @@ describe('L1Publisher integration', () => { expect(canPropose?.slot).toEqual(block.header.getSlot()); await publisher.validateBlockHeader(checkpoint.header); - await expect( - publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, Signature.empty()), - ).rejects.toThrow(/ValidatorSelection__InvalidCommitteeCommitment/); + // Enqueue no longer simulates — the bundle simulate at send time drops the failing propose + // and sendRequests returns undefined (no surviving actions). The drop is reported via a + // warn log carrying the on-chain revert reason (raw hex selector since the propose request + // has no ABI attached). + const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, Signature.empty()); + await progressToSlot(BigInt(checkpoint.header.slotNumber)); + const result = await publisher.sendRequests(); + expect(result).toBeUndefined(); + // 0xca8d5954 == ValidatorSelection__InvalidCommitteeCommitment selector + expect(loggerWarnSpy).toHaveBeenCalledWith( + 'Bundle entry dropped: action reverted in sim', + expect.objectContaining({ + action: 'propose', + returnData: expect.stringMatching(/^0xca8d5954/), + }), + ); }); it('rejects flipped proposer signature', async () => { @@ -701,13 +736,25 @@ describe('L1Publisher integration', () => { validators.find(v => v.address.equals(proposer!))!, ); - await expect( - publisher.enqueueProposeCheckpoint( - checkpoint, - attestationsAndSigners, - flipSignature(attestationsAndSignersSignature), - ), - ).rejects.toThrow(/ECDSAInvalidSignatureS/); + // Enqueue no longer simulates — the bundle simulate at send time drops the failing propose + // and sendRequests returns undefined. + const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); + await publisher.enqueueProposeCheckpoint( + checkpoint, + attestationsAndSigners, + flipSignature(attestationsAndSignersSignature), + ); + await progressToSlot(BigInt(checkpoint.header.slotNumber)); + const result = await publisher.sendRequests(); + expect(result).toBeUndefined(); + // 0xd78bce0c == ECDSAInvalidSignatureS selector + expect(loggerWarnSpy).toHaveBeenCalledWith( + 'Bundle entry dropped: action reverted in sim', + expect.objectContaining({ + action: 'propose', + returnData: expect.stringMatching(/^0xd78bce0c/), + }), + ); }); it('rejects signature with invalid recovery value', async () => { @@ -732,8 +779,20 @@ describe('L1Publisher integration', () => { const wrongV = attestationsAndSignersSignature.v - 27; const wrongSig = new Signature(attestationsAndSignersSignature.r, attestationsAndSignersSignature.s, wrongV); - await expect(publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, wrongSig)).rejects.toThrow( - /ECDSAInvalidSignature/, + // Enqueue no longer simulates — the bundle simulate at send time drops the failing propose + // and sendRequests returns undefined. + const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, wrongSig); + await progressToSlot(BigInt(checkpoint.header.slotNumber)); + const result = await publisher.sendRequests(); + expect(result).toBeUndefined(); + // 0xf645eedf == ECDSAInvalidSignature selector + expect(loggerWarnSpy).toHaveBeenCalledWith( + 'Bundle entry dropped: action reverted in sim', + expect.objectContaining({ + action: 'propose', + returnData: expect.stringMatching(/^0xf645eedf/), + }), ); }); @@ -810,9 +869,7 @@ describe('L1Publisher integration', () => { // Invalidate and propose logger.warn('Enqueuing requests to invalidate and propose the checkpoint'); publisher.enqueueInvalidateCheckpoint(invalidateRequest); - await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, { - simulationOverridesPlan: invalidationSimulationOverridesPlan, - }); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, attestationsAndSignersSignature); const result = await publisher.sendRequests(); expect(result!.successfulActions).toEqual(['invalidate-by-insufficient-attestations', 'propose']); expect(result!.failedActions).toEqual([]); @@ -853,20 +910,24 @@ describe('L1Publisher integration', () => { const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(1n)); const { checkpoint } = await buildSingleCheckpoint({ l1ToL2Messages }); - // Expect the simulation to fail - const loggerErrorSpy = jest.spyOn((publisher as any).log, 'error'); - await expect( - publisher.enqueueProposeCheckpoint( - checkpoint, - CommitteeAttestationsAndSigners.empty(getSignatureContext()), - Signature.empty(), - ), - ).rejects.toThrow(/Rollup__InvalidInHash/); - expect(loggerErrorSpy).toHaveBeenNthCalledWith( - 2, - expect.stringMatching('Rollup__InvalidInHash'), - expect.anything(), - expect.objectContaining({ checkpointNumber: 1 }), + // Enqueue no longer simulates per action — the bundle simulate at send time drops the + // failing propose and reports the on-chain revert reason via a warn log. + const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); + await publisher.enqueueProposeCheckpoint( + checkpoint, + CommitteeAttestationsAndSigners.empty(getSignatureContext()), + Signature.empty(), + ); + await progressToSlot(BigInt(checkpoint.header.slotNumber)); + const result = await publisher.sendRequests(); + expect(result).toBeUndefined(); + // 0xcd6f4233 == Rollup__InvalidInHash selector + expect(loggerWarnSpy).toHaveBeenCalledWith( + 'Bundle entry dropped: action reverted in sim', + expect.objectContaining({ + action: 'propose', + returnData: expect.stringMatching(/^0xcd6f4233/), + }), ); }); }); @@ -1022,10 +1083,21 @@ describe('L1Publisher integration', () => { expect(BigInt(block2.slot)).toEqual(initialL2Slot + 1n); sendRequestsResult = undefined; await enqueueProposeL2Checkpoint(checkpoint2); + // Align chain time so the bundle simulate at send time runs at slot N+1 (matches the + // checkpoint2 header). Without this the bundle simulate (which uses getSlotNow()) sees + // the wrong slot and drops the propose entry. + await progressToSlot(BigInt(checkpoint2.header.slotNumber)); await sendRequests(); - // Wait for the new proposal to be sent to the pool - await retryUntil(() => ethCheatCodes.getTxPoolStatus().then(s => s.queued + s.pending > 1), 'tx queued', 20, 0.1); + // Wait for the new proposal to be sent to the pool. The progressToSlot warp above may have + // already mined the cancellation from the first proposal, so the pool may hold either the + // cancel-and-new-propose (two entries) or just the new propose (one entry). + await retryUntil( + () => ethCheatCodes.getTxPoolStatus().then(s => s.queued + s.pending >= 1), + 'tx queued', + 20, + 0.1, + ); // Mine a block await ethCheatCodes.mine(); diff --git a/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts b/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts index 7d955369ffdb..57c1ab475d64 100644 --- a/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts +++ b/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts @@ -2,12 +2,12 @@ import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses'; import { Fr } from '@aztec/aztec.js/fields'; import type { Logger } from '@aztec/aztec.js/log'; import { type AztecNode, waitForTx } from '@aztec/aztec.js/node'; -import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config'; import { SecretValue } from '@aztec/foundation/config'; import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from './fixtures/utils.js'; import { submitTxsTo } from './shared/submit-transactions.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -35,21 +35,21 @@ describe('e2e_l1_with_wall_time', () => { bn254SecretKey: new SecretValue(Fr.random().toBigInt()), }, ]; - const { ethereumSlotDuration } = getL1ContractsConfigEnvVars(); + // Don't pass ethereumSlotDuration explicitly — the env default is 12s, which would clash with + // the fixture's pipelining override (aztecSlotDuration=12, ethereumSlotDuration=4). With both at + // 12s the pipelined timing model can't fit propose+attest+publish in one Aztec slot and txs + // get dropped from the mempool. Let the fixture pick its pipelining-aware defaults. ({ teardown, logger, wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup(1, { - initialValidators, - ethereumSlotDuration, - })); + } = await setup(1, { ...PIPELINING_SETUP_OPTS, initialValidators })); }); - afterEach(() => teardown()); + afterEach(() => teardown?.()); it('should produce blocks with a bunch of transactions', async () => { for (let i = 0; i < numberOfBlocks; i++) { diff --git a/yarn-project/end-to-end/src/e2e_large_public_event.test.ts b/yarn-project/end-to-end/src/e2e_large_public_event.test.ts index 81997ac4cf6b..34db71a443f1 100644 --- a/yarn-project/end-to-end/src/e2e_large_public_event.test.ts +++ b/yarn-project/end-to-end/src/e2e_large_public_event.test.ts @@ -8,9 +8,10 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; /// Tests that events exceeding MAX_EVENT_SERIALIZED_LEN can be emitted publicly. describe('LargePublicEvent', () => { @@ -28,7 +29,7 @@ describe('LargePublicEvent', () => { wallet, aztecNode, accounts: [accountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await LargePublicEventContract.deploy(wallet).send({ from: accountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 22c1964fe1f8..5756862b31e3 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -4,6 +4,7 @@ import type { Logger } from '@aztec/aztec.js/log'; import { CheatCodes } from '@aztec/aztec/testing'; import { RollupContract } from '@aztec/ethereum/contracts'; import type { DeployAztecL1ContractsReturnType } from '@aztec/ethereum/deploy-aztec-l1-contracts'; +import { BlockNumber } from '@aztec/foundation/branded-types'; import type { TestDateProvider } from '@aztec/foundation/timer'; import { LendingContract } from '@aztec/noir-contracts.js/Lending'; import { PriceFeedContract } from '@aztec/noir-contracts.js/PriceFeed'; @@ -11,6 +12,8 @@ import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { afterAll, jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; +import type { EndToEndContext } from './fixtures/setup.js'; import { mintTokensToPrivate } from './fixtures/token_utils.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; import { LendingAccount, LendingSimulator, TokenSimulator } from './simulators/index.js'; @@ -21,6 +24,7 @@ describe('e2e_lending_contract', () => { let wallet: TestWallet; let defaultAccountAddress: AztecAddress; let deployL1ContractsValues: DeployAztecL1ContractsReturnType; + let aztecNode: EndToEndContext['aztecNode']; let logger: Logger; let teardown: () => Promise; @@ -77,7 +81,7 @@ describe('e2e_lending_contract', () => { }; beforeAll(async () => { - const ctx = await setup(1); + const ctx = await setup(1, { ...AUTOMINE_E2E_OPTS }); ({ teardown, logger, @@ -85,6 +89,7 @@ describe('e2e_lending_contract', () => { wallet, deployL1ContractsValues, dateProvider, + aztecNode, accounts: [defaultAccountAddress], } = ctx); ({ lendingContract, priceFeedContract, collateralAsset, stableCoin } = await deployContracts()); @@ -123,6 +128,11 @@ describe('e2e_lending_contract', () => { await lendingSim.check(); }); + const observeBlock = async (blockNumber: number | undefined) => { + const block = await aztecNode.getBlock(BlockNumber(blockNumber!)); + lendingSim.observeBlockTimestamp(Number(block!.header.globalVariables.timestamp)); + }; + it('Mint assets for later usage', async () => { await priceFeedContract.methods.set_price(0n, 2n * 10n ** 9n).send({ from: defaultAccountAddress }); @@ -145,11 +155,15 @@ describe('e2e_lending_contract', () => { }); it('Initialize the contract', async () => { - await lendingSim.prepare(); logger.info('Initializing contract'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .init(priceFeedContract.address, 8000, collateralAsset.address, stableCoin.address) .send({ from: defaultAccountAddress }); + // init writes accumulator = BASE and last_updated_ts = block.timestamp. + // Match that exactly without advancing the accumulator from the previous (zero) time. + const block = await aztecNode.getBlock(BlockNumber(receipt.blockNumber!)); + lendingSim.prepare(); + lendingSim.time = Number(block!.header.globalVariables.timestamp); }); describe('Deposits', () => { @@ -165,8 +179,7 @@ describe('e2e_lending_contract', () => { authwitNonce, ), }); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.depositPrivate(lendingAccount.address, await lendingAccount.key(), activationThreshold); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private deposit of funds into own account. // This should: @@ -174,7 +187,7 @@ describe('e2e_lending_contract', () => { // - increase last updated timestamp. // - increase the private collateral. logger.info('Depositing 🥸 : 💰 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .deposit_private( lendingAccount.address, activationThreshold, @@ -184,6 +197,8 @@ describe('e2e_lending_contract', () => { collateralAsset.address, ) .send({ from: defaultAccountAddress, authWitnesses: [transferToPublicAuthwit] }); + await observeBlock(receipt.blockNumber); + lendingSim.depositPrivate(lendingAccount.address, await lendingAccount.key(), activationThreshold); }); it('Depositing 🥸 on behalf of recipient: 💰 -> 🏦', async () => { @@ -199,15 +214,14 @@ describe('e2e_lending_contract', () => { ), }); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.depositPrivate(lendingAccount.address, lendingAccount.address.toField(), activationThreshold); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private deposit of funds into another account, in this case, a public account. // This should: // - increase the interest accumulator // - increase last updated timestamp. // - increase the public collateral. logger.info('Depositing 🥸 on behalf of recipient: 💰 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .deposit_private( lendingAccount.address, activationThreshold, @@ -217,6 +231,8 @@ describe('e2e_lending_contract', () => { collateralAsset.address, ) .send({ from: defaultAccountAddress, authWitnesses: [transferToPublicAuthwit] }); + await observeBlock(receipt.blockNumber); + lendingSim.depositPrivate(lendingAccount.address, lendingAccount.address.toField(), activationThreshold); }); it('Depositing: 💰 -> 🏦', async () => { @@ -240,8 +256,7 @@ describe('e2e_lending_contract', () => { ); await validateAction.send(); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.depositPublic(lendingAccount.address, lendingAccount.address.toField(), activationThreshold); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a public deposit of funds into self. // This should: @@ -250,17 +265,18 @@ describe('e2e_lending_contract', () => { // - increase the public collateral. logger.info('Depositing: 💰 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .deposit_public(activationThreshold, authwitNonce, lendingAccount.address, collateralAsset.address) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.depositPublic(lendingAccount.address, lendingAccount.address.toField(), activationThreshold); }); }); describe('Borrow', () => { it('Borrow 🥸 : 🏦 -> 🍌', async () => { const borrowAmount = 69n; - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.borrow(await lendingAccount.key(), lendingAccount.address, borrowAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private borrow using the private account // This should: @@ -269,15 +285,16 @@ describe('e2e_lending_contract', () => { // - increase the private debt. logger.info('Borrow 🥸 : 🏦 -> 🍌'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .borrow_private(lendingAccount.secret, lendingAccount.address, borrowAmount) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.borrow(await lendingAccount.key(), lendingAccount.address, borrowAmount); }); it('Borrow: 🏦 -> 🍌', async () => { const borrowAmount = 69n; - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.borrow(lendingAccount.address.toField(), lendingAccount.address, borrowAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a public borrow using the private account // This should: @@ -286,9 +303,11 @@ describe('e2e_lending_contract', () => { // - increase the public debt. logger.info('Borrow: 🏦 -> 🍌'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .borrow_public(lendingAccount.address, borrowAmount) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.borrow(lendingAccount.address.toField(), lendingAccount.address, borrowAmount); }); }); @@ -301,8 +320,7 @@ describe('e2e_lending_contract', () => { action: stableCoin.methods.burn_private(lendingAccount.address, repayAmount, authwitNonce), }); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.repayPrivate(lendingAccount.address, await lendingAccount.key(), repayAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private repay of the debt in the private account // This should: @@ -311,9 +329,11 @@ describe('e2e_lending_contract', () => { // - decrease the private debt. logger.info('Repay 🥸 : 🍌 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .repay_private(lendingAccount.address, repayAmount, authwitNonce, lendingAccount.secret, 0n, stableCoin.address) .send({ from: defaultAccountAddress, authWitnesses: [burnPrivateAuthwit] }); + await observeBlock(receipt.blockNumber); + lendingSim.repayPrivate(lendingAccount.address, await lendingAccount.key(), repayAmount); }); it('Repay 🥸 on behalf of public: 🍌 -> 🏦', async () => { @@ -324,8 +344,7 @@ describe('e2e_lending_contract', () => { action: stableCoin.methods.burn_private(lendingAccount.address, repayAmount, authwitNonce), }); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.repayPrivate(lendingAccount.address, lendingAccount.address.toField(), repayAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private repay of the debt in the public account // This should: @@ -334,7 +353,7 @@ describe('e2e_lending_contract', () => { // - decrease the public debt. logger.info('Repay 🥸 on behalf of public: 🍌 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .repay_private( lendingAccount.address, repayAmount, @@ -344,6 +363,8 @@ describe('e2e_lending_contract', () => { stableCoin.address, ) .send({ from: defaultAccountAddress, authWitnesses: [burnPrivateAuthwit] }); + await observeBlock(receipt.blockNumber); + lendingSim.repayPrivate(lendingAccount.address, lendingAccount.address.toField(), repayAmount); }); it('Repay: 🍌 -> 🏦', async () => { @@ -361,8 +382,7 @@ describe('e2e_lending_contract', () => { ); await validateAction.send(); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.repayPublic(lendingAccount.address, lendingAccount.address.toField(), repayAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a public repay of the debt in the public account // This should: @@ -371,17 +391,18 @@ describe('e2e_lending_contract', () => { // - decrease the public debt. logger.info('Repay: 🍌 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .repay_public(repayAmount, authwitNonce, lendingAccount.address, stableCoin.address) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.repayPublic(lendingAccount.address, lendingAccount.address.toField(), repayAmount); }); }); describe('Withdraw', () => { it('Withdraw: 🏦 -> 💰', async () => { const withdrawAmount = 42n; - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.withdraw(lendingAccount.address.toField(), lendingAccount.address, withdrawAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Withdraw funds from the public account // This should: @@ -390,15 +411,16 @@ describe('e2e_lending_contract', () => { // - decrease the public collateral. logger.info('Withdraw: 🏦 -> 💰'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .withdraw_public(lendingAccount.address, withdrawAmount) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.withdraw(lendingAccount.address.toField(), lendingAccount.address, withdrawAmount); }); it('Withdraw 🥸 : 🏦 -> 💰', async () => { const withdrawAmount = 42n; - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.withdraw(await lendingAccount.key(), lendingAccount.address, withdrawAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Withdraw funds from the private account // This should: @@ -407,9 +429,11 @@ describe('e2e_lending_contract', () => { // - decrease the private collateral. logger.info('Withdraw 🥸 : 🏦 -> 💰'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .withdraw_private(lendingAccount.secret, lendingAccount.address, withdrawAmount) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.withdraw(await lendingAccount.key(), lendingAccount.address, withdrawAmount); }); describe('failure cases', () => { diff --git a/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts b/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts index f46ff8a3a165..5e39ebd6949f 100644 --- a/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts +++ b/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts @@ -4,6 +4,7 @@ import { TxStatus } from '@aztec/aztec.js/tx'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { type EndToEndContext, setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -24,6 +25,7 @@ describe('e2e_mempool_limit', () => { wallet, accounts: [defaultAccountAddress], } = await setup(1, { + ...AUTOMINE_E2E_OPTS, proverTestVerificationDelayMs: undefined, })); @@ -46,8 +48,9 @@ describe('e2e_mempool_limit', () => { { from: defaultAccountAddress }, ); - // set a min tx greater than the mempool so that the sequencer doesn't all of a sudden build a block - await aztecNodeAdmin!.setConfig({ maxPendingTxCount: 2, minTxsPerBlock: 4 }); + // Cap the mempool, then pause the sequencer so pending txs accumulate without being mined. + await aztecNodeAdmin!.setConfig({ maxPendingTxCount: 2 }); + await aztecNodeAdmin!.pauseSequencer(); const tx2 = await proveInteraction( wallet, diff --git a/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts b/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts index beb0ae32e5b2..727bd706883a 100644 --- a/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts +++ b/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts @@ -20,7 +20,7 @@ import 'jest-extended'; import { type Hex, type TransactionSerialized, recoverTransactionAddress } from 'viem'; import { mnemonicToAccount } from 'viem/accounts'; -import { MNEMONIC } from './fixtures/fixtures.js'; +import { MNEMONIC, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -75,15 +75,23 @@ describe('e2e_multi_eoa', () => { accounts: [defaultAccountAddress], sequencer: sequencerClient, ethCheatCodes, - } = await setup(2, { - archiverPollingIntervalMS: 200, - sequencerPollingIntervalMS: 200, - worldStateBlockCheckIntervalMS: 200, - blockCheckIntervalMS: 200, - sequencerPublisherPrivateKeys: sequencerKeysAndAddresses.map(k => k.key), - l1PublisherKey: allKeysAndAddresses[0].key, - maxSpeedUpAttempts: 0, // Disable speed ups, so that cancellation txs never make it through - })); + } = await setup( + 2, + { + ...PIPELINING_SETUP_OPTS, + archiverPollingIntervalMS: 200, + sequencerPollingIntervalMS: 200, + worldStateBlockCheckIntervalMS: 200, + blockCheckIntervalMS: 200, + sequencerPublisherPrivateKeys: sequencerKeysAndAddresses.map(k => k.key), + l1PublisherKey: allKeysAndAddresses[0].key, + maxSpeedUpAttempts: 0, // Disable speed ups, so that cancellation txs never make it through + }, + // Anchor PXE to the checkpointed chain so that a missed-publish from publisher #1 in slot N + // (which invalidates the pipelined proposed chain) doesn't drop the wallet's in-flight tx + // when slot N+1's job rotates to publisher #2. + { syncChainTip: 'checkpointed' }, + )); sequencer = sequencerClient! as TestSequencerClient; publisherManager = sequencer.publisherManager; aztecNodeAdmin = maybeAztecNodeAdmin!; @@ -204,9 +212,10 @@ describe('e2e_multi_eoa', () => { return sequencerKeysAndAddresses.findIndex(ka => ka.address === address); }; - // We should be at L2 block 2 + // We should be at L2 block 2 or later (empty pipelined checkpoints can land between setup + // and the first assertion, so accept >=2 rather than pinning to exactly 2). const blockNumber = await aztecNode.getBlockNumber(); - expect(blockNumber).toBe(2); + expect(blockNumber).toBeGreaterThanOrEqual(2); // This means that 2 of our accounts have been used to send blocks to L1. // We want to figure out which ones these are, they will be in the 'MINED' state within the sequencer diff --git a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts index e41b54eba63f..5b662846434c 100644 --- a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts +++ b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts @@ -1,12 +1,12 @@ +import type { InitialAccountData } from '@aztec/accounts/testing'; import type { Archiver } from '@aztec/archiver'; import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; +import { NO_FROM } from '@aztec/aztec.js/account'; import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses'; -import { waitForProven } from '@aztec/aztec.js/contracts'; import { ContractDeployer } from '@aztec/aztec.js/deployment'; import { Fr } from '@aztec/aztec.js/fields'; import type { Logger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; -import type { Wallet } from '@aztec/aztec.js/wallet'; import type { CheatCodes } from '@aztec/aztec/testing'; import { createExtendedL1Client } from '@aztec/ethereum/client'; import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config'; @@ -19,22 +19,30 @@ import { retryUntil } from '@aztec/foundation/retry'; import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi'; import { StatefulTestContractArtifact } from '@aztec/noir-test-contracts.js/StatefulTest'; import { CheckpointAttestation, ConsensusPayload } from '@aztec/stdlib/p2p'; +import { TxStatus } from '@aztec/stdlib/tx'; +import { jest } from '@jest/globals'; import { getContract } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../fixtures/utils.js'; +import type { TestWallet } from '../test-wallet/test_wallet.js'; const VALIDATOR_COUNT = 5; const COMMITTEE_SIZE = VALIDATOR_COUNT - 2; const PUBLISHER_COUNT = 2; describe('e2e_multi_validator_node', () => { + // Each test starts its own multi-validator network and waits for checkpointed L2 transactions. + jest.setTimeout(15 * 60 * 1000); + let initialValidatorPrivateKeys: `0x${string}`[]; let validatorAddresses: `0x${string}`[]; let teardown: () => Promise; - let wallet: Wallet; + let wallet: TestWallet; let ownerAddress: AztecAddress; + let initialFundedAccounts: InitialAccountData[]; let aztecNode: AztecNode; let config: AztecNodeConfig; let logger: Logger; @@ -67,26 +75,22 @@ describe('e2e_multi_validator_node', () => { }); const { aztecSlotDuration: _aztecSlotDuration } = getL1ContractsConfigEnvVars(); - ({ - teardown, - logger, - wallet, - accounts: [ownerAddress], - aztecNode, - config, - deployL1ContractsValues, - cheatCodes, - } = await setup(1, { - initialValidators, - aztecTargetCommitteeSize: COMMITTEE_SIZE, - sequencerPublisherPrivateKeys: publisherPrivateKeys.map(k => new SecretValue(k)), - minTxsPerBlock: 1, - archiverPollingIntervalMS: 200, - sequencerPollingIntervalMS: 200, - worldStateBlockCheckIntervalMS: 200, - blockCheckIntervalMS: 200, - startProverNode: true, - })); + ({ teardown, logger, wallet, initialFundedAccounts, aztecNode, config, deployL1ContractsValues, cheatCodes } = + await setup( + 1, + { + ...PIPELINING_SETUP_OPTS, + initialValidators, + aztecTargetCommitteeSize: COMMITTEE_SIZE, + sequencerPublisherPrivateKeys: publisherPrivateKeys.map(k => new SecretValue(k)), + archiverPollingIntervalMS: 200, + sequencerPollingIntervalMS: 200, + worldStateBlockCheckIntervalMS: 200, + blockCheckIntervalMS: 200, + skipAccountDeployment: true, + }, + { syncChainTip: 'checkpointed' }, + )); rollup = new RollupContract( deployL1ContractsValues.l1Client, @@ -109,16 +113,34 @@ describe('e2e_multi_validator_node', () => { await teardown(); }); + const deployOwnerAccount = async () => { + const accountData = initialFundedAccounts[0]; + const accountManager = await wallet.createSchnorrAccount( + accountData.secret, + accountData.salt, + accountData.signingKey, + ); + const deployMethod = await accountManager.getDeployMethod(); + await deployMethod.send({ + from: NO_FROM, + wait: { + waitForStatus: TxStatus.CHECKPOINTED, + timeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, + }, + }); + await wallet.sync(); + ownerAddress = accountManager.address; + }; + it('should build blocks & attest with multiple validator keys', async () => { + await deployOwnerAccount(); + const deployer = new ContractDeployer(artifact, wallet); logger.info(`Deploying contract from ${ownerAddress}`); const { receipt: tx } = await deployer .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) .send({ from: ownerAddress }); - await waitForProven(aztecNode, tx, { - provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, - }); expect(tx.blockNumber).toBeDefined(); const dataStore = (aztecNode as AztecNodeService).getBlockSource() as Archiver; @@ -166,6 +188,7 @@ describe('e2e_multi_validator_node', () => { BigInt(await cheatCodes.rollup.getEpoch()) + BigInt(config.lagInEpochsForValidatorSet + 1), ), ); + await deployOwnerAccount(); // check that the committee is undefined const committee = await rollup.getCurrentEpochCommittee(); @@ -177,9 +200,6 @@ describe('e2e_multi_validator_node', () => { const { receipt: tx } = await deployer .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) .send({ from: ownerAddress }); - await waitForProven(aztecNode, tx, { - provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, - }); expect(tx.blockNumber).toBeDefined(); const dataStore = (aztecNode as AztecNodeService).getBlockSource() as Archiver; @@ -196,8 +216,13 @@ describe('e2e_multi_validator_node', () => { expect(attestations.length).toBeGreaterThanOrEqual((COMMITTEE_SIZE * 2) / 3 + 1); - const signers = attestations.map(att => att.getSender()!.toString()); + const signers = attestations.map(att => att.getSender()!.toString().toLowerCase()); + const validatorAddressesLower = validatorAddresses.map(a => a.toLowerCase()); + expect(signers.every(s => validatorAddressesLower.includes(s))).toBe(true); - expect(signers).toEqual(expect.arrayContaining(validatorAddresses.slice(0, COMMITTEE_SIZE))); + const committeeAtCheckpoint = await rollup.getCommitteeAt(publishedCheckpoint.checkpoint.header.timestamp); + expect(committeeAtCheckpoint?.length).toBe(COMMITTEE_SIZE); + const committeeAtCheckpointLower = committeeAtCheckpoint!.map(a => a.toString().toLowerCase()); + expect(signers.every(s => committeeAtCheckpointLower.includes(s))).toBe(true); }); }); diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index dd61f6328e4f..b8948b1c5f46 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -5,6 +5,7 @@ import type { Logger } from '@aztec/aztec.js/log'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, expectTokenBalance } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; @@ -38,7 +39,10 @@ describe('e2e_multiple_accounts_1_enc_key', () => { }), ); - ({ teardown, logger, wallet, accounts } = await setup(numAccounts, { initialFundedAccounts })); + ({ teardown, logger, wallet, accounts } = await setup(numAccounts, { + ...AUTOMINE_E2E_OPTS, + initialFundedAccounts, + })); logger.info('Account contracts deployed'); ({ contract: token } = await deployToken(wallet, accounts[0], initialBalance, logger)); @@ -96,5 +100,5 @@ describe('e2e_multiple_accounts_1_enc_key', () => { expectedBalancesAfterTransfer2[2] + transferAmount3, ]; await transfer(1, 2, transferAmount3, expectedBalancesAfterTransfer3); - }, 120_000); + }, 300_000); }); diff --git a/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts b/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts index 316fd63a5bba..f14dacab2420 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts @@ -13,6 +13,7 @@ import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import { L2Block } from '@aztec/stdlib/block'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_multiple_blobs', () => { @@ -34,7 +35,7 @@ describe('e2e_multiple_blobs', () => { aztecNodeAdmin: maybeAztecNodeAdmin, wallet, teardown, - } = await setup(1)); + } = await setup(1, { ...PIPELINING_SETUP_OPTS })); aztecNodeAdmin = maybeAztecNodeAdmin!; ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts index aab6d6fb59c4..abee1fff29d8 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts @@ -1,6 +1,7 @@ import { ImportTestContract } from '@aztec/noir-test-contracts.js/ImportTest'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -10,7 +11,7 @@ describe('e2e_nested_contract manual', () => { let { wallet, logger, defaultAccountAddress } = t; beforeAll(async () => { - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ wallet, logger, defaultAccountAddress } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts index d702434c7f10..46ce281b4387 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts @@ -1,3 +1,4 @@ +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -5,7 +6,7 @@ describe('e2e_nested_contract manual', () => { let { parentContract, childContract, defaultAccountAddress } = t; beforeAll(async () => { - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); await t.applyManual(); ({ parentContract, childContract, defaultAccountAddress } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts index 0e19664a5662..3996780c3895 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts @@ -3,6 +3,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { ParentContract } from '@aztec/noir-test-contracts.js/Parent'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual_enqueue', () => { @@ -14,7 +15,7 @@ describe('e2e_nested_contract manual_enqueue', () => { beforeAll(async () => { // We don't deploy contracts in beforeAll because every test requires a fresh setup - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ wallet, defaultAccountAddress, aztecNode } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts index a699ea8f1764..53ddaa2c06f6 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts @@ -4,6 +4,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; import { serializeToBuffer } from '@aztec/foundation/serialize'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -14,7 +15,7 @@ describe('e2e_nested_contract manual', () => { aztecNode.getPublicStorageAt('latest', child.address, new Fr(1)); beforeAll(async () => { - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); await t.applyManual(); ({ wallet, parentContract, childContract, defaultAccountAddress, aztecNode } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts index 769db81c1ba0..d68dcc808b16 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts @@ -7,6 +7,7 @@ import { ParentContract } from '@aztec/noir-test-contracts.js/Parent'; import { type EndToEndContext, + type SetupOptions, deployAccounts, publicDeployAccounts, setup, @@ -50,9 +51,10 @@ export class NestedContractTest { await publicDeployAccounts(this.wallet, [this.defaultAccountAddress]); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up fresh subsystems'); this.context = await setup(0, { + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, }); diff --git a/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts b/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts index 1d7ba02c11c8..d06520a1ae6b 100644 --- a/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts @@ -5,9 +5,10 @@ import type { UtilityCallAuthorizationRequest } from '@aztec/pxe/server'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; // Verifies nested utility calls via pow_utility(x, n) = x^n (recursive utility→utility), // calling it from a private function via pow_private, and the default hook behavior. @@ -25,7 +26,7 @@ describe('Nested utility calls', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: contractA } = await NestedUtilityContract.deploy(wallet).send({ from: defaultAccountAddress })); ({ contract: contractB } = await NestedUtilityContract.deploy(wallet).send({ from: defaultAccountAddress })); }); @@ -77,6 +78,7 @@ describe('authorizeUtilityCall hook', () => { wallet, accounts: [defaultAccountAddress], } = await setup(1, { + ...AUTOMINE_E2E_OPTS, pxeCreationOptions: { hooks: { authorizeUtilityCall: (req: UtilityCallAuthorizationRequest) => { diff --git a/yarn-project/end-to-end/src/e2e_nft.test.ts b/yarn-project/end-to-end/src/e2e_nft.test.ts index 7e7f8da1079a..61ed76a31318 100644 --- a/yarn-project/end-to-end/src/e2e_nft.test.ts +++ b/yarn-project/end-to-end/src/e2e_nft.test.ts @@ -5,9 +5,10 @@ import { NFTContract } from '@aztec/noir-contracts.js/NFT'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; // This is a very simple test checking only the happy path. More complete tests of the NFT are implemented with TXE. // This test is only kept around to check that public data writes are squashed as expected. @@ -30,7 +31,7 @@ describe('NFT', () => { beforeAll(async () => { let accounts: AztecAddress[]; - ({ teardown, wallet, accounts } = await setup(4)); + ({ teardown, wallet, accounts } = await setup(4, { ...AUTOMINE_E2E_OPTS })); [adminAddress, minterAddress, user1Address, user2Address] = accounts; ({ contract: nftContract } = await NFTContract.deploy(wallet, adminAddress, 'FROG', 'FRG').send({ diff --git a/yarn-project/end-to-end/src/e2e_note_getter.test.ts b/yarn-project/end-to-end/src/e2e_note_getter.test.ts index a72a1fc61393..db658379f610 100644 --- a/yarn-project/end-to-end/src/e2e_note_getter.test.ts +++ b/yarn-project/end-to-end/src/e2e_note_getter.test.ts @@ -4,6 +4,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { NoteGetterContract } from '@aztec/noir-test-contracts.js/NoteGetter'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; interface NoirBoundedVec { @@ -25,7 +26,7 @@ describe('e2e_note_getter', () => { teardown, wallet, accounts: [defaultAddress], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); }); afterAll(() => teardown()); diff --git a/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts b/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts index fe8db573792b..a44255b1e78e 100644 --- a/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts +++ b/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts @@ -5,11 +5,12 @@ import { OffchainEffectContract, type TestEvent } from '@aztec/noir-test-contrac import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('e2e_offchain_effect', () => { let contract1: OffchainEffectContract; @@ -25,7 +26,7 @@ describe('e2e_offchain_effect', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: contract1 } = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress })); ({ contract: contract2 } = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts b/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts index 52087116c316..c1158d3a998a 100644 --- a/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts +++ b/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts @@ -1,26 +1,24 @@ /* eslint-disable camelcase */ +import type { AztecNodeService } from '@aztec/aztec-node'; import { AztecAddress } from '@aztec/aztec.js/addresses'; import { extractOffchainOutput } from '@aztec/aztec.js/contracts'; import type { AztecNode } from '@aztec/aztec.js/node'; -import type { CheatCodes } from '@aztec/aztec/testing'; -import type { BlockNumber } from '@aztec/foundation/branded-types'; import { retryUntil } from '@aztec/foundation/retry'; import { OffchainPaymentContract } from '@aztec/noir-test-contracts.js/OffchainPayment'; -import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { getLogger, setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('e2e_offchain_payment', () => { let contract: OffchainPaymentContract; let aztecNode: AztecNode; - let aztecNodeAdmin: AztecNodeAdmin; - let cheatCodes: CheatCodes; + let aztecNodeService: AztecNodeService; let wallet: TestWallet; let accounts: AztecAddress[]; let teardown: () => Promise; @@ -29,7 +27,8 @@ describe('e2e_offchain_payment', () => { jest.setTimeout(TIMEOUT); beforeAll(async () => { - ({ teardown, wallet, accounts, aztecNode, aztecNodeAdmin, cheatCodes } = await setup(2, { + ({ teardown, wallet, accounts, aztecNode, aztecNodeService } = await setup(2, { + ...AUTOMINE_E2E_OPTS, anvilSlotsInAnEpoch: 32, })); }); @@ -43,43 +42,14 @@ describe('e2e_offchain_payment', () => { async function forceEmptyBlock() { const blockBefore = await aztecNode.getBlockNumber(); logger.info(`Forcing empty block. Current L2 block: ${blockBefore}`); - await aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); - await retryUntil( - async () => { - const current = await aztecNode.getBlockNumber(); - logger.info(`Waiting for new L2 block. Current: ${current}`); - return current > blockBefore; - }, - 'new L2 block', - 30, - 1, - ); - await aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); + await aztecNodeService.mineBlock(); + logger.info(`Empty block mined. New L2 block: ${await aztecNode.getBlockNumber()}`); } - async function forceReorg(block: BlockNumber) { - // Pause sync as soon as the block is checkpointed so finalization doesn't race ahead - // of the rollback target. Without this, the archiver can finalize past the target block - // between the retryUntil returning and pauseSync executing. - await retryUntil( - async () => { - const tips = await aztecNode.getChainTips(); - if (tips.checkpointed.block.number >= block) { - await aztecNodeAdmin.pauseSync(); - return true; - } - return false; - }, - 'checkpointed block', - 30, - 1, - ); - - await cheatCodes.eth.reorg(1); - // Pass resumeSync=false so the archiver doesn't immediately re-download the same checkpoint - // (which would re-sync the PXE before callers can inspect the rolled-back state). - await aztecNodeAdmin.rollbackTo(Number(block) - 1, /* force */ false, /* resumeSync */ false); - expect(await aztecNode.getBlockNumber()).toBe(Number(block) - 1); + async function forceReorg(checkpointBeforeTx: number) { + const automine = aztecNodeService.getAutomineSequencer()!; + await automine.revertToCheckpoint(checkpointBeforeTx); + logger.info(`Reverted to checkpoint ${checkpointBeforeTx}`); } it('processes an offchain-delivered private payment via QR-style handoff', async () => { @@ -142,6 +112,9 @@ describe('e2e_offchain_payment', () => { await contract.methods.mint(mintAmount, alice).send({ from: alice }); + // Capture the checkpoint tip before the transfer tx so we know where to revert to. + const checkpointBeforeTx = (await aztecNode.getChainTips()).checkpointed.checkpoint.number; + const provenTx = await proveInteraction(wallet, contract.methods.transfer_offchain(paymentAmount, bob), { from: alice, }); @@ -149,7 +122,6 @@ describe('e2e_offchain_payment', () => { const receipt = await provenTx.send(); expect(receipt.blockNumber).toBeDefined(); - const txBlockNumber = receipt.blockNumber!; const txHash = provenTx.getTxHash(); const txEffectBeforeReorg = await aztecNode.getTxEffect(txHash); @@ -196,7 +168,7 @@ describe('e2e_offchain_payment', () => { const { result: aliceBalance } = await contract.methods.get_balance(alice).simulate({ from: alice }); expect(aliceBalance).toBe(mintAmount - paymentAmount); - await forceReorg(txBlockNumber); + await forceReorg(checkpointBeforeTx); // Verify that the payment TX is no longer present after the reorg const txEffectAfterRollback = await aztecNode.getTxEffect(txHash); @@ -210,13 +182,23 @@ describe('e2e_offchain_payment', () => { const { result: aliceAfterRollback } = await contract.methods.get_balance(alice).simulate({ from: alice }); expect(aliceAfterRollback).toBe(mintAmount); - // Resume sync so the archiver can re-download the checkpoints and the sequencer can produce blocks. - await aztecNodeAdmin.resumeSync(); - - // The archiver re-syncs the same checkpoints from L1 after the reorg, so the tx gets re-mined automatically. - // Force an empty block so the PXE re-syncs and reprocesses the offchain-delivered notes. + // The p2p tx pool marks rolled-back txs as pending again, so the AutomineSequencer + // re-mines the transfer tx automatically. Force a block build so the PXE re-syncs + // and reprocesses the offchain-delivered notes. await forceEmptyBlock(); + // Wait for the PXE to process the re-mined block and update its note view. + // The PXE syncs asynchronously from the archiver, so the balance may lag briefly. + await retryUntil( + async () => { + const { result } = await contract.methods.get_balance(bob).simulate({ from: bob }); + return result === paymentAmount; + }, + 'Bob balance restored after re-mine', + 30, + 0.1, + ); + // Check that the message was reprocessed and Bob has his payment again. // Notice what we want to test here is that the offchain effects don't need to be re-enqueued // for the system to re-process it. diff --git a/yarn-project/end-to-end/src/e2e_option_params.test.ts b/yarn-project/end-to-end/src/e2e_option_params.test.ts index 99c373092636..1ece966388d9 100644 --- a/yarn-project/end-to-end/src/e2e_option_params.test.ts +++ b/yarn-project/end-to-end/src/e2e_option_params.test.ts @@ -5,9 +5,10 @@ import { OptionParamContract } from '@aztec/noir-test-contracts.js/OptionParam'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; const U64_MAX = 2n ** 64n - 1n; const I64_MIN = -(2n ** 63n); @@ -32,7 +33,7 @@ describe('Option params', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); contract = (await OptionParamContract.deploy(wallet).send({ from: defaultAccountAddress })).contract; }); diff --git a/yarn-project/end-to-end/src/e2e_orderbook.test.ts b/yarn-project/end-to-end/src/e2e_orderbook.test.ts index 4f566ca466c8..6a959b27de86 100644 --- a/yarn-project/end-to-end/src/e2e_orderbook.test.ts +++ b/yarn-project/end-to-end/src/e2e_orderbook.test.ts @@ -9,11 +9,12 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; // Unhappy path tests are written only in Noir. // @@ -47,7 +48,7 @@ describe('Orderbook', () => { accounts: [adminAddress, makerAddress, takerAddress], aztecNode, logger, - } = await setup(3)); + } = await setup(3, { ...AUTOMINE_E2E_OPTS })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_ordering.test.ts b/yarn-project/end-to-end/src/e2e_ordering.test.ts index 56f8df05058a..c7f15e8cc36b 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -11,6 +11,7 @@ import { computeCalldataHash } from '@aztec/stdlib/hash'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -26,8 +27,7 @@ describe('e2e_ordering', () => { let defaultAccountAddress: AztecAddress; let teardown: () => Promise; - const expectLogsFromLastBlockToBe = async (logMessages: bigint[]) => { - const fromBlock = await aztecNode.getBlockNumber(); + const expectLogsFromBlockToBe = async (logMessages: bigint[], fromBlock: number) => { const logFilter = { fromBlock, toBlock: fromBlock + 1, @@ -45,7 +45,7 @@ describe('e2e_ordering', () => { wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); }, TIMEOUT); afterEach(() => teardown()); @@ -77,7 +77,7 @@ describe('e2e_ordering', () => { const action = parent.methods[method](child.address, pubSetValueSelector); const tx = await proveInteraction(wallet, action, { from: defaultAccountAddress }); - await tx.send(); + const receipt = await tx.send(); // There are two enqueued calls const enqueuedPublicCalls = tx.getPublicCallRequestsWithCalldata(); @@ -94,7 +94,7 @@ describe('e2e_ordering', () => { expect(enqueuedPublicCalls.map(c => c.args[0].toBigInt())).toEqual(expectedOrder); // Logs are emitted in the expected order - await expectLogsFromLastBlockToBe(expectedOrder); + await expectLogsFromBlockToBe(expectedOrder, receipt.blockNumber!); // The final value of the child is the last one set const value = await aztecNode.getPublicStorageAt('latest', child.address, new Fr(1)); @@ -133,10 +133,10 @@ describe('e2e_ordering', () => { ] as const)('orders public logs in %s', async method => { const expectedOrder = expectedOrders[method]; - await child.methods[method]().send({ from: defaultAccountAddress }); + const { receipt } = await child.methods[method]().send({ from: defaultAccountAddress }); // Logs are emitted in the expected order - await expectLogsFromLastBlockToBe(expectedOrder); + await expectLogsFromBlockToBe(expectedOrder, receipt.blockNumber!); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts index e386f7ae17c3..5c4c468fbcdf 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts @@ -10,7 +10,7 @@ import { RollupCheatCodes } from '@aztec/aztec/testing'; import { FeeAssetHandlerContract, RegistryContract, RollupContract } from '@aztec/ethereum/contracts'; import { deployRollupForUpgrade } from '@aztec/ethereum/deploy-aztec-l1-contracts'; import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract'; -import { type L1ContractAddresses, pickL1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses'; +import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses'; import { L1TxUtils, createL1TxUtils } from '@aztec/ethereum/l1-tx-utils'; import type { ExtendedViemWalletClient } from '@aztec/ethereum/types'; import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; @@ -555,8 +555,7 @@ describe('e2e_p2p_add_rollup', () => { dataDirectory: DATA_DIR_NEW, rollupVersion: Number(newVersion), governanceProposerPayload: EthAddress.ZERO, - ...t.ctx.deployL1ContractsValues.l1ContractAddresses, - ...addresses, + l1Contracts: { ...t.ctx.deployL1ContractsValues.l1ContractAddresses, ...addresses }, }; await setupSharedBlobStorage(newConfig); @@ -611,7 +610,7 @@ describe('e2e_p2p_add_rollup', () => { nodes[0], initialTestAccounts[0], t.ctx.deployL1ContractsValues.l1Client, - pickL1ContractAddresses(newConfig), + newConfig.l1Contracts, BigInt(newConfig.rollupVersion), newConfig.l1RpcUrls, ); diff --git a/yarn-project/end-to-end/src/e2e_p2p/broadcasted_invalid_block_proposal_slash.test.ts b/yarn-project/end-to-end/src/e2e_p2p/broadcasted_invalid_block_proposal_slash.test.ts index 02dd223b3b86..2915bca2ce86 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/broadcasted_invalid_block_proposal_slash.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/broadcasted_invalid_block_proposal_slash.test.ts @@ -1,4 +1,5 @@ import type { AztecNodeService } from '@aztec/aztec-node'; +import type { TestAztecNodeService } from '@aztec/aztec-node/test'; import { EthAddress } from '@aztec/aztec.js/addresses'; import { EpochNumber } from '@aztec/foundation/branded-types'; import { promiseWithResolvers } from '@aztec/foundation/promise'; @@ -13,7 +14,7 @@ import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; import { createNodes } from '../fixtures/setup_p2p_test.js'; import { P2PNetworkTest } from './p2p_network.js'; -import { awaitCommitteeExists, awaitOffenseDetected } from './shared.js'; +import { advanceToEpochBeforeProposer, awaitCommitteeExists, awaitOffenseDetected } from './shared.js'; const TEST_TIMEOUT = 1_000_000; @@ -114,10 +115,14 @@ describe('e2e_p2p_broadcasted_invalid_block_proposal_slash', () => { t.logger.warn('Creating nodes'); - // Create first node that broadcasts invalid proposals + // Create first node that broadcasts invalid proposals. Keep its sequencer stopped until + // every node has joined the P2P mesh; otherwise (under proposer pipelining) the invalid + // proposer can publish its sole bad block to slot N before the honest nodes are connected, + // and they will reject the proposal as "invalid slot number" instead of slashing it. const invalidProposerConfig = { ...t.ctx.aztecNodeConfig, broadcastInvalidBlockProposal: true, + dontStartSequencer: true, }; const invalidProposerNodes = await createNodes( invalidProposerConfig, @@ -134,9 +139,9 @@ describe('e2e_p2p_broadcasted_invalid_block_proposal_slash', () => { const invalidProposerAddress = invalidProposerNodes[0].getSequencer()!.validatorAddresses![0]; t.logger.warn(`Invalid proposer address: ${invalidProposerAddress.toString()}`); - // Create remaining honest nodes + // Create remaining honest nodes, also with sequencers stopped, for the same reason. const honestNodes = await createNodes( - t.ctx.aztecNodeConfig, + { ...t.ctx.aztecNodeConfig, dontStartSequencer: true }, t.ctx.dateProvider, t.bootstrapNodeEnr, NUM_VALIDATORS - 1, @@ -149,42 +154,39 @@ describe('e2e_p2p_broadcasted_invalid_block_proposal_slash', () => { nodes = [...invalidProposerNodes, ...honestNodes]; - // Wait for P2P mesh to be fully formed before proceeding + // Wait for P2P mesh to be fully formed before starting sequencers await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); await awaitCommitteeExists({ rollup, logger: t.logger }); - const startSlot = await rollup.getSlotNumber(); - const proposerEarliestSlot = startSlot + 1; - - // Wait until the bad proposer has had a slot - await retryUntil( - async () => { - const currentSlot = await rollup.getSlotNumber(); - return currentSlot >= proposerEarliestSlot; - }, - 'Wait for next slot...', - TEST_TIMEOUT / 1000, - ETHEREUM_SLOT_DURATION, - ); - - await retryUntil( - async () => { - const currentProposer = await rollup.getCurrentProposer(); - if (!currentProposer.equals(invalidProposerAddress)) { - t.logger.info( - `Current proposer: ${currentProposer}, waiting for malicious proposer ${invalidProposerAddress} to get a slot...`, - ); - return false; - } - return true; - }, - 'Wait for malicious proposer slot...', - TEST_TIMEOUT / 1000, - ETHEREUM_SLOT_DURATION, - ); + // Find an epoch where the invalid proposer is selected, stopping one epoch before so + // we have time to start sequencers before the target epoch arrives. + const epochCache = (honestNodes[0] as TestAztecNodeService).epochCache; + const { targetEpoch } = await advanceToEpochBeforeProposer({ + epochCache, + cheatCodes: t.ctx.cheatCodes.rollup, + targetProposer: invalidProposerAddress, + logger: t.logger, + }); - const offenses = await awaitOffenseDetected({ + // Start all sequencers while still one epoch before the target + t.logger.warn('Starting all sequencers'); + await Promise.all(nodes.map(n => n.getSequencer()!.start())); + + // Now warp to one slot before the target epoch — sequencers are already running. + // Under proposer pipelining, the invalid proposer begins building for the first slot + // of the target epoch one slot earlier; warping to the start of the epoch would force + // the bad proposal to serialize past the slot boundary, after which honest receivers + // reject it as late. + t.logger.warn(`Advancing to one slot before target epoch ${targetEpoch}`); + await t.ctx.cheatCodes.rollup.advanceToEpoch(targetEpoch, { offset: -AZTEC_SLOT_DURATION }); + + // Wait for offense to be detected. Under proposer pipelining, the invalid block proposal is + // broadcast at the slot boundary while a receiver's wall clock may have already advanced + // past the build slot — when that happens, the honest node rejects the gossip with "invalid + // slot number" before slashing logic runs. Collect offenses from every node so we catch + // whichever node managed to process the proposal while still in the build slot. + await awaitOffenseDetected({ epochDuration: t.ctx.aztecNodeConfig.aztecEpochDuration, logger: t.logger, nodeAdmin: nodes[1], // Use honest node to check for offenses @@ -193,10 +195,23 @@ describe('e2e_p2p_broadcasted_invalid_block_proposal_slash', () => { timeoutSeconds: AZTEC_SLOT_DURATION * 16, }); - // Check offense is correct - expect(offenses).toHaveLength(1); - expect(offenses[0].offenseType).toEqual(OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL); - expect(offenses[0].validator.toString()).toEqual(t.validators[0].attester.toString()); + const invalidBlockOffenses = await retryUntil( + async () => { + const allOffenses = (await Promise.all(nodes.map(n => n.getSlashOffenses('all')))).flat(); + const filtered = allOffenses.filter(o => o.offenseType === OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL); + if (filtered.length > 0) { + return filtered; + } + }, + 'broadcasted invalid block proposal offense', + AZTEC_SLOT_DURATION * 4, + ); + + t.logger.warn(`Collected broadcasted invalid block proposal offenses`, { invalidBlockOffenses }); + expect(invalidBlockOffenses.length).toBeGreaterThan(0); + for (const offense of invalidBlockOffenses) { + expect(offense.validator.toString()).toEqual(invalidProposerAddress.toString()); + } // Check slash is recorded on chain const slashPromise = promiseWithResolvers<{ amount: bigint; attester: EthAddress }>(); diff --git a/yarn-project/end-to-end/src/e2e_p2p/data_withholding_slash.test.ts b/yarn-project/end-to-end/src/e2e_p2p/data_withholding_slash.test.ts index 808b7222a1d0..bf3bb2aac524 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/data_withholding_slash.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/data_withholding_slash.test.ts @@ -1,8 +1,9 @@ import type { AztecNodeService } from '@aztec/aztec-node'; import { waitForTx } from '@aztec/aztec.js/node'; -import { EpochNumber } from '@aztec/foundation/branded-types'; -import { times } from '@aztec/foundation/collection'; +import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types'; +import { retryUntil } from '@aztec/foundation/retry'; import { OffenseType } from '@aztec/slasher'; +import { Tx, TxHash } from '@aztec/stdlib/tx'; import { jest } from '@jest/globals'; import fs from 'fs'; @@ -11,43 +12,56 @@ import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; import { createNodes } from '../fixtures/setup_p2p_test.js'; -import { P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js'; -import { awaitCommitteeExists, awaitCommitteeKicked, awaitOffenseDetected, submitTransactions } from './shared.js'; +import { P2PNetworkTest } from './p2p_network.js'; +import { awaitCommitteeExists, awaitOffenseDetected, submitTransactions } from './shared.js'; -jest.setTimeout(1000000); +const TEST_TIMEOUT = 1_000_000; +jest.setTimeout(TEST_TIMEOUT); -// Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds +// Don't set this above 9 — each node uses a distinct anvil seed for its publisher account. const NUM_VALIDATORS = 4; const BOOT_NODE_UDP_PORT = 4500; const COMMITTEE_SIZE = NUM_VALIDATORS; - -// This test needs longer slot window to ensure that the client has enough time to submit their txs, -// and have the nodes get recreated, prior to the reorg. -const AZTEC_SLOT_DURATION = process.env.AZTEC_SLOT_DURATION ? parseInt(process.env.AZTEC_SLOT_DURATION) : 32; +const ETHEREUM_SLOT_DURATION = 4; +const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 3; +const TOLERANCE_SLOTS = 3; const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'data-withholding-slash-')); /** - * Demonstrate that slashing occurs when the chain is pruned, and we are unable to collect the transactions data post-hoc. - * - * The setup of the test is as follows: - * 1. Create the "initial" node, and 4 other nodes - * 2. Await the 4 other nodes to form the committee - * 3. Send a tx to the initial node - * 4. Stop all the nodes and wipe their data directories - * 5. Re-create the nodes - * 6. Expect that a slash payload is deployed with the data withholding offense + * Verifies the per-slot data-withholding slash path (A-523). * - * The reason is that with the data directories wiped, they have no way to get the original transaction data - * when the chain is pruned. So they slash themselves. + * Scenario — a realistic data-withholding attack: * + * 1. 4 validators, all in the committee. slashSelfAllowed, quorum 3. + * 2. Pick one validator to be the malicious proposer (A). Its outbound tx gossip is + * stubbed so the tx never leaves A's mempool. The tx is sent directly to A. + * 3. Two other committee members (B, C) are configured to "attest blindly" — their + * block- and checkpoint-proposal handlers are stubbed to return isValid:true without + * re-executing. They sign whatever A broadcasts. + * 4. The fourth committee member (D) is honest: it tries to fetch the missing tx, can't, + * and refuses to attest. + * 5. Tx-collection is also stubbed on every node so no path can pull the tx from A — + * not at proposal time, not via post-mining backfill. This simulates the data being + * genuinely unavailable to anyone except A. + * 6. A self-attests + collects B's and C's attestations → quorum 3 → publishes. + * 7. After `slashDataWithholdingToleranceSlots` full slots, the watchers on B, C, and D + * probe `getAvailableTxs` against their own mempools, find the tx missing, and emit + * a slot-keyed DATA_WITHHOLDING for the three attesters (A, B, C). + * 8. With slashSelfAllowed the offense reaches quorum; A, B, C are slashed on L1. D is + * not slashed because it never attested. */ describe('e2e_p2p_data_withholding_slash', () => { let t: P2PNetworkTest; - let nodes: AztecNodeService[]; + let nodes: AztecNodeService[] = []; const slashingUnit = BigInt(1e18); const slashingQuorum = 3; + // L1 enforces `QUORUM > ROUND_SIZE / 2`, so with quorum=3 we cap round size at 5. + // With committee 4 and only B/C/D voting (A has the tx and never detects the offense), + // a single 4-slot round only meets quorum when all three of B/C/D happen to propose + // (~23% probability). Extending slashOffenseExpirationRounds gives us several rounds to + // hit quorum before the offense expires. const slashingRoundSize = 4; const aztecEpochDuration = 2; @@ -62,17 +76,20 @@ describe('e2e_p2p_data_withholding_slash', () => { anvilSlotsInAnEpoch: 4, listenAddress: '127.0.0.1', aztecEpochDuration, - ethereumSlotDuration: 4, + ethereumSlotDuration: ETHEREUM_SLOT_DURATION, aztecSlotDuration: AZTEC_SLOT_DURATION, - aztecProofSubmissionEpochs: 0, // effectively forces instant reorgs aztecTargetCommitteeSize: COMMITTEE_SIZE, + // Long proof submission window so the legacy L1-prune path is irrelevant. + aztecProofSubmissionEpochs: 1024, + slashInactivityConsecutiveEpochThreshold: 32, slashingQuorum, slashingRoundSizeInEpochs: slashingRoundSize / aztecEpochDuration, slashAmountSmall: slashingUnit, slashAmountMedium: slashingUnit * 2n, slashAmountLarge: slashingUnit * 3n, slashSelfAllowed: true, - minTxsPerBlock: 0, + slashDataWithholdingToleranceSlots: TOLERANCE_SLOTS, + minTxsPerBlock: 1, enableProposerPipelining: true, inboxLag: 2, }, @@ -83,41 +100,53 @@ describe('e2e_p2p_data_withholding_slash', () => { }); afterEach(async () => { - await t.stopNodes(nodes); + if (nodes.length > 0) { + await t.stopNodes(nodes); + } await t.teardown(); for (let i = 0; i < NUM_VALIDATORS; i++) { fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); } }); - const debugRollup = async () => { - await t.ctx.cheatCodes.rollup.debugRollup(); - }; - - it('slashes the committee when data is unavailable for the pruned epoch', async () => { + it('slashes attesters that attest to proposals containing withheld transactions', async () => { if (!t.bootstrapNodeEnr) { throw new Error('Bootstrap node ENR is not available'); } - const { rollup, slashingProposer } = await t.getContracts(); - - // Jump forward to an epoch in the future such that the validator set is not empty - await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); - await debugRollup(); + const { rollup } = await t.getContracts(); + + // Jump to an epoch where the validator set is non-empty. The validator set rotates per + // epoch and sometimes lands empty for early epochs, so advance epoch-by-epoch until we + // find one with a full committee. + let epoch = EpochNumber(4); + await retryUntil( + async () => { + await t.ctx.cheatCodes.rollup.advanceToEpoch(epoch); + const committee = await rollup.getCurrentEpochCommittee(); + if (committee?.length === NUM_VALIDATORS) { + t.logger.warn(`Found valid committee of ${committee.length} at epoch ${epoch}`); + return true; + } + t.logger.warn(`Epoch ${epoch} has ${committee?.length ?? 0} committee members, advancing`); + epoch = EpochNumber(epoch + 1); + return false; + }, + 'epoch with full committee', + 120, + 0, + ); const [activationThreshold, ejectionThreshold, localEjectionThreshold] = await Promise.all([ rollup.getActivationThreshold(), rollup.getEjectionThreshold(), rollup.getLocalEjectionThreshold(), ]); - - // Slashing amount should be enough to kick validators out const slashingAmount = slashingUnit * 3n; const biggestEjection = ejectionThreshold > localEjectionThreshold ? ejectionThreshold : localEjectionThreshold; expect(activationThreshold - slashingAmount).toBeLessThan(biggestEjection); t.ctx.aztecNodeConfig.slashDataWithholdingPenalty = slashingAmount; - t.ctx.aztecNodeConfig.slashPrunePenalty = slashingAmount; t.ctx.aztecNodeConfig.minTxsPerBlock = 1; t.logger.warn('Creating nodes'); @@ -129,124 +158,106 @@ describe('e2e_p2p_data_withholding_slash', () => { BOOT_NODE_UDP_PORT, t.genesis, DATA_DIR, - // To collect metrics - run in aztec-packages `docker compose --profile metrics up` and set COLLECT_METRICS=true shouldCollectMetrics(), ); - // Wait for P2P mesh to be fully formed before proceeding await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); - await debugRollup(); - const committee = await awaitCommitteeExists({ rollup, logger: t.logger }); - await debugRollup(); + await awaitCommitteeExists({ rollup, logger: t.logger }); - // Jump forward more time to ensure we're at the beginning of an epoch. - // This should reduce flake, since we need to have the transaction included - // and the nodes recreated, prior to the reorg. - // Considering the slot duration is 32 seconds, - // Considering the epoch duration is 2 slots, - // we have ~64 seconds to do this. + // The validator watchers floor processing at their boot slot. Advance past it so the tx + // checkpoint lands in a slot the watcher will actually process. await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(8)); - await t.sendDummyTx(); - await debugRollup(); - - // Send L2 txs through a validator node to ensure blocks are built (needed for pruning to trigger). - t.logger.warn('Sending L2 txs through a validator node'); - const txHashes = await submitTransactions(t.logger, nodes[0], 1, t.fundedAccount); - await Promise.all(txHashes.map(txHash => waitForTx(nodes[0], txHash, { timeout: WAIT_FOR_TX_TIMEOUT }))); - t.logger.warn('L2 txs mined'); - - t.logger.warn('Stopping nodes'); - // removeInitialNode sends a dummy L1 tx and awaits its receipt to sync the - // dateProvider, so it must run while L1 mining is still active. - await t.removeInitialNode(); - - // Pause L1 block production while we tear down and recreate validators. With - // `aztecProofSubmissionEpochs=0`, epoch 8 becomes prunable as soon as epoch 9 begins - // (~32s after slot 17). The stop/wipe/recreate cycle takes longer than that, so L1 - // would otherwise race past the prune deadline before the recreated nodes come up. - // When that happens, the recreated archivers detect the prune during their initial - // sync (`handleEpochPrune` emits `L2PruneUnproven`), but the `EpochPruneWatcher` - // listener is only attached after `archiver.waitForInitialSync()` resolves - // (see `aztec-node/server.ts`), so the event is dropped and `DATA_WITHHOLDING` is - // never emitted. By freezing L1 here, the recreated archivers ingest checkpoint 1 - // cleanly during initial sync, the watcher starts and attaches its listener, and - // then we resume L1 below so the prune fires while the listener is live. - const ethCheatCodes = t.ctx.cheatCodes.eth; - await ethCheatCodes.setAutomine(false); - await ethCheatCodes.setIntervalMining(0); - - // Fail fast if we paused too late — i.e. if L1 already crossed into epoch 9 before - // we got here. In that case the recreated nodes would still see the prune during - // initial sync and the test would flake exactly the same way. - const epochAtPause = await rollup.getCurrentEpoch(); - expect(Number(epochAtPause)).toBeLessThan(9); - - // Now stop the validator nodes. With L1 paused, any in-flight L1 submissions from - // the validator sequencers would hang `sequencer.stop()` (it awaits pending L1 - // submissions). Since `minTxsPerBlock=1` and no txs are queued for slot 18+, the - // sequencers don't submit further L1 transactions after the slot-17 checkpoint - // (already published before `waitForTx` returned), so this is safe. - await t.stopNodes(nodes); - // And remove the data directories (which forms the crux of the "attack") - for (let i = 0; i < NUM_VALIDATORS; i++) { - fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); - } - // Re-create the nodes. - // ASSUMING they sync in the middle of the epoch, they will "see" the reorg, and try to slash. - // Reset minTxsPerBlock to 0 so re-created validators build empty checkpoints. Under proposer - // pipelining, the vote-offenses signature is bound to the target slot and the multicall is only - // delayed to the target slot start when a checkpoint is being proposed; without a proposal, - // votes would mine in the current wall-clock slot, causing the EIP-712 signature verification to fail. - t.ctx.aztecNodeConfig.minTxsPerBlock = 0; - t.logger.warn('Re-creating nodes'); - nodes = await createNodes( - t.ctx.aztecNodeConfig, - t.ctx.dateProvider, - t.bootstrapNodeEnr, - NUM_VALIDATORS, - BOOT_NODE_UDP_PORT, - t.genesis, - DATA_DIR, + // Assign roles. With minTxsPerBlock=1 and tx gossip suppressed on the proposer, only the + // proposer can ever build a block, so we just wait for it to be designated proposer. + const [proposerNode, blindAttester1, blindAttester2, honestNode] = nodes; + const proposerAddress = proposerNode.getSequencer()!.validatorAddresses![0]; + const blindAttester1Address = blindAttester1.getSequencer()!.validatorAddresses![0]; + const blindAttester2Address = blindAttester2.getSequencer()!.validatorAddresses![0]; + const honestAddress = honestNode.getSequencer()!.validatorAddresses![0]; + t.logger.warn( + `Proposer ${proposerAddress}, blind attesters ${blindAttester1Address}/${blindAttester2Address}, honest ${honestAddress}`, ); - // Wait for P2P mesh to be fully formed before proceeding - await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); + // 1. Stub outbound tx gossip on the proposer. Tx messages going out are dropped silently; + // other gossip topics (proposals, attestations) pass through. + const proposerP2pService: any = (proposerNode as any).p2pClient.p2pService; + const originalPropagate = proposerP2pService.propagate.bind(proposerP2pService); + jest.spyOn(proposerP2pService, 'propagate').mockImplementation(((msg: any) => { + if (msg instanceof Tx) { + t.logger.info(`Suppressing outbound tx gossip from proposer ${proposerAddress}`); + return Promise.resolve(); + } + return originalPropagate(msg); + }) as any); + + // 2. Stub tx-collection on EVERY node so nothing can pull the tx back from the proposer + // over reqresp (neither at proposal time nor via post-mining backfill). + for (const node of nodes) { + const txCollection: any = (node as any).p2pClient.txCollection; + jest.spyOn(txCollection, 'collectFastFor').mockResolvedValue([]); + jest.spyOn(txCollection, 'collectFastForBlock').mockResolvedValue(undefined); + } + + // 3. Stub block- and checkpoint-proposal handling on the blind attesters so they attest + // without re-executing or fetching txs. + for (const node of [blindAttester1, blindAttester2]) { + const proposalHandler: any = (node as any).validatorClient.getProposalHandler(); + jest.spyOn(proposalHandler, 'handleBlockProposal').mockImplementation((async () => { + const blockNumber = await node.getBlockNumber(); + return { isValid: true, blockNumber: BlockNumber(blockNumber + 1) }; + }) as any); + jest.spyOn(proposalHandler, 'handleCheckpointProposal').mockResolvedValue({ + isValid: true, + checkpointNumber: CheckpointNumber(1), + } as any); + } - // Resume L1 block production. Warp L1 forward to current wall-clock time so the - // epoch-8 deadline is crossed immediately on the next L1 block, then re-enable - // interval mining. By now each recreated archiver has block 1 stored locally and - // its `EpochPruneWatcher` listener is attached, so the next sync iteration emits - // `L2PruneUnproven` for epoch 8 to a live listener → `DATA_WITHHOLDING`. - const resumeTimestamp = Math.floor(t.ctx.dateProvider.now() / 1000); - await ethCheatCodes.setNextBlockTimestamp(resumeTimestamp); - await ethCheatCodes.mine(); - await ethCheatCodes.setIntervalMining(t.ctx.aztecNodeConfig.ethereumSlotDuration); + // 4. Send the tx directly to the proposer; it propagates into the local mempool and stays + // there (gossip suppressed). Combined with `minTxsPerBlock: 1`, only the proposer can + // build a block, so the tx sits in the mempool until the proposer is next selected. + t.logger.warn(`Submitting tx through proposer ${proposerAddress}`); + const [txHash] = await submitTransactions(t.logger, proposerNode, 1, t.fundedAccount); + await waitForTx(proposerNode, txHash, { timeout: AZTEC_SLOT_DURATION * 6 * 1000 }); + const checkpointSlot = await getMinedSlot(proposerNode, txHash); + t.logger.warn(`Tx ${txHash} mined at checkpoint slot ${checkpointSlot}`); + + // 5. After the tolerance window, every non-proposer's watcher should fire for the 3 + // attesters (proposer A self-signs, plus blind attesters B and C). + const expectedOffendedAddresses = [proposerAddress, blindAttester1Address, blindAttester2Address] + .map(a => a.toString()) + .sort(); const offenses = await awaitOffenseDetected({ epochDuration: t.ctx.aztecNodeConfig.aztecEpochDuration, logger: t.logger, - nodeAdmin: nodes[0], + nodeAdmin: honestNode, slashingRoundSize, - waitUntilOffenseCount: COMMITTEE_SIZE, + waitUntilOffenseCount: 3, + timeoutSeconds: AZTEC_SLOT_DURATION * (TOLERANCE_SLOTS + 8), }); - // Check offenses are correct - expect(offenses.map(o => o.validator.toString()).sort()).toEqual(committee.map(a => a.toString()).sort()); - expect(offenses.map(o => o.offenseType)).toEqual(times(COMMITTEE_SIZE, () => OffenseType.DATA_WITHHOLDING)); - const offenseEpoch = Number(offenses[0].epochOrSlot); - - await awaitCommitteeKicked({ - rollup, - cheatCodes: t.ctx.cheatCodes.rollup, - committee, - slashingProposer, - slashingRoundSize, - aztecSlotDuration: AZTEC_SLOT_DURATION, - logger: t.logger, - offenseEpoch, - aztecEpochDuration, - }); + expect(offenses).toHaveLength(3); + expect(offenses.map(o => o.offenseType)).toEqual(offenses.map(() => OffenseType.DATA_WITHHOLDING)); + for (const offense of offenses) { + expect(offense.epochOrSlot).toEqual(BigInt(checkpointSlot)); + } + expect(offenses.map(o => o.validator.toString()).sort()).toEqual(expectedOffendedAddresses); + // The honest non-attester must NOT be slashed. + expect(offenses.map(o => o.validator.toString())).not.toContain(honestAddress.toString()); }); }); + +/** Returns the slot at which a tx was included, by querying the node's tx receipt. */ +async function getMinedSlot(node: AztecNodeService, txHash: TxHash): Promise { + const receipt = await node.getTxReceipt(txHash); + if (!receipt.blockNumber) { + throw new Error(`Tx ${txHash} has no block number on receipt`); + } + const block = await node.getBlock(receipt.blockNumber); + if (!block) { + throw new Error(`Block ${receipt.blockNumber} not found`); + } + return Number(block.header.getSlot()); +} diff --git a/yarn-project/end-to-end/src/e2e_p2p/duplicate_attestation_slash.test.ts b/yarn-project/end-to-end/src/e2e_p2p/duplicate_attestation_slash.test.ts index ce4a8f706999..9c27e88a5f4f 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/duplicate_attestation_slash.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/duplicate_attestation_slash.test.ts @@ -213,6 +213,18 @@ describe('e2e_p2p_duplicate_attestation_slash', () => { nodes = [maliciousNode1, maliciousNode2, honestNode1, honestNode2]; + // Stub the proposer's own-checkpoint-proposal loopback on the malicious nodes. The default + // path awaits a local handleCheckpointProposal → validateCheckpointProposal that retries + // until the proposed block lands in the archiver — but skipPushProposedBlocksToArchiver + // means it never does, so the await hangs until the retry deadline (~one slot). By the + // time the proposer returns from broadcast, the wallclock is in the target slot and the + // staleness gate refuses the self-attestation, so no duplicate attestations are ever + // broadcast. + for (const node of [maliciousNode1, maliciousNode2]) { + const p2pService: any = (node as any).p2pClient.p2pService; + jest.spyOn(p2pService, 'notifyOwnCheckpointProposal').mockResolvedValue(undefined); + } + // Wait for P2P mesh on all needed topics before starting sequencers await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS, 30, 0.1, [ TopicType.tx, diff --git a/yarn-project/end-to-end/src/e2e_p2p/fee_asset_price_oracle_gossip.test.ts b/yarn-project/end-to-end/src/e2e_p2p/fee_asset_price_oracle_gossip.test.ts index c384797a938c..06fc7ac0d486 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/fee_asset_price_oracle_gossip.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/fee_asset_price_oracle_gossip.test.ts @@ -63,6 +63,8 @@ describe('e2e_p2p_network', () => { slashingRoundSizeInEpochs: 2, slashingQuorum: 5, listenAddress: '127.0.0.1', + // Pipelining: target-slot is one ahead of build-slot; inboxLag sources L1->L2 + // messages from the previous checkpoint to avoid L1ToL2MessagesNotReadyError. enableProposerPipelining: true, inboxLag: 2, }, diff --git a/yarn-project/end-to-end/src/e2e_p2p/multiple_validators_sentinel.parallel.test.ts b/yarn-project/end-to-end/src/e2e_p2p/multiple_validators_sentinel.parallel.test.ts index b270212db706..eb907ce5571e 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/multiple_validators_sentinel.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/multiple_validators_sentinel.parallel.test.ts @@ -1,6 +1,6 @@ import type { AztecNodeService } from '@aztec/aztec-node'; import { RollupContract } from '@aztec/ethereum/contracts'; -import type { SlotNumber } from '@aztec/foundation/branded-types'; +import { SlotNumber } from '@aztec/foundation/branded-types'; import { retryUntil } from '@aztec/foundation/retry'; import { tryStop } from '@aztec/stdlib/interfaces/server'; @@ -216,7 +216,7 @@ describe('e2e_p2p_multiple_validators_sentinel', () => { const firstNodeBlockProposedHistory = firstNodeValidators .flatMap(v => stats.stats[v.toString().toLowerCase()].history) .filter(h => h.slot > initialSlot && h.slot <= slotForSentinel) - .filter(h => h.status === 'checkpoint-proposed'); + .filter(h => h.status === 'checkpoint-valid' || h.status === 'checkpoint-mined'); expect(firstNodeBlockProposedHistory).not.toBeEmpty(); // And all of the proposers for the offline node must be seen as missed attestation or proposal diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp.test.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp.test.ts index bb6fdba84001..18b9e94818b5 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp.test.ts @@ -1,10 +1,16 @@ import type { AztecNodeService } from '@aztec/aztec-node'; +import { jest } from '@jest/globals'; + import type { P2PNetworkTest } from '../p2p_network.js'; import { cleanupReqrespTest, createReqrespDataDir, createReqrespTest, runReqrespTxTest } from './utils.js'; const DATA_DIR = createReqrespDataDir(); +// Under pipelining a 36s aztec slot plus build-slot/target-slot round trip + L1 +// publish exceeds the default 5 min jest test timeout. Allow 15 min. +jest.setTimeout(15 * 60 * 1000); + describe('e2e_p2p_reqresp_tx', () => { let t: P2PNetworkTest; let nodes: AztecNodeService[]; diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp_no_handshake.test.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp_no_handshake.test.ts index 9816c47621e8..48d503d127d7 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp_no_handshake.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp_no_handshake.test.ts @@ -1,5 +1,7 @@ import type { AztecNodeService } from '@aztec/aztec-node'; +import { jest } from '@jest/globals'; + import type { P2PNetworkTest } from '../p2p_network.js'; import { cleanupReqrespTest, createReqrespDataDir, createReqrespTest, runReqrespTxTest } from './utils.js'; @@ -9,6 +11,10 @@ import { cleanupReqrespTest, createReqrespDataDir, createReqrespTest, runReqresp const DATA_DIR = createReqrespDataDir(); +// Under pipelining a 36s aztec slot plus build-slot/target-slot round trip + L1 +// publish exceeds the default 5 min jest test timeout. Allow 15 min. +jest.setTimeout(15 * 60 * 1000); + describe('e2e_p2p_reqresp_tx_no_handshake', () => { let t: P2PNetworkTest; let nodes: AztecNodeService[]; diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts index 71f440695add..84ed608550ca 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts @@ -14,7 +14,7 @@ import path from 'path'; import { getBootNodeUdpPort, shouldCollectMetrics } from '../../fixtures/fixtures.js'; import { createNodes } from '../../fixtures/setup_p2p_test.js'; -import { P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from '../p2p_network.js'; +import { P2PNetworkTest } from '../p2p_network.js'; import { prepareTransactions } from '../shared.js'; // Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds @@ -49,6 +49,10 @@ export async function createReqrespTest(options: ReqrespOptions = {}): Promise

L2 + // messages from the previous checkpoint to avoid L1ToL2MessagesNotReadyError. + enableProposerPipelining: true, + inboxLag: 2, }, }); await t.setup(); @@ -125,7 +129,15 @@ export async function runReqrespTxTest(params: { t.ctx.dateProvider.setTime(Number(timestamp) * 1000); const startSlotTimestamp = BigInt(timestamp); - const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes(t, startSlotTimestamp); + // Under pipelining the active builder during wallclock slot S targets slot S+1, so + // we must address the proposer of S+1 (not S) for batch 0. Shift the proposer lookup + // window by the pipelining offset so we always send to the currently-building proposer. + const proposerSlotOffset = t.ctx.aztecNodeConfig.enableProposerPipelining ? 1 : 0; + const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes( + t, + startSlotTimestamp, + proposerSlotOffset, + ); t.logger.info(`Turning off tx gossip for nodes: ${nodesToTurnOffTxGossip.map(getNodePort)}`); t.logger.info(`Sending txs to proposer nodes: ${proposerIndexes.map(getNodePort)}`); @@ -176,12 +188,17 @@ export async function runReqrespTxTest(params: { t.logger.info(`Node ${getNodePort(i)} pool has ${count} pending txs`); } + // Use the test's own aztecSlotDuration (not the env default that p2p_network's + // WAIT_FOR_TX_TIMEOUT is derived from) so the timeout scales with this test's 36s slot. + // Under pipelining the round-trip is roughly build-slot + target-slot + L1 publish, so + // budget for >= 3 slots. + const waitForTxTimeout = t.ctx.aztecNodeConfig.aztecSlotDuration * 4.5; t.logger.info('Waiting for all transactions to be mined'); await Promise.all( submittedTxs.flatMap((batch, batchIndex) => batch.map(async (submittedTx, txIndex) => { t.logger.info(`Waiting for tx ${batchIndex}-${txIndex} ${submittedTx.txHash.toString()} to be mined`); - await waitForTx(submittedTx.node, submittedTx.txHash, { timeout: WAIT_FOR_TX_TIMEOUT * 1.5 }); + await waitForTx(submittedTx.node, submittedTx.txHash, { timeout: waitForTxTimeout }); t.logger.info(`Tx ${batchIndex}-${txIndex} ${submittedTx.txHash.toString()} has been mined`); }), ), @@ -223,7 +240,7 @@ export async function runReqrespTxTest(params: { return nodes; } -async function getProposerIndexes(t: P2PNetworkTest, startSlotTimestamp: bigint) { +async function getProposerIndexes(t: P2PNetworkTest, startSlotTimestamp: bigint, slotOffset = 0) { // Get the nodes for the next set of slots const rollupContract = new RollupContract( t.ctx.deployL1ContractsValues.l1Client, @@ -235,7 +252,7 @@ async function getProposerIndexes(t: P2PNetworkTest, startSlotTimestamp: bigint) const proposers = await Promise.all( Array.from({ length: 3 }, async (_, i) => { - const slot = SlotNumber(startSlot + i); + const slot = SlotNumber(startSlot + slotOffset + i); const slotTimestamp = await rollupContract.getTimestampForSlot(slot); return await rollupContract.getProposerAt(slotTimestamp); }), diff --git a/yarn-project/end-to-end/src/e2e_p2p/sentinel_status_slash.parallel.test.ts b/yarn-project/end-to-end/src/e2e_p2p/sentinel_status_slash.parallel.test.ts new file mode 100644 index 000000000000..bf315256df17 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_p2p/sentinel_status_slash.parallel.test.ts @@ -0,0 +1,414 @@ +import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; +import type { TestAztecNodeService } from '@aztec/aztec-node/test'; +import type { EthAddress } from '@aztec/aztec.js/addresses'; +import { RollupContract } from '@aztec/ethereum/contracts'; +import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { unique } from '@aztec/foundation/collection'; +import { retryUntil } from '@aztec/foundation/retry'; +import { OffenseType } from '@aztec/slasher'; +import { tryStop } from '@aztec/stdlib/interfaces/server'; +import type { ValidatorStatusInSlot } from '@aztec/stdlib/validators'; + +import { jest } from '@jest/globals'; +import fs from 'fs'; +import 'jest-extended'; +import os from 'os'; +import path from 'path'; + +import { shouldCollectMetrics } from '../fixtures/fixtures.js'; +import { createNodes } from '../fixtures/setup_p2p_test.js'; +import { P2PNetworkTest } from './p2p_network.js'; +import { awaitCommitteeExists } from './shared.js'; + +/** + * Exercises the sentinel's six-case proposer-status taxonomy end-to-end by driving each of the + * status variants via in-tree validator-config flags (no jest stubbing of internals): + * + * 1. `checkpoint-unvalidated` (case 3) — one validator runs with `broadcastInvalidBlockProposal`, + * so honest observers reject its block proposals (state_mismatch) and never push them to + * their archivers. When the checkpoint proposal arrives, observers fail to load the last + * block → record `unvalidated`; the sentinel slashes the proposer for inactivity. + * + * 2. `checkpoint-invalid` (case 4) — one validator runs with + * `broadcastInvalidCheckpointProposalOnly`, so its block proposals stay valid (pushed to + * observers' archivers) but its checkpoint proposal carries a random archive. Observers + * load the last block, find an archive mismatch, and record `invalid`; the sentinel + * slashes the proposer for inactivity. + * + * 3. Successful re-execution + missing attestor (case 5) — all six validators start + * honest, then one is stopped mid-test. The stopped node misses its own proposer slots + * and stops attesting to others; the sentinel slashes it for inactivity. + */ + +const TEST_TIMEOUT = 1_000_000; +jest.setTimeout(TEST_TIMEOUT); + +const NUM_VALIDATORS = 6; +const COMMITTEE_SIZE = NUM_VALIDATORS; +const BOOT_NODE_UDP_PORT = 4700; +const ETHEREUM_SLOT_DURATION = process.env.CI ? 8 : 4; +const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 2; +const AZTEC_EPOCH_DURATION = 2; +const SLASHING_UNIT = BigInt(1e18); +const SLASHING_AMOUNT = SLASHING_UNIT * 3n; +const SLASHING_QUORUM = 3; +const SLASHING_ROUND_SIZE_IN_EPOCHS = 2; + +const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'sentinel-status-slash-')); + +describe('e2e_p2p_sentinel_status_slash', () => { + let t: P2PNetworkTest; + let nodes: AztecNodeService[] = []; + let rollup: RollupContract; + + beforeEach(async () => { + t = await P2PNetworkTest.create({ + testName: 'e2e_p2p_sentinel_status_slash', + numberOfNodes: 0, + numberOfValidators: NUM_VALIDATORS, + basePort: BOOT_NODE_UDP_PORT, + metricsPort: shouldCollectMetrics(), + startProverNode: true, + initialConfig: { + anvilSlotsInAnEpoch: 4, + listenAddress: '127.0.0.1', + aztecTargetCommitteeSize: COMMITTEE_SIZE, + aztecSlotDuration: AZTEC_SLOT_DURATION, + ethereumSlotDuration: ETHEREUM_SLOT_DURATION, + aztecEpochDuration: AZTEC_EPOCH_DURATION, + aztecProofSubmissionEpochs: 1024, + minTxsPerBlock: 0, + enableProposerPipelining: true, + inboxLag: 2, + mockGossipSubNetwork: true, + sentinelEnabled: true, + // A single proposer-fault slot in an epoch gives missed/total = 1/6 ≈ 0.167; threshold + // 0.1 lets that single fault trip inactivity. + slashInactivityTargetPercentage: 0.1, + slashInactivityConsecutiveEpochThreshold: 1, + slashingQuorum: SLASHING_QUORUM, + slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE_IN_EPOCHS, + slashAmountSmall: SLASHING_UNIT, + slashAmountMedium: SLASHING_UNIT * 2n, + slashAmountLarge: SLASHING_AMOUNT, + slashInactivityPenalty: SLASHING_AMOUNT, + slashSelfAllowed: true, + // Sentinel evaluates an epoch's performance once this buffer has elapsed past its last slot. + sentinelEpochEndBufferSlots: 2, + // Suppress the BROADCASTED_INVALID_BLOCK_PROPOSAL slash so the only slashing signal in + // tests 1 and 2 is the INACTIVITY offense from the sentinel. + slashBroadcastedInvalidBlockPenalty: 0n, + }, + }); + + await t.setup(); + await t.applyBaseSetup(); + + ({ rollup } = await t.getContracts()); + + // Advance until the committee is populated. + let epoch = EpochNumber(4); + await retryUntil( + async () => { + await t.ctx.cheatCodes.rollup.advanceToEpoch(epoch); + const committee = await rollup.getCurrentEpochCommittee(); + if (committee?.length === NUM_VALIDATORS) { + return true; + } + epoch = EpochNumber(epoch + 1); + return false; + }, + 'epoch with full committee', + 120, + 0, + ); + }); + + afterEach(async () => { + if (nodes.length > 0) { + await t.stopNodes(nodes); + nodes = []; + } + await t.teardown(); + for (let i = 0; i < NUM_VALIDATORS; i++) { + fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); + } + }); + + it('slashes the proposer with INACTIVITY when checkpoint validation records unvalidated', async () => { + // One malicious node broadcasts invalid block proposals; honest observers reject them via + // re-execution state_mismatch and therefore never push to their archivers, so the malicious + // node's checkpoint proposals can't find their last block and observers record `unvalidated`. + const targetAddress = await spawnMaliciousAndHonestNodes({ broadcastInvalidBlockProposal: true }); + // Warp near the malicious node's proposer slot to keep wall-clock down. We discover the slot at + // which the fault is actually recorded rather than assuming it is the warped block-proposer + // slot: the re-execution outcome is keyed by the checkpoint proposal's slot, and a proposer + // only emits a checkpoint proposal when its slot closes a checkpoint, which does not always + // coincide with the block-proposer slot we warp to. + await warpToSlotBeforeTargetProposer(targetAddress); + // nodes[0] is the malicious node; honest observers are nodes[1..]. + const honestObservers = nodes.slice(1); + const faultSlot = await findObservedStatusSlot(honestObservers, targetAddress, 'checkpoint-unvalidated'); + await assertAllObserversSentinelStatus(honestObservers, targetAddress, faultSlot, 'checkpoint-unvalidated'); + // The malicious node self-records `checkpoint-valid` for that slot using the locally computed + // archive (broadcastInvalidBlockProposal only corrupts the broadcast archive, not the + // proposer's local state). + await assertAllObserversSentinelStatus([nodes[0]], targetAddress, faultSlot, 'checkpoint-valid'); + await assertInactivityOffenseFor(targetAddress, nodes[1]); + }); + + it('slashes the proposer with INACTIVITY when checkpoint validation records invalid', async () => { + // One malicious node broadcasts invalid CHECKPOINT proposals while keeping the underlying + // block proposals valid; observers accept the blocks (so they land in the archiver) but + // reject the checkpoint via header_mismatch, recording `invalid`. + const targetAddress = await spawnMaliciousAndHonestNodes({ broadcastInvalidCheckpointProposalOnly: true }); + await warpToSlotBeforeTargetProposer(targetAddress); + const honestObservers = nodes.slice(1); + const faultSlot = await findObservedStatusSlot(honestObservers, targetAddress, 'checkpoint-invalid'); + await assertAllObserversSentinelStatus(honestObservers, targetAddress, faultSlot, 'checkpoint-invalid'); + // Malicious self-records `checkpoint-valid` for that slot — proposers always consider their + // own freshly-built proposal valid from their local-state perspective. + await assertAllObserversSentinelStatus([nodes[0]], targetAddress, faultSlot, 'checkpoint-valid'); + await assertInactivityOffenseFor(targetAddress, nodes[1]); + }); + + it('slashes an attestor that gets stopped after the network is running', async () => { + nodes = await createNodes( + t.ctx.aztecNodeConfig, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + NUM_VALIDATORS, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + ); + + await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); + await awaitCommitteeExists({ rollup, logger: t.logger }); + + // Pick the last node as the one to stop so that target proposer rotation is unaffected. + const targetIdx = NUM_VALIDATORS - 1; + const targetAddress = (nodes[targetIdx] as any).getSequencer()!.validatorAddresses![0] as EthAddress; + t.logger.warn(`Stopping node ${targetIdx} (validator ${targetAddress})`); + await tryStop(nodes[targetIdx]); + // Remove from the array we will tear down in afterEach to avoid double-stop. + nodes = nodes.filter((_, i) => i !== targetIdx); + + // All remaining nodes are honest observers. + await assertAllObserversObservedAttestationMissed(nodes, targetAddress); + await assertInactivityOffenseFor(targetAddress, nodes[0]); + }); + + // -- helpers ------------------------------------------------------------------------------ + + /** + * Spawns 1 malicious node at index 0 with the given config override, then `NUM_VALIDATORS - 1` + * honest nodes at indices 1..N-1. Returns the malicious node's validator address. + */ + async function spawnMaliciousAndHonestNodes(maliciousOverride: Partial): Promise { + const maliciousNodes = await createNodes( + { ...t.ctx.aztecNodeConfig, ...maliciousOverride }, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + 1, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + 0, + ); + const targetAddress = (maliciousNodes[0] as any).getSequencer()!.validatorAddresses![0] as EthAddress; + t.logger.warn(`Malicious node validator address: ${targetAddress}`, { maliciousOverride }); + + const honestNodes = await createNodes( + t.ctx.aztecNodeConfig, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + NUM_VALIDATORS - 1, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + 1, + ); + + nodes = [...maliciousNodes, ...honestNodes]; + + await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); + await awaitCommitteeExists({ rollup, logger: t.logger }); + await t.monitor.waitUntilCheckpoint(CheckpointNumber(1)); + + return targetAddress; + } + + /** + * Finds the next slot at which `targetAddress` is the proposer and warps L1 time to the slot + * just before it (so the proposer-pipelining build phase for the target's slot lands on the + * malicious node immediately, with no need to poll for the slot to come around naturally). + * + * Probes the NEXT epoch's slots only (further epochs revert with `EpochNotStable`). If the + * target isn't selected next epoch, advances one epoch and tries again. + */ + async function warpToSlotBeforeTargetProposer(targetAddress: EthAddress): Promise { + const epochCache = (nodes[0] as TestAztecNodeService).epochCache; + const cheatCodes = t.ctx.cheatCodes.rollup; + const maxEpochAttempts = 20; + // Minimum slots between the warp landing (`targetSlot - 1`) and where we currently are. + // Without this, the malicious's bad broadcast lands while observers are still transitioning + // across the epoch boundary and gossipsub may drop the proposal. Two slots of real-time + // is enough for everyone to stabilise. + const minBufferSlots = 2; + + for (let attempt = 0; attempt < maxEpochAttempts; attempt++) { + const currentSlot = Number(await cheatCodes.getSlot()); + const currentEpoch = Math.floor(currentSlot / AZTEC_EPOCH_DURATION); + // Search the remainder of the current epoch and all of the next epoch (the second-next + // epoch's committee may revert with EpochNotStable). Skip slots within `minBufferSlots` + // of the current slot — too close to warp into safely. + const searchStart = currentSlot + minBufferSlots; + const searchEnd = (currentEpoch + 2) * AZTEC_EPOCH_DURATION - 1; + + let targetSlot: number | undefined; + for (let s = searchStart; s <= searchEnd; s++) { + const proposer = await epochCache.getProposerAttesterAddressInSlot(SlotNumber(s)); + if (proposer && targetAddress.equals(proposer)) { + targetSlot = s; + break; + } + } + + if (targetSlot === undefined) { + t.logger.info(`Target not selected as proposer in slots ${searchStart}..${searchEnd}; advancing one epoch`); + await cheatCodes.advanceToNextEpoch(); + continue; + } + + // Land 2 slots before the target. The malicious's sequencer pipelines for slot N during + // slot N-1, so landing at N-2 gives the network one full slot (N-1) of real-time to + // settle after the warp before the malicious starts building. Use the absolute-slot + // helper rather than `advanceSlots(N)` so any real-time elapsed between the slot search + // above and this call doesn't push us past the intended landing slot. + const landingSlot = SlotNumber(targetSlot - 2); + t.logger.warn( + `Target proposes at slot ${targetSlot}; warping to slot ${landingSlot} (target is 2 slots ahead to let gossipsub stabilise before the malicious broadcasts)`, + ); + if (landingSlot > currentSlot) { + await cheatCodes.advanceToSlot(landingSlot); + } + return SlotNumber(targetSlot); + } + + throw new Error( + `Target proposer ${targetAddress} not found with sufficient buffer within ${maxEpochAttempts} epochs`, + ); + } + + /** + * Finds the earliest slot at which EVERY honest observer has recorded `expectedStatus` for + * `targetAddress`. The slot at which the malicious node closes its checkpoint (and so the fault + * is recorded) is not necessarily the block-proposer slot we warp to, so we discover it rather + * than assuming it. Requiring cross-observer agreement avoids picking a slot that only one + * observer saw (e.g. one peer happened to be synced to the malicious proposer's gossip earlier + * than the others), which would then time out the downstream per-observer assertion. Times out + * — and therefore fails the test — if no common fault slot is ever recorded, so a genuine + * failure to detect the malicious proposal is still caught. + */ + async function findObservedStatusSlot( + observerNodes: AztecNodeService[], + targetAddress: EthAddress, + expectedStatus: ValidatorStatusInSlot, + ): Promise { + const slot = await retryUntil( + async () => { + const slotSets = await Promise.all( + observerNodes.map(async observerNode => { + const stats = await observerNode.getValidatorsStats(); + const history = stats.stats[targetAddress.toString()]?.history ?? []; + return new Set(history.filter(h => h.status === expectedStatus).map(h => Number(h.slot))); + }), + ); + if (slotSets.some(s => s.size === 0)) { + return undefined; + } + const [first, ...rest] = slotSets; + const common = [...first].filter(s => rest.every(other => other.has(s))).sort((a, b) => a - b); + return common.length > 0 ? SlotNumber(common[0]) : undefined; + }, + `cross-observer ${expectedStatus} for ${targetAddress}`, + AZTEC_SLOT_DURATION * 15, + ); + return slot; + } + + /** + * Polls every honest observer node until each has its sentinel record `expectedStatus` for the + * target at the given slot. Asserts the recorded status matches exactly on every observer. + */ + async function assertAllObserversSentinelStatus( + observerNodes: AztecNodeService[], + targetAddress: EthAddress, + slot: SlotNumber, + expectedStatus: ValidatorStatusInSlot, + ): Promise { + for (const observerNode of observerNodes) { + const status = await retryUntil( + async () => { + const stats = await observerNode.getValidatorsStats(); + const validator = stats.stats[targetAddress.toString()]; + const entry = validator?.history.find(h => Number(h.slot) === Number(slot)); + return entry?.status; + }, + `sentinel status for ${targetAddress} at slot ${slot}`, + AZTEC_SLOT_DURATION * 10, + ); + expect(status).toEqual(expectedStatus); + } + t.logger.warn( + `All ${observerNodes.length} observers recorded ${expectedStatus} for ${targetAddress} at slot ${slot}`, + ); + } + + /** + * Polls every honest observer node until each one has at least one `attestation-missed` entry + * for the target. Used by the stopped-attestor test where the slot of the miss is + * non-deterministic. + */ + async function assertAllObserversObservedAttestationMissed( + observerNodes: AztecNodeService[], + targetAddress: EthAddress, + ): Promise { + for (const observerNode of observerNodes) { + const slot = await retryUntil( + async () => { + const stats = await observerNode.getValidatorsStats(); + const validator = stats.stats[targetAddress.toString()]; + const miss = validator?.history.find(h => h.status === 'attestation-missed'); + return miss?.slot; + }, + `attestation-missed entry for ${targetAddress}`, + AZTEC_SLOT_DURATION * 20, + ); + expect(slot).toBeDefined(); + } + t.logger.warn(`All ${observerNodes.length} observers recorded attestation-missed for ${targetAddress}`); + } + + /** Polls the given honest observer node until an INACTIVITY offense for the target appears. */ + async function assertInactivityOffenseFor(targetAddress: EthAddress, observerNode: AztecNodeService): Promise { + const offenses = await retryUntil( + async () => { + const collected = await observerNode.getSlashOffenses('all'); + const inactivityForTarget = collected.filter( + o => o.offenseType === OffenseType.INACTIVITY && targetAddress.equals(o.validator), + ); + return inactivityForTarget.length > 0 ? inactivityForTarget : undefined; + }, + 'inactivity offense for target', + AZTEC_SLOT_DURATION * 40, + ); + t.logger.warn(`Detected ${offenses.length} INACTIVITY offense(s) for ${targetAddress}`, { offenses }); + expect(unique(offenses.map(o => o.validator.toString()))).toEqual([targetAddress.toString()]); + expect(unique(offenses.map(o => o.offenseType))).toEqual([OffenseType.INACTIVITY]); + } +}); diff --git a/yarn-project/end-to-end/src/e2e_p2p/valid_epoch_pruned_slash.test.ts b/yarn-project/end-to-end/src/e2e_p2p/valid_epoch_pruned_slash.test.ts deleted file mode 100644 index c9129bf2f3d6..000000000000 --- a/yarn-project/end-to-end/src/e2e_p2p/valid_epoch_pruned_slash.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -import type { AztecNodeService } from '@aztec/aztec-node'; -import { EpochNumber } from '@aztec/foundation/branded-types'; -import { times } from '@aztec/foundation/collection'; -import { sleep } from '@aztec/foundation/sleep'; -import { SpamContract } from '@aztec/noir-test-contracts.js/Spam'; -import { OffenseType } from '@aztec/slasher'; - -import { jest } from '@jest/globals'; -import fs from 'fs'; -import os from 'os'; -import path from 'path'; - -import { shouldCollectMetrics } from '../fixtures/fixtures.js'; -import { createNodes } from '../fixtures/setup_p2p_test.js'; -import { P2PNetworkTest } from './p2p_network.js'; -import { awaitCommitteeExists, awaitCommitteeKicked, awaitOffenseDetected } from './shared.js'; - -jest.setTimeout(10 * 60_000); // 10 minutes - -// Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds -const NUM_VALIDATORS = 4; -const COMMITTEE_SIZE = NUM_VALIDATORS; -const BOOT_NODE_UDP_PORT = 4500; - -const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'valid-epoch-pruned-slash-')); - -/** - * Test that we slash the committee when the pruned epoch could have been proven. - * We don't need to do anything special for this test other than to run it without a prover node - * (which is the default), and this will produce pruned epochs that could have been proven. But we do - * need to send a tx to make sure that the slash is due to valid epoch prune and not data withholding. - * - * TODO(palla/mbps): Add tests for 1) out messages and 2) partial epoch prunes - */ -describe('e2e_p2p_valid_epoch_pruned_slash', () => { - let t: P2PNetworkTest; - let nodes: AztecNodeService[]; - - const slashingQuorum = 3; - const slashingRoundSize = 4; - const ethereumSlotDuration = 8; - const aztecSlotDuration = 24; - const aztecEpochDuration = 2; - const initialEpoch = 8; - const slashingUnit = BigInt(1e18); - - beforeEach(async () => { - t = await P2PNetworkTest.create({ - testName: 'e2e_p2p_valid_epoch_pruned', - numberOfNodes: 0, - numberOfValidators: NUM_VALIDATORS, - basePort: BOOT_NODE_UDP_PORT, - metricsPort: shouldCollectMetrics(), - initialConfig: { - anvilSlotsInAnEpoch: 4, - enforceTimeTable: true, - cancelTxOnTimeout: false, - sequencerPublisherAllowInvalidStates: true, - listenAddress: '127.0.0.1', - aztecEpochDuration, - ethereumSlotDuration, - aztecSlotDuration, - aztecProofSubmissionEpochs: 1, - slashingQuorum, - slashingRoundSizeInEpochs: slashingRoundSize / aztecEpochDuration, - slashSelfAllowed: true, - slashGracePeriodL2Slots: initialEpoch * aztecEpochDuration, - slashAmountSmall: slashingUnit, - slashAmountMedium: slashingUnit * 2n, - slashAmountLarge: slashingUnit * 3n, - aztecTargetCommitteeSize: COMMITTEE_SIZE, - enableProposerPipelining: true, - inboxLag: 2, - }, - }); - - await t.setup(); - await t.applyBaseSetup(); - }); - - afterEach(async () => { - await t.stopNodes(nodes); - await t.teardown(); - for (let i = 0; i < NUM_VALIDATORS; i++) { - fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); - } - }); - - const debugRollup = async () => { - await t.ctx.cheatCodes.rollup.debugRollup(); - }; - - it('slashes the committee when the pruned epoch could have been proven', async () => { - // create the bootstrap node for the network - if (!t.bootstrapNodeEnr) { - throw new Error('Bootstrap node ENR is not available'); - } - - const { rollup, slashingProposer } = await t.getContracts(); - const [activationThreshold, ejectionThreshold, localEjectionThreshold] = await Promise.all([ - rollup.getActivationThreshold(), - rollup.getEjectionThreshold(), - rollup.getLocalEjectionThreshold(), - ]); - - // Slashing amount should be enough to kick validators out - const slashingAmount = slashingUnit * 3n; - const biggestEjection = ejectionThreshold > localEjectionThreshold ? ejectionThreshold : localEjectionThreshold; - expect(activationThreshold - slashingAmount).toBeLessThan(biggestEjection); - - t.ctx.aztecNodeConfig.slashPrunePenalty = slashingAmount; - t.ctx.aztecNodeConfig.minTxsPerBlock = 1; - t.ctx.aztecNodeConfig.txPoolDeleteTxsAfterReorg = true; - - t.logger.warn(`Creating ${NUM_VALIDATORS} new nodes`); - nodes = await createNodes( - t.ctx.aztecNodeConfig, - t.ctx.dateProvider, - t.bootstrapNodeEnr, - NUM_VALIDATORS, - BOOT_NODE_UDP_PORT, - t.genesis, - DATA_DIR, - // To collect metrics - run in aztec-packages `docker compose --profile metrics up` and set COLLECT_METRICS=true - shouldCollectMetrics(), - ); - - // Wait a bit for peers to discover each other - await sleep(4000); - await debugRollup(); - - // Wait for the committee to exist - await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(2)); - await t.ctx.cheatCodes.rollup.markAsProven(); - const committee = await awaitCommitteeExists({ rollup, logger: t.logger }); - await debugRollup(); - - // Set up a wallet and keep it out of reorgs - await t.ctx.cheatCodes.rollup.markAsProven(); - t.setupWalletOnNode(nodes[0]); - await t.setupAccount(); - await t.ctx.cheatCodes.rollup.markAsProven(); - - // Warp forward to after the initial grace period - expect(await rollup.getCurrentEpoch()).toBeLessThan(initialEpoch); - await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(initialEpoch), { offset: -ethereumSlotDuration }); - await t.ctx.cheatCodes.rollup.markAsProven(); - - // Send a tx to deploy a contract so that we have a tx with public function execution in the pruned epoch - // This allows us to test that the slashed offense is valid epoch prune and not data withholding - t.logger.warn(`Submitting deployment tx to the network`); - const _spamContract = await SpamContract.deploy(t.wallet!).send({ from: t.defaultAccountAddress! }); - - // And send a tx that depends on a tx with public function execution on a contract class that will be reorged out - // This allows us to test that we handle pruned contract classes correctly - // TODO(palla/A-51): For this check to actually check what we need, we need to ensure the deployment and the - // this tx are in different blocks but within the same epoch, so it gets reexecuted by the prune-watcher. - // This does not always happen in the current test setup. - // t.logger.warn(`Submitting tx with public function execution to the network`); - // await spamContract.methods.spam(1, 1, true).send({ from: t.defaultAccountAddress! }); - - // Remove initial node (it's a lightweight archiver with no P2P/validator/sequencer, but clean up anyway) - t.logger.warn(`Removing initial node`); - await t.removeInitialNode(); - - // Wait for epoch to be pruned and the offense to be detected - const offenses = await awaitOffenseDetected({ - logger: t.logger, - nodeAdmin: nodes[0], - slashingRoundSize, - epochDuration: t.ctx.aztecNodeConfig.aztecEpochDuration, - waitUntilOffenseCount: COMMITTEE_SIZE, - }); - - // Check offenses are correct - expect(offenses.map(o => o.validator.toString()).sort()).toEqual(committee.map(a => a.toString()).sort()); - expect(offenses.map(o => o.offenseType)).toEqual(times(COMMITTEE_SIZE, () => OffenseType.VALID_EPOCH_PRUNED)); - const offenseEpoch = Number(offenses[0].epochOrSlot); - - // And then wait for them to be kicked out - await awaitCommitteeKicked({ - rollup, - cheatCodes: t.ctx.cheatCodes.rollup, - committee, - slashingProposer, - slashingRoundSize, - aztecSlotDuration, - logger: t.logger, - offenseEpoch, - aztecEpochDuration, - }); - }); -}); diff --git a/yarn-project/end-to-end/src/e2e_partial_notes.test.ts b/yarn-project/end-to-end/src/e2e_partial_notes.test.ts index 8742a20129a0..ec1e4be32ac2 100644 --- a/yarn-project/end-to-end/src/e2e_partial_notes.test.ts +++ b/yarn-project/end-to-end/src/e2e_partial_notes.test.ts @@ -5,10 +5,11 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('partial notes', () => { jest.setTimeout(TIMEOUT); @@ -32,7 +33,7 @@ describe('partial notes', () => { wallet, accounts: [adminAddress, liquidityProviderAddress], logger, - } = await setup(2)); + } = await setup(2, { ...AUTOMINE_E2E_OPTS })); const { contract } = await deployToken(wallet, adminAddress, 0n, logger); token0 = contract; diff --git a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts index 05e3086eccda..7eebbe478baf 100644 --- a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts @@ -10,6 +10,7 @@ import { } from '@aztec/constants'; import { PendingNoteHashesContract } from '@aztec/noir-test-contracts.js/PendingNoteHashes'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -28,14 +29,25 @@ describe('e2e_pending_note_hashes_contract', () => { wallet, logger, accounts: [owner], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); }); afterAll(() => teardown()); + // Find the most recent block containing tx effects; pipelining may produce empty blocks after a tx lands. + const getLatestNonEmptyBlock = async () => { + const latest = await aztecNode.getBlockNumber(); + for (let n = latest; n > 0; n--) { + const block = (await aztecNode.getBlocks(n, 1, { includeTransactions: true }))[0]; + if (block.body.txEffects.length > 0) { + return block; + } + } + throw new Error('No non-empty block found'); + }; + const expectNoteHashesSquashedExcept = async (exceptFirstFew: number) => { - const blockNum = await aztecNode.getBlockNumber(); - const block = (await aztecNode.getBlocks(blockNum, 1, { includeTransactions: true }))[0]; + const block = await getLatestNonEmptyBlock(); const noteHashes = block.body.txEffects.flatMap(txEffect => txEffect.noteHashes); @@ -50,8 +62,7 @@ describe('e2e_pending_note_hashes_contract', () => { }; const expectNullifiersSquashedExcept = async (exceptFirstFew: number) => { - const blockNum = await aztecNode.getBlockNumber(); - const block = (await aztecNode.getBlocks(blockNum, 1, { includeTransactions: true }))[0]; + const block = await getLatestNonEmptyBlock(); const nullifierArray = block.body.txEffects.flatMap(txEffect => txEffect.nullifiers); @@ -66,8 +77,7 @@ describe('e2e_pending_note_hashes_contract', () => { }; const expectNoteLogsSquashedExcept = async (exceptFirstFew: number) => { - const blockNum = await aztecNode.getBlockNumber(); - const block = (await aztecNode.getBlocks(blockNum, 1, { includeTransactions: true }))[0]; + const block = await getLatestNonEmptyBlock(); const privateLogs = block.body.txEffects.flatMap(txEffect => txEffect.privateLogs); expect(privateLogs.length).toBe(exceptFirstFew); diff --git a/yarn-project/end-to-end/src/e2e_phase_check.test.ts b/yarn-project/end-to-end/src/e2e_phase_check.test.ts index 793368f9c582..bf72a88f06d3 100644 --- a/yarn-project/end-to-end/src/e2e_phase_check.test.ts +++ b/yarn-project/end-to-end/src/e2e_phase_check.test.ts @@ -9,6 +9,7 @@ import { getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contra import { PublicDataTreeLeaf } from '@aztec/stdlib/trees'; import { defaultInitialAccountFeeJuice } from '@aztec/world-state/testing'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -33,7 +34,7 @@ describe('Phase check', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { genesisPublicData: [genesisBalanceEntry] })); + } = await setup(1, { ...AUTOMINE_E2E_OPTS, genesisPublicData: [genesisBalanceEntry] })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); sponsoredFPC = await SponsoredFPCNoEndSetupContract.deploy(wallet, { diff --git a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts index 6a60739c2d36..98065f606d98 100644 --- a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts @@ -5,6 +5,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { PrivateVotingContract } from '@aztec/noir-contracts.js/PrivateVoting'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_voting_contract', () => { @@ -23,7 +24,7 @@ describe('e2e_voting_contract', () => { wallet, logger, accounts: [owner], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: votingContract } = await PrivateVotingContract.deploy(wallet, owner).send({ from: owner })); diff --git a/yarn-project/end-to-end/src/e2e_prover/client.test.ts b/yarn-project/end-to-end/src/e2e_prover/client.test.ts index aef6fcd86af6..f7821478e99a 100644 --- a/yarn-project/end-to-end/src/e2e_prover/client.test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/client.test.ts @@ -4,15 +4,20 @@ import type { ExtendedViemWalletClient } from '@aztec/ethereum/types'; import { parseBooleanEnv } from '@aztec/foundation/config'; import { FeeJuicePortalAbi, TestERC20Abi } from '@aztec/l1-artifacts'; -import '@jest/globals'; +import { jest } from '@jest/globals'; import { type GetContractReturnType, getContract } from 'viem'; import { FullProverTest } from '../fixtures/e2e_prover_test.js'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { proveInteraction } from '../test-wallet/utils.js'; // Set a very long 20 minute timeout. const TIMEOUT = 1_200_000; +// Pipelined 12s-slot setup chain (account deploys + token deploy + mint + epoch advance + +// prover-node startup) exceeds the default 5min jest per-test budget. +jest.setTimeout(15 * 60 * 1000); + describe('client_prover', () => { const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS); const COINBASE_ADDRESS = EthAddress.random(); @@ -25,26 +30,29 @@ describe('client_prover', () => { let feeJuiceToken: GetContractReturnType; let feeJuicePortal: GetContractReturnType; - beforeAll(async () => { - t.logger.warn(`Running suite with ${REAL_PROOFS ? 'real' : 'fake'} proofs`); + beforeAll( + async () => { + t.logger.warn(`Running suite with ${REAL_PROOFS ? 'real' : 'fake'} proofs`); - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); - ({ provenAsset, accounts, logger, wallet } = t); - [sender, recipient] = accounts; + ({ provenAsset, accounts, logger, wallet } = t); + [sender, recipient] = accounts; - feeJuicePortal = getContract({ - abi: FeeJuicePortalAbi, - address: t.l1Contracts.l1ContractAddresses.feeJuicePortalAddress.toString(), - client: t.l1Contracts.l1Client, - }); + feeJuicePortal = getContract({ + abi: FeeJuicePortalAbi, + address: t.l1Contracts.l1ContractAddresses.feeJuicePortalAddress.toString(), + client: t.l1Contracts.l1Client, + }); - feeJuiceToken = getContract({ - abi: TestERC20Abi, - address: t.l1Contracts.l1ContractAddresses.feeJuiceAddress.toString(), - client: t.l1Contracts.l1Client, - }); - }, 120_000); + feeJuiceToken = getContract({ + abi: TestERC20Abi, + address: t.l1Contracts.l1ContractAddresses.feeJuiceAddress.toString(), + client: t.l1Contracts.l1Client, + }); + }, + 15 * 60 * 1000, + ); afterAll(async () => { await t.teardown(); diff --git a/yarn-project/end-to-end/src/e2e_prover/full.test.ts b/yarn-project/end-to-end/src/e2e_prover/full.test.ts index 0afaf59aac08..615a54b23725 100644 --- a/yarn-project/end-to-end/src/e2e_prover/full.test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/full.test.ts @@ -1,6 +1,6 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import { EthAddress } from '@aztec/aztec.js/addresses'; -import { NO_WAIT, waitForProven } from '@aztec/aztec.js/contracts'; +import { BatchCall, NO_WAIT, waitForProven } from '@aztec/aztec.js/contracts'; import { waitForTx } from '@aztec/aztec.js/node'; import { Tx, TxExecutionResult } from '@aztec/aztec.js/tx'; import { RollupContract } from '@aztec/ethereum/contracts'; @@ -10,6 +10,8 @@ import { parseBooleanEnv } from '@aztec/foundation/config'; import { getTestData, isGenerateTestDataEnabled } from '@aztec/foundation/testing'; import { updateProtocolCircuitSampleInputs } from '@aztec/foundation/testing/files'; import { FeeJuicePortalAbi, TestERC20Abi } from '@aztec/l1-artifacts'; +import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; +import { ParentContract } from '@aztec/noir-test-contracts.js/Parent'; import { Gas } from '@aztec/stdlib/gas'; import { PrivateKernelTailCircuitPublicInputs } from '@aztec/stdlib/kernel'; import { ChonkProof } from '@aztec/stdlib/proofs'; @@ -17,17 +19,25 @@ import type { CircuitName } from '@aztec/stdlib/stats'; import { TX_ERROR_INVALID_PROOF } from '@aztec/stdlib/tx'; import TOML from '@iarna/toml'; -import '@jest/globals'; +import { jest } from '@jest/globals'; import { type GetContractReturnType, getContract } from 'viem'; import { FullProverTest } from '../fixtures/e2e_prover_test.js'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { ProvenTx, proveInteraction } from '../test-wallet/utils.js'; -// Set a very long 15 minute timeout. -const TIMEOUT = 900_000; +const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS); + +// Real proving can take 10+ min per epoch; under pipelined 12s slots a multi-epoch test +// can exceed 30 min. Keep 15 min for fake proofs, 45 min for real. +const TIMEOUT = REAL_PROOFS ? 45 * 60 * 1000 : 15 * 60 * 1000; + +// Apply the same budget to module-level hooks (beforeAll/afterAll/afterEach) so the +// pipelined setup chain (account deploys + token deploy + mint + epoch advance + +// prover-node startup) doesn't time out. +jest.setTimeout(TIMEOUT); describe('full_prover', () => { - const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS); const COINBASE_ADDRESS = EthAddress.random(); const t = new FullProverTest('full_prover', 1, COINBASE_ADDRESS, REAL_PROOFS); @@ -42,7 +52,7 @@ describe('full_prover', () => { beforeAll(async () => { t.logger.warn(`Running suite with ${REAL_PROOFS ? 'real' : 'fake'} proofs`); - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); ({ provenAsset, accounts, tokenSim, logger, cheatCodes, provenWallet, aztecNode } = t); [sender, recipient] = accounts; @@ -60,7 +70,7 @@ describe('full_prover', () => { address: t.l1Contracts.l1ContractAddresses.feeJuiceAddress.toString(), client: t.l1Contracts.l1Client, }); - }, 120_000); + }, TIMEOUT); afterAll(async () => { await t.teardown(); @@ -182,6 +192,34 @@ describe('full_prover', () => { if (!isGenerateTestDataEnabled() || REAL_PROOFS) { return; } + // Deploy Parent + Child and prove three private chains to regenerate + // `private-kernel-inner{,-2,-3}/Prover.toml`. The Token transfers below pack into init_2 / + // init_3 and never invoke plain `inner` / `inner_2` / `inner_3`. The planner is N=3 greedy, + // so we exercise it with three transactions: + // - 4 apps (entrypoint → parent.private_nested_static_call → parent.private_call → + // child.private_get_value) → init_3 + inner + // - 5 apps (BatchCall: nested chain + one extra leaf call) → init_3 + inner_2 + // - 6 apps (BatchCall: nested chain + two extra leaf calls) → init_3 + inner_3 + // `proveInteraction` alone is enough to capture `pushTestData('private-kernel-inner{,-2,-3}', + // ...)`; no need to land the txs. + logger.info(`Deploying Parent + Child contracts to exercise inner kernels`); + const { contract: childContract } = await ChildContract.deploy(provenWallet).send({ from: sender }); + const { contract: parentContract } = await ParentContract.deploy(provenWallet).send({ from: sender }); + // Seed a note in child so the static private_get_value reads below have something to return. + await childContract.methods.private_set_value(42n, sender).send({ from: sender }); + const getValueSelector = await childContract.methods.private_get_value.selector(); + const nestedChain = () => + parentContract.methods.private_nested_static_call(childContract.address, getValueSelector, [42n, sender]); + const extraLeaf = () => childContract.methods.private_get_value(42n, sender); + logger.info(`Proving 4-app nested-call tx to populate private-kernel-inner test data`); + await proveInteraction(provenWallet, nestedChain(), { from: sender }); + logger.info(`Proving 5-app batched tx to populate private-kernel-inner-2 test data`); + await proveInteraction(provenWallet, new BatchCall(provenWallet, [nestedChain(), extraLeaf()]), { from: sender }); + logger.info(`Proving 6-app batched tx to populate private-kernel-inner-3 test data`); + await proveInteraction(provenWallet, new BatchCall(provenWallet, [nestedChain(), extraLeaf(), extraLeaf()]), { + from: sender, + }); + // Create the two transactions const { result: privateBalance } = await provenAsset.methods.balance_of_private(sender).simulate({ from: sender }); const privateSendAmount = privateBalance / 20n; @@ -250,7 +288,11 @@ describe('full_prover', () => { ( [ 'private-kernel-init', + 'private-kernel-init-2', + 'private-kernel-init-3', 'private-kernel-inner', + 'private-kernel-inner-2', + 'private-kernel-inner-3', 'private-kernel-tail', 'private-kernel-tail-to-public', 'private-kernel-reset', diff --git a/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts b/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts index e83ca1782c54..460ddd1b4a26 100644 --- a/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts +++ b/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts @@ -1,22 +1,27 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import type { Logger } from '@aztec/aztec.js/log'; -import type { AztecNode } from '@aztec/aztec.js/node'; import { MerkleTreeId } from '@aztec/aztec.js/trees'; import type { Wallet } from '@aztec/aztec.js/wallet'; +import { CheatCodes } from '@aztec/aztec/testing'; import { retryUntil } from '@aztec/foundation/retry'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; +import { jest } from '@jest/globals'; + +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; // Tests PXE interacting with a node that has pruned relevant blocks, preventing usage of the archive API (which PXE // should not rely on). describe('e2e_pruned_blocks', () => { + jest.setTimeout(5 * 60 * 1000); + let logger: Logger; let teardown: () => Promise; - let aztecNode: AztecNode; - let aztecNodeAdmin: AztecNodeAdmin | undefined; + let aztecNode: AztecNode & AztecNodeDebug; + let cheatCodes: CheatCodes; let wallet: Wallet; @@ -36,12 +41,13 @@ describe('e2e_pruned_blocks', () => { beforeAll(async () => { ({ aztecNode, - aztecNodeAdmin, + cheatCodes, logger, teardown, wallet, accounts: [admin, sender, recipient], } = await setup(3, { + ...AUTOMINE_E2E_OPTS, worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY, worldStateBlockCheckIntervalMS: WORLD_STATE_CHECK_INTERVAL_MS, archiverPollingIntervalMS: ARCHIVER_POLLING_INTERVAL_MS, @@ -54,10 +60,10 @@ describe('e2e_pruned_blocks', () => { afterAll(() => teardown()); - async function waitBlocks(blocks: number): Promise { - logger.warn(`Awaiting ${blocks} blocks to be mined`); + async function mineEmptyBlocks(blocks: number): Promise { + logger.warn(`Mining ${blocks} empty blocks`); for (let i = 0; i < blocks; i++) { - await token.methods.private_get_name().send({ from: admin }); + await aztecNode.mineBlock(); logger.warn(`Mined ${i + 1}/${blocks} blocks`); } } @@ -87,13 +93,15 @@ describe('e2e_pruned_blocks', () => { .data, ).toBeGreaterThan(0); - // Mine enough blocks so the first mint block gets pruned. The test infrastructure auto-proves every - // checkpoint as it lands, and with slotsInAnEpoch=1 Anvil reports finalized = latest - 2, so - // finalization lags proving by just 2 L1 blocks. We mine WORLD_STATE_CHECKPOINT_HISTORY + 3 blocks: - // WORLD_STATE_CHECKPOINT_HISTORY to push the first mint block far enough back in history, and 3 to - // account for the 2-block finality lag plus one buffer. - await aztecNodeAdmin!.setConfig({ minTxsPerBlock: 0 }); - await waitBlocks(WORLD_STATE_CHECKPOINT_HISTORY + 3); + // Mine enough empty blocks past the first mint block so it becomes eligible for pruning, then + // mark the chain as proven. AUTOMINE_E2E_OPTS disables AnvilTestWatcher (no auto-markAsProven + // loop) and no EpochTestSettler is wired in the e2e fixture, so we mark explicitly here. + // World-state prunes on the chain-finalized event; with Anvil's `finalized = latest - 2` + // heuristic, we need a couple of additional L1 blocks after markAsProven so the archiver's + // `getFinalizedL1Block` query resolves to a block that already sees the new proven tip. + await mineEmptyBlocks(WORLD_STATE_CHECKPOINT_HISTORY + 1); + await cheatCodes.rollup.markAsProven(); + await cheatCodes.eth.mineEmptyBlock(3); // The same historical query we performed before should now fail since this block is not available anymore. We poll // the node for a bit until it processes the blocks we marked as proven, causing the historical query to fail. @@ -108,8 +116,8 @@ describe('e2e_pruned_blocks', () => { } }, 'waiting for pruning', - (WORLD_STATE_CHECK_INTERVAL_MS + ARCHIVER_POLLING_INTERVAL_MS) * 5, - 0.2, + 60, + 0.5, ); // We've completed the setup we were interested in, and can now simply mint the second half of the amount, transfer diff --git a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts index bf507e00cbe2..a8eb16753b3f 100644 --- a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts @@ -7,6 +7,7 @@ import { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken'; import { foundry, sepolia } from 'viem/chains'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { setup } from '../fixtures/utils.js'; // process.env.SEQ_PUBLISHER_PRIVATE_KEY = ''; @@ -30,6 +31,7 @@ describe(`deploys and transfers a private only token`, () => { ({ logger, teardown, wallet, accounts } = await setup( 2, // Deploy 2 accounts. { + ...PIPELINING_SETUP_OPTS, numberOfInitialFundedAccounts: 2, // Fund 2 accounts. stateLoad: undefined, }, diff --git a/yarn-project/end-to-end/src/e2e_publisher_funding_multi.test.ts b/yarn-project/end-to-end/src/e2e_publisher_funding_multi.test.ts index e48477c8fefa..940174e33e24 100644 --- a/yarn-project/end-to-end/src/e2e_publisher_funding_multi.test.ts +++ b/yarn-project/end-to-end/src/e2e_publisher_funding_multi.test.ts @@ -17,6 +17,7 @@ import { join } from 'path'; import { type Hex, parseEther } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from './fixtures/utils.js'; // Key indices from the test MNEMONIC (all pre-funded by Anvil): @@ -89,6 +90,7 @@ describe('e2e_publisher_funding_multi', () => { sequencer: sequencerClient, ethCheatCodes, } = await setup(0, { + ...PIPELINING_SETUP_OPTS, initialValidators, keyStoreDirectory, publisherFundingThreshold: FUNDING_THRESHOLD, @@ -156,9 +158,11 @@ describe('e2e_publisher_funding_multi', () => { // Funder should have sent 2 * FUNDING_AMOUNT plus gas costs (single multicall) expect(funderSpent).toBeGreaterThanOrEqual(2n * FUNDING_AMOUNT); - // Second round: after funding, publishers are above threshold. The active publisher will - // spend gas publishing blocks and eventually drop below threshold again, triggering re-funding - // for that one publisher. + // Second round: deterministically drop one publisher below threshold after the first refill. + // Waiting for organic gas depletion is brittle under pipelined publisher rotation: the exact + // publisher cadence and L1 gas burn vary enough that the balance may not cross the threshold + // before the test timeout, even though the periodic funding loop is healthy. + await ethCheatCodes.setBalance(publisher1Address, LOW_BALANCE); const funderBalanceBefore2 = await ethCheatCodes.getBalance(funderAddress); logger.info(`Waiting for second funding round`); diff --git a/yarn-project/end-to-end/src/e2e_pxe.test.ts b/yarn-project/end-to-end/src/e2e_pxe.test.ts index efeb60c27cbe..8b34d702cac0 100644 --- a/yarn-project/end-to-end/src/e2e_pxe.test.ts +++ b/yarn-project/end-to-end/src/e2e_pxe.test.ts @@ -3,6 +3,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -20,7 +21,7 @@ describe('e2e_pxe', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts b/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts index 5c8e4e2fdfc2..d12c4fe0d80f 100644 --- a/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts +++ b/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts @@ -2,6 +2,7 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { ScopeTestContract } from '@aztec/noir-test-contracts.js/ScopeTest'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e scope isolation', () => { @@ -18,7 +19,7 @@ describe('e2e scope isolation', () => { const BOB_NOTE_VALUE = 100n; beforeAll(async () => { - ({ teardown, wallet, accounts } = await setup(3)); + ({ teardown, wallet, accounts } = await setup(3, { ...AUTOMINE_E2E_OPTS })); [alice, bob, charlie] = accounts; ({ contract } = await ScopeTestContract.deploy(wallet).send({ from: alice })); diff --git a/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts index a333e9129db4..216b0abef73e 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts @@ -20,6 +20,7 @@ import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../fixtures/utils.js'; const OPEN_THE_HATCH = true; @@ -61,20 +62,25 @@ describe('e2e_escape_hatch_vote_only', () => { }); const context = await setup(1, { + ...PIPELINING_SETUP_OPTS, anvilAccounts: 10, aztecTargetCommitteeSize: COMMITTEE_SIZE, initialValidators: validators.map(v => ({ ...v, bn254SecretKey: new SecretValue(Fr.random().toBigInt()) })), validatorPrivateKeys: new SecretValue(validators.map(v => v.privateKey)), governanceProposerRoundSize: ROUND_SIZE, governanceProposerQuorum: QUORUM_SIZE, + // Override PIPELINING_SETUP_OPTS slot durations for the longer cadence this test needs. ethereumSlotDuration: ETHEREUM_SLOT_DURATION, aztecSlotDuration: AZTEC_SLOT_DURATION, aztecEpochDuration: AZTEC_EPOCH_DURATION, // Keep pruning far away for this test. aztecProofSubmissionEpochs: 15, // needed so ACTIVE_DURATION=2 is a valid EscapeHatch config - minTxsPerBlock: 0, enforceTimeTable: true, automineL1Setup: true, + // Pipelining opts — exercise the §6 B5 fix (tryVoteWhenEscapeHatchOpen signing/submitting for targetSlot). + // inboxLag: 2 so the sequencer sources L1->L2 messages from a sealed checkpoint when building for slot+1. + enableProposerPipelining: true, + inboxLag: 2, }); ({ @@ -142,25 +148,45 @@ describe('e2e_escape_hatch_vote_only', () => { afterEach(() => teardown()); it('casts governance signals and advances checkpoints while escape hatch is closed', async () => { + const sequencer = sequencerClient!.getSequencer(); + // Enable voting from the sequencer. await aztecNodeAdmin!.setConfig({ governanceProposerPayload: newGovernanceProposerPayloadAddress, minTxsPerBlock: 0, }); - // Set up event listeners to track sequencer behavior + // We need to set it for hatch 1, and then make a time jump. We do this such that we don't pollute the epoch cache. + // The warp must happen before we attach failure-event listeners, because any checkpoint proposal in flight at warp + // time will fail (its propose tx becomes invalid after the L1 timestamp jump) — that is a test-setup artifact, not + // a behavior we are asserting on. + if (OPEN_THE_HATCH) { + await ethCheatCodes.store( + await rollup.getEscapeHatchAddress(), + ethCheatCodes.keccak256(BigInt(EscapeHatchStorage.find(s => s.label === '$designatedProposer')!.slot), 1n), + escapeHatchProposerAddress.toField().toBigInt(), + ); + expect(await rollup.isEscapeHatchOpen(EpochNumber(Number(ESCAPE_HATCH_FREQUENCY)))).toBeTruthy(); + + logger.info(`Advancing to epoch ${ESCAPE_HATCH_FREQUENCY}`); + + await cheatCodes.rollup.advanceToEpoch(EpochNumber(Number(ESCAPE_HATCH_FREQUENCY)), { + offset: -ETHEREUM_SLOT_DURATION, + }); + } + + // Set up event listeners to track sequencer behavior during the vote-only window const failEvents: Array<{ type: keyof SequencerEvents; args: any }> = []; const blockProposedEvents: Array<{ blockNumber: any; slot: any }> = []; const checkpointPublishedEvents: Array<{ checkpoint: any; slot: any }> = []; - const sequencer = sequencerClient!.getSequencer(); - // Track failure events that indicate problems const failEventTypes: (keyof SequencerEvents)[] = [ 'block-build-failed', 'checkpoint-publish-failed', 'proposer-rollup-check-failed', 'checkpoint-error', + 'header-validation-failed', ]; failEventTypes.forEach(eventType => { @@ -191,22 +217,6 @@ describe('e2e_escape_hatch_vote_only', () => { logger.warn(`Sequencer published checkpoint when escape hatch should be open`, args); }); - // We need to set it for hatch 1, and then make a time jump. We do this such that we don't pollute the epoch cache - if (OPEN_THE_HATCH) { - await ethCheatCodes.store( - await rollup.getEscapeHatchAddress(), - ethCheatCodes.keccak256(BigInt(EscapeHatchStorage.find(s => s.label === '$designatedProposer')!.slot), 1n), - escapeHatchProposerAddress.toField().toBigInt(), - ); - expect(await rollup.isEscapeHatchOpen(EpochNumber(Number(ESCAPE_HATCH_FREQUENCY)))).toBeTruthy(); - - logger.info(`Advancing to epoch ${ESCAPE_HATCH_FREQUENCY}`); - - await cheatCodes.rollup.advanceToEpoch(EpochNumber(Number(ESCAPE_HATCH_FREQUENCY)), { - offset: -ETHEREUM_SLOT_DURATION, - }); - } - const getStats = async () => ({ slot: await rollup.getSlotNumber(), epoch: await rollup.getEpochNumberForSlotNumber(await rollup.getSlotNumber()), @@ -228,20 +238,37 @@ describe('e2e_escape_hatch_vote_only', () => { 1, ); - const finalStats = await getStats(); - - // Due to the the stats not being pulled at the same time, a vote could land after the slot is fetched, but before the votes are. - // Therefore, we use the slots passed as the lower bound. - const slotsPassed = finalStats.slot - initialStats.slot; + // Snapshot the slot we will assert against now; under proposer pipelining the sequencer signs a vote in build + // slot N for target slot N+1 and submits it at the start of N+1, so the votes corresponding to slots up through + // `slotAtMeasurement` lag the current slot by one. Wait for the L1 slot to advance one more so the last + // in-flight vote (signed for `slotAtMeasurement`) has time to mine before we count votes. + const slotAtMeasurement = await rollup.getSlotNumber(); + const slotsPassed = slotAtMeasurement - initialStats.slot; expect(slotsPassed).toBeGreaterThan(0); + const drainTarget = slotAtMeasurement + 2; + await retryUntil( + () => rollup.getSlotNumber().then(s => s >= drainTarget), + 'pipelined vote drain', + AZTEC_SLOT_DURATION * 4, + 1, + ); + + const finalStats = await getStats(); expect(finalStats.votes - initialStats.votes).toBeGreaterThanOrEqual(slotsPassed); if (OPEN_THE_HATCH) { expect(finalStats.pending - initialStats.pending).toBe(0); // When escape hatch is open, sequencer should only vote, not build blocks nor checkpoints, but there should also be no failures. - expect(blockProposedEvents).toEqual([]); - expect(failEvents).toEqual([]); - expect(checkpointPublishedEvents).toEqual([]); + // Filter out events corresponding to pre-warp slots — they are checkpoint proposals that were in flight when + // the test warped past their target slot and whose L1 propose tx then fails. That's a setup artifact of the + // warp, not behavior we are asserting on in the vote-only window. + const inVoteOnlyWindow = (e: T) => { + const slotValue = (e as any).slot ?? (e as any).args?.slot; + return slotValue === undefined || Number(slotValue) >= Number(initialStats.slot); + }; + expect(blockProposedEvents.filter(inVoteOnlyWindow)).toEqual([]); + expect(failEvents.filter(inVoteOnlyWindow)).toEqual([]); + expect(checkpointPublishedEvents.filter(inVoteOnlyWindow)).toEqual([]); } else { expect(finalStats.pending - initialStats.pending).toBeGreaterThanOrEqual(slotsPassed); } diff --git a/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts index 8795dc257a6f..ec03b1615960 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts @@ -28,6 +28,7 @@ import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client' import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../fixtures/utils.js'; const ETHEREUM_SLOT_DURATION = 8; @@ -66,6 +67,7 @@ describe('e2e_gov_proposal', () => { let accounts: AztecAddress[] = []; const context = await setup(1, { + ...PIPELINING_SETUP_OPTS, anvilAccounts: 100, aztecTargetCommitteeSize: COMMITTEE_SIZE, initialValidators: validators.map(v => ({ ...v, bn254SecretKey: new SecretValue(Fr.random().toBigInt()) })), @@ -78,6 +80,15 @@ describe('e2e_gov_proposal', () => { minTxsPerBlock: TXS_PER_BLOCK, enforceTimeTable: true, automineL1Setup: true, // speed up setup + // Force the L1 sync to fetch blobs rather than promote the locally-proposed checkpoint. + // The "should vote even when unable to build blocks" test relies on the blob client being the + // only source of truth for block sync: disabling the blob client should make the tx un-syncable. + // Under pipelining the proposer also enters its proposed checkpoint into the local store + // (proposal_handler.ts § setProposedCheckpointFromBlocks), and the L1 synchronizer would then + // promote that proposed checkpoint into a published one without going through the blob client + // (l1_synchronizer.ts § tryBuildPublishedCheckpointFromProposed). Forcing the blob path here + // restores the legacy assumption for both tests in this describe block. + skipPromoteProposedCheckpointDuringL1Sync: true, }); ({ @@ -138,8 +149,12 @@ describe('e2e_gov_proposal', () => { round, }); - // We warp to one L1 slot before the start of the slot, since that's when we start building the L2 block - await cheatCodes.eth.warp(Number(nextRoundBeginsAtTimestamp) - ETHEREUM_SLOT_DURATION, { + // Under proposer pipelining the sequencer for slot N builds during slot N-1 and the L1 propose mines in slot N. + // So to land a vote in the very first slot of the round we need to be in the build slot for it, which is one + // L2 slot (not one L1 slot) earlier. Warping just one L1 slot before the round start puts the sequencer in the + // build slot for round_start+1, costing us the first vote of the round. Warp one full L2 slot earlier instead + // so the build slot for round_start fires while we are inside the round. + await cheatCodes.eth.warp(Number(nextRoundBeginsAtTimestamp) - AZTEC_SLOT_DURATION - ETHEREUM_SLOT_DURATION, { resetBlockInterval: true, }); @@ -168,6 +183,12 @@ describe('e2e_gov_proposal', () => { // We know that this will last at least as long as the round duration, // since we wait for the txs to be mined, and do so `roundDuration` times. // Simultaneously, we should be voting for the proposal in every slot. + // + // Under proposer pipelining, the proposer for slot N builds in slot N-1 and the L1 propose tx mines during + // slot N. After the L1-time warp in setupVotingRound, the first post-warp checkpoint takes at least two slots + // to land (one to detect the new wall-clock slot and start a pipelined build, one for the propose to mine). + // Allow up to 3 slots per tx to absorb that warp catch-up and pipelining lag. + const waitForTxTimeout = AZTEC_SLOT_DURATION * 3 + 10; for (let i = 0; i < roundDuration; i++) { const txHashes = await timesAsync(TXS_PER_BLOCK, async () => { const { txHash } = await testContract.methods @@ -178,7 +199,7 @@ describe('e2e_gov_proposal', () => { await Promise.all( txHashes.map((hash, j) => { logger.info(`Waiting for tx ${i}-${j}: ${hash} to be mined`); - return waitForTx(aztecNode!, hash, { timeout: AZTEC_SLOT_DURATION + 10 }); + return waitForTx(aztecNode!, hash, { timeout: waitForTxTimeout }); }), ); } @@ -190,21 +211,39 @@ describe('e2e_gov_proposal', () => { it('should vote even when unable to build blocks', async () => { const monitor = new ChainMonitor(rollup, dateProvider).start(); - // Break the blob client so no new blocks are synced + // Disable the in-process proposer→archiver block shortcut (validator-client and + // checkpoint_proposal_job both push the just-built block into the local archiver) and then + // disable the blob client. The archiver-side `skipPromoteProposedCheckpointDuringL1Sync` + // shortcut is disabled at setup() — without it the L1 synchronizer would promote the locally + // proposed checkpoint into a published one without going through the blob client, and the + // tx would still be observed as `checkpointed` regardless of the disabled blob client. With + // all three shortcuts off the node has no choice but to rely on the blob client for sync. + await aztecNodeAdmin!.setConfig({ skipPushProposedBlocksToArchiver: true }); ((aztecNodeAdmin as AztecNodeService).getBlobClient() as HttpBlobClient).setDisabled(true); await sleep(1000); const lastBlockSynced = await aztecNode!.getBlockNumber(); logger.warn(`blob client is disabled (last block synced is ${lastBlockSynced})`); - // And send a tx which shouldnt be syncable but does move the block forward + // And send a tx which shouldnt be syncable but does move the block forward. + // Under proposer pipelining the proposer builds in slot N-1 and the L1 propose mines in slot N, so a single + // slot is not enough to observe the L1 checkpoint advance. Wait at least two slots before declaring the tx + // un-syncable and before checking that L1 has progressed. await expect(() => testContract.methods .create_l2_to_l1_message_arbitrary_recipient_private(Fr.random(), EthAddress.random()) - .send({ from: defaultAccountAddress, wait: { timeout: AZTEC_SLOT_DURATION + 2 } }), + .send({ from: defaultAccountAddress, wait: { timeout: AZTEC_SLOT_DURATION * 2 + 2 } }), ).rejects.toThrow(TimeoutError); logger.warn(`Test tx timed out as expected`); - // Check that the block number has indeed increased on L1 so sequencers cant pass the sync check + // Check that the block number has indeed increased on L1 so sequencers cant pass the sync check. + // Allow another slot for any in-flight L1 propose to mine, since the work loop above hits its wait timeout the + // moment the tx misses L2 sync, not the moment the L1 tx lands. + await retryUntil( + async () => (await monitor.run().then(b => b.checkpointNumber)) > lastBlockSynced, + 'L1 checkpoint to advance after disabling blob client', + AZTEC_SLOT_DURATION + 5, + 1, + ); expect(await monitor.run().then(b => b.checkpointNumber)).toBeGreaterThan(lastBlockSynced); logger.warn(`L2 block number has increased on L1`); @@ -212,9 +251,11 @@ describe('e2e_gov_proposal', () => { await aztecNodeAdmin!.setConfig({ governanceProposerPayload: newGovernanceProposerAddress }); const { round, roundDuration, nextRoundBeginsAtSlot } = await setupVotingRound(); - // And wait until the round is over + // And wait until the round is over. Add one extra slot to absorb pipelining catch-up after the L1 warp in + // setupVotingRound — the proposer for round_start builds during the slot before it, so the L1 chain takes + // an extra slot to advance past nextRoundEndsAtSlot. const nextRoundEndsAtSlot = SlotNumber(nextRoundBeginsAtSlot + Number(roundDuration)); - const timeout = AZTEC_SLOT_DURATION * Number(roundDuration + 1n) + 20; + const timeout = AZTEC_SLOT_DURATION * Number(roundDuration + 2n) + 20; logger.warn(`Waiting until slot ${nextRoundEndsAtSlot} for round to end (timeout ${timeout}s)`); await retryUntil(() => rollup.getSlotNumber().then(s => s > nextRoundEndsAtSlot), 'round end', timeout, 1); diff --git a/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts index 30e71f924153..89c975f297b6 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts @@ -19,6 +19,7 @@ import { tmpdir } from 'os'; import { join } from 'path'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../fixtures/utils.js'; const VALIDATOR_KEY_INDICES = [0, 2, 4, 5]; @@ -92,6 +93,7 @@ describe('e2e_reload_keystore', () => { accounts: [ownerAddress], sequencer: sequencerClient, } = await setup(1, { + ...PIPELINING_SETUP_OPTS, initialValidators, aztecTargetCommitteeSize: COMMITTEE_SIZE, keyStoreDirectory, diff --git a/yarn-project/end-to-end/src/e2e_sequencer/slasher_config.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/slasher_config.test.ts index bbd0e37baf45..da24120ff255 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/slasher_config.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/slasher_config.test.ts @@ -2,6 +2,7 @@ import type { TestAztecNodeService } from '@aztec/aztec-node/test'; import type { SlasherClientInterface } from '@aztec/slasher'; import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { type EndToEndContext, setup } from '../fixtures/utils.js'; describe('e2e_slasher_config', () => { @@ -11,6 +12,7 @@ describe('e2e_slasher_config', () => { beforeAll(async () => { ({ aztecNodeAdmin, aztecNode, teardown } = await setup(0, { + ...PIPELINING_SETUP_OPTS, anvilSlotsInAnEpoch: 4, slashInactivityTargetPercentage: 1, slashInactivityPenalty: 42n, diff --git a/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts b/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts index 40316c6152ea..91c964ed1e07 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts @@ -12,6 +12,7 @@ import { EmbeddedWallet } from '@aztec/wallets/embedded'; import { jest } from '@jest/globals'; import 'jest-extended'; +import { PIPELINED_FEE_PADDING, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_sequencer_config', () => { @@ -35,6 +36,7 @@ describe('e2e_sequencer_config', () => { beforeAll(async () => { const [botAccount] = await getInitialTestAccountsData(); ({ teardown, sequencer, aztecNode, logger } = await setup(0, { + ...PIPELINING_SETUP_OPTS, maxL2BlockGas: manaTarget * 2, manaTarget: BigInt(manaTarget), initialFundedAccounts: [botAccount], @@ -43,7 +45,10 @@ describe('e2e_sequencer_config', () => { ...getBotDefaultConfig(), followChain: 'CHECKPOINTED', botMode: 'transfer', - txMinedWaitSeconds: 12, + txMinedWaitSeconds: 60, + // Match pipelining fee padding so the bot's maxFeesPerGas keeps up with + // fee-asset price evolution between PXE snapshot and inclusion. + minFeePadding: PIPELINED_FEE_PADDING, }; wallet = await EmbeddedWallet.create(aztecNode, { ephemeral: true }); const accountManager = await wallet.createSchnorrAccount( diff --git a/yarn-project/end-to-end/src/e2e_simple.test.ts b/yarn-project/end-to-end/src/e2e_simple.test.ts index 0732b761fb88..c58e75d68ef9 100644 --- a/yarn-project/end-to-end/src/e2e_simple.test.ts +++ b/yarn-project/end-to-end/src/e2e_simple.test.ts @@ -11,6 +11,7 @@ import { StatefulTestContractArtifact } from '@aztec/noir-test-contracts.js/Stat import { jest } from '@jest/globals'; import 'jest-extended'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_simple', () => { @@ -37,14 +38,13 @@ describe('e2e_simple', () => { config, aztecNode, } = await setup(1, { + ...PIPELINING_SETUP_OPTS, archiverPollingIntervalMS: 200, sequencerPollingIntervalMS: 200, worldStateBlockCheckIntervalMS: 200, blockCheckIntervalMS: 200, minTxsPerBlock: 1, aztecEpochDuration: 4, - aztecSlotDuration: 12, - ethereumSlotDuration: 4, aztecTargetCommitteeSize: 0, startProverNode: true, })); diff --git a/yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts b/yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts new file mode 100644 index 000000000000..3dc0f67ad3e5 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts @@ -0,0 +1,574 @@ +import type { AztecNodeService } from '@aztec/aztec-node'; +import type { TestAztecNodeService } from '@aztec/aztec-node/test'; +import { EthAddress } from '@aztec/aztec.js/addresses'; +import { NO_WAIT } from '@aztec/aztec.js/contracts'; +import { Fr, GrumpkinScalar } from '@aztec/aztec.js/fields'; +import type { RollupCheatCodes } from '@aztec/aztec/testing'; +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { BlockNumber, EpochNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; +import { Buffer32 } from '@aztec/foundation/buffer'; +import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; +import { retryUntil } from '@aztec/foundation/retry'; +import { getPXEConfig } from '@aztec/pxe/server'; +import type { SequencerEvents } from '@aztec/sequencer-client'; +import { OffenseType } from '@aztec/slasher'; +import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { makeBlockHeader, makeBlockProposal } from '@aztec/stdlib/testing'; +import { TxHash } from '@aztec/stdlib/tx'; + +import { jest } from '@jest/globals'; +import fs from 'fs'; +import os from 'os'; +import path from 'path'; + +import { P2PNetworkTest } from '../e2e_p2p/p2p_network.js'; +import { awaitCommitteeExists } from '../e2e_p2p/shared.js'; +import { shouldCollectMetrics } from '../fixtures/fixtures.js'; +import { SchnorrHardcodedKeyAccountContract } from '../fixtures/schnorr_hardcoded_account_contract.js'; +import { ATTESTER_PRIVATE_KEYS_START_INDEX, createNode } from '../fixtures/setup_p2p_test.js'; +import { getPrivateKeyFromIndex } from '../fixtures/utils.js'; +import { TestWallet } from '../test-wallet/test_wallet.js'; + +const TEST_TIMEOUT = 1_000_000; + +jest.setTimeout(TEST_TIMEOUT); + +const NUM_VALIDATORS = 3; +const BOOT_NODE_UDP_PORT = 4700; +const COMMITTEE_SIZE = NUM_VALIDATORS; +const ETHEREUM_SLOT_DURATION = 4; +const AZTEC_SLOT_DURATION = 36; +const BLOCK_DURATION_MS = 8_000; +const BLOCKS_PER_CHECKPOINT = 3; +const BAD_BLOCK_INDEX_WITHIN_CHECKPOINT = 1; +const BAD_SLOT_COMPLETION_TIMEOUT = AZTEC_SLOT_DURATION * 3; +const LAZY_ATTESTATION_TIMEOUT = AZTEC_SLOT_DURATION * 3; +const OFFENSE_DETECTION_TIMEOUT = AZTEC_SLOT_DURATION * 3; +const INVALID_BLOCK_REMOVAL_TIMEOUT = AZTEC_SLOT_DURATION * 3; + +const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'attested-invalid-proposal-')); + +type BlockProposedEvent = Parameters[0]; +type SlashOffense = Awaited>[number]; + +function findSlashOffense(offenses: SlashOffense[], validator: EthAddress, offenseType: OffenseType, slot: SlotNumber) { + return offenses.find( + offense => + offense.validator.equals(validator) && + offense.offenseType === offenseType && + offense.epochOrSlot === BigInt(slot), + ); +} + +function getAttesterSigner(validatorIndex: number) { + const privateKey = getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + validatorIndex)!; + return new Secp256k1Signer(Buffer32.fromBuffer(privateKey)); +} + +async function makeEquivocatedBlockProposal({ + blockNumber, + targetSlot, + signer, + signatureContext, +}: { + blockNumber: number; + targetSlot: SlotNumber; + signer: Secp256k1Signer; + signatureContext: CoordinationSignatureContext; +}) { + return await makeBlockProposal({ + blockHeader: makeBlockHeader(0xa521, { + blockNumber: BlockNumber(blockNumber), + slotNumber: targetSlot, + }), + indexWithinCheckpoint: IndexWithinCheckpoint(BAD_BLOCK_INDEX_WITHIN_CHECKPOINT), + txHashes: [TxHash.random()], + archiveRoot: Fr.random(), + signer, + signatureContext, + }); +} + +async function submitDeploymentTxsWithoutWaiting(node: AztecNodeService, t: P2PNetworkTest, numTxs: number) { + const wallet = await TestWallet.create( + node, + { ...getPXEConfig(), proverEnabled: false, syncChainTip: 'checkpointed' }, + { loggerActorLabel: 'pxe-tx' }, + ); + const fundedAccountManager = await wallet.createAccount({ + secret: t.fundedAccount.secret, + salt: t.fundedAccount.salt, + contract: new SchnorrHardcodedKeyAccountContract(), + }); + + const txHashes = []; + for (let i = 0; i < numTxs; i++) { + const accountManager = await wallet.createSchnorrAccount(Fr.random(), Fr.random(), GrumpkinScalar.random()); + const deployMethod = await accountManager.getDeployMethod(); + const { txHash } = await deployMethod.send({ from: fundedAccountManager.address, wait: NO_WAIT }); + txHashes.push(txHash); + } + return txHashes; +} + +async function getBlockHash(node: AztecNodeService, blockNumber: number) { + const block = await node.getBlockData(BlockNumber(blockNumber)); + return block ? (await block.header.hash()).toString() : undefined; +} + +async function advanceToEpochBeforePipelinedTargetSlot({ + epochCache, + cheatCodes, + targetProposer, + logger, + maxAttempts = 30, +}: { + epochCache: EpochCacheInterface; + cheatCodes: RollupCheatCodes; + targetProposer: EthAddress; + logger: P2PNetworkTest['logger']; + maxAttempts?: number; +}): Promise<{ targetEpoch: EpochNumber; targetSlot: SlotNumber }> { + const { epochDuration } = await cheatCodes.getConfig(); + + for (let attempt = 0; attempt < maxAttempts; attempt++) { + const currentEpoch = await cheatCodes.getEpoch(); + const nextEpoch = Number(currentEpoch) + 1; + const firstSlotOfNextEpoch = nextEpoch * Number(epochDuration); + const pipelinedTargetSlot = SlotNumber(firstSlotOfNextEpoch + 1); + const proposer = await epochCache.getProposerAttesterAddressInSlot(pipelinedTargetSlot); + + logger.info( + `Checking pipelined target slot ${pipelinedTargetSlot} in epoch ${nextEpoch} for proposer ${targetProposer}`, + { proposer: proposer?.toString() }, + ); + + if (proposer?.equals(targetProposer)) { + return { targetEpoch: EpochNumber(nextEpoch), targetSlot: pipelinedTargetSlot }; + } + + await cheatCodes.advanceToNextEpoch(); + } + + throw new Error(`Target proposer ${targetProposer.toString()} not found after ${maxAttempts} epoch attempts`); +} + +describe('e2e_slashing_attested_invalid_proposal', () => { + let t: P2PNetworkTest; + let nodes: AztecNodeService[] = []; + + beforeEach(async () => { + t = await P2PNetworkTest.create({ + testName: 'e2e_slashing_attested_invalid_proposal', + numberOfNodes: 0, + numberOfValidators: NUM_VALIDATORS, + basePort: BOOT_NODE_UDP_PORT, + metricsPort: shouldCollectMetrics(), + initialConfig: { + anvilSlotsInAnEpoch: 4, + listenAddress: '127.0.0.1', + aztecEpochDuration: 2, + ethereumSlotDuration: ETHEREUM_SLOT_DURATION, + aztecSlotDuration: AZTEC_SLOT_DURATION, + aztecTargetCommitteeSize: COMMITTEE_SIZE, + aztecProofSubmissionEpochs: 1024, + slashInactivityConsecutiveEpochThreshold: 32, + mockGossipSubNetwork: true, + minTxsPerBlock: 1, + maxTxsPerBlock: 1, + minBlocksForCheckpoint: BLOCKS_PER_CHECKPOINT, + maxBlocksPerCheckpoint: BLOCKS_PER_CHECKPOINT, + publishTxsWithProposals: true, + enforceTimeTable: true, + blockDurationMs: BLOCK_DURATION_MS, + l1PublishingTime: 2, + attestationPropagationTime: 0.5, + enableProposerPipelining: true, + slashDuplicateProposalPenalty: 1n, + }, + }); + + await t.setup(); + await t.applyBaseSetup(); + }); + + afterEach(async () => { + await t.stopNodes(nodes); + await t.teardown(); + for (let i = 0; i < NUM_VALIDATORS; i++) { + fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); + } + }); + + async function createInvalidProposalSlashingScenario({ + badProposerConfig = {}, + }: { badProposerConfig?: Partial[0]> } = {}) { + const { rollup } = await t.getContracts(); + + await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); + await t.ctx.cheatCodes.rollup.debugRollup(); + + const badProposerNode = await createNode( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + invalidBlockProposalIndexWithinCheckpoint: BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + ...badProposerConfig, + }, + t.ctx.dateProvider!, + BOOT_NODE_UDP_PORT + 1, + t.bootstrapNodeEnr, + 0, + t.genesis, + `${DATA_DIR}-0`, + shouldCollectMetrics(), + ); + + const lazyValidatorNode = await createNode( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + skipProposalSlotValidation: true, + skipCheckpointProposalValidation: true, + }, + t.ctx.dateProvider!, + BOOT_NODE_UDP_PORT + 2, + t.bootstrapNodeEnr, + 1, + t.genesis, + `${DATA_DIR}-1`, + shouldCollectMetrics(), + ); + + const honestValidatorNode = await createNode( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + skipProposalSlotValidation: true, + }, + t.ctx.dateProvider!, + BOOT_NODE_UDP_PORT + 3, + t.bootstrapNodeEnr, + 2, + t.genesis, + `${DATA_DIR}-2`, + shouldCollectMetrics(), + ); + + nodes = [badProposerNode, lazyValidatorNode, honestValidatorNode]; + + const badProposer = t.validators[0].attester; + const lazyValidator = t.validators[1].attester; + const honestValidator = t.validators[2].attester; + t.logger.warn('Created invalid proposal slashing scenario actors', { + badProposer: badProposer.toString(), + lazyValidator: lazyValidator.toString(), + honestValidator: honestValidator.toString(), + }); + + await awaitCommitteeExists({ rollup, logger: t.logger }); + + const epochCache = (honestValidatorNode as TestAztecNodeService).epochCache; + const { targetEpoch, targetSlot } = await advanceToEpochBeforePipelinedTargetSlot({ + epochCache, + cheatCodes: t.ctx.cheatCodes.rollup, + targetProposer: badProposer, + logger: t.logger, + }); + + const txHashes = await submitDeploymentTxsWithoutWaiting(badProposerNode, t, BLOCKS_PER_CHECKPOINT); + t.logger.warn(`Submitted ${txHashes.length} transactions for the checkpoint`, { + txHashes: txHashes.map(txHash => txHash.toString()), + targetEpoch, + targetSlot, + }); + + await retryUntil( + async () => { + const pendingTxCount = await badProposerNode.getPendingTxCount(); + t.logger.info(`Bad proposer pending tx count is ${pendingTxCount}`); + return pendingTxCount >= 3; + }, + 'bad proposer pending txs', + AZTEC_SLOT_DURATION, + 0.5, + ); + + const badProposerBlockProposedEvents: BlockProposedEvent[] = []; + badProposerNode + .getSequencer()! + .getSequencer() + .on('block-proposed', (args: BlockProposedEvent) => { + if (Number(args.slot) !== Number(targetSlot)) { + return; + } + + badProposerBlockProposedEvents.push(args); + t.logger.warn('Captured bad proposer block-proposed event', { + ...args, + blockHash: args.blockHash.toString(), + }); + }); + + await Promise.all(nodes.map(node => node.getSequencer()!.start())); + + t.logger.warn(`Advancing to epoch ${targetEpoch}; bad proposer should build for slot ${targetSlot}`); + await t.ctx.cheatCodes.rollup.advanceToEpoch(targetEpoch); + + const badCheckpointBlockHashes = await retryUntil( + () => { + const blocksByNumber = new Map( + badProposerBlockProposedEvents.map(event => [ + event.blockNumber.toString(), + { + number: Number(event.blockNumber), + checkpointNumber: Number(event.checkpointNumber), + indexWithinCheckpoint: Number(event.indexWithinCheckpoint), + hash: event.blockHash.toString(), + }, + ]), + ); + const proposedBlocks = [...blocksByNumber.values()].sort( + (a, b) => a.indexWithinCheckpoint - b.indexWithinCheckpoint, + ); + const badBlock = proposedBlocks.find( + block => block.indexWithinCheckpoint === BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + ); + + t.logger.warn('Waiting for bad proposer block-proposed events for invalid checkpoint', { + targetSlot, + badBlockIndexWithinCheckpoint: BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + proposedBlocks, + badBlock, + }); + + return proposedBlocks.length >= BLOCKS_PER_CHECKPOINT && badBlock ? proposedBlocks : undefined; + }, + 'bad proposer invalid checkpoint block-proposed events', + AZTEC_SLOT_DURATION, + 1, + ); + const badBlock = badCheckpointBlockHashes.find( + block => block.indexWithinCheckpoint === BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + ); + t.logger.warn('Captured invalid checkpoint blocks from bad proposer block-proposed events', { + targetSlot, + badBlockIndexWithinCheckpoint: BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + badBlock, + badCheckpointBlockHashes, + }); + + const lazyAttestations = await retryUntil( + async () => { + const attestations = await lazyValidatorNode.getP2P().getCheckpointAttestationsForSlot(targetSlot); + const lazyValidatorAttestations = attestations.filter(attestation => + attestation.getSender()?.equals(lazyValidator), + ); + t.logger.warn('Waiting for lazy validator attestation before checking assertions', { + targetSlot, + attestationCount: attestations.length, + lazyValidatorAttestationCount: lazyValidatorAttestations.length, + attesters: attestations.map(attestation => attestation.getSender()?.toString()), + }); + return lazyValidatorAttestations.length > 0 ? attestations : undefined; + }, + 'lazy validator checkpoint attestation', + LAZY_ATTESTATION_TIMEOUT, + 1, + ); + const honestAttestations = await honestValidatorNode.getP2P().getCheckpointAttestationsForSlot(targetSlot); + const initialOffenses = await honestValidatorNode.getSlashOffenses('all'); + t.logger.warn('Observed state after invalid checkpoint proposal scenario', { + targetSlot, + invalidBlockIndexWithinCheckpoint: BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + lazyNodeAttestationCount: lazyAttestations.length, + lazyNodeAttesters: lazyAttestations.map(attestation => attestation.getSender()?.toString()), + honestNodeAttestationCount: honestAttestations.length, + honestNodeAttesters: honestAttestations.map(attestation => attestation.getSender()?.toString()), + offenses: initialOffenses, + }); + + const expectedSlashOffenses = [ + { + description: 'bad proposer broadcasted invalid block proposal', + validator: badProposer, + offenseType: OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL, + }, + { + description: 'lazy validator attested to invalid checkpoint proposal', + validator: lazyValidator, + offenseType: OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, + }, + ]; + + const offensesWithExpectedSlashes = await retryUntil( + async () => { + const currentOffenses = await honestValidatorNode.getSlashOffenses('all'); + t.logger.warn('Waiting for expected slash offenses on honest validator', { + targetSlot, + offenses: currentOffenses, + }); + return expectedSlashOffenses.every( + ({ validator, offenseType }) => + findSlashOffense(currentOffenses, validator, offenseType, targetSlot) !== undefined, + ) + ? currentOffenses + : undefined; + }, + 'honest validator slash offenses for invalid proposal attestation', + OFFENSE_DETECTION_TIMEOUT, + 1, + ); + + for (const { description, validator, offenseType } of expectedSlashOffenses) { + const offense = findSlashOffense(offensesWithExpectedSlashes, validator, offenseType, targetSlot)!; + expect(offense.amount).toBeGreaterThan(0n); + t.logger.warn(`Observed expected slash offense: ${description}`, { offense }); + } + + return { + rollup, + badProposerNode, + lazyValidatorNode, + honestValidatorNode, + badProposer, + lazyValidator, + honestValidator, + targetSlot, + badCheckpointBlockHashes, + }; + } + + it('slashes a lazy attester for an invalid checkpoint and clears it on delayed equivocation', async () => { + const { + rollup, + badProposerNode, + honestValidatorNode, + badProposer, + lazyValidator, + targetSlot, + badCheckpointBlockHashes, + } = await createInvalidProposalSlashingScenario({ + badProposerConfig: { + broadcastEquivocatedProposals: true, + }, + }); + + await retryUntil( + async () => { + const currentSlot = await rollup.getSlotNumber(); + t.logger.warn('Waiting for invalid checkpoint proposal slot to complete', { + targetSlot, + currentSlot, + }); + return currentSlot >= targetSlot + 1 ? currentSlot : undefined; + }, + 'wait for invalid checkpoint proposal slot to complete', + BAD_SLOT_COMPLETION_TIMEOUT, + 1, + ); + + const getNodeBadCheckpointHashes = () => + Promise.all( + nodes.map(async (node, nodeIndex) => ({ + nodeIndex, + blocks: await Promise.all( + badCheckpointBlockHashes.map(async block => ({ + ...block, + nodeBlockHash: await getBlockHash(node, block.number), + })), + ), + })), + ); + + const nodeBlockHashes = await retryUntil( + async () => { + const currentNodeBlockHashes = await getNodeBadCheckpointHashes(); + t.logger.warn('Waiting for invalid checkpoint blocks to be absent from node block data', { + targetSlot, + nodeBlockHashes: currentNodeBlockHashes, + }); + return currentNodeBlockHashes.every(nodeState => + nodeState.blocks.every(block => block.nodeBlockHash !== block.hash), + ) + ? currentNodeBlockHashes + : undefined; + }, + 'invalid checkpoint blocks absent from node block data', + INVALID_BLOCK_REMOVAL_TIMEOUT, + 1, + ); + + for (const nodeState of nodeBlockHashes) { + for (const block of nodeState.blocks) { + expect(block.nodeBlockHash).not.toEqual(block.hash); + } + } + + const badBlock = badCheckpointBlockHashes.find( + block => block.indexWithinCheckpoint === BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + ); + expect(badBlock).toBeDefined(); + + const equivocatedProposal = await makeEquivocatedBlockProposal({ + blockNumber: badBlock!.number, + targetSlot, + signer: getAttesterSigner(0), + signatureContext: { + chainId: t.ctx.aztecNodeConfig.l1ChainId, + rollupAddress: t.ctx.deployL1ContractsValues.l1ContractAddresses.rollupAddress, + }, + }); + + t.logger.warn('Broadcasting delayed equivocated block proposal for already-slashed slot', { + targetSlot, + indexWithinCheckpoint: equivocatedProposal.indexWithinCheckpoint, + payloadHash: equivocatedProposal.getPayloadHash().toString(), + proposer: equivocatedProposal.getSender()?.toString(), + }); + await badProposerNode.getP2P().broadcastProposal(equivocatedProposal); + + const offensesAfterClear = await retryUntil( + async () => { + const currentOffenses = await honestValidatorNode.getSlashOffenses('all'); + const badAttestationOffense = findSlashOffense( + currentOffenses, + lazyValidator, + OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, + targetSlot, + ); + const duplicateProposalOffense = findSlashOffense( + currentOffenses, + badProposer, + OffenseType.DUPLICATE_PROPOSAL, + targetSlot, + ); + + t.logger.warn('Waiting for delayed equivocation to clear bad attestation slash', { + targetSlot, + badAttestationOffense, + duplicateProposalOffense, + currentOffenses, + }); + + return !badAttestationOffense && duplicateProposalOffense ? currentOffenses : undefined; + }, + 'bad attestation slash cleared after delayed block proposal equivocation', + OFFENSE_DETECTION_TIMEOUT, + 1, + ); + + expect( + findSlashOffense( + offensesAfterClear, + lazyValidator, + OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, + targetSlot, + ), + ).toBeUndefined(); + expect( + findSlashOffense(offensesAfterClear, badProposer, OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL, targetSlot), + ).toBeDefined(); + expect(findSlashOffense(offensesAfterClear, badProposer, OffenseType.DUPLICATE_PROPOSAL, targetSlot)).toBeDefined(); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts b/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts new file mode 100644 index 000000000000..c6244020b214 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts @@ -0,0 +1,489 @@ +import type { AztecNodeService } from '@aztec/aztec-node'; +import type { TestAztecNodeService } from '@aztec/aztec-node/test'; +import { Fr } from '@aztec/aztec.js/fields'; +import { BlockNumber, EpochNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; +import { Buffer32 } from '@aztec/foundation/buffer'; +import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; +import { retryUntil } from '@aztec/foundation/retry'; +import { sleep } from '@aztec/foundation/sleep'; +import { OffenseType } from '@aztec/slasher'; +import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { + makeBlockHeader, + makeBlockProposal, + makeCheckpointHeader, + makeCheckpointProposal, +} from '@aztec/stdlib/testing'; +import { TxHash } from '@aztec/stdlib/tx'; + +import { jest } from '@jest/globals'; +import fs from 'fs'; +import os from 'os'; +import path from 'path'; + +import { P2PNetworkTest } from '../e2e_p2p/p2p_network.js'; +import { advanceToEpochBeforeProposer, awaitCommitteeExists } from '../e2e_p2p/shared.js'; +import { shouldCollectMetrics } from '../fixtures/fixtures.js'; +import { ATTESTER_PRIVATE_KEYS_START_INDEX, createNode, createNodes } from '../fixtures/setup_p2p_test.js'; +import { getPrivateKeyFromIndex } from '../fixtures/utils.js'; + +const TEST_TIMEOUT = 1_000_000; + +jest.setTimeout(TEST_TIMEOUT); + +const NUM_VALIDATORS = 2; +const BOOT_NODE_UDP_PORT = 4900; +const COMMITTEE_SIZE = NUM_VALIDATORS; +const ETHEREUM_SLOT_DURATION = 4; +const AZTEC_EPOCH_DURATION = 2; +const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * AZTEC_EPOCH_DURATION; +const SLASHING_QUORUM = 5; +const SLASHING_ROUND_SIZE = 8; +const TERMINAL_BLOCK_INDEX = IndexWithinCheckpoint(1); +const HIGHER_BLOCK_INDEX = IndexWithinCheckpoint(2); + +const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'broadcasted-invalid-checkpoint-proposal-slash-')); + +type SlashOffense = Awaited>[number]; + +function getAttesterSigner(validatorIndex: number) { + const privateKey = getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + validatorIndex)!; + return new Secp256k1Signer(Buffer32.fromBuffer(privateKey)); +} + +function findBroadcastedInvalidCheckpointOffense( + offenses: SlashOffense[], + validator: string, + slot: SlotNumber, +): SlashOffense | undefined { + return offenses.find( + offense => + offense.validator.toString() === validator && + offense.offenseType === OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL && + offense.epochOrSlot === BigInt(slot), + ); +} + +async function awaitBroadcastedInvalidCheckpointOffense({ + node, + validator, + slot, +}: { + node: AztecNodeService; + validator: string; + slot: SlotNumber; +}) { + return await retryUntil( + async () => { + const offenses = await node.getSlashOffenses('all'); + return findBroadcastedInvalidCheckpointOffense(offenses, validator, slot); + }, + `A-520 offense for slot ${slot}`, + AZTEC_SLOT_DURATION * 3, + 1, + ); +} + +async function awaitAnyBroadcastedInvalidCheckpointOffense({ + nodes, + validator, +}: { + nodes: AztecNodeService[]; + validator: string; +}) { + return await retryUntil( + async () => { + const offenses = (await Promise.all(nodes.map(node => node.getSlashOffenses('all')))).flat(); + const matchingOffenses = offenses.filter( + offense => + offense.validator.toString() === validator && + offense.offenseType === OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + ); + return matchingOffenses.length > 0 ? matchingOffenses : undefined; + }, + `broadcasted invalid checkpoint proposal offense for ${validator}`, + AZTEC_SLOT_DURATION * 12, + 1, + ); +} + +async function expectNoBroadcastedInvalidCheckpointOffense({ + node, + validator, + slot, +}: { + node: AztecNodeService; + validator: string; + slot: SlotNumber; +}) { + // The watcher polls every second with this test's slot timing; wait long enough + // for the closed slot to be scanned before asserting no offense was recorded. + await sleep(2_000); + const offenses = await node.getSlashOffenses('all'); + expect(findBroadcastedInvalidCheckpointOffense(offenses, validator, slot)).toBeUndefined(); +} + +async function awaitRetainedProposalsForSlot({ + node, + slot, + blockCount, + checkpointCount, +}: { + node: AztecNodeService; + slot: SlotNumber; + blockCount: number; + checkpointCount: number; +}) { + return await retryUntil( + async () => { + const proposals = await node.getP2P().getProposalsForSlot(slot); + return proposals.blockProposals.length === blockCount && proposals.checkpointProposals.length === checkpointCount + ? proposals + : undefined; + }, + `retained proposals for slot ${slot}`, + 5, + 0.2, + ); +} + +async function makeBlock({ + signer, + signatureContext, + targetSlot, + indexWithinCheckpoint, + seed, +}: { + signer: Secp256k1Signer; + signatureContext: CoordinationSignatureContext; + targetSlot: SlotNumber; + indexWithinCheckpoint: IndexWithinCheckpoint; + seed: number; +}) { + return await makeBlockProposal({ + blockHeader: makeBlockHeader(seed, { + blockNumber: BlockNumber(seed), + slotNumber: targetSlot, + }), + indexWithinCheckpoint, + txHashes: [TxHash.random()], + archiveRoot: Fr.random(), + signer, + signatureContext, + }); +} + +async function makeInvalidCheckpointProposals({ + signer, + signatureContext, + targetSlot, + seed, + includeTerminalBlockAsLastBlock = false, +}: { + signer: Secp256k1Signer; + signatureContext: CoordinationSignatureContext; + targetSlot: SlotNumber; + seed: number; + includeTerminalBlockAsLastBlock?: boolean; +}) { + const earlierBlock = await makeBlock({ + signer, + signatureContext, + targetSlot, + indexWithinCheckpoint: IndexWithinCheckpoint(0), + seed, + }); + const terminalBlock = await makeBlock({ + signer, + signatureContext, + targetSlot, + indexWithinCheckpoint: TERMINAL_BLOCK_INDEX, + seed: seed + 1, + }); + const higherBlock = await makeBlock({ + signer, + signatureContext, + targetSlot, + indexWithinCheckpoint: HIGHER_BLOCK_INDEX, + seed: seed + 2, + }); + const checkpoint = await makeCheckpointProposal({ + signer, + checkpointHeader: makeCheckpointHeader(seed, { slotNumber: targetSlot }), + archiveRoot: terminalBlock.archive, + lastBlock: includeTerminalBlockAsLastBlock + ? { + blockHeader: terminalBlock.blockHeader, + indexWithinCheckpoint: terminalBlock.indexWithinCheckpoint, + txHashes: terminalBlock.txHashes, + } + : undefined, + signatureContext, + }); + + return { earlierBlock, terminalBlock, higherBlock, checkpoint }; +} + +describe('e2e_slashing_broadcasted_invalid_checkpoint_proposal_slash', () => { + let t: P2PNetworkTest; + let nodes: AztecNodeService[] = []; + + const slashingUnit = BigInt(1e14); + + beforeEach(async () => { + t = await P2PNetworkTest.create({ + testName: 'e2e_slashing_broadcasted_invalid_checkpoint_proposal_slash', + numberOfNodes: 0, + numberOfValidators: NUM_VALIDATORS, + basePort: BOOT_NODE_UDP_PORT, + metricsPort: shouldCollectMetrics(), + initialConfig: { + anvilSlotsInAnEpoch: 4, + listenAddress: '127.0.0.1', + aztecEpochDuration: AZTEC_EPOCH_DURATION, + ethereumSlotDuration: ETHEREUM_SLOT_DURATION, + aztecSlotDuration: AZTEC_SLOT_DURATION, + aztecTargetCommitteeSize: COMMITTEE_SIZE, + aztecProofSubmissionEpochs: 1024, + minTxsPerBlock: 0, + enableProposerPipelining: true, + inboxLag: 2, + mockGossipSubNetwork: true, + slashingQuorum: SLASHING_QUORUM, + slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE / AZTEC_EPOCH_DURATION, + slashAmountSmall: slashingUnit, + slashAmountMedium: slashingUnit * 2n, + slashAmountLarge: slashingUnit * 3n, + slashDataWithholdingPenalty: 0n, + slashInactivityPenalty: 0n, + slashBroadcastedInvalidBlockPenalty: 0n, + slashBroadcastedInvalidCheckpointProposalPenalty: slashingUnit, + slashDuplicateProposalPenalty: 0n, + slashDuplicateAttestationPenalty: 0n, + slashProposeInvalidAttestationsPenalty: 0n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 0n, + slashAttestInvalidCheckpointProposalPenalty: 0n, + slashUnknownPenalty: 0n, + slashSelfAllowed: true, + }, + }); + + await t.setup(); + await t.applyBaseSetup(); + }); + + afterEach(async () => { + await t.stopNodes(nodes); + if (t.monitor) { + await t.teardown(); + } + for (let i = 0; i < NUM_VALIDATORS; i++) { + fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); + } + }); + + const setupNodeAndValidator = async () => { + const { rollup } = await t.getContracts(); + + await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); + await t.ctx.cheatCodes.rollup.debugRollup(); + + const node = await createNode( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + minTxsPerBlock: 0, + enableProposerPipelining: true, + slashBroadcastedInvalidCheckpointProposalPenalty: slashingUnit, + slashSelfAllowed: true, + }, + t.ctx.dateProvider, + BOOT_NODE_UDP_PORT + 1, + t.bootstrapNodeEnr, + 0, + t.genesis, + `${DATA_DIR}-0`, + shouldCollectMetrics(), + ); + nodes = [node]; + + await retryUntil(() => node.isReady(), 'node ready', 30, 0.5); + await awaitCommitteeExists({ rollup, logger: t.logger }); + + const currentSlot = await rollup.getSlotNumber(); + expect(currentSlot).toBeGreaterThan(2); + + const signer = getAttesterSigner(0); + const validator = t.validators[0].attester.toString(); + const signatureContext: CoordinationSignatureContext = { + chainId: t.ctx.aztecNodeConfig.l1ChainId, + rollupAddress: t.ctx.deployL1ContractsValues.l1ContractAddresses.rollupAddress, + }; + + return { node, currentSlot, signer, validator, signatureContext }; + }; + + it('slashes a validator that broadcasts a checkpoint truncated below its own retained block proposal', async () => { + const { node, currentSlot, signer, validator, signatureContext } = await setupNodeAndValidator(); + const targetSlot = SlotNumber(Number(currentSlot) - 2); + + const alreadyRetainedProposals = await makeInvalidCheckpointProposals({ + signer, + signatureContext, + targetSlot, + seed: 0xa520, + }); + + await node.getP2P().broadcastProposal(alreadyRetainedProposals.earlierBlock); + await node.getP2P().broadcastProposal(alreadyRetainedProposals.terminalBlock); + await node.getP2P().broadcastProposal(alreadyRetainedProposals.higherBlock); + await node.getP2P().broadcastCheckpointProposal(alreadyRetainedProposals.checkpoint); + + const firstProposals = await awaitRetainedProposalsForSlot({ + node, + slot: targetSlot, + blockCount: 3, + checkpointCount: 1, + }); + expect(firstProposals.blockProposals.map(proposal => proposal.getSender()?.toString())).toEqual([ + validator, + validator, + validator, + ]); + expect(firstProposals.checkpointProposals[0].getSender()?.toString()).toEqual(validator); + + const firstOffense = await awaitBroadcastedInvalidCheckpointOffense({ + node, + validator, + slot: targetSlot, + }); + expect(firstOffense.amount).toEqual(slashingUnit); + }); + + it('slashes a validator that broadcasts a checkpoint with a mismatched header', async () => { + const { rollup } = await t.getContracts(); + + await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); + await t.ctx.cheatCodes.rollup.debugRollup(); + + const invalidProposerNodes = await createNodes( + { + ...t.ctx.aztecNodeConfig, + broadcastInvalidCheckpointProposalOnly: true, + dontStartSequencer: true, + minTxsPerBlock: 0, + slashBroadcastedInvalidCheckpointProposalPenalty: slashingUnit, + slashSelfAllowed: true, + }, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + 1, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + 0, + ); + const honestNodes = await createNodes( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + minTxsPerBlock: 0, + slashBroadcastedInvalidCheckpointProposalPenalty: slashingUnit, + slashSelfAllowed: true, + }, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + NUM_VALIDATORS - 1, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + 1, + ); + nodes = [...invalidProposerNodes, ...honestNodes]; + + await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); + await awaitCommitteeExists({ rollup, logger: t.logger }); + + const invalidProposer = invalidProposerNodes[0].getSequencer()!.validatorAddresses![0]; + const epochCache = (honestNodes[0] as TestAztecNodeService).epochCache; + const { targetEpoch } = await advanceToEpochBeforeProposer({ + epochCache, + cheatCodes: t.ctx.cheatCodes.rollup, + targetProposer: invalidProposer, + logger: t.logger, + }); + + await Promise.all(nodes.map(node => node.getSequencer()!.start())); + await t.ctx.cheatCodes.rollup.advanceToEpoch(targetEpoch, { offset: -AZTEC_SLOT_DURATION }); + + const offenses = await awaitAnyBroadcastedInvalidCheckpointOffense({ + nodes: honestNodes, + validator: invalidProposer.toString(), + }); + + t.logger.warn(`Collected broadcasted invalid checkpoint proposal offenses`, { offenses }); + expect(offenses.length).toBeGreaterThan(0); + for (const offense of offenses) { + expect(offense.validator.toString()).toEqual(invalidProposer.toString()); + expect(offense.offenseType).toEqual(OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL); + expect(offense.amount).toEqual(slashingUnit); + expect(offense.epochOrSlot > 0n).toBe(true); + } + }); + + it('does not slash a valid checkpoint whose lastBlock supplies the terminal proposal until a delayed higher-index block is retained', async () => { + const { node, currentSlot, signer, validator, signatureContext } = await setupNodeAndValidator(); + const targetSlot = SlotNumber(Number(currentSlot) - 2); + const lateHigherBlockProposals = await makeInvalidCheckpointProposals({ + signer, + signatureContext, + targetSlot, + seed: 0xa530, + includeTerminalBlockAsLastBlock: true, + }); + + await node.getP2P().broadcastProposal(lateHigherBlockProposals.earlierBlock); + await node.getP2P().broadcastCheckpointProposal(lateHigherBlockProposals.checkpoint); + + const validProposals = await awaitRetainedProposalsForSlot({ + node, + slot: targetSlot, + blockCount: 2, + checkpointCount: 1, + }); + expect(validProposals.blockProposals.map(proposal => proposal.getSender()?.toString())).toEqual([ + validator, + validator, + ]); + const terminalProposal = validProposals.blockProposals.find( + proposal => proposal.indexWithinCheckpoint === TERMINAL_BLOCK_INDEX, + ); + expect(terminalProposal?.archive.toString()).toEqual(lateHigherBlockProposals.terminalBlock.archive.toString()); + expect(terminalProposal?.getSender()?.toString()).toEqual(validator); + expect(validProposals.checkpointProposals[0].getSender()?.toString()).toEqual(validator); + await expectNoBroadcastedInvalidCheckpointOffense({ node, validator, slot: targetSlot }); + + await node.getP2P().broadcastProposal(lateHigherBlockProposals.higherBlock); + + const invalidProposals = await awaitRetainedProposalsForSlot({ + node, + slot: targetSlot, + blockCount: 3, + checkpointCount: 1, + }); + expect(invalidProposals.blockProposals.map(proposal => proposal.getSender()?.toString())).toEqual([ + validator, + validator, + validator, + ]); + + const offense = await awaitBroadcastedInvalidCheckpointOffense({ + node, + validator, + slot: targetSlot, + }); + expect(offense.amount).toEqual(slashingUnit); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_snapshot_sync.test.ts b/yarn-project/end-to-end/src/e2e_snapshot_sync.test.ts index 965a158c367f..0ae9e0969f96 100644 --- a/yarn-project/end-to-end/src/e2e_snapshot_sync.test.ts +++ b/yarn-project/end-to-end/src/e2e_snapshot_sync.test.ts @@ -15,6 +15,7 @@ import { cp, mkdtemp, readFile, readdir, rm, writeFile } from 'fs/promises'; import { tmpdir } from 'os'; import { join } from 'path'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { type EndToEndContext, setup } from './fixtures/utils.js'; const L1_BLOCK_TIME_IN_S = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : 8; @@ -32,7 +33,7 @@ describe('e2e_snapshot_sync', () => { beforeAll(async () => { context = await setup(0, { - minTxsPerBlock: 0, + ...PIPELINING_SETUP_OPTS, ethereumSlotDuration: L1_BLOCK_TIME_IN_S, aztecSlotDuration: L1_BLOCK_TIME_IN_S * 2, aztecEpochDuration: 64, diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index d1f1c32d0644..b94cfa307c13 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -7,11 +7,12 @@ import { StateVarsContract } from '@aztec/noir-test-contracts.js/StateVars'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; -const TIMEOUT = 180_000; +const TIMEOUT = 300_000; describe('e2e_state_vars', () => { jest.setTimeout(TIMEOUT); @@ -32,7 +33,7 @@ describe('e2e_state_vars', () => { aztecNode, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await StateVarsContract.deploy(wallet).send({ from: defaultAccountAddress })); }); @@ -352,12 +353,6 @@ describe('e2e_state_vars', () => { const aztecSlotDuration = DefaultL1ContractsConfig.aztecSlotDuration; - const delay = async (blocks: number) => { - for (let i = 0; i < blocks; i++) { - await authContract.methods.get_authorized().send({ from: defaultAccountAddress }); - } - }; - beforeAll(async () => { // We use the auth contract here because has a nice, clear, simple implementation of Delayed Public Mutable ({ contract: authContract } = await AuthContract.deploy(wallet, defaultAccountAddress).send({ @@ -372,29 +367,46 @@ describe('e2e_state_vars', () => { }); it('sets the expiration timestamp property', async () => { + // Mirrors CHANGE_AUTHORIZED_DELAY in noir-contracts/contracts/app/auth_contract/src/main.nr. + const oldDelay = 360n; const newDelay = BigInt(aztecSlotDuration * 2); // We change the DelayedPublicMutable authorized delay here to 2 slots, this means that a change to the "authorized" // value can only be applied 2 slots after it is initiated, and thus read requests on a historical state without // an initiated change is valid for at least 2 slots. - await authContract.methods.set_authorized_delay(newDelay).send({ from: defaultAccountAddress }); - - // Note: Because we are decreasing the delay, we must first wait for the (full previous delay - 1 slot). - // Since the CHANGE_AUTHORIZED_DELAY in the Auth contract is equal to 5 slots we just wait for 4 blocks. - await delay(4); - - // The validity of our DelayedPublicMutable read request should be limited to the new delay - // Note: We subtract 1 because blocks within the same checkpoint can share timestamps so the earliest scheduling - // can happen at the anchor timestamp itself. For this reason, the latest timestamp at which a change is - // guaranteed to not have happened is the anchor timestamp + the new delay - 1. - const expectedModifiedExpirationTimestamp = - (await aztecNode.getBlockData('latest'))!.header.globalVariables.timestamp + newDelay - 1n; + const setDelayResult = await authContract.methods + .set_authorized_delay(newDelay) + .send({ from: defaultAccountAddress }); + const setDelayBlockNumber = setDelayResult.receipt.blockNumber; + if (setDelayBlockNumber === undefined) { + throw new Error('set_authorized_delay tx did not return a block number'); + } + const setDelayBlock = await aztecNode.getBlockData(setDelayBlockNumber); + // When *decreasing* the delay, ScheduledDelayChange::schedule_change sets the scheduled + // timestamp_of_change to `current_timestamp + (oldDelay - newDelay)` — not `current_timestamp + oldDelay`. + // See noir-protocol-circuits/crates/types/src/delayed_public_mutable/scheduled_delay_change.nr. + const timestampOfChange = setDelayBlock!.header.globalVariables.timestamp + (oldDelay - newDelay); + + // Advance the chain until the scheduled timestamp_of_change has been reached, so any future + // anchor block falls in the "post" branch of get_effective_minimum_delay_at and the effective + // delay equals newDelay - 1 (not the larger time_until_delay_change + newDelay - 1). We send + // no-op txs to push fresh blocks rather than relying on wall-clock time: the e2e fixture + // forces aztecSlotDuration=12s under pipelining (see fixtures/setup.ts), so a fixed + // `delay(N blocks)` cannot count for the schedule — block timestamp polling is the + // slot-duration-agnostic way to know we have crossed the schedule. + while ((await aztecNode.getBlockData('latest'))!.header.globalVariables.timestamp < timestampOfChange) { + await authContract.methods.get_authorized().send({ from: defaultAccountAddress }); + } - // We now call our AuthContract to see if the change in expiration timestamp has reflected our delay change + // We now call our AuthContract to see if the change in expiration timestamp has reflected our delay change. + // expirationTimestamp is `anchor.timestamp + effective_minimum_delay`, where the anchor is the + // historical header the PXE pinned at the start of proveTx. Compare directly against that anchor + // so the assertion isn't flaky against chain drift between the "latest" snapshot and proveTx's own sync. const tx = await proveInteraction(wallet, authContract.methods.get_authorized_in_private(), { from: defaultAccountAddress, }); - expect(tx.data.expirationTimestamp).toEqual(expectedModifiedExpirationTimestamp); + const anchorTimestamp = tx.data.constants.anchorBlockHeader.globalVariables.timestamp; + expect(tx.data.expirationTimestamp).toEqual(anchorTimestamp + newDelay - 1n); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_static_calls.test.ts b/yarn-project/end-to-end/src/e2e_static_calls.test.ts index 6bab6c4cbdf0..5039644c6373 100644 --- a/yarn-project/end-to-end/src/e2e_static_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_static_calls.test.ts @@ -3,7 +3,11 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { StaticChildContract } from '@aztec/noir-test-contracts.js/StaticChild'; import { StaticParentContract } from '@aztec/noir-test-contracts.js/StaticParent'; -import { STATIC_CALL_STATE_MODIFICATION_ERROR, STATIC_CONTEXT_ASSERTION_ERROR } from './fixtures/fixtures.js'; +import { + AUTOMINE_E2E_OPTS, + STATIC_CALL_STATE_MODIFICATION_ERROR, + STATIC_CONTEXT_ASSERTION_ERROR, +} from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_static_calls', () => { @@ -19,7 +23,7 @@ describe('e2e_static_calls', () => { teardown, wallet, accounts: [owner], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); sender = owner; ({ contract: parentContract } = await StaticParentContract.deploy(wallet).send({ from: owner })); ({ contract: childContract } = await StaticChildContract.deploy(wallet).send({ from: owner })); diff --git a/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts b/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts index 70c6ce8b0b8f..b3baf6a8ea67 100644 --- a/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts +++ b/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts @@ -2,6 +2,7 @@ import { StorageProofTestContract } from '@aztec/noir-test-contracts.js/StorageP import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { type EndToEndContext, setup, teardown } from '../fixtures/setup.js'; import { buildStorageProofCapsules, loadStorageProofArgs } from './fixtures/storage_proof_fixture.js'; @@ -12,7 +13,7 @@ describe('Storage proof', () => { let contract: StorageProofTestContract; beforeAll(async () => { - ctx = await setup(1); + ctx = await setup(1, { ...AUTOMINE_E2E_OPTS }); ({ contract } = await StorageProofTestContract.deploy(ctx.wallet).send({ from: ctx.accounts[0] })); }); diff --git a/yarn-project/end-to-end/src/e2e_synching.test.ts b/yarn-project/end-to-end/src/e2e_synching.test.ts index 54e278458161..2e00ab15bf9e 100644 --- a/yarn-project/end-to-end/src/e2e_synching.test.ts +++ b/yarn-project/end-to-end/src/e2e_synching.test.ts @@ -66,6 +66,7 @@ import * as fs from 'fs'; import { type MockProxy, mock } from 'jest-mock-extended'; import { getContract } from 'viem'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { mintTokensToPrivate } from './fixtures/token_utils.js'; import { type EndToEndContext, setup, setupPXEAndGetWallet } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; @@ -340,6 +341,7 @@ describe('e2e_synching', () => { initialFundedAccounts, cheatCodes, } = await setup(1, { + ...PIPELINING_SETUP_OPTS, l1StartTime: START_TIME, l2StartTime: START_TIME + 200 * ETHEREUM_SLOT_DURATION, numberOfInitialFundedAccounts: variant.txCount + 1, @@ -422,6 +424,7 @@ describe('e2e_synching', () => { initialFundedAccounts, dateProvider, } = await setup(0, { + ...PIPELINING_SETUP_OPTS, l1StartTime: START_TIME, numberOfInitialFundedAccounts: 10, }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts index 50ac4a7f36be..bf1008cf4510 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts @@ -1,3 +1,4 @@ +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract access control', () => { @@ -5,7 +6,7 @@ describe('e2e_token_contract access control', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts index b9760a983627..c256dc91e27d 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR, U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR, U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract burn', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract burn', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, wallet, adminAddress, tokenSim, adminAddress, account1Address } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts index 46908a688eab..75320121fa15 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts @@ -1,4 +1,4 @@ -import { U128_OVERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, U128_OVERFLOW_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract minting', () => { @@ -7,7 +7,7 @@ describe('e2e_token_contract minting', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ asset, tokenSim, adminAddress, account1Address } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts index ffa5688df3b5..ee4b057ffb84 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts @@ -1,6 +1,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; import { TokenContract, type Transfer } from '@aztec/noir-contracts.js/Token'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { mintNotes } from '../fixtures/token_utils.js'; import { TokenContractTest } from './token_contract_test.js'; @@ -10,7 +11,7 @@ describe('e2e_token_contract private transfer recursion', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ asset, wallet, adminAddress, account1Address, node } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts index 185ac4231e8e..b58142beb64c 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts @@ -1,5 +1,6 @@ import { readFieldCompressedString } from '@aztec/aztec.js/utils'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract reading constants', () => { @@ -8,7 +9,7 @@ describe('e2e_token_contract reading constants', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts index bbc7f024fd19..74b8e590bf54 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts @@ -7,7 +7,14 @@ import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAcc import { jest } from '@jest/globals'; -import { type EndToEndContext, deployAccounts, publicDeployAccounts, setup, teardown } from '../fixtures/setup.js'; +import { + type EndToEndContext, + type SetupOptions, + deployAccounts, + publicDeployAccounts, + setup, + teardown, +} from '../fixtures/setup.js'; import { mintTokensToPrivate } from '../fixtures/token_utils.js'; import { TokenSimulator } from '../simulators/token_simulator.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; @@ -115,8 +122,9 @@ export class TokenContractTest { ); } - async setup() { + async setup(opts: Partial = {}) { this.context = await setup(0, { + ...opts, metricsPort: this.metricsPort, fundSponsoredFPC: true, skipAccountDeployment: true, diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts index 564707a74c77..900fb20af049 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts @@ -2,6 +2,7 @@ import { AztecAddress, CompleteAddress } from '@aztec/aztec.js/addresses'; import { BlockNumber } from '@aztec/foundation/branded-types'; import { TokenContract, type Transfer } from '@aztec/noir-contracts.js/Token'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer private', () => { @@ -11,7 +12,7 @@ describe('e2e_token_contract transfer private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ asset, adminAddress, wallet, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts index 385c912cec06..676285ea1b3f 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash, computeInnerAuthWitHashFromAction } from '@a import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer private', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract transfer private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ asset, tokenSim, wallet, adminAddress, account1Address, badAccount } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts index f50c89d80b5a..550d34fbe0b3 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts @@ -1,6 +1,6 @@ import { Fr } from '@aztec/aztec.js/fields'; -import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { type AlertConfig, GrafanaClient } from '../quality_of_service/grafana_client.js'; import { TokenContractTest } from './token_contract_test.js'; @@ -25,7 +25,7 @@ describe('e2e_token_contract transfer public', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, tokenSim, wallet, adminAddress, account1Address, badAccount } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts index 2688fea57172..03bf880e7318 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts @@ -1,4 +1,4 @@ -import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer_to_private', () => { @@ -8,7 +8,7 @@ describe('e2e_token_contract transfer_to_private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, adminAddress, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts index 1ff6f31ef53b..debb3f2b0234 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer_to_public', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract transfer_to_public', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, wallet, adminAddress, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts b/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts index 3755a88e45e3..907439f12a75 100644 --- a/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts +++ b/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts @@ -19,6 +19,7 @@ import type { TxEffect, TxHash } from '@aztec/stdlib/tx'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 120_000; @@ -48,7 +49,7 @@ describe('e2e tx effect oracle', () => { wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); const { contract: deployed, receipt } = await TxEffectOracleTestContract.deploy(wallet).send({ from: defaultAccountAddress, }); diff --git a/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts b/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts index a41d75782959..3e345cd6d98b 100644 --- a/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts +++ b/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts @@ -24,6 +24,7 @@ import { getACVMConfig } from './get_acvm_config.js'; import { getBBConfig } from './get_bb_config.js'; import { type EndToEndContext, + type SetupOptions, deployAccounts, getPrivateKeyFromIndex, getSponsoredFPCAddress, @@ -124,9 +125,10 @@ export class FullProverTest { ); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up subsystems from fresh'); this.context = await setup(0, { + ...opts, startProverNode: true, coinbase: this.coinbase, fundSponsoredFPC: true, diff --git a/yarn-project/end-to-end/src/fixtures/fixtures.ts b/yarn-project/end-to-end/src/fixtures/fixtures.ts index 0e4878212440..11c343e3a737 100644 --- a/yarn-project/end-to-end/src/fixtures/fixtures.ts +++ b/yarn-project/end-to-end/src/fixtures/fixtures.ts @@ -12,6 +12,70 @@ export const DEFAULT_MIN_FEE_PADDING = 5; */ export const LARGE_MIN_FEE_PADDING = 15; +/** + * Fee padding used by tests running under proposer pipelining. Under pipelining the fee-asset + * price modifier evolves faster across the build/publish gap, so client-set maxFeesPerGas (sized + * for the default 5x padding) was getting bumped past by the time the tx mined a few slots later. + * Observed worst case in CI: fee evolved ~20x between PXE snapshot and inclusion, exceeding even + * LARGE_MIN_FEE_PADDING (15x). + */ +export const PIPELINED_FEE_PADDING = 30; + +/** + * Setup option preset that opts a test into proposer pipelining. Use with `setup()`: + * + * await setup(N, { ...PIPELINING_SETUP_OPTS, ...otherOpts }); + * + * The preset sets: + * - `enableProposerPipelining: true` so the sequencer builds for `slot + 1`. + * - `inboxLag: 2` so the sequencer sources L1->L2 messages from checkpoint N-1 (already sealed), + * avoiding `L1ToL2MessagesNotReadyError` when building for slot N during slot N-1. + * - `minTxsPerBlock: 0` so empty checkpoints land even when a tx arrives late in the build window + * (otherwise the chain stalls on alternating slots). + * - `aztecSlotDuration: 12` / `ethereumSlotDuration: 4` so the pipelined cycle fits inside the + * default 300s Jest hook budget. Tests that depend on the env-default 72s/12s should override. + * - `walletMinFeePadding: PIPELINED_FEE_PADDING` (30x) to absorb the wider fee evolution window. + */ +export const PIPELINING_SETUP_OPTS = { + enableProposerPipelining: true, + inboxLag: 2, + minTxsPerBlock: 0, + aztecSlotDuration: 12, + ethereumSlotDuration: 4, + walletMinFeePadding: PIPELINED_FEE_PADDING, +} as const; + +/** + * Setup option preset that opts a test into the deterministic AutomineSequencer path. + * Use only for single-sequencer tests that don't exercise block-building or consensus + * (e.g. e2e_token, e2e_amm, e2e_authwit). Not compatible with `e2e_p2p/*`, + * `e2e_epochs/*`, `e2e_slashing/*`, `e2e_block_building`, or any multi-validator suite. + * + * await setup(N, { ...AUTOMINE_E2E_OPTS, ...otherOpts }); + * + * The preset: + * - Swaps the production Sequencer for an AutomineSequencer that builds one block per + * submitted tx, publishes synchronously to L1, and owns all time control through a + * serial queue (see `sequencer-client/src/sequencer/automine/automine_sequencer.ts`). + * - Disables the validator client and AnvilTestWatcher (the AutomineSequencer needs + * neither). + * - Disables proposer pipelining and uses `inboxLag: 1` (synchronous, non-pipelined). + * - Switches anvil into automine mode at setup time (no interval mining); each L1 tx + * mines an L1 block immediately. + * + * Requires `aztecTargetCommitteeSize: 0`, which is the e2e default at `setup.ts:317`. + */ +export const AUTOMINE_E2E_OPTS = { + useAutomineSequencer: true, + disableAnvilTestWatcher: true, + enableProposerPipelining: false, + inboxLag: 1, + minTxsPerBlock: 0, + aztecSlotDuration: 12, + ethereumSlotDuration: 4, + walletMinFeePadding: PIPELINED_FEE_PADDING, +} as const; + /** Returns worst-case predicted min fees with padding applied, mirroring the BaseWallet pattern. */ export async function getPaddedMaxFeesPerGas(node: AztecNode, padding = DEFAULT_MIN_FEE_PADDING): Promise { const predicted = await node.getPredictedMinFees(); diff --git a/yarn-project/end-to-end/src/fixtures/setup.ts b/yarn-project/end-to-end/src/fixtures/setup.ts index fb6b464defca..c83bcd3b5df6 100644 --- a/yarn-project/end-to-end/src/fixtures/setup.ts +++ b/yarn-project/end-to-end/src/fixtures/setup.ts @@ -213,6 +213,9 @@ export type SetupOptions = { /** Whether the initial node should be a lightweight RPC-only node (no sequencer, no validator). * Use for tests that create their own validator nodes and don't need the initial sequencer. */ skipInitialSequencer?: boolean; + /** Whether to swap the production Sequencer for the minimal AutomineSequencer. + * Use only for single-sequencer non-block-building tests. See AUTOMINE_E2E_OPTS in `fixtures.ts`. */ + useAutomineSequencer?: boolean; /** Options forwarded to PXE creation (e.g. execution hooks). */ pxeCreationOptions?: PXECreationOptions; } & Partial; @@ -457,6 +460,24 @@ export async function setup( Object.assign(config, deployL1ContractsValues.l1ContractAddresses); config.rollupVersion = deployL1ContractsValues.rollupVersion; + // Propagate L1-contracts-config overrides back to the node config so the archiver's + // `l1Constants` (and any other node-side consumer) agrees with what was actually deployed. + // Without this, a per-test override like `aztecEpochDuration: 4` lands on the rollup contract + // but the node config keeps the default (32), so `archiver.isEpochComplete(0)` computes + // `endSlot=31` and `EpochTestSettler`/`EpochMonitor` never fires — letting the + // `aztecProofSubmissionEpochs` window expire mid-test and prune the pending chain. + // Skip undefined values: callers (e.g. `P2PNetworkTest`) sometimes build `l1ContractsArgs` + // by spreading a partial `AztecNodeConfig`, which leaves unset fields (notably `dataDirectory`) + // as `undefined`. A blind Object.assign would then clobber the temp `dataDirectory` set earlier + // in this function and crash `setupSharedBlobStorage`. + if (opts.l1ContractsArgs) { + for (const [key, value] of Object.entries(opts.l1ContractsArgs)) { + if (value !== undefined) { + (config as unknown as Record)[key] = value; + } + } + } + if (enableAutomine) { await ethCheatCodes.setAutomine(false); await ethCheatCodes.setIntervalMining(config.ethereumSlotDuration); @@ -526,7 +547,11 @@ export async function setup( const shouldDeployAccounts = numberOfAccounts > 0 && !opts.skipAccountDeployment; // Only set minTxsPerBlock=0 if we need an empty block (no accounts at all, not skipped deployment) const needsEmptyBlock = numberOfAccounts === 0 && !opts.skipAccountDeployment; - config.minTxsPerBlock = shouldDeployAccounts ? 1 : needsEmptyBlock ? 0 : originalMinTxsPerBlock; + // Under proposer pipelining the sequencer builds during slot N-1 for slot N. A tx submitted at + // slot N start is too late -- it arrives after the build. Forcing minTxsPerBlock=1 then stalls + // the chain on alternating slots, so allow empty checkpoints under pipelining. + const accountsDeployMinTxs = config.enableProposerPipelining ? 0 : 1; + config.minTxsPerBlock = shouldDeployAccounts ? accountsDeployMinTxs : needsEmptyBlock ? 0 : originalMinTxsPerBlock; config.p2pEnabled = opts.mockGossipSubNetwork || config.p2pEnabled; config.p2pIp = opts.p2pIp ?? config.p2pIp ?? '127.0.0.1'; @@ -598,7 +623,12 @@ export async function setup( wallet.setMinFeePadding(opts.walletMinFeePadding); } - const cheatCodes = await CheatCodes.create(config.l1RpcUrls, aztecNodeService, dateProvider); + const cheatCodes = await CheatCodes.create( + config.l1RpcUrls, + aztecNodeService, + dateProvider, + aztecNodeService.getAutomineSequencer(), + ); if ( (opts.aztecTargetCommitteeSize && opts.aztecTargetCommitteeSize > 0) || @@ -627,6 +657,11 @@ export async function setup( accounts = accountManagers.map(accountManager => accountManager.address); } else if (needsEmptyBlock) { logger.info('No accounts are being deployed, waiting for an empty block 1 to be mined'); + // AutomineSequencer only builds on tx arrival; explicitly request an empty block. + const automine = aztecNodeService.getAutomineSequencer(); + if (automine) { + await automine.buildEmptyBlock(); + } while ((await aztecNodeService.getBlockNumber()) === 0) { await sleep(2000); } diff --git a/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts b/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts index 0e3c32f8d6e1..2bec4011d503 100644 --- a/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts +++ b/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts @@ -88,6 +88,10 @@ export type CreateNodeConfig = AztecNodeConfig & { dontStartSequencer?: boolean; /** Override the private key (instead of deriving from addressIndex). */ validatorPrivateKey?: `0x${string}`; + /** Corrupt only the block proposal at this indexWithinCheckpoint (testing only). */ + invalidBlockProposalIndexWithinCheckpoint?: number; + /** Accept proposal gossip regardless of slot timing (testing only). */ + skipProposalSlotValidation?: boolean; }; /** Creates a P2P enabled instance of Aztec Node Service with a validator. */ diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index 0ed3abf104d7..b49e09322174 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -8,6 +8,7 @@ import { Schnorr } from '@aztec/foundation/crypto/schnorr'; import { SchnorrHardcodedAccountContractArtifact } from '@aztec/noir-contracts.js/SchnorrHardcodedAccount'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { setup } from '../fixtures/utils.js'; import { TestWallet } from '../test-wallet/test_wallet.js'; @@ -44,7 +45,7 @@ describe('guides/writing_an_account_contract', () => { let context: Awaited>; beforeEach(async () => { - context = await setup(1); + context = await setup(1, { ...AUTOMINE_E2E_OPTS }); }); afterEach(() => context.teardown()); diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index 1950d9925e4a..8a52e28d826d 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -32,7 +32,7 @@ import { CrossChainTestHarness } from './cross_chain_test_harness.js'; // anvil --fork-url https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c --fork-block-number 17514288 --chain-id 31337 // For CI, this is configured in `run_tests.sh` and `docker-compose-images.yml` -const TIMEOUT = 360_000; +const TIMEOUT = 15 * 60 * 1000; export const uniswapL1L2TestSuite = ( setup: () => Promise, diff --git a/yarn-project/end-to-end/src/simulators/lending_simulator.ts b/yarn-project/end-to-end/src/simulators/lending_simulator.ts index ae299b31e249..defcc7965273 100644 --- a/yarn-project/end-to-end/src/simulators/lending_simulator.ts +++ b/yarn-project/end-to-end/src/simulators/lending_simulator.ts @@ -7,6 +7,7 @@ import { SlotNumber } from '@aztec/foundation/branded-types'; import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon'; import type { TestDateProvider } from '@aztec/foundation/timer'; import type { LendingContract } from '@aztec/noir-contracts.js/Lending'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import type { TokenSimulator } from './token_simulator.js'; @@ -92,15 +93,25 @@ export class LendingSimulator { public stableCoin: TokenSimulator, ) {} - async prepare() { + prepare() { this.accumulator = BASE; - const slot = await this.rollup.getSlotAt( - BigInt(await this.cc.eth.lastBlockTimestamp()) + BigInt(this.ethereumSlotDuration), - ); - this.time = Number(await this.rollup.getTimestampForSlot(slot)); + this.time = 0; } - async progressSlots(diff: number, dateProvider?: TestDateProvider) { + /** + * Advances the simulator's accumulator and clock to match a block timestamp observed on chain. + * Call this BEFORE applying any accumulator-sensitive mutation (borrow/repay) so the mutation + * sees the same accumulator as the contract did during execution. + */ + observeBlockTimestamp(ts: number) { + const diff = ts - this.time; + if (diff > 0) { + this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(diff)), BASE); + } + this.time = ts; + } + + async progressSlots(diff: number, _dateProvider?: TestDateProvider, node?: AztecNode & AztecNodeDebug) { if (diff <= 1) { return; } @@ -108,16 +119,19 @@ export class LendingSimulator { const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp())); const targetSlot = SlotNumber(slot + diff); const ts = Number(await this.rollup.getTimestampForSlot(targetSlot)); - const timeDiff = ts - this.time; - this.time = ts; - // Mine ethereum blocks such that the next block will be in a new slot - await this.cc.eth.warp(this.time - this.ethereumSlotDuration); - if (dateProvider) { - dateProvider.setTime(this.time * 1000); + // Queue-aware warp under AutomineSequencer: atomic warp + mineBlock that advances L2 time to the + // target slot. The cheat code routes through the AutomineSequencer queue when one is installed, + // and otherwise falls back to a manual warp + mineBlock loop. + if (node) { + await this.cc.warpL2TimeAtLeastTo(node, ts); + } else { + await this.cc.eth.warp(ts - this.ethereumSlotDuration); } + + // Mark the latest checkpoint as proven so the rollup does not reorg pending checkpoints when + // time jumps far enough forward to cross an unproven epoch boundary. await this.cc.rollup.markAsProven(await this.rollup.getCheckpointNumber()); - this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE); } depositPrivate(from: AztecAddress, onBehalfOf: Fr, amount: bigint) { diff --git a/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts b/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts index 702e30d8ccc1..1a6d299dea6d 100644 --- a/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts +++ b/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts @@ -43,7 +43,7 @@ describe('invalidate blocks test', () => { let node: AztecNode; let origMinTxsPerBlock: number | undefined; let origSlashProposeInvalidAttestationsPenalty: bigint | undefined; - let origSlashAttestDescendantOfInvalidPenalty: bigint | undefined; + let origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: bigint | undefined; const health = new ChainHealth(config.NAMESPACE, logger); const waitForSequencersToApplyConfig = async (expected: Partial, description: string) => { @@ -78,7 +78,8 @@ describe('invalidate blocks test', () => { skipCollectingAttestations: false, minTxsPerBlock: origMinTxsPerBlock, slashProposeInvalidAttestationsPenalty: origSlashProposeInvalidAttestationsPenalty, - slashAttestDescendantOfInvalidPenalty: origSlashAttestDescendantOfInvalidPenalty, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: + origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, }; await updateSequencersConfig(config, restoreConfig); // Ensure config has actually propagated before the next scenario test starts @@ -107,7 +108,8 @@ describe('invalidate blocks test', () => { const first = configs?.[0]; origMinTxsPerBlock = first?.minTxsPerBlock ?? origMinTxsPerBlock; origSlashProposeInvalidAttestationsPenalty = first?.slashProposeInvalidAttestationsPenalty; - origSlashAttestDescendantOfInvalidPenalty = first?.slashAttestDescendantOfInvalidPenalty; + origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty = + first?.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty; const initialCheckpointNumber = (await monitor.run()).checkpointNumber; @@ -116,7 +118,7 @@ describe('invalidate blocks test', () => { await updateSequencersConfig(config, { skipCollectingAttestations: true, slashProposeInvalidAttestationsPenalty: 0n, - slashAttestDescendantOfInvalidPenalty: 0n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 0n, minTxsPerBlock: 0, }); diff --git a/yarn-project/end-to-end/src/spartan/n_tps.test.ts b/yarn-project/end-to-end/src/spartan/n_tps.test.ts index 16bda90b2799..e15ced7cb33f 100644 --- a/yarn-project/end-to-end/src/spartan/n_tps.test.ts +++ b/yarn-project/end-to-end/src/spartan/n_tps.test.ts @@ -6,6 +6,7 @@ import { SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee'; import { type AztecNode, createAztecNodeClient } from '@aztec/aztec.js/node'; import { AccountManager } from '@aztec/aztec.js/wallet'; import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants'; +import { BlockNumber } from '@aztec/foundation/branded-types'; import { times, timesParallel } from '@aztec/foundation/collection'; import { randomBigInt } from '@aztec/foundation/crypto/random'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -552,6 +553,34 @@ describe('sustained N TPS test', () => { })); const startedAt = new Date().toISOString(); + // Block-watcher: stamps wall-clock minedAtMs on each sent tx the first time + // its block becomes visible to this client. Runs throughout sending AND the + // post-window waitForTx tail so late blocks still get a true client-observed + // timestamp. recordMinedTx (in waitForTx) is the slow-path fallback for any + // tx the watcher misses. + let lastSeenBlock = await aztecNode.getBlockNumber(); + const blockWatcher = new RunningPromise( + async () => { + const current = await aztecNode.getBlockNumber(); + while (lastSeenBlock < current) { + const n = BlockNumber.add(lastSeenBlock, 1); + const block = await aztecNode.getBlock(n, { includeTransactions: true }); + lastSeenBlock = n; + if (!block) { + continue; + } + metrics.observeBlockForMinedTxs( + n, + block.body.txEffects.map(t => t.txHash), + Date.now(), + ); + } + }, + logger, + 1000, + ); + blockWatcher.start(); + sendTxsAtTps(logger, abortController.signal, lowValueLanes, lowValueTps, lowValueSendTx); const sentTxHashes = sendTxsAtTps(logger, abortController.signal, highValueLanes, highValueTps, highValueSendTx); @@ -564,11 +593,6 @@ describe('sustained N TPS test', () => { highValueSent: sentTxHashes.length, }); - // metadata about the test run for the scraper script - const metadataPath = '/tmp/n_tps_timing_data.json'; - await writeFile(metadataPath, JSON.stringify({ startedAt, endedAt, runId: process.env.BENCH_RUN_ID })); - logger.info('Wrote benchmark metadata', { path: metadataPath, startedAt, endedAt }); - const results: { success: boolean; txHash: string; error?: any }[] = []; const waitForTx = async (txHash: string, txName: string) => { try { @@ -607,6 +631,24 @@ describe('sustained N TPS test', () => { logger.debug('Processed tx batch', { processed: index, remaining: sentTxHashes.length }); } + await blockWatcher.stop(); + + // Metadata + per-tx inclusion records for the bench_scrape script. Records + // are filtered to the high-value group, so this is the authoritative + // client-observed inclusion-latency dataset for the run. + const inclusionRecords = metrics.getInclusionRecords('tx_inclusion_time'); + const metadataPath = '/tmp/n_tps_timing_data.json'; + await writeFile( + metadataPath, + JSON.stringify({ startedAt, endedAt, runId: process.env.BENCH_RUN_ID, inclusionRecords }), + ); + logger.info('Wrote benchmark metadata', { + path: metadataPath, + startedAt, + endedAt, + inclusionRecords: inclusionRecords.length, + }); + // Count successes and failures const successCount = results.filter(r => r.success).length; const failureCount = results.filter(r => !r.success).length; diff --git a/yarn-project/end-to-end/src/spartan/tx_metrics.ts b/yarn-project/end-to-end/src/spartan/tx_metrics.ts index e027926e0f72..bac38184aac7 100644 --- a/yarn-project/end-to-end/src/spartan/tx_metrics.ts +++ b/yarn-project/end-to-end/src/spartan/tx_metrics.ts @@ -134,9 +134,12 @@ export class ProvingMetrics { export type TxInclusionData = { txHash: string; - sentAt: number; - minedAt: number; - attestedAt: number; + /** Wall-clock at client when the tx was submitted, in ms (Date.now()). */ + sentAtMs: number; + /** Wall-clock at client when the block containing the tx first became visible, in ms (Date.now()). -1 if never observed. */ + minedAtMs: number; + /** Reserved for future attestation-observed-at signal; -1 today. */ + attestedAtMs: number; blocknumber: number; priorityFee: number; totalFee: number; @@ -174,9 +177,9 @@ export class TxInclusionMetrics { this.data.set(txHash, { txHash, - sentAt: Math.trunc(Date.now() / 1000), - minedAt: -1, - attestedAt: -1, + sentAtMs: Date.now(), + minedAtMs: -1, + attestedAtMs: -1, blocknumber: -1, priorityFee: Number(priorityFees.feePerDaGas + priorityFees.feePerL2Gas), totalFee: -1, @@ -186,6 +189,28 @@ export class TxInclusionMetrics { this.groups.add(group); } + /** + * Stamp mined-at metadata for any tracked tx contained in this block, using + * `observedAtMs` (caller-supplied wall-clock at the moment they first saw the + * block). Idempotent: existing minedAtMs is preserved so the first observer + * wins (typically the block-watcher; recordMinedTx is a fallback). + */ + observeBlockForMinedTxs( + blockNumber: number, + txHashes: ReadonlyArray<{ toString(): string }>, + observedAtMs: number, + ): void { + txHashes.forEach((txHash, position) => { + const data = this.data.get(txHash.toString()); + if (!data || data.minedAtMs !== -1) { + return; + } + data.blocknumber = blockNumber; + data.minedAtMs = observedAtMs; + data.positionInBlock = position; + }); + } + async recordMinedTx(txReceipt: TxReceipt): Promise { const { txHash, blockNumber } = txReceipt; if (!txReceipt.isMined() || !txReceipt.hasExecutionSucceeded() || !blockNumber) { @@ -197,26 +222,43 @@ export class TxInclusionMetrics { return; } - if (!this.blocks.has(blockNumber)) { - this.blocks.set(blockNumber, this.aztecNode.getBlock(blockNumber, { includeTransactions: true })); - } - - const block = await this.blocks.get(blockNumber)!; - if (!block) { - this.logger?.warn('Failed to load block for mined tx receipt', { txHash: txHash.toString(), blockNumber }); - return; - } const data = this.data.get(txHash.toString()); if (!data) { const message = `Missing sent tx record for mined tx ${txHash.toString()}`; this.logger?.warn(message, { txHash: txHash.toString(), blockNumber }); throw new Error(message); } - data.blocknumber = blockNumber; - data.minedAt = Number(block.header.globalVariables.timestamp); - data.attestedAt = -1; data.totalFee = Number(txReceipt.transactionFee ?? 0n); - data.positionInBlock = block.body.txEffects.findIndex(txEffect => txEffect.txHash.equals(txHash)); + + // Fallback path for txs the block-watcher missed (e.g. observed only after + // the watcher stopped). Stamp with the block's L2 slot timestamp; this is + // earlier than the true client-observed time by attestation+propagation + // lag, but it's the only deterministic timestamp available post-hoc. + if (data.minedAtMs === -1) { + if (!this.blocks.has(blockNumber)) { + this.blocks.set(blockNumber, this.aztecNode.getBlock(blockNumber, { includeTransactions: true })); + } + const block = await this.blocks.get(blockNumber)!; + if (!block) { + this.logger?.warn('Failed to load block for mined tx receipt', { txHash: txHash.toString(), blockNumber }); + return; + } + data.blocknumber = blockNumber; + data.minedAtMs = Number(block.header.globalVariables.timestamp) * 1000; + data.positionInBlock = block.body.txEffects.findIndex(txEffect => txEffect.txHash.equals(txHash)); + } + } + + /** Per-tx inclusion records for a group. Used to serialise out for downstream tooling. */ + getInclusionRecords(group?: string): TxInclusionData[] { + const out: TxInclusionData[] = []; + for (const tx of this.data.values()) { + if (group !== undefined && tx.group !== group) { + continue; + } + out.push({ ...tx }); + } + return out; } public inclusionTimeInSeconds(group: string): { @@ -231,19 +273,23 @@ export class TxInclusionMetrics { const histogram = createHistogram({}); let nonPositive = 0; for (const tx of this.data.values()) { - if (!tx.blocknumber || tx.group !== group || tx.minedAt === -1) { + if (!tx.blocknumber || tx.group !== group || tx.minedAtMs === -1) { continue; } - // `minedAt` is the block's L2 slot timestamp (seconds) while `sentAt` is the wall-clock - // send time. Because the slot timestamp can precede or equal the send time, the delta - // can be <= 0, which perf_hooks.createHistogram rejects. Skip those instead of crashing. - const delta = tx.minedAt - tx.sentAt; - if (delta <= 0) { + // Both timestamps are client wall-clock (ms). A negative delta should be + // impossible since the watcher stamps minedAtMs strictly after sentAtMs, + // but the fallback path (recordMinedTx via L2 slot timestamp) can stamp + // earlier than sentAtMs. perf_hooks.createHistogram rejects <=0; skip + // those instead of crashing. + const deltaMs = tx.minedAtMs - tx.sentAtMs; + if (deltaMs <= 0) { nonPositive++; continue; } - histogram.record(delta); + // Histogram is recorded in seconds (rounded) to match the existing + // toGithubActionBenchmarkJSON output unit; per-tx records carry the raw ms. + histogram.record(Math.max(1, Math.round(deltaMs / 1000))); } if (nonPositive > 0) { this.logger?.debug(`Dropped ${nonPositive} tx inclusion samples with non-positive delta`, { group }); diff --git a/yarn-project/end-to-end/src/test-wallet/utils.ts b/yarn-project/end-to-end/src/test-wallet/utils.ts index ec7b2554a414..de361a62823b 100644 --- a/yarn-project/end-to-end/src/test-wallet/utils.ts +++ b/yarn-project/end-to-end/src/test-wallet/utils.ts @@ -1,4 +1,5 @@ import { + BatchCall, ContractFunctionInteraction, DeployMethod, type DeployOptions, @@ -62,7 +63,7 @@ export class ProvenTx extends Tx { export async function proveInteraction( wallet: TestWallet, - interaction: ContractFunctionInteraction | DeployMethod, + interaction: ContractFunctionInteraction | DeployMethod | BatchCall, options: SendInteractionOptions | DeployOptions, ) { const execPayload = await interaction.request(options); diff --git a/yarn-project/ethereum/src/contracts/chain_state_override.test.ts b/yarn-project/ethereum/src/contracts/chain_state_override.test.ts index 77d3b79f2459..f88c6574d9b2 100644 --- a/yarn-project/ethereum/src/contracts/chain_state_override.test.ts +++ b/yarn-project/ethereum/src/contracts/chain_state_override.test.ts @@ -66,6 +66,30 @@ describe('SimulationOverridesBuilder', () => { expect(plan?.chainTipsOverride).toEqual({ pending: CheckpointNumber(7), proven: CheckpointNumber(3) }); }); + it('merge does not erase prior chain tip values when the incoming half is undefined', () => { + const builder = new SimulationOverridesBuilder().withChainTips({ + pending: CheckpointNumber(7), + proven: CheckpointNumber(5), + }); + builder.merge({ chainTipsOverride: { pending: undefined, proven: CheckpointNumber(6) } }); + const plan = builder.build(); + expect(plan?.chainTipsOverride).toEqual({ pending: CheckpointNumber(7), proven: CheckpointNumber(6) }); + }); + + it('merge does not erase prior pending checkpoint state when the incoming field is undefined', () => { + const archive = Fr.random(); + const builder = new SimulationOverridesBuilder() + .withChainTips({ pending: CheckpointNumber(7) }) + .withPendingArchive(archive); + builder.merge({ + chainTipsOverride: { pending: CheckpointNumber(7) }, + pendingCheckpointState: { archive: undefined, slotNumber: SlotNumber(42) }, + }); + const plan = builder.build(); + expect(plan?.pendingCheckpointState?.archive).toEqual(archive); + expect(plan?.pendingCheckpointState?.slotNumber).toEqual(SlotNumber(42)); + }); + it('attaches temp checkpoint log fields under the configured pending checkpoint', () => { const headerHash = Fr.random(); const outHash = Fr.random(); diff --git a/yarn-project/ethereum/src/contracts/chain_state_override.ts b/yarn-project/ethereum/src/contracts/chain_state_override.ts index 6358f0cde0e0..8693981098d0 100644 --- a/yarn-project/ethereum/src/contracts/chain_state_override.ts +++ b/yarn-project/ethereum/src/contracts/chain_state_override.ts @@ -1,6 +1,7 @@ import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer'; import type { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; import type { Buffer32 } from '@aztec/foundation/buffer'; +import { merge } from '@aztec/foundation/collection'; import type { Fr } from '@aztec/foundation/curves/bn254'; import type { StateOverride } from 'viem'; @@ -45,18 +46,22 @@ export class SimulationOverridesBuilder { return new SimulationOverridesBuilder().merge(plan); } - /** Merges another plan into this builder. Later values win on a per-half basis for chain tips. */ + /** + * Merges another plan into this builder. Later values win on a per-half basis for chain tips, + * but explicit `undefined` fields in the incoming plan are ignored so they cannot erase a + * previously-set value. + */ public merge(plan: SimulationOverridesPlan | undefined): this { if (!plan) { return this; } if (plan.chainTipsOverride) { - this.chainTipsOverride = { ...(this.chainTipsOverride ?? {}), ...plan.chainTipsOverride }; + this.chainTipsOverride = merge(this.chainTipsOverride ?? {}, plan.chainTipsOverride); + } + if (plan.pendingCheckpointState) { + this.pendingCheckpointState = merge(this.pendingCheckpointState ?? {}, plan.pendingCheckpointState); } - this.pendingCheckpointState = plan.pendingCheckpointState - ? { ...(this.pendingCheckpointState ?? {}), ...plan.pendingCheckpointState } - : this.pendingCheckpointState; this.disableBlobCheck = this.disableBlobCheck || (plan.disableBlobCheck ?? false); return this; @@ -87,15 +92,21 @@ export class SimulationOverridesBuilder { } /** - * Overrides the locally-derivable `tempCheckpointLogs` cell fields for the configured pending - * checkpoint. Callers populate these together because they all come from the same proposed - * checkpoint payload — there is no use case for setting them independently. + * Overrides one or more `tempCheckpointLogs` cell fields for the configured pending checkpoint. + * Fields are independent: any subset can be provided. The translator (`makeTempCheckpointLogOverride`) + * emits a stateDiff entry per field actually set, so unspecified fields stay at their on-chain + * values. + * + * `slotNumber` is load-bearing for `STFLib.canPruneAtTime`: when the simulation overrides `pending` + * to a checkpoint that has no on-chain `tempCheckpointLogs` entry yet, the missing slotNumber falls + * back to 0 and the contract treats the pending tip as belonging to epoch 0, triggering a phantom + * prune that silently undoes the `pending` override. */ public withPendingTempCheckpointLogFields(fields: { - headerHash: Fr; - outHash: Fr; - payloadDigest: Buffer32; - slotNumber: SlotNumber; + headerHash?: Fr; + outHash?: Fr; + payloadDigest?: Buffer32; + slotNumber?: SlotNumber; }): this { this.assertPendingCheckpointNumber(); this.pendingCheckpointState = { ...(this.pendingCheckpointState ?? {}), ...fields }; diff --git a/yarn-project/ethereum/src/contracts/governance_proposer.ts b/yarn-project/ethereum/src/contracts/governance_proposer.ts index 0210211bb28a..b9e169475854 100644 --- a/yarn-project/ethereum/src/contracts/governance_proposer.ts +++ b/yarn-project/ethereum/src/contracts/governance_proposer.ts @@ -20,6 +20,14 @@ import { ReadOnlyGovernanceContract, extractProposalIdFromLogs } from './governa export class GovernanceProposerContract implements IEmpireBase { private readonly proposer: GetContractReturnType; + /** + * Cache of bytecode-existence checks keyed by payload address. The check is stable for a + * contract's lifetime -- a contract either has code or it does not, and code cannot be removed + * after deployment (selfdestruct aside, which is not relevant here). Safe to memoize + * indefinitely for the lifetime of this instance. + */ + private readonly emptyPayloadCache: Map = new Map(); + constructor( public readonly client: ViemClient, address: Hex | EthAddress, @@ -133,6 +141,28 @@ export class GovernanceProposerContract implements IEmpireBase { return governance.hasActiveProposalWithPayload(payload); } + /** + * Returns true if the given payload address has no deployed bytecode. Used as a cheap + * pre-flight check before casting a governance signal — voting for a zero-code address + * is unrecoverable. + * + * We only cache the `false` result (address has bytecode). The `true` result is NOT + * cached because a CREATE2-redeployed address could go from empty to populated, and + * caching `true` would make us keep skipping a payload that later becomes valid. + */ + public async isPayloadEmpty(payload: EthAddress): Promise { + const key = payload.toString() as Hex; + if (this.emptyPayloadCache.get(key) === false) { + return false; + } + const code = await this.client.getCode({ address: key }); + const isEmpty = !code || code === '0x'; + if (!isEmpty) { + this.emptyPayloadCache.set(key, false); + } + return isEmpty; + } + public async submitRoundWinner( round: bigint, l1TxUtils: L1TxUtils, diff --git a/yarn-project/ethereum/src/contracts/multicall.test.ts b/yarn-project/ethereum/src/contracts/multicall.test.ts index 1804eaf1e307..c63077e1bb29 100644 --- a/yarn-project/ethereum/src/contracts/multicall.test.ts +++ b/yarn-project/ethereum/src/contracts/multicall.test.ts @@ -17,7 +17,6 @@ import { L1TxUtils, createL1TxUtils } from '../l1_tx_utils/index.js'; import type { Anvil } from '../test/start_anvil.js'; import { startAnvil } from '../test/start_anvil.js'; import type { ExtendedViemWalletClient } from '../types.js'; -import { FormattedViemError } from '../utils.js'; import { MULTI_CALL_3_ADDRESS, Multicall3, deployMulticall3 } from './multicall.js'; describe('Multicall3', () => { @@ -97,34 +96,65 @@ describe('Multicall3', () => { abi: GovernanceProposerAbi, }); - it('should be able to call multiple functions in a single transaction', async () => { + it('should not revert by default if a single call fails', async () => { await deployMulticall3(walletClient, logger); - const result = await Multicall3.forward( - [makeSuccessfulCall(), makeFailingCall()], - l1TxUtils, - undefined, - undefined, - deployed.l1ContractAddresses.rollupAddress.toString(), - logger, - { revertOnFailure: true }, - ); + const result = await Multicall3.forward([makeSuccessfulCall(), makeFailingCall()], l1TxUtils, undefined, undefined); expect(result).toBeDefined(); - expect(result).toBeInstanceOf(FormattedViemError); - const formattedError = result as FormattedViemError; - expect(formattedError.message).toContain('ValidatorSelection__InsufficientValidatorSetSize'); + expect(result.receipt.status).toBe('success'); }); - it('should not revert by default if a single call fails', async () => { - await deployMulticall3(walletClient, logger); - const result = await Multicall3.forward( - [makeSuccessfulCall(), makeFailingCall()], - l1TxUtils, - undefined, - undefined, - deployed.l1ContractAddresses.rollupAddress.toString(), - logger, - ); - expect(result).toBeDefined(); - expect('receipt' in result && result.receipt.status).toBe('success'); + describe('simulateAggregate3', () => { + beforeAll(async () => { + await deployMulticall3(walletClient, logger); + }); + + it('decodes per-entry results when all entries succeed', async () => { + const result = await Multicall3.simulateAggregate3([makeSuccessfulCall(), makeSuccessfulCall()], l1TxUtils); + expect(result.kind).toBe('decoded'); + if (result.kind !== 'decoded') { + return; + } + expect(result.entries).toHaveLength(2); + expect(result.entries[0].success).toBe(true); + expect(result.entries[1].success).toBe(true); + expect(result.gasUsed).toBeGreaterThan(0n); + }); + + it('marks reverted entries with a decoded revert reason', async () => { + const result = await Multicall3.simulateAggregate3([makeSuccessfulCall(), makeFailingCall()], l1TxUtils); + expect(result.kind).toBe('decoded'); + if (result.kind !== 'decoded') { + return; + } + expect(result.entries).toHaveLength(2); + expect(result.entries[0].success).toBe(true); + expect(result.entries[1].success).toBe(false); + expect(result.entries[1].revertReason).toContain('ValidatorSelection__InsufficientValidatorSetSize'); + }); + + it('honours fakeSenderBalance by overriding the sender balance for the simulate', async () => { + // Use a sender we have not funded so a real send would fail with insufficient funds. + const poorPrivateKey = '0x' + 'aa'.repeat(32); + const poorAccount = privateKeyToAccount(poorPrivateKey as `0x${string}`); + const poorClient = createExtendedL1Client([rpcUrl], poorAccount, foundry); + const poorL1TxUtils = createL1TxUtils(poorClient, { logger }); + + // Without fakeSenderBalance, the simulate would not fail on entry-level (call doesn't need + // value), but the eth_simulateV1 may still validate sender funds for gas. Either way, with + // fakeSenderBalance we explicitly cap balance high enough that no balance-related path can + // fail in the simulate. + const result = await Multicall3.simulateAggregate3([makeSuccessfulCall()], poorL1TxUtils, { + fakeSenderBalance: 10n ** 20n, + }); + expect(result.kind).toBe('decoded'); + if (result.kind !== 'decoded') { + return; + } + expect(result.entries[0].success).toBe(true); + }); + + it('reports hasCode() true after deployMulticall3', async () => { + expect(await Multicall3.hasCode(l1TxUtils)).toBe(true); + }); }); }); diff --git a/yarn-project/ethereum/src/contracts/multicall.ts b/yarn-project/ethereum/src/contracts/multicall.ts index 40e17970e5db..f0b22bf71dac 100644 --- a/yarn-project/ethereum/src/contracts/multicall.ts +++ b/yarn-project/ethereum/src/contracts/multicall.ts @@ -1,16 +1,37 @@ -import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer'; -import { TimeoutError } from '@aztec/foundation/error'; +import { EthAddress } from '@aztec/foundation/eth-address'; import type { Logger } from '@aztec/foundation/log'; -import { type Address, type EncodeFunctionDataParameters, type Hex, encodeFunctionData, multicall3Abi } from 'viem'; +import { + type Abi, + type Address, + type BlockOverrides, + type Hex, + type RequiredBy, + type StateOverride, + type TransactionReceipt, + decodeFunctionResult, + encodeFunctionData, + multicall3Abi, +} from 'viem'; import type { L1BlobInputs, L1TxConfig, L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js'; import type { ExtendedViemWalletClient } from '../types.js'; -import { FormattedViemError, formatViemError } from '../utils.js'; -import { RollupContract } from './rollup.js'; +import { tryDecodeRevertReason } from '../utils.js'; export const MULTI_CALL_3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11' as const; +/** + * Thrown by `Multicall3.forward` when the forwarder transaction lands but the receipt reports a + * reverted status. This is not expected (aggregate3 uses allowFailure: true), so callers should + * treat it as a fatal on-chain failure rather than retrying on a different publisher. + */ +export class MulticallForwarderRevertedError extends Error { + constructor(public readonly receipt: TransactionReceipt) { + super(`Multicall3 forwarder tx reverted: ${receipt.transactionHash}`); + this.name = 'MulticallForwarderRevertedError'; + } +} + /** ABI fragment for aggregate3Value — not included in viem's multicall3Abi. */ export const aggregate3ValueAbi = [ { @@ -44,116 +65,169 @@ export const aggregate3ValueAbi = [ }, ] as const; +/** A single call to embed inside an aggregate3 simulation. The abi is used to decode revert reasons. */ +export type SimulateAggregate3Request = { + to: Address; + data: Hex; + /** Optional ABI used to decode the revert reason if this entry reverts. */ + abi?: Abi; +}; + +export type SimulateAggregate3EntryResult = { + success: boolean; + /** Decoded revert reason text when `success === false` and a request abi was provided. */ + revertReason?: string; + /** Raw return data hex. `'0x'` for successful entries with void return. */ + returnData: Hex; +}; + +/** + * Outcome of a bundle simulation. + * - `decoded`: eth_simulateV1 ran and produced a per-entry Result[]. Use `entries` for filtering. + * - `fallback`: the node does not support eth_simulateV1; `fallbackGasEstimate` was returned and no + * per-entry info is available. Caller should send the bundle as-is with a conservative gas cap. + */ +export type SimulateAggregate3Result = + | { kind: 'decoded'; entries: SimulateAggregate3EntryResult[]; gasUsed: bigint } + | { kind: 'fallback'; gasUsed: bigint }; + +export type SimulateAggregate3Options = { + blockOverrides?: BlockOverrides; + stateOverrides?: StateOverride; + /** + * If set, append a state override that fakes the sender's balance during the simulation so a + * low or zero balance does not cause the simulate to fail with insufficient funds. The fake + * balance is applied to `l1TxUtils.getSenderAddress()`. + */ + fakeSenderBalance?: bigint; + /** Gas cap to pass on the simulate call itself (defaults to viem's behavior). */ + gas?: bigint; + /** When eth_simulateV1 is unavailable, fall back to this gas estimate instead of throwing. */ + fallbackGasEstimate?: bigint; +}; + export class Multicall3 { - static async forward( + /** + * Returns true iff Multicall3 bytecode is deployed at MULTI_CALL_3_ADDRESS. An empty result from + * a non-existent contract would otherwise silently validate any bundle that uses Multicall3. + */ + static async hasCode(l1TxUtils: L1TxUtils): Promise { + const code = await l1TxUtils.getCode(EthAddress.fromString(MULTI_CALL_3_ADDRESS)); + return !!code && code !== '0x'; + } + + /** + * Simulates an aggregate3 call composed of the given requests via eth_simulateV1 and decodes the + * per-entry Result[]. Entries that revert are returned with a decoded revertReason (if the request + * provided an abi). + * + * Use this to pre-validate a bundle before sending it through `Multicall3.forward`. The caller can + * drop reverted entries from the bundle and re-simulate with the reduced list to get an accurate + * `gasUsed`. + */ + static async simulateAggregate3( + requests: SimulateAggregate3Request[], + l1TxUtils: L1TxUtils, + opts: SimulateAggregate3Options = {}, + ): Promise { + const calldata = encodeFunctionData({ + abi: multicall3Abi, + functionName: 'aggregate3', + args: [ + requests.map(r => ({ + target: r.to, + callData: r.data, + allowFailure: true, + })), + ], + }); + + const stateOverrides: StateOverride = [...(opts.stateOverrides ?? [])]; + if (opts.fakeSenderBalance !== undefined) { + stateOverrides.push({ + address: l1TxUtils.getSenderAddress().toString(), + balance: opts.fakeSenderBalance, + }); + } + + const simResult = await l1TxUtils.simulate( + { to: MULTI_CALL_3_ADDRESS, data: calldata, gas: opts.gas }, + opts.blockOverrides, + stateOverrides, + multicall3Abi, + { fallbackGasEstimate: opts.fallbackGasEstimate }, + ); + + if (simResult.result === '0x') { + return { kind: 'fallback', gasUsed: simResult.gasUsed }; + } + + const decoded = decodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + data: simResult.result, + }) as readonly { success: boolean; returnData: `0x${string}` }[]; + + const entries: SimulateAggregate3EntryResult[] = decoded.map((entry, i) => { + if (entry.success) { + return { success: true, returnData: entry.returnData }; + } + const abi = requests[i].abi; + const revertReason = abi ? tryDecodeRevertReason(entry.returnData, abi) : undefined; + return { success: false, returnData: entry.returnData, revertReason }; + }); + + return { kind: 'decoded', entries, gasUsed: simResult.gasUsed }; + } + + /** + * Sends a batch of requests through aggregate3. Individual calls may fail (allowFailure: true), + * but the top-level multicall is expected to land successfully. Throws if the send fails or if + * the receipt reports a reverted status. + */ + static async forward( requests: L1TxRequest[], l1TxUtils: L1TxUtils, - gasConfig: L1TxConfig | undefined, + gasConfig: TOptGasLimitRequired extends true ? RequiredBy : L1TxConfig | undefined, blobConfig: L1BlobInputs | undefined, - rollupAddress: Hex, - logger: Logger, - opts: { revertOnFailure?: boolean } = {}, + opts: { gasLimitRequired?: TOptGasLimitRequired } = {}, ) { - requests = requests.filter(request => request.to !== null); - const args = requests.map(r => ({ - target: r.to!, - callData: r.data!, - allowFailure: !opts.revertOnFailure, - })); - const forwarderFunctionData: Required> = { + if (opts.gasLimitRequired && !gasConfig?.gasLimit) { + throw new Error('Multicall gasLimit is required when gasLimitRequired is true'); + } + + const args = requests + .filter(request => request.to !== null) + .map(r => ({ + target: r.to!, + callData: r.data!, + allowFailure: true, + })); + const encodedForwarderData = encodeFunctionData({ abi: multicall3Abi, functionName: 'aggregate3', args: [args], - }; - - const encodedForwarderData = encodeFunctionData(forwarderFunctionData); - try { - const { receipt, state } = await l1TxUtils.sendAndMonitorTransaction( - { - to: MULTI_CALL_3_ADDRESS, - data: encodedForwarderData, - abi: multicall3Abi, - }, - gasConfig, - blobConfig, - ); - - if (receipt.status === 'success') { - const stats = await l1TxUtils.getTransactionStats(receipt.transactionHash); - return { receipt, stats }; - } else { - logger.error('Forwarder transaction failed', undefined, { receipt }); - - const args = { - ...forwarderFunctionData, - address: MULTI_CALL_3_ADDRESS, - }; - - let errorMsg: string | undefined; - - if (blobConfig) { - const maxFeePerBlobGas = blobConfig.maxFeePerBlobGas ?? state.gasPrice.maxFeePerBlobGas; - if (maxFeePerBlobGas === undefined) { - errorMsg = 'maxFeePerBlobGas is required to get the error message'; - } else { - logger.debug('Trying to get error from reverted tx with blob config'); - errorMsg = await l1TxUtils.tryGetErrorFromRevertedTx( - encodedForwarderData, - args, - { - blobs: blobConfig.blobs, - kzg: blobConfig.kzg, - maxFeePerBlobGas, - }, - [ - { - address: rollupAddress, - stateDiff: [ - { - slot: toPaddedHex(RollupContract.checkBlobStorageSlot, true), - value: toPaddedHex(0n, true), - }, - ], - }, - ], - ); - } - } else { - logger.debug('Trying to get error from reverted tx without blob config'); - errorMsg = await l1TxUtils.tryGetErrorFromRevertedTx(encodedForwarderData, args, undefined, []); - } - - return { receipt, errorMsg }; - } - } catch (err) { - if (err instanceof TimeoutError) { - throw err; - } + }); - for (const request of requests) { - logger.debug('Simulating request', { request }); - const result = await l1TxUtils - .simulate(request, undefined, [ - { - address: rollupAddress, - stateDiff: [ - { slot: toPaddedHex(RollupContract.checkBlobStorageSlot, true), value: toPaddedHex(0n, true) }, - ], - }, - ]) - .catch(err => formatViemError(err, request.abi)); - if (result instanceof FormattedViemError) { - logger.error('Found error in simulation', result, { - to: request.to ?? 'null', - data: request.data, - }); - - return result; - } - } - logger.warn('Failed to get error from reverted tx', { err }); - throw err; + const { receipt } = await l1TxUtils.sendAndMonitorTransaction( + { + to: MULTI_CALL_3_ADDRESS, + data: encodedForwarderData, + abi: multicall3Abi, + }, + gasConfig, + blobConfig, + ); + + // This shouldn't happen. Any failure in individual calls is swallowed by forward since we set + // allowFailure to true for all calls, so a reverted status here would indicate a problem with + // the Multicall3 contract itself or the forwarder transaction (such as an out-of-gas). + if (receipt.status !== 'success') { + throw new MulticallForwarderRevertedError(receipt); } + + const stats = await l1TxUtils.getTransactionStats(receipt.transactionHash); + return { receipt, stats, multicallData: encodedForwarderData }; } /** Batch multiple value transfers into a single aggregate3Value call on Multicall3. */ diff --git a/yarn-project/ethereum/src/l1_tx_utils/l1_tx_utils.ts b/yarn-project/ethereum/src/l1_tx_utils/l1_tx_utils.ts index 3ca1526cecdb..8ed7825cd6b6 100644 --- a/yarn-project/ethereum/src/l1_tx_utils/l1_tx_utils.ts +++ b/yarn-project/ethereum/src/l1_tx_utils/l1_tx_utils.ts @@ -131,6 +131,14 @@ export class L1TxUtils extends ReadOnlyL1TxUtils { ); } + /** + * Clears the cached `lastSentNonce` so the next `sendTransaction` call fetches the real + * nonce from the chain. Call this after an L1 reorg to prevent stale nonce references. + */ + public resetNonce(): void { + this.lastSentNonce = undefined; + } + public getSenderAddress() { return this.address; } @@ -213,6 +221,19 @@ export class L1TxUtils extends ReadOnlyL1TxUtils { return await this.signTransaction(txRequest as TransactionSerializable); } + private async checkInterruptedOrTimedOut(gasConfig: Pick): Promise { + if (this.interrupted) { + throw new InterruptError(`Transaction sending is interrupted`); + } + const now = new Date(await this.getL1Timestamp()); + if (gasConfig.txTimeoutAt && now > gasConfig.txTimeoutAt) { + throw new TimeoutError( + `Transaction timed out before sending (now ${now.toISOString()} > timeoutAt ${gasConfig.txTimeoutAt.toISOString()})`, + ); + } + return now; + } + /** * Sends a transaction with gas estimation and pricing * @param request - The transaction request (to, data, value) @@ -225,14 +246,15 @@ export class L1TxUtils extends ReadOnlyL1TxUtils { blobInputs?: L1BlobInputs, stateChange: TxUtilsState = TxUtilsState.SENT, ): Promise<{ txHash: Hex; state: L1TxState }> { - if (this.interrupted) { - throw new InterruptError(`Transaction sending is interrupted`); - } - try { const gasConfig = merge(this.config, gasConfigOverrides); const account = this.getSenderAddress().toString(); + // Fail fast before doing any work (gas estimation, balance check) if we've been interrupted + // or if the caller's deadline has already passed. The same check is repeated after gas + // estimation in case it took long enough to push us past the deadline. + await this.checkInterruptedOrTimedOut(gasConfig); + let gasLimit: bigint; if (this.debugMaxGasLimit) { gasLimit = MAX_L1_TX_LIMIT; @@ -245,16 +267,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils { const gasPrice = await this.getGasPrice(gasConfig, !!blobInputs); - if (this.interrupted) { - throw new InterruptError(`Transaction sending is interrupted`); - } - - const now = new Date(await this.getL1Timestamp()); - if (gasConfig.txTimeoutAt && now > gasConfig.txTimeoutAt) { - throw new TimeoutError( - `Transaction timed out before sending (now ${now.toISOString()} > timeoutAt ${gasConfig.txTimeoutAt.toISOString()})`, - ); - } + const now = await this.checkInterruptedOrTimedOut(gasConfig); let txHash: Hex; let nonce: number; diff --git a/yarn-project/ethereum/src/test/eth_cheat_codes.ts b/yarn-project/ethereum/src/test/eth_cheat_codes.ts index b1cbdd199d6f..82f90873f77b 100644 --- a/yarn-project/ethereum/src/test/eth_cheat_codes.ts +++ b/yarn-project/ethereum/src/test/eth_cheat_codes.ts @@ -95,6 +95,16 @@ export class EthCheatCodes { return parseInt(res.timestamp, 16); } + /** + * Get the timestamp of the pending L1 block — the block that anvil will mine next. + * Reflects any prior `setNextBlockTimestamp` call or the configured block interval. + * @returns The pending block timestamp in seconds. + */ + public async nextBlockTimestamp(): Promise { + const res = await this.doRpcCall('eth_getBlockByNumber', ['pending', false]); + return parseInt(res.timestamp, 16); + } + /** * Advance the chain by a number of blocks * @param numberOfBlocks - The number of blocks to mine diff --git a/yarn-project/ethereum/src/test/rollup_cheat_codes.ts b/yarn-project/ethereum/src/test/rollup_cheat_codes.ts index 48ef7ad3df77..2c7343e56518 100644 --- a/yarn-project/ethereum/src/test/rollup_cheat_codes.ts +++ b/yarn-project/ethereum/src/test/rollup_cheat_codes.ts @@ -178,6 +178,21 @@ export class RollupCheatCodes { return [timestamp, nextSlot]; } + /** + * Warps L1 time to the start of an explicit absolute slot. Unlike `advanceSlots(N)` which is + * relative to the current L1 timestamp at call time and therefore races with real-time + * progression between query and warp, this lands at the slot regardless of latency. + * + * Throws if the requested slot is in the past relative to current L1 time (anvil cannot + * rewind). + */ + public async advanceToSlot(slot: SlotNumber) { + const timestamp = await this.rollup.read.getTimestampForSlot([BigInt(slot)]); + await this.ethCheatCodes.warp(Number(timestamp), { silent: true, resetBlockInterval: true }); + this.logger.warn(`Advanced to slot ${slot}`, { timestamp }); + return timestamp; + } + /** * Warps time in L1 equivalent to however many slots. * @param howMany - The number of slots to advance. diff --git a/yarn-project/ethereum/src/utils.ts b/yarn-project/ethereum/src/utils.ts index 81673660565f..3079fbaf457a 100644 --- a/yarn-project/ethereum/src/utils.ts +++ b/yarn-project/ethereum/src/utils.ts @@ -276,6 +276,24 @@ function stripAbis(obj: any) { }); } +/** + * Best-effort decode of a raw revert payload (`0x...`) against an ABI. + * Returns a human-readable `ErrorName(arg1, arg2, ...)` string, or `undefined` if the selector + * is unknown or the payload is empty. Use to surface decoded error names alongside the raw + * payload in log lines for operators. + */ +export function tryDecodeRevertReason(data: Hex | undefined, abi: Abi): string | undefined { + if (!data || data === '0x') { + return undefined; + } + try { + const decoded = decodeErrorResult({ abi, data }); + return `${decoded.errorName}(${decoded.args?.join(', ') ?? ''})`; + } catch { + return undefined; + } +} + export function tryGetCustomErrorName(err: any) { try { // See https://viem.sh/docs/contract/simulateContract#handling-custom-errors diff --git a/yarn-project/foundation/package.json b/yarn-project/foundation/package.json index 3b798a313bff..be856d8324ba 100644 --- a/yarn-project/foundation/package.json +++ b/yarn-project/foundation/package.json @@ -62,6 +62,7 @@ "./eth-signature": "./dest/eth-signature/index.js", "./queue": "./dest/queue/index.js", "./fifo": "./dest/fifo/index.js", + "./fifo-set": "./dest/fifo_set/index.js", "./fs": "./dest/fs/index.js", "./buffer": "./dest/buffer/index.js", "./json-rpc": "./dest/json-rpc/index.js", diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index 87728f041c20..c62136c29ca7 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -76,6 +76,7 @@ export type EnvVar = | 'DEBUG' | 'DEBUG_P2P_DISABLE_COLOCATION_PENALTY' | 'ENABLE_PROVER_NODE' + | 'USE_AUTOMINE_SEQUENCER' | 'ETHEREUM_HOSTS' | 'ETHEREUM_DEBUG_HOSTS' | 'ETHEREUM_ALLOW_NO_DEBUG_HOSTS' @@ -101,8 +102,10 @@ export type EnvVar = | 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT' | 'OTEL_EXPORTER_OTLP_LOGS_ENDPOINT' | 'OTEL_COLLECT_INTERVAL_MS' + | 'OTEL_BSP_MAX_QUEUE_SIZE' | 'OTEL_EXCLUDE_METRICS' | 'OTEL_INCLUDE_METRICS' + | 'OTEL_MIN_TRACE_DURATION_MS' | 'OTEL_EXPORT_TIMEOUT_MS' | 'PUBLIC_OTEL_EXPORTER_OTLP_METRICS_ENDPOINT' | 'PUBLIC_OTEL_INCLUDE_METRICS' @@ -159,7 +162,7 @@ export type EnvVar = | 'P2P_DROP_TX_CHANCE' | 'P2P_TX_POOL_DELETE_TXS_AFTER_REORG' | 'P2P_MIN_TX_POOL_AGE_MS' - | 'P2P_MISSING_TX_COLLECTION_DEADLINE_MS' + | 'P2P_MISSING_TX_COLLECTION_DEADLINE_SLOTS' | 'P2P_RPC_PRICE_BUMP_PERCENTAGE' | 'DEBUG_P2P_INSTRUMENT_MESSAGES' | 'PEER_ID_PRIVATE_KEY' @@ -210,7 +213,8 @@ export type EnvVar = | 'RPC_SIMULATE_PUBLIC_MAX_DEBUG_LOG_MEMORY_READS' | 'SENTINEL_ENABLED' | 'SENTINEL_HISTORY_LENGTH_IN_EPOCHS' - | 'SENTINEL_HISTORIC_PROVEN_PERFORMANCE_LENGTH_IN_EPOCHS' + | 'SENTINEL_HISTORIC_EPOCH_PERFORMANCE_LENGTH_IN_EPOCHS' + | 'SENTINEL_EPOCH_END_BUFFER_SLOTS' | 'SEQ_ENABLE_PROPOSER_PIPELINING' | 'SEQ_MAX_TX_PER_BLOCK' | 'SEQ_MAX_TX_PER_CHECKPOINT' @@ -240,17 +244,18 @@ export type EnvVar = | 'SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT' | 'SLASH_VALIDATORS_ALWAYS' | 'SLASH_VALIDATORS_NEVER' - | 'SLASH_PRUNE_PENALTY' | 'SLASH_DATA_WITHHOLDING_PENALTY' + | 'SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS' | 'SLASH_INACTIVITY_PENALTY' | 'SLASH_INACTIVITY_TARGET_PERCENTAGE' | 'SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD' | 'SLASH_INVALID_BLOCK_PENALTY' + | 'SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY' | 'SLASH_DUPLICATE_PROPOSAL_PENALTY' | 'SLASH_DUPLICATE_ATTESTATION_PENALTY' | 'SLASH_OVERRIDE_PAYLOAD' | 'SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY' - | 'SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY' + | 'SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY' | 'SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY' | 'SLASH_UNKNOWN_PENALTY' | 'SLASH_GRACE_PERIOD_L2_SLOTS' diff --git a/yarn-project/foundation/src/config/network_name.ts b/yarn-project/foundation/src/config/network_name.ts index e00dcb200ec7..7bde88ab1fa0 100644 --- a/yarn-project/foundation/src/config/network_name.ts +++ b/yarn-project/foundation/src/config/network_name.ts @@ -1,6 +1,5 @@ export type NetworkNames = | 'local' - | 'staging-ignition' | 'staging-public' | 'testnet' | 'mainnet' @@ -12,8 +11,6 @@ export function getActiveNetworkName(name?: string): NetworkNames { const network = name || process.env.NETWORK; if (!network || network === '' || network === 'local') { return 'local'; - } else if (network === 'staging-ignition') { - return network; } else if (network === 'staging-public') { return network; } else if (network === 'testnet' || network === 'alpha-testnet') { diff --git a/yarn-project/foundation/src/curves/grumpkin/point.test.ts b/yarn-project/foundation/src/curves/grumpkin/point.test.ts index 2adf80cf4543..e3569ae45b45 100644 --- a/yarn-project/foundation/src/curves/grumpkin/point.test.ts +++ b/yarn-project/foundation/src/curves/grumpkin/point.test.ts @@ -8,7 +8,7 @@ describe('Point', () => { it('always returns a valid point', async () => { for (let i = 0; i < 100; ++i) { const point = await Point.random(); - expect(point.isOnGrumpkin()).toEqual(true); + expect(point.isOnCurve()).toEqual(true); } }); @@ -26,7 +26,6 @@ describe('Point', () => { const p = new Point( new Fr(0x30426e64aee30e998c13c8ceecda3a77807dbead52bc2f3bf0eae851b4b710c1n), new Fr(0x113156a068f603023240c96b4da5474667db3b8711c521c748212a15bc034ea6n), - false, ); const [x, sign] = p.toXAndSign(); @@ -53,7 +52,6 @@ describe('Point', () => { const p = new Point( new Fr(0x1af41f5de96446dc3776a1eb2d98bb956b7acd9979a67854bec6fa7c2973bd73n), new Fr(0x07fc22c7f2c7057571f137fe46ea9c95114282bc95d37d71ec4bfb88de457d4an), - false, ); expect(p.toXAndSign()[1]).toBe(true); @@ -74,7 +72,6 @@ describe('Point', () => { const p = new Point( new Fr(0x247371652e55dd74c9af8dbe9fb44931ba29a9229994384bd7077796c14ee2b5n), new Fr(0x26441aec112e1ae4cee374f42556932001507ad46e255ffb27369c7e3766e5c0n), - false, ); expect(p.toXAndSign()[1]).toBe(false); diff --git a/yarn-project/foundation/src/curves/grumpkin/point.ts b/yarn-project/foundation/src/curves/grumpkin/point.ts index 05405446058d..6d798bb952ec 100644 --- a/yarn-project/foundation/src/curves/grumpkin/point.ts +++ b/yarn-project/foundation/src/curves/grumpkin/point.ts @@ -1,5 +1,4 @@ import { toBigIntBE } from '../../bigint-buffer/index.js'; -import { poseidon2Hash } from '../../crypto/poseidon/index.js'; import { randomBoolean } from '../../crypto/random/index.js'; import { hexSchemaFor } from '../../schemas/utils.js'; import { BufferReader, FieldReader, serializeToBuffer } from '../../serialize/index.js'; @@ -13,13 +12,16 @@ import { Fr } from '../bn254/field.js'; * TODO(#7386): Clean up this class. */ export class Point { - static ZERO = new Point(Fr.ZERO, Fr.ZERO, false); + static INFINITY = new Point(Fr.ZERO, Fr.ZERO); static SIZE_IN_BYTES = Fr.SIZE_IN_BYTES * 2; static COMPRESSED_SIZE_IN_BYTES = Fr.SIZE_IN_BYTES; /** Used to differentiate this class from AztecAddress */ public readonly kind = 'point'; + /** Whether the point is at infinity */ + public readonly isInfinite: boolean; + constructor( /** * The point's x coordinate @@ -29,12 +31,10 @@ export class Point { * The point's y coordinate */ public readonly y: Fr, - /** - * Whether the point is at infinity - */ - public readonly isInfinite: boolean, ) { // TODO(#7386): check if on curve + // NOTE: now there is no isInfinite in the struct, empty == inf, so an empty class would pass an on-curve check. This may be fine depending on the usage. + this.isInfinite = x.isZero() && y.isZero(); } toJSON() { @@ -61,7 +61,7 @@ export class Point { if (obj instanceof Buffer || Buffer.isBuffer(obj)) { return Point.fromBuffer(obj); } - return new Point(Fr.fromPlainObject(obj.x), Fr.fromPlainObject(obj.y), obj.isInfinite ?? false); + return new this(Fr.fromPlainObject(obj.x), Fr.fromPlainObject(obj.y)); } /** @@ -92,7 +92,7 @@ export class Point { */ static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new this(Fr.fromBuffer(reader), Fr.fromBuffer(reader), false); + return new this(Fr.fromBuffer(reader), Fr.fromBuffer(reader)); } /** @@ -125,19 +125,17 @@ export class Point { } /** - * Returns the contents of the point as an array of 3 fields. - * @returns The point as an array of 3 fields + * Returns the contents of the point as an array of 2 fields. + * @returns The point as an array of 2 fields */ - // TODO(F-553): Once we take the breaking change and drop the custom Noir `Point` wrapper in - // `noir-projects/noir-protocol-circuits/crates/types/src/point.nr`, revert this to serialize as `[x, y]` (2 fields) - // and drop the `is_infinite` flag from `fromFields` / `toNoirStruct` below. toFields() { - return [this.x, this.y, new Fr(this.isInfinite)]; + return [this.x, this.y]; } static fromFields(fields: Fr[] | FieldReader) { const reader = FieldReader.asReader(fields); - return new this(reader.readField(), reader.readField(), reader.readBoolean()); + const [x, y] = [reader.readField(), reader.readField()]; + return new this(x, y); } /** @@ -162,11 +160,12 @@ export class Point { const finalY = sign ? new Fr(yPositiveBigInt) : new Fr(yNegativeBigInt); // Create and return the new Point - return new this(x, finalY, false); + return new this(x, finalY); } /** - * @returns + * @param x - The x coordinate of the point + * @returns y^2 such that y^2 = x^3 - 17 */ static YFromX(x: Fr): Promise { // Calculate y^2 = x^3 - 17 (i.e. the Grumpkin curve equation) @@ -194,24 +193,15 @@ export class Point { return { x: this.x.toBigInt(), y: this.y.toBigInt(), - isInfinite: this.isInfinite ? 1n : 0n, }; } /** * Converts the Point instance to a Buffer representation of the coordinates. * @returns A Buffer representation of the Point instance. - * @dev Note that toBuffer does not include the isInfinite flag and other serialization methods do (e.g. toFields). - * This is because currently when we work with point as bytes we don't want to populate the extra bytes for - * isInfinite flag because: - * 1. Our Grumpkin BB API currently does not handle point at infinity, - * 2. we use toBuffer when serializing notes and events and there we only work with public keys and point at infinity - * is not considered a valid public key and the extra byte would raise DA cost. + * @dev Note that toBuffer does not include the isInfinite flag. The point at infinity is serialized as (0, 0). */ toBuffer() { - if (this.isInfinite) { - throw new Error('Cannot serialize infinite point with isInfinite flag'); - } const buf = serializeToBuffer([this.x, this.y]); if (buf.length !== Point.SIZE_IN_BYTES) { throw new Error(`Invalid buffer length for Point: ${buf.length}`); @@ -261,12 +251,10 @@ export class Point { } toNoirStruct() { - /* eslint-disable camelcase */ - return { x: this.x, y: this.y, is_infinite: this.isInfinite }; - /* eslint-enable camelcase */ + return { x: this.x, y: this.y }; } - // Used for IvpkM, OvpkM, NpkM and TpkM. TODO(#8124): Consider removing this method. + // Used for IvpkM. TODO(#8124): Consider removing this method. toWrappedNoirStruct() { return { inner: this.toNoirStruct() }; } @@ -286,21 +274,13 @@ export class Point { return this.x.isZero() && this.y.isZero(); } - hash() { - return poseidon2Hash(this.toFields()); - } - /** - * Check if this is point at infinity. - * Check this is consistent with how bb is encoding the point at infinity + * @param x - The x coordinate of the point + * @param y - The y coordinate of the point + * @returns Whether the point exists on Grumpkin */ - public get inf() { - return this.isInfinite; - } - - isOnGrumpkin() { - // TODO: Check this against how bb handles curve check and infinity point check - if (this.inf) { + isOnCurve() { + if (this.isInfinite) { return true; } diff --git a/yarn-project/foundation/src/fifo_set/fifo_set.test.ts b/yarn-project/foundation/src/fifo_set/fifo_set.test.ts new file mode 100644 index 000000000000..f0b4628131d1 --- /dev/null +++ b/yarn-project/foundation/src/fifo_set/fifo_set.test.ts @@ -0,0 +1,62 @@ +import { FifoSet } from './fifo_set.js'; + +describe('FifoSet', () => { + it('keeps entries up to the limit', () => { + const set = FifoSet.withLimit(3); + + set.add('a'); + set.add('b'); + set.add('c'); + + expect([...set]).toEqual(['a', 'b', 'c']); + expect(set.size).toBe(3); + expect(set.limit).toBe(3); + }); + + it('evicts the oldest entry when adding past the limit', () => { + const set = FifoSet.withLimit(2); + + set.add('a'); + set.add('b'); + set.add('c'); + + expect([...set]).toEqual(['b', 'c']); + }); + + it('compacts initial values to the newest entries', () => { + const set = FifoSet.withLimit(2, ['a', 'b', 'c']); + + expect([...set]).toEqual(['b', 'c']); + }); + + it('does not evict when adding a duplicate', () => { + const set = FifoSet.withLimit(2, ['a', 'b']); + + set.add('a'); + + expect([...set]).toEqual(['a', 'b']); + }); + + it('adds absent values and reports whether the set changed', () => { + const set = FifoSet.withLimit(2, ['a']); + + expect(set.addIfAbsent('a')).toBe(false); + expect(set.addIfAbsent('b')).toBe(true); + expect(set.addIfAbsent('c')).toBe(true); + expect([...set]).toEqual(['b', 'c']); + }); + + it('can evict undefined values', () => { + const set = FifoSet.withLimit(1, [undefined, 'a']); + + expect([...set]).toEqual(['a']); + + set.add(undefined); + + expect([...set]).toEqual([undefined]); + }); + + it.each([0, -1, 1.5, Number.NaN, Number.POSITIVE_INFINITY])('throws for invalid limit %s', limit => { + expect(() => FifoSet.withLimit(limit)).toThrow('FifoSet limit must be a positive safe integer'); + }); +}); diff --git a/yarn-project/foundation/src/fifo_set/fifo_set.ts b/yarn-project/foundation/src/fifo_set/fifo_set.ts new file mode 100644 index 000000000000..dcf8d494456c --- /dev/null +++ b/yarn-project/foundation/src/fifo_set/fifo_set.ts @@ -0,0 +1,52 @@ +/** A Set capped to a fixed number of entries, evicting the oldest inserted value when full. */ +export class FifoSet extends Set { + private _limit: number | undefined; + + private constructor(values?: Iterable) { + super(values); + } + + /** Creates a bounded set with a positive integer limit. */ + static withLimit(limit: number, values?: Iterable): FifoSet { + if (!Number.isSafeInteger(limit) || limit <= 0) { + throw new TypeError(`FifoSet limit must be a positive safe integer: ${limit}`); + } + + const set = new FifoSet(values); + set._limit = limit; + set.compact(); + + return set; + } + + override add(value: T): this { + super.add(value); + this.compact(); + return this; + } + + /** Maximum number of entries retained by this set. */ + public get limit(): number { + return this._limit ?? Infinity; + } + + /** Evicts oldest entries until the set is within its limit. */ + public compact(): void { + while (this.size > this.limit) { + const head = this.values().next(); + if (head.done) { + return; + } + this.delete(head.value); + } + } + + /** Adds a value only if it is absent, returning whether the set changed. */ + public addIfAbsent(value: T): boolean { + if (this.has(value)) { + return false; + } + this.add(value); + return true; + } +} diff --git a/yarn-project/foundation/src/fifo_set/index.ts b/yarn-project/foundation/src/fifo_set/index.ts new file mode 100644 index 000000000000..28d7234fc93a --- /dev/null +++ b/yarn-project/foundation/src/fifo_set/index.ts @@ -0,0 +1 @@ +export * from './fifo_set.js'; diff --git a/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.test.ts b/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.test.ts index faf3af004d14..0682209fcd23 100644 --- a/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.test.ts +++ b/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.test.ts @@ -91,6 +91,64 @@ describe('SafeJsonRpcServer', () => { expectError(response, 400, 'Test state failed'); }); + it('runs diagnostics around the dispatched RPC function', async () => { + const calls: string[] = []; + server = createSafeJsonRpcServer(testState, TestStateSchema, { + diagnostic: async (ctx, next) => { + calls.push(`start:${ctx.method}:${ctx.id}:${ctx.headers['x-test-header']}`); + await next(); + calls.push(`end:${ctx.method}`); + }, + }); + + const response = await request(server.getApp().callback()) + .post('/') + .send({ jsonrpc: '2.0', method: 'count', params: [], id: 42 }) + .set({ 'content-type': 'application/json', 'x-test-header': 'test-value' }); + + expect(response.status).toBe(200); + expect(response.text).toEqual(JSON.stringify({ jsonrpc, id: 42, result: 2 })); + expect(calls).toEqual(['start:count:42:test-value', 'end:count']); + }); + + it('runs diagnostics for each request in a batch', async () => { + const methods: string[] = []; + server = createSafeJsonRpcServer(testState, TestStateSchema, { + diagnostic: async (ctx, next) => { + methods.push(ctx.method); + await next(); + }, + maxBatchSize: 10, + }); + + const response = await sendBatch( + { jsonrpc: '2.0', method: 'getStatus', params: [], id: 42 }, + { jsonrpc: '2.0', method: 'clear', params: [], id: 43 }, + ); + + expect(response.status).toBe(200); + expect(methods).toEqual(['getStatus', 'clear']); + }); + + it('lets diagnostics observe handler failures', async () => { + const errors: string[] = []; + server = createSafeJsonRpcServer(testState, TestStateSchema, { + diagnostic: async (ctx, next) => { + try { + await next(); + } catch (err) { + errors.push(`${ctx.method}:${err instanceof Error ? err.message : String(err)}`); + throw err; + } + }, + }); + + const response = await send({ method: 'fail', params: [] }); + + expectError(response, 400, 'Test state failed'); + expect(errors).toEqual(['fail:Test state failed']); + }); + it('fails if sends invalid JSON', async () => { const response = await send('{'); expectError(response, 400, expect.stringContaining('Parse error')); diff --git a/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.ts b/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.ts index f1b0a6fa1105..a4bd066ba5be 100644 --- a/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.ts +++ b/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.ts @@ -59,8 +59,10 @@ export class SafeJsonRpcServer { config: Partial = {}, /** Health check function */ private readonly healthCheck: StatusCheckFn = () => true, - /** Additional middlewares */ + /** Additional Koa middlewares */ private extraMiddlewares: Application.Middleware[] = [], + /** Additional per-request diagnostics middlewares */ + private diagnosticsMiddleware?: DiagnosticsMiddleware, /** Logger */ private log = createLogger('json-rpc:server'), ) { @@ -161,7 +163,7 @@ export class SafeJsonRpcServer { }; return; } - const resp = await this.processBatch(ctx.request.body); + const resp = await this.processBatch(ctx.request.body, ctx.request.headers); if (Array.isArray(resp)) { ctx.status = 200; ctx.body = resp; @@ -170,7 +172,7 @@ export class SafeJsonRpcServer { ctx.body = resp; } } else { - const resp = await this.processRequest(ctx.request.body); + const resp = await this.processRequest(ctx.request.body, ctx.request.headers); if ('error' in resp) { ctx.status = this.config.http200OnError ? 200 : 400; } @@ -182,11 +184,11 @@ export class SafeJsonRpcServer { return router; } - private async processBatch(requests: any[]) { + private async processBatch(requests: any[], headers: http.IncomingHttpHeaders = {}) { if (requests.length === 0) { return { jsonrpc: '2.0', error: { code: -32600, message: 'Invalid Request' }, id: null }; } - const results = await Promise.allSettled(requests.map(req => this.processRequest(req))); + const results = await Promise.allSettled(requests.map(req => this.processRequest(req, headers))); return results.map(res => { if (res.status === 'fulfilled') { return res.value; @@ -197,7 +199,7 @@ export class SafeJsonRpcServer { }); } - private async processRequest(request: any) { + private async processRequest(request: any, headers: http.IncomingHttpHeaders = {}) { if (!request || typeof request !== 'object') { return { jsonrpc: '2.0', error: { code: -32600, message: 'Invalid Request' }, id: null }; } @@ -212,7 +214,16 @@ export class SafeJsonRpcServer { return { jsonrpc, id, error: { code: -32601, message: `Method not found: ${method}` } }; } else { try { - const result = await this.proxy.call(method, params); + let result: any; + + if (this.diagnosticsMiddleware) { + await this.diagnosticsMiddleware({ id: id ?? null, method, params, headers }, async () => { + result = await this.proxy.call(method, params); + }); + } else { + result = await this.proxy.call(method, params); + } + return { jsonrpc, id, result }; } catch (err: any) { if (err && err instanceof ZodError) { @@ -383,6 +394,7 @@ function makeAggregateHealthcheck(namedHandlers: NamespacedApiHandlers, log?: Lo export type SafeJsonRpcServerOptions = Partial< SafeJsonRpcServerConfig & { healthCheck: StatusCheckFn; + diagnostic: DiagnosticsMiddleware; log: Logger; middlewares: Application.Middleware[]; } @@ -397,10 +409,10 @@ export function createNamespacedSafeJsonRpcServer( handlers: NamespacedApiHandlers, options: Omit = {}, ): SafeJsonRpcServer { - const { middlewares, log } = options; + const { diagnostic, middlewares, log } = options; const proxy = new NamespacedSafeJsonProxy(handlers); const healthCheck = makeAggregateHealthcheck(handlers, log); - return new SafeJsonRpcServer(proxy, options, healthCheck, middlewares, log); + return new SafeJsonRpcServer(proxy, options, healthCheck, middlewares, diagnostic, log); } export function createSafeJsonRpcServer( @@ -408,9 +420,9 @@ export function createSafeJsonRpcServer( schema: ApiSchemaFor, options: SafeJsonRpcServerOptions = {}, ) { - const { log, healthCheck, middlewares: extraMiddlewares } = options; + const { diagnostic, log, healthCheck, middlewares: extraMiddlewares } = options; const proxy = new SafeJsonProxy(handler, schema); - return new SafeJsonRpcServer(proxy, options, healthCheck, extraMiddlewares, log); + return new SafeJsonRpcServer(proxy, options, healthCheck, extraMiddlewares, diagnostic, log); } /** diff --git a/yarn-project/foundation/src/timer/index.ts b/yarn-project/foundation/src/timer/index.ts index f993d7adffd9..991c10ee9039 100644 --- a/yarn-project/foundation/src/timer/index.ts +++ b/yarn-project/foundation/src/timer/index.ts @@ -1,4 +1,4 @@ export * from './date.js'; export { elapsed, elapsedSync } from './elapsed.js'; -export { TimeoutTask, executeTimeout, timeoutPromise } from './timeout.js'; +export { TimeoutTask, execWithSignal, executeTimeout, timeoutPromise } from './timeout.js'; export { Timer } from './timer.js'; diff --git a/yarn-project/foundation/src/timer/timeout.test.ts b/yarn-project/foundation/src/timer/timeout.test.ts index 647341086919..6d8cda64d3ee 100644 --- a/yarn-project/foundation/src/timer/timeout.test.ts +++ b/yarn-project/foundation/src/timer/timeout.test.ts @@ -1,7 +1,7 @@ import { jest } from '@jest/globals'; import { sleep } from '../sleep/index.js'; -import { executeTimeout } from './timeout.js'; +import { execWithSignal, executeTimeout } from './timeout.js'; describe('timeout', () => { it('execs within timeout', async () => { @@ -25,4 +25,32 @@ describe('timeout', () => { /The value of .* is out of range/, ); }); + + it('execs with a non-aborted signal', async () => { + const controller = new AbortController(); + await expect(execWithSignal(() => sleep(20).then(() => 'ok'), controller.signal)).resolves.toEqual('ok'); + }); + + it('rejects with custom error when signal aborts', async () => { + const controller = new AbortController(); + const promise = execWithSignal( + () => sleep(500), + controller.signal, + () => new Error('Aborted!'), + ); + + controller.abort(); + + await expect(promise).rejects.toThrow('Aborted!'); + }); + + it('execs with AbortSignal.timeout', async () => { + await expect( + execWithSignal( + () => sleep(500), + AbortSignal.timeout(20), + signal => new Error(signal.reason?.name ?? 'Aborted'), + ), + ).rejects.toThrow('TimeoutError'); + }); }); diff --git a/yarn-project/foundation/src/timer/timeout.ts b/yarn-project/foundation/src/timer/timeout.ts index 91ac59e46bc4..b8c75ecef1b1 100644 --- a/yarn-project/foundation/src/timer/timeout.ts +++ b/yarn-project/foundation/src/timer/timeout.ts @@ -92,6 +92,37 @@ export async function executeTimeout( return await task.exec(); } +function defaultSignalError(signal: AbortSignal) { + if (signal.reason instanceof Error) { + return signal.reason; + } + + return new Error(signal.reason ? String(signal.reason) : 'Operation aborted'); +} + +/** Executes a function until it completes or the given signal aborts. */ +export async function execWithSignal( + fn: (signal: AbortSignal) => Promise, + signal: AbortSignal, + errorFn: (signal: AbortSignal) => Error = defaultSignalError, +) { + if (signal.aborted) { + throw errorFn(signal); + } + + const abortPromise = promiseWithResolvers(); + const abortListener = () => abortPromise.reject(errorFn(signal)); + signal.addEventListener('abort', abortListener, { once: true }); + + try { + return await Promise.race([fn(signal), abortPromise.promise]); + } finally { + if (abortListener) { + signal.removeEventListener('abort', abortListener); + } + } +} + /** Returns a promise that rejects after the given timeout */ export function timeoutPromise(timeoutMs: number, errorMessage?: string) { const promise = promiseWithResolvers(); diff --git a/yarn-project/key-store/src/key_store.test.ts b/yarn-project/key-store/src/key_store.test.ts index 01736543b080..4f83ae9023cd 100644 --- a/yarn-project/key-store/src/key_store.test.ts +++ b/yarn-project/key-store/src/key_store.test.ts @@ -1,7 +1,7 @@ import { Fr } from '@aztec/foundation/curves/bn254'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; -import { deriveKeys, derivePublicKeyFromSecretKey } from '@aztec/stdlib/keys'; +import { deriveKeys, derivePublicKeyFromSecretKey, hashPublicKey } from '@aztec/stdlib/keys'; import { KeyStore } from './key_store.js'; @@ -13,52 +13,45 @@ describe('KeyStore', () => { const sk = new Fr(8923n); const keys = await deriveKeys(sk); const derivedMasterNullifierPublicKey = await derivePublicKeyFromSecretKey(keys.masterNullifierHidingKey); - const computedMasterNullifierPublicKeyHash = await derivedMasterNullifierPublicKey.hash(); + const computedMasterNullifierPublicKeyHash = await hashPublicKey(derivedMasterNullifierPublicKey); + const computedMasterIncomingViewingPublicKeyHash = await hashPublicKey(keys.publicKeys.ivpkM); const partialAddress = new Fr(243523n); const { address: accountAddress } = await keyStore.addAccount(sk, partialAddress); expect(accountAddress.toString()).toMatchInlineSnapshot( - `"0x2e54c8067c410d03d417dddd51e1cad76cece48ff39fa0fe908782b93a209a52"`, + `"0x1751d51775aece66a86f69085a9003ac539fc5c3b225d49bd4e3a58247ec5700"`, ); - const { pkM: masterNullifierPublicKey } = await keyStore.getKeyValidationRequest( + const { pkMHash: returnedNpkMHash } = await keyStore.getKeyValidationRequest( computedMasterNullifierPublicKeyHash, await AztecAddress.random(), // Address is random because we are not interested in the app secret key here ); - expect(masterNullifierPublicKey.toString()).toMatchInlineSnapshot( - `"0x0d86b380f66ec74d32bb04d98f5b2dcef6d92f344e65604a21640f87fb6d078e2b68df4d20985b71c252746a3f2cc5af32b5f0c32739b94f166dfa230f50397b"`, - ); + expect(returnedNpkMHash.equals(computedMasterNullifierPublicKeyHash)).toBe(true); const masterIncomingViewingPublicKey = await keyStore.getMasterIncomingViewingPublicKey(accountAddress); - expect(masterIncomingViewingPublicKey.toString()).toMatchInlineSnapshot( - `"0x0e0eb5bc3eb9959d6e05cbc0e37b2fa4cfb113c1db651c384907547f1f8670101db2e49c6845619ba432a951d86de2d41680157b0f54556246916900c0fcdcf2"`, - ); + expect(masterIncomingViewingPublicKey.equals(keys.publicKeys.ivpkM)).toBe(true); const masterOutgoingViewingPublicKey = await keyStore.getMasterOutgoingViewingPublicKey(accountAddress); - expect(masterOutgoingViewingPublicKey.toString()).toMatchInlineSnapshot( - `"0x2721eaed30c0c9fae14c2ca4af7668a46278762d4a6066ab7a5defcc242f559c0bd0c4b0ec90ebafe511f20e818fb359a1322ab0f02fe3ebec95af5df502015d"`, - ); + expect(masterOutgoingViewingPublicKey.equals(keys.masterOutgoingViewingPublicKey)).toBe(true); const masterTaggingPublicKey = await keyStore.getMasterTaggingPublicKey(accountAddress); - expect(masterTaggingPublicKey.toString()).toMatchInlineSnapshot( - `"0x0fabb6adca7c2bf7f6202c65fe2785096efb317897bc545c427635a61d5369552cc356e6e5b68fd64d33c96fad7bb1394956c53930fefdf0bb536812ec604459"`, - ); + expect(masterTaggingPublicKey.equals(keys.masterTaggingPublicKey)).toBe(true); const masterIncomingViewingSecretKey = await keyStore.getMasterIncomingViewingSecretKey(accountAddress); - expect(masterIncomingViewingSecretKey.toString()).toMatchInlineSnapshot( - `"0x0d3e4402946f2f712d942e1a3962b12fc521effc39fe93777f91285f1ad414cb"`, - ); + expect(masterIncomingViewingSecretKey.equals(keys.masterIncomingViewingSecretKey)).toBe(true); // Arbitrary app contract address const appAddress = AztecAddress.fromBigInt(624n); - const { pkM: obtainedMasterNullifierPublicKey, skApp: appNullifierHidingKey } = - await keyStore.getKeyValidationRequest(computedMasterNullifierPublicKeyHash, appAddress); + const { pkMHash: obtainedNpkMHash, skApp: appNullifierHidingKey } = await keyStore.getKeyValidationRequest( + computedMasterNullifierPublicKeyHash, + appAddress, + ); expect(appNullifierHidingKey.toString()).toMatchInlineSnapshot( `"0x165cc265d187ed42f0e3f5adbb5a0055a77e205daeb68dd1735796ee402e502f"`, ); - expect(obtainedMasterNullifierPublicKey).toEqual(masterNullifierPublicKey); + expect(obtainedNpkMHash).toEqual(computedMasterNullifierPublicKeyHash); const appOutgoingViewingSecretKey = await keyStore.getAppOutgoingViewingSecretKey(accountAddress, appAddress); expect(appOutgoingViewingSecretKey.toString()).toMatchInlineSnapshot( @@ -68,20 +61,17 @@ describe('KeyStore', () => { // Returned accounts are as expected const accounts = await keyStore.getAccounts(); expect(accounts.toString()).toMatchInlineSnapshot( - `"0x2e54c8067c410d03d417dddd51e1cad76cece48ff39fa0fe908782b93a209a52"`, + `"0x1751d51775aece66a86f69085a9003ac539fc5c3b225d49bd4e3a58247ec5700"`, ); - // Manages to find master nullifier hiding key for pub key - const masterNullifierHidingKey = await keyStore.getMasterSecretKey(masterNullifierPublicKey); - expect(masterNullifierHidingKey.toString()).toMatchInlineSnapshot( - `"0x26dd6f83a99b5b1cea47692f40b7aece47756a1a5e93138c5b8f7e7afd36ed1a"`, - ); + // Manages to find master nullifier hiding key for the pk_m hash + const masterNullifierHidingKey = await keyStore.getMasterSecretKey(computedMasterNullifierPublicKeyHash); + expect(masterNullifierHidingKey.equals(keys.masterNullifierHidingKey)).toBe(true); - // Manages to find master incoming viewing secret key for pub key - const masterIncomingViewingSecretKeyFromPublicKey = - await keyStore.getMasterSecretKey(masterIncomingViewingPublicKey); - expect(masterIncomingViewingSecretKeyFromPublicKey.toString()).toMatchInlineSnapshot( - `"0x0d3e4402946f2f712d942e1a3962b12fc521effc39fe93777f91285f1ad414cb"`, + // Manages to find master incoming viewing secret key for the pk_m hash + const masterIncomingViewingSecretKeyFromPublicKey = await keyStore.getMasterSecretKey( + computedMasterIncomingViewingPublicKeyHash, ); + expect(masterIncomingViewingSecretKeyFromPublicKey.equals(keys.masterIncomingViewingSecretKey)).toBe(true); }); }); diff --git a/yarn-project/key-store/src/key_store.ts b/yarn-project/key-store/src/key_store.ts index 86cab0cc9752..a23f4f71befe 100644 --- a/yarn-project/key-store/src/key_store.ts +++ b/yarn-project/key-store/src/key_store.ts @@ -15,6 +15,7 @@ import { computeAppSecretKey, deriveKeys, derivePublicKeyFromSecretKey, + hashPublicKey, } from '@aztec/stdlib/keys'; /** Maps a key prefix to the storage suffix for the corresponding master secret key. */ @@ -57,17 +58,21 @@ export class KeyStore { masterIncomingViewingSecretKey, masterOutgoingViewingSecretKey, masterTaggingSecretKey, + masterNullifierPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, publicKeys, } = await deriveKeys(sk); - const completeAddress = await CompleteAddress.fromSecretKeyAndPartialAddress(sk, partialAddress); + const completeAddress = await CompleteAddress.fromPublicKeysAndPartialAddress(publicKeys, partialAddress); const { address: account } = completeAddress; - // Compute hashes before transaction - const masterNullifierPublicKeyHash = await publicKeys.masterNullifierPublicKey.hash(); - const masterIncomingViewingPublicKeyHash = await publicKeys.masterIncomingViewingPublicKey.hash(); - const masterOutgoingViewingPublicKeyHash = await publicKeys.masterOutgoingViewingPublicKey.hash(); - const masterTaggingPublicKeyHash = await publicKeys.masterTaggingPublicKey.hash(); + // The kernel cannot check that nhpk/ovpk/tpk are on-curve or non-infinity, so the PXE/key-store + // must guarantee it before persistence. By design, the above derivation produces points that are on + // the curve and not at infinity. + + // The npk/ovpk/tpk hashes are already in publicKeys; ivpk_m_hash is computed for indexing. + const masterIncomingViewingPublicKeyHash = await hashPublicKey(publicKeys.ivpkM); await this.#db.transactionAsync(async () => { // Naming of keys is as follows ${account}-${n/iv/ov/t}${sk/pk}_m @@ -76,17 +81,17 @@ export class KeyStore { await this.#keys.set(`${account.toString()}-tsk_m`, masterTaggingSecretKey.toBuffer()); await this.#keys.set(`${account.toString()}-nhk_m`, masterNullifierHidingKey.toBuffer()); - await this.#keys.set(`${account.toString()}-npk_m`, publicKeys.masterNullifierPublicKey.toBuffer()); - await this.#keys.set(`${account.toString()}-ivpk_m`, publicKeys.masterIncomingViewingPublicKey.toBuffer()); - await this.#keys.set(`${account.toString()}-ovpk_m`, publicKeys.masterOutgoingViewingPublicKey.toBuffer()); - await this.#keys.set(`${account.toString()}-tpk_m`, publicKeys.masterTaggingPublicKey.toBuffer()); + await this.#keys.set(`${account.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${account.toString()}-ivpk_m`, publicKeys.ivpkM.toBuffer()); + await this.#keys.set(`${account.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); + await this.#keys.set(`${account.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); // We store pk_m_hash under `account-{n/iv/ov/t}pk_m_hash` key to be able to obtain address and key prefix // using the #getKeyPrefixAndAccount function later on - await this.#keys.set(`${account.toString()}-npk_m_hash`, masterNullifierPublicKeyHash.toBuffer()); + await this.#keys.set(`${account.toString()}-npk_m_hash`, publicKeys.npkMHash.toBuffer()); await this.#keys.set(`${account.toString()}-ivpk_m_hash`, masterIncomingViewingPublicKeyHash.toBuffer()); - await this.#keys.set(`${account.toString()}-ovpk_m_hash`, masterOutgoingViewingPublicKeyHash.toBuffer()); - await this.#keys.set(`${account.toString()}-tpk_m_hash`, masterTaggingPublicKeyHash.toBuffer()); + await this.#keys.set(`${account.toString()}-ovpk_m_hash`, publicKeys.ovpkMHash.toBuffer()); + await this.#keys.set(`${account.toString()}-tpk_m_hash`, publicKeys.tpkMHash.toBuffer()); }); // At last, we return the newly derived account address @@ -120,7 +125,9 @@ export class KeyStore { return this.#db.transactionAsync(async () => { const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkMHash); - // Now we find the master public key for the account + // Load the stored master public key point. The returned KVR carries only the hash, but we + // use the point here as a witness for two integrity checks below: (1) it matches the supplied + // hash, and (2) it matches the value derived from the stored secret key. const pkMBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}pk_m`); if (!pkMBuffer) { throw new Error( @@ -142,7 +149,7 @@ export class KeyStore { const skM = GrumpkinScalar.fromBuffer(skMBuffer); // The remaining awaits are non-DB computations. They are safe because no further IDB operations follow them. - const computedPkMHash = await pkM.hash(); + const computedPkMHash = await hashPublicKey(pkM); if (!computedPkMHash.equals(pkMHash)) { throw new Error(`Could not find ${keyPrefix}pkM for ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`); } @@ -154,7 +161,7 @@ export class KeyStore { const skApp = await computeAppSecretKey(skM, contractAddress, keyPrefix!); - return new KeyValidationRequest(pkM, skApp); + return new KeyValidationRequest(pkMHash, skApp); }); } @@ -261,31 +268,36 @@ export class KeyStore { } /** - * Retrieves the sk_m corresponding to the pk_m. - * @throws If the provided public key is not associated with any of the registered accounts. - * @param pkM - The master public key to get secret key for. + * Retrieves the sk_m corresponding to the given pk_m hash. + * @throws If the provided hash is not associated with any of the registered accounts. + * @param pkMHash - The master public key hash to get secret key for. * @returns A Promise that resolves to sk_m. * @dev Used when feeding the sk_m to the kernel circuit for keys verification. */ - public getMasterSecretKey(pkM: PublicKey): Promise { + public getMasterSecretKey(pkMHash: Fr): Promise { return this.#db.transactionAsync(async () => { - const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkM); + const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkMHash); const skStorageSuffix = secretKeyStorageSuffix(keyPrefix); const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`); if (!secretKeyBuffer) { throw new Error( - `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`, + `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m_hash ${pkMHash.toString()}. This should not happen.`, ); } const skM = GrumpkinScalar.fromBuffer(secretKeyBuffer); // Non-DB computation — safe because no further IDB operations follow. - const derivedpkM = await derivePublicKeyFromSecretKey(skM); - if (!derivedpkM.equals(pkM)) { + // Integrity check: confirm the stored secret key still derives the requested hash. The check + // is hash-based rather than point-equal because the on-disk identifier is `pk_m_hash`; + // cryptographic collision resistance of `hashPublicKey` makes this equivalent to a + // direct point comparison in practice. + const derivedPkM = await derivePublicKeyFromSecretKey(skM); + const derivedPkMHash = await hashPublicKey(derivedPkM); + if (!derivedPkMHash.equals(pkMHash)) { throw new Error( - `Could not find ${skStorageSuffix} for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`, + `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m_hash ${pkMHash.toString()} in secret keys buffer.`, ); } diff --git a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap index ac3e1e5042d6..b6dec7a8b6c9 100644 --- a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap +++ b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap @@ -2,46 +2,46 @@ exports[`Data generation for noir tests Computes contract info for defaultContract 1`] = ` { - "address": "AztecAddress { inner: 0x136422d2d758eb9181240eee44720fa9bc433d3a16bc13163699dc4f47540b0d }", + "address": "AztecAddress { inner: 0x1599beafce80b22c56446667e1627d865bb87ea94b8f1bdc757979f78a596042 }", "artifact_hash": "0x0000000000000000000000000000000000000000000000000000000000003039", "contract_address_salt": "0x000000000000000000000000000000000000000000000000000000000000ddd5", "contract_class_id": "ContractClassId { inner: 0x2888d24c26f34b139f0f1d30278df8f9007d06da3b63cfe6eeb9a710d51f4f4a }", "deployer": "AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }", - "partial_address": "PartialAddress { inner: 0x1676695fc9a4f3bc8816e4dc82a8856b2ae565d4872691a6e944cc3ce8897e72 }", + "partial_address": "PartialAddress { inner: 0x13bf689e2b04d5a75694270c1872e74b0c998c3f7f2f3a0a95648f9f41600808 }", "private_functions_root": "0x2653ec1bf2be3a13fa9b645cec2557f2b543286fc39168ec42b705835a301bb6", "public_bytecode_commitment": "0x256abef672381d551191d5bbecf2dec6ac9cc2a81189f886ac22e29e5c58c49c", - "public_keys": "PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f }", - "salted_initialization_hash": "SaltedInitializationHash { inner: 0x1d83f43991ef3c393247a1796b194020c559aaf129e515adc6eace265f726452 }", + "public_keys": "PublicKeys { inner: 0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a2600c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1510e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0 }", + "salted_initialization_hash": "SaltedInitializationHash { inner: 0x20b8accdca7010cfebfcc932f55e3acf5136dfe57ba51d386dac8e9d110d9567 }", } `; exports[`Data generation for noir tests Computes contract info for parentContract 1`] = ` { - "address": "AztecAddress { inner: 0x2e90a78904fdb353ddf6eda97aedcfc2b8bf5a942f10f57a1e85373b740e7eca }", + "address": "AztecAddress { inner: 0x1ea25c8d3d0223005170fc2cc0a0e8e3593e322bfcdebc817cc2a02cc95fca9c }", "artifact_hash": "0x00000000000000000000000000000000000000000000000000000000000004bc", "contract_address_salt": "0x0000000000000000000000000000000000000000000000000000000000001618", "contract_class_id": "ContractClassId { inner: 0x2998b9cf4a582f068a01b43c141dbcc5fd8f5cd17a797484b5a5db2386cf7574 }", "deployer": "AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }", - "partial_address": "PartialAddress { inner: 0x2cfac19f0c29a86d17b4c60b205376bbd4c8e45d1dfd02dcd33820638d1d6d1e }", + "partial_address": "PartialAddress { inner: 0x09dba9fffbfd68d6828334a178433b7bfae9d07c3c6f424ee4afa0304655c5d3 }", "private_functions_root": "0x03cca4d59a01776df283eb2c8915cb144ad3f40a0b0ba06e9c24c532c59e3c43", "public_bytecode_commitment": "0x1cfb8e870870be1d102249b47923b63c2d54f33ca81e3028d74a06d8dd5944ca", - "public_keys": "PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f }", - "salted_initialization_hash": "SaltedInitializationHash { inner: 0x2bfefc4cfdd56352f0d6cf62ae70abe702d7d948f5ccff4eeb51f9aefaece295 }", + "public_keys": "PublicKeys { inner: 0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a2600c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1510e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0 }", + "salted_initialization_hash": "SaltedInitializationHash { inner: 0x1384ae0b0212cbeb6cd53d6c8d9dfc6334318553dd6f33fdaa97b5dae4ab9dbb }", } `; exports[`Data generation for noir tests Computes contract info for updatedContract 1`] = ` { - "address": "AztecAddress { inner: 0x1a56e3cef400d47addbbf65a95ea505b8f628a2d65a096d0e4d46a8cc9bd72c3 }", + "address": "AztecAddress { inner: 0x144f3aaae816b99f40fbea5b9f80fe4683bf68a14876e7379c4171c871a1ef09 }", "artifact_hash": "0x0000000000000000000000000000000000000000000000000000000000054501", "contract_address_salt": "0x0000000000000000000000000000000000000000000000000000000000000315", "contract_class_id": "ContractClassId { inner: 0x07a63b1343bb8515d1115202c71cdc95f9bcda9c2237bdfc25435b89ffa06b46 }", "deployer": "AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }", - "partial_address": "PartialAddress { inner: 0x04a4ed87aa4cff86962b974fe3f79d76e4bf3f034d4e2bde2bb50765927fad40 }", + "partial_address": "PartialAddress { inner: 0x12b89345d5d63f8bf9f73f5890d5caa0c5f023c61d313b1abeea40e300a83755 }", "private_functions_root": "0x2b26caef823c6be4c41ef1980dace9b61825f8e6a16792c765a2cd8cb2121e75", "public_bytecode_commitment": "0x225d884cfeaddc5292dadbf921e7699632336876c65a33459d3b2ad9b5ec0da3", - "public_keys": "PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f }", - "salted_initialization_hash": "SaltedInitializationHash { inner: 0x0bbf968b28a0a1fa3a90ceb4c7104d63e7a8dc845a9c885781d74018d1579e59 }", + "public_keys": "PublicKeys { inner: 0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a2600c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1510e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0 }", + "salted_initialization_hash": "SaltedInitializationHash { inner: 0x1f121db378dbceaf871eed1b9f0b20efcdca988e76f8abeaa11b2cdc80474189 }", } `; diff --git a/yarn-project/noir-protocol-circuits-types/src/conversion/client.ts b/yarn-project/noir-protocol-circuits-types/src/conversion/client.ts index 4e403b9f496d..fad43cd8d913 100644 --- a/yarn-project/noir-protocol-circuits-types/src/conversion/client.ts +++ b/yarn-project/noir-protocol-circuits-types/src/conversion/client.ts @@ -92,7 +92,6 @@ import { mapNullifierLeafPreimageToNoir, mapNumberFromNoir, mapNumberToNoir, - mapPointFromNoir, mapPointToNoir, mapPrivateLogFromNoir, mapPrivateLogToNoir, @@ -260,7 +259,7 @@ function mapScopedReadRequestFromNoir(scoped: Scoped>): Scope */ export function mapKeyValidationRequestToNoir(request: KeyValidationRequest): KeyValidationRequestsNoir { return { - pk_m: mapPointToNoir(request.pkM), + pk_m_hash: mapFieldToNoir(request.pkMHash), sk_app: mapFieldToNoir(request.skApp), }; } @@ -280,7 +279,7 @@ export function mapKeyValidationRequestAndSeparatorToNoir( * @returns The TS KeyValidationRequest. */ function mapKeyValidationRequestFromNoir(request: KeyValidationRequestsNoir): KeyValidationRequest { - return new KeyValidationRequest(mapPointFromNoir(request.pk_m), mapFieldFromNoir(request.sk_app)); + return new KeyValidationRequest(mapFieldFromNoir(request.pk_m_hash), mapFieldFromNoir(request.sk_app)); } function mapKeyValidationRequestAndSeparatorFromNoir( @@ -479,18 +478,12 @@ export function mapPrivateCircuitPublicInputsToNoir( export function mapPublicKeysToNoir(publicKeys: PublicKeys): PublicKeysNoir { return { - npk_m: { - inner: mapPointToNoir(publicKeys.masterNullifierPublicKey), - }, + npk_m_hash: mapFieldToNoir(publicKeys.npkMHash), ivpk_m: { - inner: mapPointToNoir(publicKeys.masterIncomingViewingPublicKey), - }, - ovpk_m: { - inner: mapPointToNoir(publicKeys.masterOutgoingViewingPublicKey), - }, - tpk_m: { - inner: mapPointToNoir(publicKeys.masterTaggingPublicKey), + inner: mapPointToNoir(publicKeys.ivpkM), }, + ovpk_m_hash: mapFieldToNoir(publicKeys.ovpkMHash), + tpk_m_hash: mapFieldToNoir(publicKeys.tpkMHash), }; } diff --git a/yarn-project/noir-protocol-circuits-types/src/conversion/common.ts b/yarn-project/noir-protocol-circuits-types/src/conversion/common.ts index a9a99d52f050..5868f473ca49 100644 --- a/yarn-project/noir-protocol-circuits-types/src/conversion/common.ts +++ b/yarn-project/noir-protocol-circuits-types/src/conversion/common.ts @@ -74,7 +74,7 @@ import type { AztecAddress as NoirAztecAddress, EthAddress as NoirEthAddress, Field as NoirField, - Point as NoirPoint, + EmbeddedCurvePoint as NoirPoint, NullifierLeafPreimage as NullifierLeafPreimageNoir, PartialStateReference as PartialStateReferenceNoir, Log as PrivateLogNoir, @@ -175,7 +175,6 @@ export function mapPointToNoir(point: Point): NoirPoint { return { x: mapFieldToNoir(point.x), y: mapFieldToNoir(point.y), - is_infinite: point.isInfinite, }; } @@ -185,7 +184,7 @@ export function mapPointToNoir(point: Point): NoirPoint { * @returns The point. */ export function mapPointFromNoir(point: NoirPoint): Point { - return new Point(mapFieldFromNoir(point.x), mapFieldFromNoir(point.y), point.is_infinite); + return new Point(mapFieldFromNoir(point.x), mapFieldFromNoir(point.y)); } /** diff --git a/yarn-project/noir-protocol-circuits-types/src/conversion/type_conversion.test.ts b/yarn-project/noir-protocol-circuits-types/src/conversion/type_conversion.test.ts index c6c569c61f83..f207bc9e3f1a 100644 --- a/yarn-project/noir-protocol-circuits-types/src/conversion/type_conversion.test.ts +++ b/yarn-project/noir-protocol-circuits-types/src/conversion/type_conversion.test.ts @@ -29,7 +29,7 @@ describe('Noir<>stdlib type conversion test suite', () => { expect(mapFieldFromNoir(mapFieldToNoir(field))).toEqual(field); }); - const point = new Point(new Fr(27n), new Fr(28n), false); + const point = new Point(new Fr(27n), new Fr(28n)); it('should map points', () => { expect(mapPointFromNoir(mapPointToNoir(point))).toEqual(point); diff --git a/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts b/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts index b5b9b31845f8..ee13d4afb7d3 100644 --- a/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts +++ b/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts @@ -20,7 +20,7 @@ describe('Data generation for noir tests', () => { setupCustomSnapshotSerializers(expect); type FixtureContractData = Omit & - Pick & + Pick & Pick & { toString: () => string }; const defaultContract: FixtureContractData = { @@ -28,6 +28,7 @@ describe('Data generation for noir tests', () => { packedBytecode: Buffer.from([3, 4, 5, 6, 7]), publicKeys: PublicKeys.default(), salt: new Fr(56789), + immutablesHash: new Fr(7890), privateFunctions: [ { selector: FunctionSelector.fromField(new Fr(1010101)), vkHash: new Fr(123123) }, { selector: FunctionSelector.fromField(new Fr(2020202)), vkHash: new Fr(456456) }, @@ -40,6 +41,7 @@ describe('Data generation for noir tests', () => { packedBytecode: Buffer.from([3, 4, 3, 4]), publicKeys: PublicKeys.default(), salt: new Fr(5656), + immutablesHash: new Fr(7890), privateFunctions: [{ selector: FunctionSelector.fromField(new Fr(334455)), vkHash: new Fr(789789) }], toString: () => 'parentContract', }; @@ -49,6 +51,7 @@ describe('Data generation for noir tests', () => { packedBytecode: Buffer.from([5, 6, 7, 8, 9, 0]), publicKeys: PublicKeys.default(), salt: new Fr(789), + immutablesHash: new Fr(7890), privateFunctions: [ { selector: FunctionSelector.fromField(new Fr(1010101)), vkHash: new Fr(7788) }, { selector: FunctionSelector.fromField(new Fr(2020202)), vkHash: new Fr(9900) }, @@ -78,7 +81,7 @@ describe('Data generation for noir tests', () => { const deployer = AztecAddress.ZERO; const instance: ContractInstance = { ...contract, - version: 1, + version: 2, initializationHash, currentContractClassId: contractClassId, originalContractClassId: contractClassId, diff --git a/yarn-project/p2p/src/client/interface.ts b/yarn-project/p2p/src/client/interface.ts index b7bf5fb19d0c..636385ce92f2 100644 --- a/yarn-project/p2p/src/client/interface.ts +++ b/yarn-project/p2p/src/client/interface.ts @@ -9,11 +9,7 @@ import type { ENR } from '@nethermindeth/enr'; import type { P2PConfig } from '../config.js'; import type { AuthRequest, StatusMessage } from '../services/index.js'; -import type { - ReqRespSubProtocol, - ReqRespSubProtocolHandler, - ReqRespSubProtocolValidators, -} from '../services/reqresp/interface.js'; +import type { ReqRespSubProtocol, ReqRespSubProtocolHandler } from '../services/reqresp/interface.js'; import type { DuplicateAttestationInfo, DuplicateProposalInfo, @@ -228,11 +224,7 @@ export type P2P = P2PClient & { /** Clears the db. */ clear(): Promise; - addReqRespSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise; + addReqRespSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise; handleAuthRequestFromPeer(authRequest: AuthRequest, peerId: PeerId): Promise; diff --git a/yarn-project/p2p/src/client/p2p_client.test.ts b/yarn-project/p2p/src/client/p2p_client.test.ts index 86df6d146a25..01c03e0d206d 100644 --- a/yarn-project/p2p/src/client/p2p_client.test.ts +++ b/yarn-project/p2p/src/client/p2p_client.test.ts @@ -41,7 +41,6 @@ describe('P2P Client', () => { txPool.addPendingTxs.mockResolvedValue({ accepted: [], ignored: [], rejected: [] }); p2pService = mock(); - p2pService.sendBatchRequest.mockResolvedValue([]); l1Constants = EmptyL1RollupConstants; txCollection = mock(); @@ -50,6 +49,7 @@ describe('P2P Client', () => { epochCache = mock(); epochCache.getCurrentAndNextSlot.mockReturnValue({ currentSlot: SlotNumber(0), nextSlot: SlotNumber(1) }); epochCache.getTargetAndNextSlot.mockReturnValue({ targetSlot: SlotNumber(0), nextSlot: SlotNumber(1) }); + epochCache.getL1Constants.mockReturnValue(l1Constants); attestationPool = await createTestAttestationPool(); diff --git a/yarn-project/p2p/src/client/p2p_client.ts b/yarn-project/p2p/src/client/p2p_client.ts index a91755a81b00..8a4ba30a701f 100644 --- a/yarn-project/p2p/src/client/p2p_client.ts +++ b/yarn-project/p2p/src/client/p2p_client.ts @@ -24,6 +24,7 @@ import { type L2TipsStore, } from '@aztec/stdlib/block'; import type { ContractDataSource } from '@aztec/stdlib/contract'; +import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { type PeerInfo, tryStop } from '@aztec/stdlib/interfaces/server'; import { type BlockProposal, CheckpointAttestation, type CheckpointProposal, type TopicType } from '@aztec/stdlib/p2p'; import type { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx'; @@ -34,15 +35,11 @@ import type { ENR } from '@nethermindeth/enr'; import { type P2PConfig, getP2PDefaultConfig } from '../config.js'; import { TxPoolError } from '../errors/tx-pool.error.js'; -import type { AttestationPoolApi } from '../mem_pools/attestation_pool/attestation_pool.js'; +import type { AttestationPoolApi, ProposalsForSlot } from '../mem_pools/attestation_pool/attestation_pool.js'; import type { MemPools } from '../mem_pools/interface.js'; import type { TxPoolV2 } from '../mem_pools/tx_pool_v2/interfaces.js'; import type { AuthRequest, StatusMessage } from '../services/index.js'; -import { - ReqRespSubProtocol, - type ReqRespSubProtocolHandler, - type ReqRespSubProtocolValidators, -} from '../services/reqresp/interface.js'; +import { ReqRespSubProtocol, type ReqRespSubProtocolHandler } from '../services/reqresp/interface.js'; import type { DuplicateAttestationInfo, DuplicateProposalInfo, @@ -269,7 +266,6 @@ export class P2PClient extends WithTracer implements P2P { throw new Error('Block stream not initialized'); } this.blockStream.start(); - await this.txCollection.start(); this.txFileStore?.start(); // Start slot monitor to call prepareForSlot when the slot changes @@ -283,12 +279,8 @@ export class P2PClient extends WithTracer implements P2P { return this.syncPromise; } - addReqRespSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { - return this.p2pService.addReqRespSubProtocol(subProtocol, handler, validator); + addReqRespSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise { + return this.p2pService.addReqRespSubProtocol(subProtocol, handler); } private initBlockStream(startingBlock?: BlockNumber) { @@ -372,8 +364,21 @@ export class P2PClient extends WithTracer implements P2P { // Store our own last-block proposal so we can respond to req/resp requests for it. await this.attestationPool.tryAddBlockProposal(blockProposal); } + const checkpointCore = proposal.toCore(); + const { count } = await this.attestationPool.tryAddCheckpointProposal(checkpointCore); + if (count > 1) { + if (this.config.broadcastEquivocatedProposals) { + this.log.warn(`Broadcasting equivocated checkpoint proposal for slot ${proposal.slotNumber}`, { + slot: proposal.slotNumber, + archive: proposal.archive.toString(), + count, + }); + } else { + throw new Error(`Attempted to broadcast a duplicate checkpoint proposal for slot ${proposal.slotNumber}`); + } + } // Gossipsub doesn't deliver own messages, so fire the all-nodes handler locally - await this.p2pService.notifyOwnCheckpointProposal(proposal.toCore()); + await this.p2pService.notifyOwnCheckpointProposal(checkpointCore); return this.p2pService.propagate(proposal); } @@ -395,6 +400,10 @@ export class P2PClient extends WithTracer implements P2P { return this.attestationPool.addOwnCheckpointAttestations(attestations); } + public getProposalsForSlot(slot: SlotNumber): Promise { + return this.attestationPool.getProposalsForSlot(slot); + } + public hasBlockProposalsForSlot(slot: SlotNumber): Promise { return this.attestationPool.hasBlockProposalsForSlot(slot); } @@ -655,7 +664,16 @@ export class P2PClient extends WithTracer implements P2P { `Starting collection of ${missingTxHashes.length} missing txs for unproven mined block ${block.number}`, { missingTxHashes, blockNumber: block.number, blockHash: await block.hash().then(h => h.toString()) }, ); - const deadline = new Date(this._dateProvider.now() + this.config.p2pMissingTxCollectionDeadlineMs); + // Both `slashDataWithholdingToleranceSlots` and `p2pMissingTxCollectionDeadlineSlots` + // count *full slots after the block slot* — value N means collection runs until + // `slotStart(block.slot + N + 1)`. Take the larger of the two so collection never + // gives up before the data-withholding slash verdict is rendered. + const blockSlot = block.header.getSlot(); + const toleranceSlots = this.config.slashDataWithholdingToleranceSlots; + const configuredSlots = this.config.p2pMissingTxCollectionDeadlineSlots ?? 0; + const deadlineSlot = SlotNumber(blockSlot + Math.max(toleranceSlots, configuredSlots) + 1); + const deadlineSeconds = getTimestampForSlot(deadlineSlot, this.epochCache.getL1Constants()); + const deadline = new Date(Number(deadlineSeconds) * 1000); await this.txCollection.collectFastForBlock(block, missingTxHashes, { deadline }); } } diff --git a/yarn-project/p2p/src/client/test/tx_proposal_collector/README.md b/yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.README.md similarity index 71% rename from yarn-project/p2p/src/client/test/tx_proposal_collector/README.md rename to yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.README.md index 3a489503faab..50867738fbb6 100644 --- a/yarn-project/p2p/src/client/test/tx_proposal_collector/README.md +++ b/yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.README.md @@ -1,6 +1,6 @@ -# ProposalTxCollector Benchmarks +# BatchTxRequester Benchmarks -This benchmark suite measures **how quickly a proposer node can fetch missing transactions from P2P peers** when building a block proposal. It compares two alternative transaction-collection implementations under several controlled "who-has-which-txs" distributions. +This benchmark suite measures **how quickly a proposer node can fetch missing transactions from P2P peers** when building a block proposal under several controlled "who-has-which-txs" distributions. ## Purpose @@ -10,12 +10,6 @@ This benchmark answers: - How long does it take to fetch **N missing txs** (N ∈ **{10, 50, 100, 500}**)? - How do different **peer availability patterns** affect performance? -- Which collector strategy performs better under each pattern? - -The suite compares two collectors: - -- **`BatchTxRequesterCollector`** (collector type: `batch-requester`) -- **`SendBatchRequestCollector`** (collector type: `send-batch-request`) ## Architecture @@ -24,7 +18,7 @@ The benchmark runs a small simulated network on localhost: ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Test Process (Driver) │ -│ p2p_client.proposal_tx_collector.bench.test.ts │ +│ p2p_client.batch_tx_requester.bench.test.ts │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ WorkerClientManager │ │ │ │ (src/testbench/worker_client_manager.ts) │ │ @@ -34,7 +28,7 @@ The benchmark runs a small simulated network on localhost: │ ▼ ▼ ▼ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ Worker 0 │◄──────►│ Worker 1 │◄──────►│ Worker N-1│ │ -│ │ (Collector│ P2P │(Responder)│ P2P │(Responder)│ │ +│ │(Aggregator│ P2P │(Responder)│ P2P │(Responder)│ │ │ │ Node) │ │ │ │ │ │ │ │ TxPool:[] │ │ TxPool: │ │ TxPool: │ │ │ │ │ │ [txs...] │ │ [txs...] │ │ @@ -54,12 +48,12 @@ Using separate OS processes makes the setup closer to real networking behavior ( The network is intentionally asymmetric: -- **Worker 0 is the collector/proposer node** +- **Worker 0 is the aggregator/proposer node** - Starts with an **empty tx pool** (`[]`) - - Is the only worker instructed to run the collector for each `BENCH_REQRESP` command + - Is the only worker instructed to run `BatchTxRequester` for each `BENCH_REQRESP` command - **Workers 1..N-1 are responder peers** - Locally generate and filter txs according to the distribution pattern - - Respond to req/resp queries made by Worker 0's collector + - Respond to req/resp queries made by Worker 0's `BatchTxRequester` This models a proposer that has only `txHashes` in a proposal and must fetch the full tx bodies from the network. @@ -72,7 +66,7 @@ Each benchmark case generates `missingTxCount` mock txs and assigns them to peer **Every responder peer has every transaction.** - Simulates the best-case: high replication / high gossip success -- Expectation: collector should quickly succeed; differences mostly reflect collector overhead and batching strategy +- Expectation: the requester should quickly succeed; differences mostly reflect requester overhead and batching strategy ### `sparse` @@ -81,7 +75,7 @@ Each benchmark case generates `missingTxCount` mock txs and assigns them to peer Each responder is bucketed and holds txs whose index falls into its bucket or the "next" bucket (striped by tx index). - Simulates partial propagation, churn, or uneven mempool convergence -- Expectation: collector must query multiple peers and cope with "misses" +- Expectation: the requester must query multiple peers and cope with "misses" ### `pinned-only` @@ -92,33 +86,13 @@ Each responder is bucketed and holds txs whose index falls into its bucket or th > **Guardrail:** the pinned peer index must be within `(0, numberOfPeers)` (Worker 0 cannot be pinned). -## Collectors Under Test - -### `BatchTxRequesterCollector` (`batch-requester`) - -```typescript -new BatchTxRequesterCollector(p2pService, logger, new DateProvider()) -``` - -Uses the P2P service plus internal logic to fetch missing txs, coordinating requests in a batched or staged way. - -### `SendBatchRequestCollector` (`send-batch-request`) - -```typescript -const maxPeers = 10; -const maxRetryAttempts = Math.max(peerIds.length, 3); -new SendBatchRequestCollector(p2pService, maxPeers, maxRetryAttempts) -``` - -Explicitly caps the number of peers it will involve (`maxPeers`) and uses a retry budget derived from peer count. - ## Test Parameters | Parameter | Value | Description | |-----------|-------|-------------| | `PEERS_PER_RUN` | 30 | Number of worker processes spawned | | `MISSING_TX_COUNTS` | 10, 50, 100, 500 | Number of missing transactions to fetch | -| `TIMEOUT_MS` | 30,000 ms | Collector timeout per case | +| `TIMEOUT_MS` | 30,000 ms | Per-case timeout for the requester | | `TEST_TIMEOUT_MS` | 600,000 ms | Overall Jest timeout (10 minutes) | ## Running @@ -127,13 +101,13 @@ From the p2p package: ```bash cd yarn-project/p2p -yarn test src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts +yarn test src/client/test/p2p_client.batch_tx_requester.bench.test.ts ``` Or from repo root: ```bash -yarn test p2p_client.proposal_tx_collector.bench.test.ts +yarn test p2p_client.batch_tx_requester.bench.test.ts ``` The benchmark is intentionally long due to spawning many processes and running multiple cases. @@ -145,14 +119,12 @@ The benchmark is intentionally long due to spawning many processes and running m If no env vars are set, the suite prints a table: ``` -| Collector | Distribution | Missing | Duration (ms) | Fetched | Success | -|---------------------|--------------|---------|---------------|---------|---------| -| batch-requester | pinned-only | 10 | 123 | 10 | Yes | -| send-batch-request | pinned-only | 10 | 145 | 10 | Yes | +| Distribution | Missing | Duration (ms) | Fetched | Success | +|--------------|---------|---------------|---------|---------| +| pinned-only | 10 | 123 | 10 | Yes | +| pinned-only | 50 | 145 | 50 | Yes | ``` -Plus a comparison summary stating which collector was faster per `(distribution, missing)` pair. - ### JSON metrics (for CI/dashboards) ```bash @@ -160,8 +132,8 @@ BENCH_OUTPUT=/path/results.json yarn test ... ``` Writes JSON metrics like: -- `ProposalTxCollector///missing_/duration` (ms) -- `ProposalTxCollector///missing_/fetched` (txs) +- `BatchTxRequester//missing_/duration` (ms) +- `BatchTxRequester//missing_/fetched` (txs) ### Markdown file output @@ -175,14 +147,14 @@ Writes the pretty table + summary to disk. For each case the benchmark records: -- `durationMs`: wall-clock time spent inside the collector call -- `fetchedCount`: how many txs were returned by the collector +- `durationMs`: wall-clock time spent inside the requester call +- `fetchedCount`: how many txs were returned by the requester - `success`: `fetchedCount === missingTxCount` **Guidelines:** - **Always check `Success` first.** A faster run that fetched fewer txs is not a win. -- Compare collectors **within the same distribution + missing count** only. +- Compare runs **within the same distribution + missing count** only. - Expect `pinned-only` to highlight pinned-peer behavior (fast if pinned peer is used effectively; slow if the algorithm wastes time sampling other peers). - Expect `sparse` to be the most "network-like" stress case, since many peers won't have each requested tx. @@ -193,7 +165,7 @@ Inside each worker, the benchmark intentionally reduces variability: - **Unlimited rate limits** are installed so the req/resp rate limiter doesn't dominate results - **Deterministic tx generation** ensures all workers see the same tx set without large IPC payloads -This makes the benchmark better for *comparing collectors* (A vs B), but it is **not** a perfect model of production networking conditions. +This makes the benchmark better for tracking regressions, but it is **not** a perfect model of production networking conditions. ## Limitations @@ -207,9 +179,7 @@ This benchmark does **not** measure: | File | Purpose | |------|---------| -| `p2p_client.proposal_tx_collector.bench.test.ts` | Test suite (cases, distributions, output formatting) | -| `proposal_tx_collector_worker.ts` | Collector-specific worker implementation | -| `proposal_tx_collector_worker_protocol.ts` | IPC message types and serialization | +| `p2p_client.batch_tx_requester.bench.test.ts` | Test suite (cases, distributions, output formatting) | | `src/testbench/worker_client_manager.ts` | Worker process manager (forking, IPC, orchestration) | | `src/testbench/p2p_client_testbench_worker.ts` | General testbench worker implementation | | `src/test-helpers/testbench-utils.ts` | Shared mocks and utilities (InMemoryTxPool, InMemoryAttestationPool, etc.) | diff --git a/yarn-project/p2p/src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts b/yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.test.ts similarity index 96% rename from yarn-project/p2p/src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts rename to yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.test.ts index 148783fbd1ed..d14db02583a7 100644 --- a/yarn-project/p2p/src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts +++ b/yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.test.ts @@ -9,7 +9,7 @@ import { type DistributionPattern, WorkerClientManager, testChainConfig, -} from '../../../testbench/worker_client_manager.js'; +} from '../../testbench/worker_client_manager.js'; const TEST_TIMEOUT_MS = 600_000; // 10 minutes jest.setTimeout(TEST_TIMEOUT_MS); @@ -75,7 +75,7 @@ const CASES: readonly BenchmarkCase[] = BASE_SCENARIOS.flatMap(base => })), ); -describe('ProposalTxCollector Benchmarks', () => { +describe('BatchTxRequester Benchmarks', () => { const results: BenchmarkResult[] = []; let logger: Logger; @@ -181,7 +181,7 @@ function toPrettyString(benchResults: BenchmarkResult[]): string { lines.push(''); lines.push('='.repeat(80)); - lines.push('ProposalTxCollector Benchmark Results'); + lines.push('BatchTxRequester Benchmark Results'); lines.push('='.repeat(80)); lines.push(''); lines.push('| Distribution | Missing | Duration (ms) | Fetched | Success |'); @@ -212,7 +212,7 @@ function toBenchmarkJSON(benchResults: BenchmarkResult[], indent = 2): string { const metrics: JsonBenchmarkResult[] = []; for (const result of benchResults) { - const baseName = `ProposalTxCollector/${result.distribution}/missing_${result.missingTxCount}`; + const baseName = `BatchTxRequester/${result.distribution}/missing_${result.missingTxCount}`; metrics.push( { name: `${baseName}/duration`, diff --git a/yarn-project/p2p/src/client/test/p2p_client.integration_batch_txs.test.ts b/yarn-project/p2p/src/client/test/p2p_client.integration_batch_txs.test.ts index 1858f94786ac..03cc0405c9ba 100644 --- a/yarn-project/p2p/src/client/test/p2p_client.integration_batch_txs.test.ts +++ b/yarn-project/p2p/src/client/test/p2p_client.integration_batch_txs.test.ts @@ -9,7 +9,7 @@ import { sleep } from '@aztec/foundation/sleep'; import { emptyChainConfig } from '@aztec/stdlib/config'; import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import { makeBlockHeader, makeBlockProposal, mockTx } from '@aztec/stdlib/testing'; -import { Tx, TxHash } from '@aztec/stdlib/tx'; +import { Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx'; import { describe, expect, it, jest } from '@jest/globals'; import { type MockProxy, mock } from 'jest-mock-extended'; @@ -20,7 +20,6 @@ import type { AttestationPool } from '../../mem_pools/attestation_pool/attestati import type { TxPoolV2 } from '../../mem_pools/tx_pool_v2/interfaces.js'; import { BatchTxRequester } from '../../services/reqresp/batch-tx-requester/batch_tx_requester.js'; import type { BatchTxRequesterLibP2PService } from '../../services/reqresp/batch-tx-requester/interface.js'; -import type { IBatchRequestTxValidator } from '../../services/reqresp/batch-tx-requester/tx_validator.js'; import type { ConnectionSampler } from '../../services/reqresp/connection-sampler/connection_sampler.js'; import { RequestTracker } from '../../services/tx_collection/request_tracker.js'; import { generatePeerIdPrivateKeys } from '../../test-helpers/generate-peer-id-private-keys.js'; @@ -39,7 +38,7 @@ describe('p2p client integration batch txs', () => { let mockP2PService: MockProxy; let connectionSampler: MockProxy; - let txValidator: IBatchRequestTxValidator; + let txValidator: TxValidator; let logger: Logger; let p2pBaseConfig: P2PConfig; @@ -53,10 +52,12 @@ describe('p2p client integration batch txs', () => { epochCache = mock(); worldState = mock(); connectionSampler = mock(); - mockP2PService = mock({ connectionSampler }); + mockP2PService = mock({ + connectionSampler, + validateRequestedBlockTxsConsistency: () => Promise.resolve(true), + }); txValidator = { - validateRequestedTx: () => Promise.resolve({ result: 'valid' }), - validateRequestedTxs: txs => Promise.resolve(txs.map(() => ({ result: 'valid' }))), + validateTx: () => Promise.resolve({ result: 'valid' }), }; logger = createLogger('p2p:test:integration:batch'); diff --git a/yarn-project/p2p/src/client/test/p2p_client.integration_reqresp.test.ts b/yarn-project/p2p/src/client/test/p2p_client.integration_reqresp.test.ts index c6454f17a1d2..ac3cc50c88e5 100644 --- a/yarn-project/p2p/src/client/test/p2p_client.integration_reqresp.test.ts +++ b/yarn-project/p2p/src/client/test/p2p_client.integration_reqresp.test.ts @@ -113,44 +113,6 @@ describe('p2p client integration reqresp', () => { return (p2pService as any).node.peerId; }; - it('can request txs from peers via mock reqresp', async () => { - const numberOfNodes = 2; - const mockGossipSubNetwork = new MockGossipSubNetwork(); - - const testConfig = { - p2pBaseConfig: { ...p2pBaseConfig, rollupVersion: 1 }, - mockAttestationPool: attestationPool, - mockTxPool: txPool, - mockEpochCache: epochCache, - mockWorldState: worldState, - alwaysTrueVerifier: true, - mockGossipSubNetwork, - logger, - }; - - const clientsAndConfig = await makeAndStartTestP2PClients(numberOfNodes, testConfig); - clients = clientsAndConfig.map(c => c.client); - - await sleep(1000); - - // Create a mock tx and configure the shared pool to return it - const tx = await createMockTxWithMetadata(testConfig.p2pBaseConfig); - const txHash = tx.getTxHash(); - - txPool.getTxByHash.mockImplementation((hash: TxHash) => Promise.resolve(hash.equals(txHash) ? tx : undefined)); - - // Request the tx from node-2, which will route to node-1 via the mock network - const reqresp = getReqResp(clients[1]); - const responses = await reqresp.sendBatchRequest(ReqRespSubProtocol.TX, [new TxHashArray(txHash)], undefined); - - expect(responses).toHaveLength(1); - const txArray = responses[0] as TxArray; - expect(txArray).toHaveLength(1); - - const receivedTxHash = txArray[0].getTxHash(); - expect(receivedTxHash.toString()).toEqual(txHash.toString()); - }); - it('sendRequestToPeer routes to the correct peer handler', async () => { const numberOfNodes = 2; const mockGossipSubNetwork = new MockGossipSubNetwork(); @@ -197,36 +159,4 @@ describe('p2p client integration reqresp', () => { expect(receivedTxHash.toString()).toEqual(txHash.toString()); } }); - - it('reqresp returns empty when peer has no matching txs', async () => { - const numberOfNodes = 2; - const mockGossipSubNetwork = new MockGossipSubNetwork(); - - const testConfig = { - p2pBaseConfig: { ...p2pBaseConfig, rollupVersion: 1 }, - mockAttestationPool: attestationPool, - mockTxPool: txPool, - mockEpochCache: epochCache, - mockWorldState: worldState, - alwaysTrueVerifier: true, - mockGossipSubNetwork, - logger, - }; - - const clientsAndConfig = await makeAndStartTestP2PClients(numberOfNodes, testConfig); - clients = clientsAndConfig.map(c => c.client); - - await sleep(1000); - - // Request a random tx hash that no peer has - const randomTxHash = TxHash.random(); - const reqresp = getReqResp(clients[1]); - const responses = await reqresp.sendBatchRequest(ReqRespSubProtocol.TX, [new TxHashArray(randomTxHash)], undefined); - - // The handler returns an empty TxArray (serialized as a 4-byte vector with count 0), - // so sendBatchRequest includes it as a response with an empty TxArray. - expect(responses).toHaveLength(1); - const txArray = responses[0] as TxArray; - expect(txArray).toHaveLength(0); - }); }); diff --git a/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts b/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts deleted file mode 100644 index ae8121da7d8d..000000000000 --- a/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +++ /dev/null @@ -1,345 +0,0 @@ -import { MockL2BlockSource } from '@aztec/archiver/test'; -import { SecretValue } from '@aztec/foundation/config'; -import { createLogger } from '@aztec/foundation/log'; -import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider, Timer, executeTimeout } from '@aztec/foundation/timer'; -import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; -import type { L2BlockSource } from '@aztec/stdlib/block'; -import type { ContractDataSource } from '@aztec/stdlib/contract'; -import { GasFees } from '@aztec/stdlib/gas'; -import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server'; -import type { DataStoreConfig } from '@aztec/stdlib/kv-store'; -import { PeerErrorSeverity } from '@aztec/stdlib/p2p'; -import type { Tx, TxValidationResult } from '@aztec/stdlib/tx'; -import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client'; - -import type { PeerId } from '@libp2p/interface'; -import { peerIdFromString } from '@libp2p/peer-id'; - -import type { P2PConfig } from '../../../config.js'; -import { BatchTxRequester } from '../../../services/reqresp/batch-tx-requester/batch_tx_requester.js'; -import type { IBatchRequestTxValidator } from '../../../services/reqresp/batch-tx-requester/tx_validator.js'; -import { RateLimitStatus } from '../../../services/reqresp/rate-limiter/rate_limiter.js'; -import { RequestTracker } from '../../../services/tx_collection/request_tracker.js'; -import { - AlwaysTrueCircuitVerifier, - BENCHMARK_CONSTANTS, - InMemoryAttestationPool, - InMemoryTxPool, - UNLIMITED_RATE_LIMIT_QUOTA, - calculateInternalTimeout, - createMockEpochCache, - createMockWorldStateSynchronizer, -} from '../../../test-helpers/index.js'; -import { createP2PClient } from '../../index.js'; -import type { P2PClient } from '../../p2p_client.js'; -import { - type WorkerCommand, - type WorkerResponse, - deserializeBlockProposal, - deserializeTx, - deserializeTxHash, -} from './proposal_tx_collector_worker_protocol.js'; - -let client: P2PClient | undefined; -let txPool: InMemoryTxPool | undefined; -let attestationPool: InMemoryAttestationPool | undefined; -let logger = createLogger('p2p:proposal-bench'); -let kvStore: Awaited> | undefined; -let ipcDisconnected = false; - -function ensureClient(): P2PClient { - if (!client || !txPool) { - throw new Error('Worker client not started'); - } - return client; -} - -function isIpcDisconnectError(err: unknown): boolean { - const code = (err as NodeJS.ErrnoException | undefined)?.code; - return code === 'EPIPE' || code === 'ERR_IPC_CHANNEL_CLOSED'; -} - -function sendMessage(message: WorkerResponse): Promise { - const send = process.send; - if (!send || !process.connected || ipcDisconnected) { - return Promise.resolve(); - } - - return new Promise(resolve => { - const fallbackTimeout = setTimeout(() => resolve(), 2000); - try { - send.call(process, message, undefined, undefined, err => { - clearTimeout(fallbackTimeout); - if (!err) { - resolve(); - return; - } - if (isIpcDisconnectError(err)) { - ipcDisconnected = true; - resolve(); - return; - } - logger.warn('Failed to send IPC message', { error: err?.message ?? String(err) }); - resolve(); - }); - } catch (err: any) { - clearTimeout(fallbackTimeout); - if (isIpcDisconnectError(err)) { - ipcDisconnected = true; - resolve(); - return; - } - logger.warn('Failed to send IPC message', { error: err?.message ?? String(err) }); - resolve(); - } - }); -} - -async function startClient(config: P2PConfig, clientIndex: number) { - txPool = new InMemoryTxPool(); - attestationPool = new InMemoryAttestationPool(); - const epochCache = createMockEpochCache(); - const worldState = createMockWorldStateSynchronizer(); - const l2BlockSource = new MockL2BlockSource(); - const proofVerifier = new AlwaysTrueCircuitVerifier(); - kvStore = await openTmpStore(`proposal-bench-${clientIndex}`, true, BENCHMARK_CONSTANTS.KV_STORE_MAP_SIZE_KB); - logger = createLogger(`p2p:proposal-bench:${clientIndex}`); - - const telemetry = getTelemetryClient(); - const deps = { - txPool, - attestationPool, - store: kvStore, - logger, - }; - - client = await createP2PClient( - config as P2PConfig & DataStoreConfig, - l2BlockSource as L2BlockSource & ContractDataSource, - proofVerifier as ClientProtocolCircuitVerifier, - worldState, - epochCache, - { getCurrentMinFees: () => Promise.resolve(GasFees.empty()) }, - 'proposal-tx-collector-bench-worker', - new DateProvider(), - telemetry as TelemetryClient, - deps, - await l2BlockSource.getInitialHeader().hash(), - ); - - await client.start(); - installUnlimitedRateLimits(); - - for (let i = 0; i < 120; i++) { - if (client.isReady()) { - return; - } - await sleep(500); - } - - throw new Error('Timed out waiting for P2P client readiness'); -} - -function installSamplerOverrides(peerList: ReturnType[]) { - const reqResp = (ensureClient() as any).p2pService.reqresp as any; - const sampler = reqResp.connectionSampler as any; - - sampler.getPeerListSortedByConnectionCountAsc = (excluding?: Set) => { - if (!excluding || excluding.size === 0) { - return peerList; - } - return peerList.filter(peerId => !excluding.has(peerId.toString())); - }; - sampler.samplePeersBatch = (numberToSample: number, excluding?: Map) => { - const filtered = peerList.filter(peerId => !excluding?.has(peerId.toString())); - return filtered.slice(0, Math.min(numberToSample, filtered.length)); - }; - sampler.getPeer = (excluding?: Map) => { - const filtered = peerList.filter(peerId => !excluding?.has(peerId.toString())); - return filtered[0]; - }; -} - -function installUnlimitedRateLimits() { - const reqResp = (ensureClient() as any).p2pService.reqresp as any; - const rateLimiter = reqResp.rateLimiter as any; - - rateLimiter.getRateLimits = () => UNLIMITED_RATE_LIMIT_QUOTA; - rateLimiter.allow = () => RateLimitStatus.Allowed; -} - -async function runCollector(cmd: Extract) { - const { txHashes, blockProposal, pinnedPeerId, peerIds, timeoutMs } = cmd; - const reqResp = (ensureClient() as any).p2pService.reqresp as any; - const peerList = peerIds.map(peerId => peerIdFromString(peerId)); - - installSamplerOverrides(peerList); - installUnlimitedRateLimits(); - - const p2pService = { - reqResp, - connectionSampler: { - getPeerListSortedByConnectionCountAsc: () => peerList, - }, - txValidatorConfig: { - l1ChainId: 1, - rollupVersion: 1, - proofVerifier: { - verifyProof: () => Promise.resolve({ valid: true, durationMs: 0, totalDurationMs: 0 }), - stop: () => Promise.resolve(), - }, - }, - peerScoring: { - penalizePeer: (_peerId: PeerId, _penalty: PeerErrorSeverity) => {}, - }, - }; - - const parsedTxHashes = txHashes.map(deserializeTxHash); - const parsedProposal = deserializeBlockProposal(blockProposal); - const pinnedPeer = pinnedPeerId ? peerIdFromString(pinnedPeerId) : undefined; - - const timer = new Timer(); - let fetchedCount = 0; - - const internalTimeoutMs = calculateInternalTimeout(timeoutMs); - - const noopTxValidator: IBatchRequestTxValidator = { - validateRequestedTx: (_tx: Tx): Promise => Promise.resolve({ result: 'valid' }), - validateRequestedTxs: (txs: Tx[]): Promise => - Promise.resolve(txs.map(() => ({ result: 'valid' }))), - }; - - try { - const fetched = await executeTimeout( - (_signal: AbortSignal) => { - const tracker = RequestTracker.create(parsedTxHashes, new Date(Date.now() + internalTimeoutMs)); - const batchRequester = new BatchTxRequester( - tracker, - parsedProposal, - pinnedPeer, - p2pService, - logger, - new DateProvider(), - { txValidator: noopTxValidator }, - ); - return BatchTxRequester.collectAllTxs(batchRequester.run()); - }, - timeoutMs, - () => new Error(`Collector timed out after ${timeoutMs}ms`), - ); - fetchedCount = fetched.length; - } catch (err: any) { - logger.warn(`Collector error: ${err?.message ?? String(err)}`); - } - - return { durationMs: timer.ms(), fetchedCount }; -} - -async function stopClient() { - if (!client) { - return; - } - await client.stop(); - if (kvStore?.close) { - await kvStore.close(); - } - client = undefined; - txPool = undefined; - attestationPool = undefined; -} - -function gracefulExit(code: number = 0) { - try { - if (process.connected) { - process.disconnect(); - } - } catch { - // IPC channel already closed - } - setTimeout(() => process.exit(code), 5000).unref(); -} - -process.on('disconnect', () => { - ipcDisconnected = true; - void stopClient(); -}); - -process.on('error', err => { - if (isIpcDisconnectError(err)) { - ipcDisconnected = true; - return; - } - logger.warn('Worker process error', { error: err?.message ?? String(err) }); -}); - -process.on('message', (msg: WorkerCommand) => { - void (async () => { - if (!msg || typeof msg !== 'object') { - return; - } - - const requestId = msg.requestId; - - try { - switch (msg.type) { - case 'START': { - const rawConfig = msg.config; - const config: P2PConfig = { - ...rawConfig, - peerIdPrivateKey: rawConfig.peerIdPrivateKey ? new SecretValue(rawConfig.peerIdPrivateKey) : undefined, - } as P2PConfig; - - await startClient(config, msg.clientIndex); - const peerId = (ensureClient() as any).p2pService.node.peerId.toString(); - await sendMessage({ type: 'READY', requestId, peerId }); - break; - } - case 'SET_TXS': { - if (!txPool) { - throw new Error('Tx pool not initialized'); - } - const txs = msg.txs.map(deserializeTx); - const count = msg.mode === 'append' ? txPool.appendTxs(txs) : txPool.setTxs(txs); - await sendMessage({ type: 'TXS_SET', requestId, count }); - break; - } - case 'SET_BLOCK_PROPOSAL': { - if (!attestationPool) { - throw new Error('Attestation pool not initialized'); - } - const proposal = deserializeBlockProposal(msg.blockProposal); - await attestationPool.tryAddBlockProposal(proposal); - await sendMessage({ type: 'BLOCK_PROPOSAL_SET', requestId, archiveRoot: proposal.archive.toString() }); - break; - } - case 'RUN_COLLECTOR': { - const { durationMs, fetchedCount } = await runCollector(msg); - await sendMessage({ type: 'COLLECTOR_RESULT', requestId, durationMs, fetchedCount }); - break; - } - case 'GET_PEER_COUNT': { - const peers = await ensureClient().getPeers(); - await sendMessage({ type: 'PEER_COUNT', requestId, count: peers.length }); - break; - } - case 'STOP': { - await stopClient(); - await sendMessage({ type: 'STOPPED', requestId }); - gracefulExit(0); - break; - } - default: { - const _exhaustive: never = msg; - throw new Error(`Unknown command: ${(msg as { type?: string }).type}`); - } - } - } catch (err: any) { - await sendMessage({ type: 'ERROR', requestId, error: err?.message ?? String(err) }); - if (msg.type === 'START') { - await stopClient(); - gracefulExit(1); - } - } - })(); -}); diff --git a/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts b/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts deleted file mode 100644 index 9db03cdcfb7d..000000000000 --- a/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { BlockProposal } from '@aztec/stdlib/p2p'; -import { Tx, TxHash } from '@aztec/stdlib/tx'; - -import type { P2PConfig } from '../../../config.js'; - -export type SerializedP2PConfig = Omit & { peerIdPrivateKey?: string }; - -export type WorkerCommand = - | { type: 'START'; requestId: string; clientIndex: number; config: SerializedP2PConfig } - | { type: 'SET_TXS'; requestId: string; txs: string[]; mode?: 'replace' | 'append' } - | { type: 'SET_BLOCK_PROPOSAL'; requestId: string; blockProposal: string } - | { - type: 'RUN_COLLECTOR'; - requestId: string; - txHashes: string[]; - blockProposal: string; - pinnedPeerId?: string; - peerIds: string[]; - timeoutMs: number; - } - | { type: 'GET_PEER_COUNT'; requestId: string } - | { type: 'STOP'; requestId: string }; - -export type WorkerResponse = - | { type: 'READY'; requestId: string; peerId: string } - | { type: 'TXS_SET'; requestId: string; count: number } - | { type: 'BLOCK_PROPOSAL_SET'; requestId: string; archiveRoot: string } - | { type: 'COLLECTOR_RESULT'; requestId: string; durationMs: number; fetchedCount: number } - | { type: 'PEER_COUNT'; requestId: string; count: number } - | { type: 'STOPPED'; requestId: string } - | { type: 'ERROR'; requestId: string; error: string }; - -export const serializeTx = (tx: Tx) => tx.toBuffer().toString('hex'); -export const deserializeTx = (hex: string) => Tx.fromBuffer(Buffer.from(hex, 'hex')); - -export const serializeTxHash = (txHash: TxHash) => txHash.toString(); -export const deserializeTxHash = (hex: string) => TxHash.fromString(hex); - -export const serializeBlockProposal = (proposal: BlockProposal) => proposal.toBuffer().toString('hex'); -export const deserializeBlockProposal = (hex: string) => BlockProposal.fromBuffer(Buffer.from(hex, 'hex')); diff --git a/yarn-project/p2p/src/config.ts b/yarn-project/p2p/src/config.ts index 4986a0602b13..b8e388b98747 100644 --- a/yarn-project/p2p/src/config.ts +++ b/yarn-project/p2p/src/config.ts @@ -221,14 +221,28 @@ export interface P2PConfig /** Minimum age (ms) a transaction must have been in the pool before it's eligible for block building. */ minTxPoolAgeMs: number; - /** Deadline in ms used when collecting missing txs for unproven mined blocks. */ - p2pMissingTxCollectionDeadlineMs: number; + /** + * Number of full L2 slots to wait after a checkpoint's slot before declaring its txs missing + * for data-withholding slashing. + */ + slashDataWithholdingToleranceSlots: number; + + /** + * Number of L2 slots after a mined block's slot to keep collecting its missing txs. Clamped + * up so that collection always runs at least until the data-withholding slash verdict is + * rendered (`block.slot + slashDataWithholdingToleranceSlots + 1`). Defaults to undefined, + * in which case the tolerance window is used directly. + */ + p2pMissingTxCollectionDeadlineSlots?: number; /** Minimum percentage fee increase required to replace an existing tx via RPC (0 = no bump). */ priceBumpPercentage: bigint; /** Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only) */ skipIncomingProposals?: boolean; + + /** Accept proposal gossip regardless of slot timing (for testing only). */ + skipProposalSlotValidation?: boolean; } export const DEFAULT_P2P_PORT = 40400; @@ -554,15 +568,26 @@ export const p2pConfigMappings: ConfigMappingsType = { description: 'Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only)', ...booleanConfigHelper(false), }, + skipProposalSlotValidation: { + description: 'Accept proposal gossip regardless of slot timing (for testing only)', + ...booleanConfigHelper(false), + }, minTxPoolAgeMs: { env: 'P2P_MIN_TX_POOL_AGE_MS', description: 'Minimum age (ms) a transaction must have been in the pool before it is eligible for block building.', ...numberConfigHelper(2_000), }, - p2pMissingTxCollectionDeadlineMs: { - env: 'P2P_MISSING_TX_COLLECTION_DEADLINE_MS', - description: 'Deadline in ms used when collecting missing txs for unproven mined blocks.', - ...numberConfigHelper(72_000), + slashDataWithholdingToleranceSlots: { + env: 'SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS', + description: + 'L2 slots to wait after a checkpoint slot before declaring its txs missing. Drives both the data-withholding slasher check and the missing-tx collection deadline.', + ...numberConfigHelper(3), + }, + p2pMissingTxCollectionDeadlineSlots: { + env: 'P2P_MISSING_TX_COLLECTION_DEADLINE_SLOTS', + description: + 'Optional deadline (in L2 slots after the block slot) for collecting missing txs for unproven mined blocks. Clamped up to the data-withholding tolerance window so collection never gives up before the slash verdict.', + ...optionalNumberConfigHelper(), }, priceBumpPercentage: { env: 'P2P_RPC_PRICE_BUMP_PERCENTAGE', diff --git a/yarn-project/p2p/src/errors/reqresp.error.ts b/yarn-project/p2p/src/errors/reqresp.error.ts index 21749b7473d2..23827d882b9e 100644 --- a/yarn-project/p2p/src/errors/reqresp.error.ts +++ b/yarn-project/p2p/src/errors/reqresp.error.ts @@ -8,28 +8,3 @@ export class IndividualReqRespTimeoutError extends Error { super(`Request to peer timed out`); } } - -/** Collective request timeout error - * - * This error will be thrown when a req resp request times out regardless of the peer. - * @category Errors - */ -export class CollectiveReqRespTimeoutError extends Error { - constructor() { - super(`Request to all peers timed out`); - } -} - -/** Invalid response error - * - * This error will be thrown when a response is received that is not valid. - * - * This error does not need to be punished as message validators will handle punishing invalid - * requests - * @category Errors - */ -export class InvalidResponseError extends Error { - constructor() { - super(`Invalid response received`); - } -} diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts index 109e472aa35f..b2491ebee79d 100644 --- a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts @@ -14,7 +14,7 @@ import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instru /** Result of trying to add an item (proposal or attestation) to the pool */ export type TryAddResult = { - /** Whether the item was added to a main store. False when the slot/position/(slot,signer) already had a stored entry, even if a new equivocation hash was tracked. */ + /** Whether the item was accepted into pool state. False when it already existed, was invalid, or hit a cap. */ added: boolean; /** Whether the exact signed payload (matched by payload hash) already existed in the pool. */ alreadyExists: boolean; @@ -25,6 +25,11 @@ export type TryAddResult = { count: number; }; +export type ProposalsForSlot = { + blockProposals: BlockProposal[]; + checkpointProposals: CheckpointProposalCore[]; +}; + export const MAX_CHECKPOINT_PROPOSALS_PER_SLOT = 2; export const MAX_BLOCK_PROPOSALS_PER_POSITION = 2; /** Maximum attestations a single signer can make per slot before being rejected. */ @@ -35,6 +40,7 @@ export type AttestationPoolApi = Pick< AttestationPool, | 'tryAddBlockProposal' | 'getBlockProposalByArchive' + | 'getProposalsForSlot' | 'tryAddCheckpointProposal' | 'getCheckpointProposal' | 'addOwnCheckpointAttestations' @@ -52,11 +58,11 @@ export type AttestationPoolApi = Pick< * Attestations and proposals observed via the p2p network are stored for requests * from the validator to produce a block, or to serve to other peers. * - * Equivocation detection: each main store holds at most one entry per equivocation - * position (one checkpoint proposal per slot, one block proposal per (slot, position), - * one attestation per (slot, signer)). Distinct *signed payload hashes* arriving at - * the same position are tracked in the matching index multimap so the equivocation - * count reaches 2 even when archive collides on `feeAssetPriceModifier` variants. + * Equivocation detection: distinct *signed payload hashes* arriving at the same + * position are tracked in the matching index multimap so the equivocation count + * reaches 2 even when archive collides on `feeAssetPriceModifier` variants. + * Proposal bytes are retained per accepted payload hash, up to the same equivocation + * caps, for slashing watchers that need signed P2P proposals. */ export class AttestationPool { private metrics: PoolInstrumentation; @@ -71,26 +77,25 @@ export class AttestationPool { // Key: `${paddedSlot}-${signerAddress}`, Value: CheckpointProposalHash (`0x`-prefixed hex) private attestationHashesPerSlotAndSigner: AztecAsyncMultiMap; - // Checkpoint proposals from slot number to serialized CheckpointProposal. - // Stores the first proposal seen per slot. - private checkpointProposalPerSlot: AztecAsyncMap; + // Checkpoint proposals from `${paddedSlot}-${payloadHash}` to serialized CheckpointProposalCore. + // Stores every accepted distinct payload up to MAX_CHECKPOINT_PROPOSALS_PER_SLOT. + private checkpointProposalsPerSlotAndHash: AztecAsyncMap; // Distinct payload hashes seen per slot. Hash collision = duplicate. // Hash count reaching 2 = equivocation. // Key: slot number, Value: CheckpointProposalHash (`0x`-prefixed hex) private checkpointProposalHashesPerSlot: AztecAsyncMultiMap; - // Block proposals from positionKey to serialized BlockProposal. - // Stores the first proposal seen per (slot, indexWithinCheckpoint). - private blockProposalPerSlotAndIndex: AztecAsyncMap; + // Block proposals from `${paddedSlot}-${paddedIndex}-${payloadHash}` to serialized BlockProposal. + // Stores every accepted distinct payload up to MAX_BLOCK_PROPOSALS_PER_POSITION. + private blockProposalsPerSlotIndexAndHash: AztecAsyncMap; // Distinct payload hashes seen per (slot, indexWithinCheckpoint). // Key: slot * (1 << INDEX_BITS) + indexWithinCheckpoint, Value: BlockProposalHash (`0x`-prefixed hex) private blockProposalHashesPerSlotAndIndex: AztecAsyncMultiMap; - // Secondary index from archive root to positionKey, so that the block-txs req/resp - // handler can still resolve a stored proposal by archive root. - private blockProposalSlotAndIndexPerArchive: AztecAsyncMap; + // Secondary index from archive root to all retained block proposal keys. + private blockProposalKeysPerArchive: AztecAsyncMultiMap; constructor( private store: AztecAsyncKVStore, @@ -98,16 +103,16 @@ export class AttestationPool { private log = createLogger('aztec:attestation_pool'), ) { // Initialize block proposal storage - this.blockProposalPerSlotAndIndex = store.openMap('proposals'); + this.blockProposalsPerSlotIndexAndHash = store.openMap('block_proposals_by_slot_index_and_hash'); this.blockProposalHashesPerSlotAndIndex = store.openMultiMap('block_proposals_for_slot_and_index'); - this.blockProposalSlotAndIndexPerArchive = store.openMap('block_proposals_by_archive'); + this.blockProposalKeysPerArchive = store.openMultiMap('block_proposals_by_archive'); // Initialize checkpoint attestations storage this.attestationPerSlotAndSigner = store.openMap('checkpoint_attestations'); this.attestationHashesPerSlotAndSigner = store.openMultiMap('checkpoint_attestations_per_slot_and_signer'); // Initialize checkpoint proposal storage - this.checkpointProposalPerSlot = store.openMap('checkpoint_proposals'); + this.checkpointProposalsPerSlotAndHash = store.openMap('checkpoint_proposals_by_slot_and_hash'); this.checkpointProposalHashesPerSlot = store.openMultiMap('checkpoint_proposals_for_slot'); this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL, this.poolStats); @@ -121,13 +126,13 @@ export class AttestationPool { /** Returns whether the pool is empty. */ public async isEmpty(): Promise { - for await (const _ of this.attestationPerSlotAndSigner.entriesAsync()) { - return false; - } - for await (const _ of this.blockProposalPerSlotAndIndex.entriesAsync()) { - return false; - } - return true; + const [attestationCount, blockProposalCount, checkpointProposalCount] = await Promise.all([ + this.attestationPerSlotAndSigner.sizeAsync(), + this.blockProposalsPerSlotIndexAndHash.sizeAsync(), + this.checkpointProposalsPerSlotAndHash.sizeAsync(), + ]); + + return attestationCount === 0 && blockProposalCount === 0 && checkpointProposalCount === 0; } /** Number of bits reserved for indexWithinCheckpoint in position keys. */ @@ -143,6 +148,35 @@ export class AttestationPool { return slot.toString().padStart(AttestationPool.SLOT_PAD_DIGITS, '0'); } + /** Fixed-width decimal index string for use in composite string keys. */ + private indexPaddedKey(indexWithinCheckpoint: number): string { + return indexWithinCheckpoint.toString().padStart(4, '0'); + } + + /** Key for retained block proposals. */ + private getBlockProposalKey( + slot: SlotNumber | number, + indexWithinCheckpoint: number, + payloadHash: BlockProposalHash, + ): string { + return `${this.slotPaddedKey(slot)}-${this.indexPaddedKey(indexWithinCheckpoint)}-${payloadHash}`; + } + + /** Range bounds for all retained block proposals in a slot. */ + private getBlockProposalKeyRangeForSlot(slot: SlotNumber): { start: string; end: string } { + return { start: `${this.slotPaddedKey(slot)}-`, end: `${this.slotPaddedKey(slot + 1)}-` }; + } + + /** Key for retained checkpoint proposals. */ + private getCheckpointProposalKey(slot: SlotNumber | number, payloadHash: CheckpointProposalHash): string { + return `${this.slotPaddedKey(slot)}-${payloadHash}`; + } + + /** Range bounds for all retained checkpoint proposals in a slot. */ + private getCheckpointProposalKeyRangeForSlot(slot: SlotNumber): { start: string; end: string } { + return { start: `${this.slotPaddedKey(slot)}-`, end: `${this.slotPaddedKey(slot + 1)}-` }; + } + /** Key for the per-(slot, signer) attestation main store and equivocation index. */ private getSlotSignerKey(slot: SlotNumber, signerAddress: string): string { return `${this.slotPaddedKey(slot)}-${signerAddress}`; @@ -185,8 +219,7 @@ export class AttestationPool { * - Detects duplicates by signed-payload hash (not archive); a re-broadcast of the * exact same signed payload returns `alreadyExists: true`. * - Distinct payload hashes at the same `(slot, indexWithinCheckpoint)` are tracked - * in the equivocation index. The first hash also stores the proposal bytes; later - * distinct hashes only bump `count` so libp2p can fire its duplicate callback. + * in the equivocation index and retained up to the cap. * * @param blockProposal - The block proposal to add * @returns Result indicating whether the proposal was added and duplicate detection info @@ -210,14 +243,13 @@ export class AttestationPool { // Track the new payload hash for equivocation detection. await this.blockProposalHashesPerSlotAndIndex.set(positionKey, payloadHash); - - // Only the first distinct payload at this position is stored; later equivocations - // are detected via the multimap but their payload bytes are not retained. - const alreadyHasStored = await this.blockProposalPerSlotAndIndex.hasAsync(positionKey); - if (!alreadyHasStored) { - await this.blockProposalPerSlotAndIndex.set(positionKey, blockProposal.withoutSignedTxs().toBuffer()); - await this.blockProposalSlotAndIndexPerArchive.set(blockProposal.archive.toString(), positionKey); - } + const proposalKey = this.getBlockProposalKey( + blockProposal.slotNumber, + blockProposal.indexWithinCheckpoint, + payloadHash, + ); + await this.blockProposalsPerSlotIndexAndHash.set(proposalKey, blockProposal.withoutSignedTxs().toBuffer()); + await this.blockProposalKeysPerArchive.set(blockProposal.archive.toString(), proposalKey); this.log.debug( `Added block proposal for slot ${blockProposal.slotNumber} and index ${blockProposal.indexWithinCheckpoint}`, @@ -226,7 +258,6 @@ export class AttestationPool { payloadHash, slotNumber: blockProposal.slotNumber, indexWithinCheckpoint: blockProposal.indexWithinCheckpoint, - stored: !alreadyHasStored, }, ); @@ -237,40 +268,57 @@ export class AttestationPool { /** * Get block proposal by archive root. * - * Resolves the archive root to its `(slot, indexWithinCheckpoint)` via a secondary - * index, then fetches the stored proposal (if any). Returns the *first* proposal - * seen at that position, even if a later equivocating payload was tracked. - * Validates that the stored proposal's archive matches the requested one before - * returning, guarding against secondary-index corruption or position-key reuse. + * Resolves the archive root through the archive index and returns the first + * retained proposal for that archive. This lookup is used by block-txs req/resp, + * where any retained proposal for the requested archive gives the tx hash list. * * @param archiveRoot - The archive root to look up * @return The block proposal if it exists and its archive matches, otherwise undefined. */ public async getBlockProposalByArchive(archiveRoot: string): Promise { - const positionKey = await this.blockProposalSlotAndIndexPerArchive.getAsync(archiveRoot); - if (positionKey === undefined) { - return undefined; - } - const buffer = await this.blockProposalPerSlotAndIndex.getAsync(positionKey); - if (!buffer || buffer.length === 0) { - return undefined; + for await (const proposalKey of this.blockProposalKeysPerArchive.getValuesAsync(archiveRoot)) { + const buffer = await this.blockProposalsPerSlotIndexAndHash.getAsync(proposalKey); + if (!buffer || buffer.length === 0) { + continue; + } + try { + const proposal = BlockProposal.fromBuffer(buffer); + if (proposal.archive.toString() === archiveRoot) { + return proposal; + } + } catch { + continue; + } } - let proposal: BlockProposal; - try { - proposal = BlockProposal.fromBuffer(buffer); - } catch { - return undefined; + return undefined; + } + + /** Returns retained signed proposals for a slot. */ + public async getProposalsForSlot(slot: SlotNumber): Promise { + const blockProposals: BlockProposal[] = []; + const checkpointProposals: CheckpointProposalCore[] = []; + + for await (const [_, buffer] of this.blockProposalsPerSlotIndexAndHash.entriesAsync( + this.getBlockProposalKeyRangeForSlot(slot), + )) { + try { + blockProposals.push(BlockProposal.fromBuffer(buffer)); + } catch { + continue; + } } - const storedArchive = proposal.archive.toString(); - if (storedArchive !== archiveRoot) { - this.log.warn(`Stored block proposal archive does not match requested archive root`, { - requestedArchive: archiveRoot, - storedArchive, - positionKey, - }); - return undefined; + + for await (const [_, buffer] of this.checkpointProposalsPerSlotAndHash.entriesAsync( + this.getCheckpointProposalKeyRangeForSlot(slot), + )) { + try { + checkpointProposals.push(CheckpointProposal.fromBuffer(buffer)); + } catch { + continue; + } } - return proposal; + + return { blockProposals, checkpointProposals }; } /** Checks if any block proposals exist for a given slot (at index 0). */ @@ -286,8 +334,8 @@ export class AttestationPool { * - Detects duplicates by signed-payload hash (not archive); a re-broadcast of the * exact same signed payload returns `alreadyExists: true`. * - Distinct payload hashes at the same slot are tracked in the equivocation index. - * Only the first distinct payload's bytes are stored; later distinct hashes bump - * `count` so libp2p can fire its duplicate callback. + * Distinct payload bytes are retained up to the same cap so slashing watchers + * can recover signed proposals. * * Note: This method only handles the CheckpointProposalCore. If the original * CheckpointProposal contains a lastBlock, the caller should extract it via @@ -313,19 +361,15 @@ export class AttestationPool { // Track the new payload hash for equivocation detection. await this.checkpointProposalHashesPerSlot.set(slot, payloadHash); - - // Only the first distinct payload at this slot is stored; later equivocations - // are detected via the multimap but their payload bytes are not retained. - const alreadyHasStored = await this.checkpointProposalPerSlot.hasAsync(slot); - if (!alreadyHasStored) { - await this.checkpointProposalPerSlot.set(slot, proposal.toBuffer()); - } + await this.checkpointProposalsPerSlotAndHash.set( + this.getCheckpointProposalKey(slot, payloadHash), + proposal.toBuffer(), + ); this.log.debug(`Added checkpoint proposal for slot ${slot}`, { archive: proposal.archive.toString(), payloadHash, slotNumber: slot, - stored: !alreadyHasStored, }); return { added: true, alreadyExists: false, count: count + 1 }; @@ -333,7 +377,9 @@ export class AttestationPool { } /** - * Get the (first) checkpoint proposal stored for the given slot. + * Get a retained checkpoint proposal stored for the given slot. + * If multiple proposals were retained for an equivocation, returns the lowest + * payload hash deterministically. * * Returns a CheckpointProposalCore (without lastBlock info) since the lastBlock * is extracted and stored separately as a BlockProposal when added. @@ -342,13 +388,16 @@ export class AttestationPool { * @return The checkpoint proposal core if one is stored, otherwise undefined. */ public async getCheckpointProposal(slot: SlotNumber): Promise { - const buffer = await this.checkpointProposalPerSlot.getAsync(slot); - try { - if (buffer && buffer.length > 0) { - return CheckpointProposal.fromBuffer(buffer); + for await (const [_, buffer] of this.checkpointProposalsPerSlotAndHash.entriesAsync( + this.getCheckpointProposalKeyRangeForSlot(slot), + )) { + try { + if (buffer && buffer.length > 0) { + return CheckpointProposal.fromBuffer(buffer); + } + } catch { + continue; } - } catch { - return undefined; } return undefined; @@ -465,10 +514,13 @@ export class AttestationPool { // Delete checkpoint proposals for slots < oldestSlot. for await (const slot of this.checkpointProposalHashesPerSlot.keysAsync({ end: oldestSlot })) { await this.checkpointProposalHashesPerSlot.delete(slot); - if (await this.checkpointProposalPerSlot.hasAsync(slot)) { - await this.checkpointProposalPerSlot.delete(slot); - numberOfCheckpointProposals++; - } + } + + for await (const key of this.checkpointProposalsPerSlotAndHash.keysAsync({ + end: `${oldestSlotPadded}-`, + })) { + await this.checkpointProposalsPerSlotAndHash.delete(key); + numberOfCheckpointProposals++; } // Delete block proposals for slots < oldestSlot, using blockProposalHashesPerSlotAndIndex as index. @@ -476,17 +528,19 @@ export class AttestationPool { const blockPositionEndKey = oldestSlot * (1 << AttestationPool.INDEX_BITS); for await (const positionKey of this.blockProposalHashesPerSlotAndIndex.keysAsync({ end: blockPositionEndKey })) { await this.blockProposalHashesPerSlotAndIndex.delete(positionKey); - const stored = await this.blockProposalPerSlotAndIndex.getAsync(positionKey); - if (stored) { - try { - const proposal = BlockProposal.fromBuffer(stored); - await this.blockProposalSlotAndIndexPerArchive.delete(proposal.archive.toString()); - } catch { - // ignore decode errors when cleaning up - } - await this.blockProposalPerSlotAndIndex.delete(positionKey); - numberOfBlockProposals++; + } + + for await (const [key, buffer] of this.blockProposalsPerSlotIndexAndHash.entriesAsync({ + end: `${oldestSlotPadded}-`, + })) { + try { + const proposal = BlockProposal.fromBuffer(buffer); + await this.blockProposalKeysPerArchive.deleteValue(proposal.archive.toString(), key); + } catch { + // ignore decode errors when cleaning up } + await this.blockProposalsPerSlotIndexAndHash.delete(key); + numberOfBlockProposals++; } }); diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts index 7265d2e52a42..19180d9d156d 100644 --- a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts @@ -246,6 +246,45 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer()); expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString()); }); + + it('should retain an exact duplicate block proposal only once', async () => { + const slotNumber = 420; + const proposal = await mockBlockProposalForPool(signers[0], slotNumber); + + await ap.tryAddBlockProposal(proposal); + await ap.tryAddBlockProposal(proposal); + + const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber)); + expect(proposals.blockProposals.map(proposal => proposal.toBuffer())).toEqual([ + proposal.withoutSignedTxs().toBuffer(), + ]); + }); + + it('should retain all accepted block proposals at a position', async () => { + const slotNumber = 420; + const blockHeader = makeBlockHeader(1, { slotNumber: SlotNumber(slotNumber) }); + const proposal1 = await makeBlockProposal({ + signer: signers[0], + blockHeader, + archiveRoot: Fr.random(), + indexWithinCheckpoint: IndexWithinCheckpoint(1), + }); + const proposal2 = await makeBlockProposal({ + signer: signers[0], + blockHeader, + archiveRoot: Fr.random(), + indexWithinCheckpoint: IndexWithinCheckpoint(1), + }); + + await ap.tryAddBlockProposal(proposal1); + await ap.tryAddBlockProposal(proposal2); + + const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber)); + expect(proposals.blockProposals.map(proposal => proposal.toBuffer())).toEqual( + expect.arrayContaining([proposal1.withoutSignedTxs().toBuffer(), proposal2.withoutSignedTxs().toBuffer()]), + ); + expect(await ap.getBlockProposalByArchive(proposal2.archive.toString())).toBeDefined(); + }); }); describe('CheckpointProposal in attestation pool', () => { @@ -346,13 +385,21 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo const result2 = await ap.tryAddCheckpointProposal(proposal2); // The second distinct payload is tracked as an equivocation, count goes to 2, - // but its bytes are not retained — the first proposal stays in the main store. + // and both accepted payloads are retained by payload hash. expect(result2.added).toBe(true); expect(result2.alreadyExists).toBe(false); expect(result2.count).toBe(2); const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber)); - expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer()); + const expectedProposal = [proposal1, proposal2].sort((a, b) => + a.getPayloadHash().localeCompare(b.getPayloadHash()), + )[0]; + expect(retrievedProposal!.toBuffer()).toEqual(expectedProposal.toBuffer()); + + const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber)); + expect(proposals.checkpointProposals.map(proposal => proposal.toBuffer())).toEqual( + expect.arrayContaining([proposal1.toBuffer(), proposal2.toBuffer()]), + ); }); it('should detect equivocation when only feeAssetPriceModifier differs', async () => { @@ -385,6 +432,34 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo expect(result2.count).toBe(2); }); + it('should delete retained proposals older than a given slot', async () => { + const oldSlot = 100; + const newSlot = 200; + const oldBlock = await mockBlockProposalForPool(signers[0], oldSlot); + const newBlock = await mockBlockProposalForPool(signers[1], newSlot); + const oldCheckpoint = await mockCheckpointProposalForPool(signers[0], oldSlot); + const newCheckpoint = await mockCheckpointProposalForPool(signers[1], newSlot); + + await ap.tryAddBlockProposal(oldBlock); + await ap.tryAddBlockProposal(newBlock); + await ap.tryAddCheckpointProposal(oldCheckpoint); + await ap.tryAddCheckpointProposal(newCheckpoint); + + await ap.deleteOlderThan(SlotNumber(newSlot)); + + expect(await ap.getProposalsForSlot(SlotNumber(oldSlot))).toEqual({ + blockProposals: [], + checkpointProposals: [], + }); + const newProposals = await ap.getProposalsForSlot(SlotNumber(newSlot)); + expect(newProposals.blockProposals.map(proposal => proposal.toBuffer())).toContainEqual( + newBlock.withoutSignedTxs().toBuffer(), + ); + expect(newProposals.checkpointProposals.map(proposal => proposal.toBuffer())).toContainEqual( + newCheckpoint.toBuffer(), + ); + }); + it('should return added=false when exceeding capacity', async () => { const slotNumber = 420; diff --git a/yarn-project/p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts b/yarn-project/p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts index 51283ab6ecc5..d45e6668489c 100644 --- a/yarn-project/p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +++ b/yarn-project/p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts @@ -1,4 +1,5 @@ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { FifoSet } from '@aztec/foundation/fifo-set'; import type { Logger } from '@aztec/foundation/log'; import type { DateProvider } from '@aztec/foundation/timer'; import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store'; @@ -82,7 +83,7 @@ export class TxPoolV2Impl { #evictionManager: EvictionManager; #dateProvider: DateProvider; #instrumentation: TxPoolV2Instrumentation; - #evictedTxHashes: Set = new Set(); + #evictedTxHashes: FifoSet; #log: Logger; #callbacks: TxPoolV2Callbacks; @@ -105,6 +106,7 @@ export class TxPoolV2Impl { this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls; this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config }; + this.#evictedTxHashes = FifoSet.withLimit(this.#config.evictedTxCacheSize); this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log); this.#deletedPool = new DeletedPool(store, this.#txsDB, log); this.#dateProvider = dateProvider; @@ -903,21 +905,11 @@ export class TxPoolV2Impl { this.#instrumentation.recordEvictions(txHashes.length, reason); for (const txHashStr of txHashes) { this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason }); - this.#addToEvictedCache(txHashStr); + this.#evictedTxHashes.add(txHashStr); } await this.#deleteTxsBatch(txHashes); } - /** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */ - #addToEvictedCache(txHashStr: string): void { - if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) { - // FIFO eviction: remove the first (oldest) entry - const oldest = this.#evictedTxHashes.values().next().value!; - this.#evictedTxHashes.delete(oldest); - } - this.#evictedTxHashes.add(txHashStr); - } - // ============================================================================ // PRIVATE HELPERS - Validation & Conflict Resolution // ============================================================================ diff --git a/yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts b/yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts index 8d19408b94d1..f4e67469f975 100644 --- a/yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts +++ b/yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts @@ -13,6 +13,7 @@ export class BlockProposalValidator implements P2PValidator { maxTxsPerBlock?: number; maxBlocksPerCheckpoint?: number; p2pPropagationTime?: number; + skipSlotValidation?: boolean; signatureContext: CoordinationSignatureContext; }, ) { diff --git a/yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts b/yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts index 2a3eb9013c67..3e0057b96d90 100644 --- a/yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +++ b/yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts @@ -18,6 +18,7 @@ export class CheckpointProposalValidator implements P2PValidator { /** * Builds a PrivateLog encoding a ContractInstancePublishedEvent. - * Layout: [tag, address, version, salt, contractClassId, initializationHash, ...publicKeys(8 fields), deployer] + * Layout: [tag, address, version, salt, contractClassId, initializationHash, immutablesHash, ...publicKeys(5 fields), deployer] */ async function buildContractInstanceLog(opts?: { address?: AztecAddress }): Promise { const salt = Fr.random(); @@ -40,13 +40,15 @@ describe('ContractInstanceTxValidator', () => { const initializationHash = Fr.random(); const publicKeys = await PublicKeys.random(); const deployer = await AztecAddress.random(); + const immutablesHash = Fr.random(); const instance = { - version: 1 as const, + version: 2 as const, salt, currentContractClassId: contractClassId, originalContractClassId: contractClassId, initializationHash, + immutablesHash, publicKeys, deployer, }; @@ -55,8 +57,9 @@ describe('ContractInstanceTxValidator', () => { const address = opts?.address ?? correctAddress; // Serialize the event into fields matching the format expected by ContractInstancePublishedEvent.fromLog. - // fromLog reads from a buffer: [tag(32 bytes) | address(32) | version(32) | salt(32) | classId(32) | initHash(32) | publicKeys(4*64=256 bytes) | deployer(32)] - // PublicKeys serializes as 4 Points, each Point is 2 Fr (x, y) = 64 bytes. Total: 8 Fr fields. + // fromLog reads from a buffer: + // [tag(32) | address(32) | version(32) | salt(32) | classId(32) | initHash(32) | publicKeys(160) | deployer(32)] + // where publicKeys = npkMHash(32) + ivpkM(64 = x|y, no is_infinite) + ovpkMHash(32) + tpkMHash(32) = 5 Fr fields. const publicKeysBuffer = publicKeys.toBuffer(); const publicKeysFields: Fr[] = []; for (let i = 0; i < publicKeysBuffer.length; i += 32) { @@ -66,10 +69,11 @@ describe('ContractInstanceTxValidator', () => { const emittedFields: Fr[] = [ CONTRACT_INSTANCE_PUBLISHED_EVENT_TAG, address.toField(), - new Fr(1), // version + new Fr(2), // version salt, contractClassId, initializationHash, + immutablesHash, ...publicKeysFields, deployer.toField(), ]; diff --git a/yarn-project/p2p/src/services/dummy_service.ts b/yarn-project/p2p/src/services/dummy_service.ts index d89cfcc59635..6078c3e484cd 100644 --- a/yarn-project/p2p/src/services/dummy_service.ts +++ b/yarn-project/p2p/src/services/dummy_service.ts @@ -18,7 +18,6 @@ import type { ReqRespSubProtocol, ReqRespSubProtocolHandler, ReqRespSubProtocolHandlers, - ReqRespSubProtocolValidators, SubProtocolMap, } from './reqresp/interface.js'; import type { GoodByeReason } from './reqresp/protocols/goodbye.js'; @@ -38,6 +37,8 @@ import { * A dummy implementation of the P2P Service. */ export class DummyP2PService implements P2PService { + private allNodesCheckpointReceivedCallback?: P2PCheckpointReceivedCallback; + updateConfig(_config: Partial): void {} /** Returns an empty array for peers. */ @@ -88,10 +89,14 @@ export class DummyP2PService implements P2PService { * Register a callback into the validator client for when a checkpoint proposal is received */ public registerValidatorCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {} - public registerAllNodesCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {} + public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) { + this.allNodesCheckpointReceivedCallback = callback; + } - public notifyOwnCheckpointProposal(_checkpoint: CheckpointProposalCore): Promise { - return Promise.resolve(); + // Mirror libp2p's own-proposal loopback so the proposer's pipelined `canProposeAt` override sees its own + // in-flight parent checkpoint when running in p2p-disabled (single-node e2e) mode. + public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise { + await this.allNodesCheckpointReceivedCallback?.(checkpoint, undefined as unknown as PeerId); } /** @@ -119,19 +124,6 @@ export class DummyP2PService implements P2PService { return Promise.resolve(undefined); } - /** - * Sends a batch request to a peer. - * @param _protocol - The protocol to send the request on. - * @param _requests - The requests to send. - * @returns The responses from the peer, otherwise undefined. - */ - public sendBatchRequest( - _protocol: Protocol, - _requests: InstanceType[], - ): Promise[]> { - return Promise.resolve([]); - } - public sendRequestToPeer( _peerId: PeerId, _subProtocol: ReqRespSubProtocol, @@ -153,11 +145,7 @@ export class DummyP2PService implements P2PService { return Promise.resolve(); } - addReqRespSubProtocol( - _subProtocol: ReqRespSubProtocol, - _handler: ReqRespSubProtocolHandler, - _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { + addReqRespSubProtocol(_subProtocol: ReqRespSubProtocol, _handler: ReqRespSubProtocolHandler): Promise { return Promise.resolve(); } @@ -186,6 +174,7 @@ export class DummyP2PService implements P2PService { peerScoring: { penalizePeer: (_peerId, _penalty) => {}, }, + validateRequestedBlockTxsConsistency: () => Promise.resolve(true), }; } } @@ -291,10 +280,7 @@ export class DummyPeerManager implements PeerManagerInterface { export class DummyReqResp implements ReqRespInterface { updateConfig(_config: Partial): void {} setShouldRejectPeer(): void {} - start( - _subProtocolHandlers: ReqRespSubProtocolHandlers, - _subProtocolValidators: ReqRespSubProtocolValidators, - ): Promise { + start(_subProtocolHandlers: ReqRespSubProtocolHandlers): Promise { return Promise.resolve(); } stop(): Promise { @@ -306,16 +292,6 @@ export class DummyReqResp implements ReqRespInterface { ): Promise | undefined> { return Promise.resolve(undefined); } - sendBatchRequest( - _subProtocol: SubProtocol, - _requests: InstanceType[], - _pinnedPeer: PeerId | undefined, - _timeoutMs?: number, - _maxPeers?: number, - _maxRetryAttempts?: number, - ): Promise[]> { - return Promise.resolve([]); - } public sendRequestToPeer( _peerId: PeerId, _subProtocol: ReqRespSubProtocol, @@ -334,11 +310,7 @@ export class DummyReqResp implements ReqRespInterface { }; } - addSubProtocol( - _subProtocol: ReqRespSubProtocol, - _handler: ReqRespSubProtocolHandler, - _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { + addSubProtocol(_subProtocol: ReqRespSubProtocol, _handler: ReqRespSubProtocolHandler): Promise { return Promise.resolve(); } } diff --git a/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts b/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts index d7e78cbd4d49..3aaf4c97b9ce 100644 --- a/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts +++ b/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts @@ -19,7 +19,7 @@ import { makeCheckpointProposal, mockTx, } from '@aztec/stdlib/testing'; -import { type Tx, TxArray, TxHashArray, type TxValidator } from '@aztec/stdlib/tx'; +import { TxArray, TxHashArray } from '@aztec/stdlib/tx'; import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client'; import { ServerWorldStateSynchronizer } from '@aztec/world-state'; @@ -316,7 +316,7 @@ describe('LibP2PService', () => { }); }); - describe('validateRequestedBlockTxs', () => { + describe('validateRequestedBlockTxsConsistency', () => { function makeRequest(archiveRoot: Fr, length: number, indices: number[]): BlockTxsRequest { return new BlockTxsRequest(archiveRoot, new TxHashArray(), BitVector.init(length, indices)); } @@ -347,7 +347,7 @@ describe('LibP2PService', () => { const request = makeRequest(reqHash, 5, [0, 2]); const response = makeResponse(otherHash, 5, [0, 2], []); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -357,7 +357,7 @@ describe('LibP2PService', () => { const request = makeRequest(hash, 5, [0, 2]); const response = makeResponse(hash, 4, [0, 2], []); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -367,7 +367,7 @@ describe('LibP2PService', () => { const request = makeRequest(hash, 5, [0, 2, 3]); const response = makeResponse(hash, 5, [0, 2, 3], ['0xaaa', '0xaaa']); // duplicate - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -378,7 +378,7 @@ describe('LibP2PService', () => { const request = makeRequest(hash, 3, [0, 2]); const response = makeResponse(hash, 3, [0], ['0x1', '0x2']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -390,7 +390,7 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xgood2', '0xgood4', '0xother', '0xother2']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.LowToleranceError); }); @@ -404,7 +404,7 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.LowToleranceError); }); @@ -416,9 +416,8 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(true); - expect(service.validateRequestedTxMock).toHaveBeenCalledTimes(3); }); it('should accept partial subset when proposal exists and order matches requested indices', async () => { @@ -429,9 +428,8 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(true); - expect(service.validateRequestedTxMock).toHaveBeenCalledTimes(2); expect(mockPeerManager.penalizePeer).not.toHaveBeenCalled(); }); @@ -443,9 +441,8 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xother4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(true); - expect(service.validateRequestedTxMock).toHaveBeenCalledTimes(0); expect(mockPeerManager.penalizePeer).not.toHaveBeenCalled(); }); @@ -455,7 +452,7 @@ describe('LibP2PService', () => { const request = makeRequest(hash, 3, [1]); const response = makeResponse(hash, 3, [], ['0xsome']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -468,7 +465,7 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.LowToleranceError); }); @@ -481,7 +478,7 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.LowToleranceError); }); @@ -498,7 +495,7 @@ describe('LibP2PService', () => { }; service.setAttestationPool(mockAttestationPool); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).not.toHaveBeenCalled(); }); @@ -1315,9 +1312,6 @@ interface CreateTestLibP2PServiceOptions { * and allows construction with mocked dependencies. */ class TestLibP2PService extends LibP2PService { - /** Mocked validateRequestedTx for testing. */ - public validateRequestedTxMock: jest.Mock; - /** Controls whether first-stage gossip validation passes. Set to false to simulate first-stage failure. */ public firstStageValidationPasses = true; @@ -1330,9 +1324,6 @@ class TestLibP2PService extends LibP2PService { /** Controls the severity returned by the failing first-stage validator. */ public firstStageSeverity: PeerErrorSeverity = PeerErrorSeverity.LowToleranceError; - /** Stub validator returned by createRequestedTxValidator. */ - private stubValidator: TxValidator; - /** Exposed epoch cache for test configuration. */ public testEpochCache: MockProxy; @@ -1387,10 +1378,6 @@ class TestLibP2PService extends LibP2PService { this.mockPeerDiscoveryService = resolvedPeerDiscoveryService; this.testEpochCache = epochCache; - this.validateRequestedTxMock = jest.fn(() => Promise.resolve()); - this.stubValidator = { - validateTx: () => Promise.resolve({ result: 'valid' as const }), - }; } /** Exposes the protected handleNewGossipMessage for testing. */ @@ -1429,13 +1416,13 @@ class TestLibP2PService extends LibP2PService { }; } - /** Exposes the protected validateRequestedBlockTxs for testing. */ - public override validateRequestedBlockTxs( + /** Exposes the protected validateRequestedBlockTxsConsistency for testing. */ + public override validateRequestedBlockTxsConsistency( request: BlockTxsRequest, response: BlockTxsResponse, peerId: PeerId, ): Promise { - return super.validateRequestedBlockTxs(request, response, peerId); + return super.validateRequestedBlockTxsConsistency(request, response, peerId); } /** Exposes the protected processBlockFromPeer for testing. */ @@ -1453,21 +1440,6 @@ class TestLibP2PService extends LibP2PService { return super.validateAndStoreCheckpointAttestation(peerId, attestation); } - /** Override to use the mock. */ - protected override async validateRequestedTx( - tx: Tx, - peerId: PeerId, - _txValidator: TxValidator, - _requested?: Set<`0x${string}`>, - ): Promise { - await this.validateRequestedTxMock(tx, peerId); - } - - /** Override to return the stub validator. */ - protected override createRequestedTxValidator(): TxValidator { - return this.stubValidator; - } - /** Sets the attestation pool on the mempools for test setup. */ public setAttestationPool(attestationPool: MockAttestationPoolForTests): void { (this.mempools as any).attestationPool = attestationPool; diff --git a/yarn-project/p2p/src/services/libp2p/libp2p_service.ts b/yarn-project/p2p/src/services/libp2p/libp2p_service.ts index 1cf314d4c835..9c00dc517ba6 100644 --- a/yarn-project/p2p/src/services/libp2p/libp2p_service.ts +++ b/yarn-project/p2p/src/services/libp2p/libp2p_service.ts @@ -25,7 +25,7 @@ import { metricsTopicStrToLabels, } from '@aztec/stdlib/p2p'; import { MerkleTreeId } from '@aztec/stdlib/trees'; -import { Tx, type TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx'; +import { Tx, type TxValidationResult } from '@aztec/stdlib/tx'; import type { UInt64 } from '@aztec/stdlib/types'; import { compressComponentVersions } from '@aztec/stdlib/versioning'; import { @@ -74,7 +74,6 @@ import { createFirstStageTxValidationsForGossipedTransactions, createSecondStageTxValidationsForGossipedTransactions, createTxValidatorForBlockProposalReceivedTxs, - createTxValidatorForOnDemandReceivedTxs, } from '../../msg_validators/tx_validator/factory.js'; import { GossipSubEvent } from '../../types/index.js'; import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js'; @@ -93,15 +92,12 @@ import { AuthRequest, BlockTxsRequest, BlockTxsResponse, - DEFAULT_SUB_PROTOCOL_VALIDATORS, type ReqRespInterface, type ReqRespResponse, ReqRespSubProtocol, type ReqRespSubProtocolHandler, type ReqRespSubProtocolHandlers, - type ReqRespSubProtocolValidators, StatusMessage, - type SubProtocolMap, ValidationError, pingHandler, reqGoodbyeHandler, @@ -241,6 +237,7 @@ export class LibP2PService extends WithTracer implements P2PService { maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint, maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint, p2pPropagationTime, + skipSlotValidation: config.skipProposalSlotValidation, signatureContext: { chainId: config.l1ChainId, rollupAddress: config.rollupAddress, @@ -568,16 +565,9 @@ export class LibP2PService extends WithTracer implements P2PService { requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this); } - // Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function - const reqrespSubProtocolValidators = { - ...DEFAULT_SUB_PROTOCOL_VALIDATORS, - [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this), - [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this), - }; - await this.peerManager.initializePeers(); - await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators); + await this.reqresp.start(requestResponseHandlers); await this.node.start(); @@ -669,12 +659,8 @@ export class LibP2PService extends WithTracer implements P2PService { this.logger.info('LibP2P service stopped'); } - addReqRespSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { - return this.reqresp.addSubProtocol(subProtocol, handler, validator); + addReqRespSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise { + return this.reqresp.addSubProtocol(subProtocol, handler); } public registerThisValidatorAddresses(address: EthAddress[]): void { @@ -702,20 +688,6 @@ export class LibP2PService extends WithTracer implements P2PService { setImmediate(() => void safeJob()); } - /** - * Send a batch of requests to peers, and return the responses - * @param protocol - The request response protocol to use - * @param requests - The requests to send to the peers - * @returns The responses to the requests - */ - sendBatchRequest( - protocol: SubProtocol, - requests: InstanceType[], - pinnedPeerId: PeerId | undefined, - ): Promise[]> { - return this.reqresp.sendBatchRequest(protocol, requests, pinnedPeerId); - } - public sendRequestToPeer( peerId: PeerId, subProtocol: ReqRespSubProtocol, @@ -1535,22 +1507,21 @@ export class LibP2PService extends WithTracer implements P2PService { } /** - * Validate the requested block transactions. Allow partial returns. + * Validate the requested block transactions request-response consistency. + * It does NOT validate the transactions themselves. * @param request - The block transactions request. * @param response - The block transactions response. * @param peerId - The ID of the peer that made the request. - * @returns True if the requested block transactions are valid, false otherwise. + * @returns True if the request-response is consistent, false otherwise. */ - @trackSpan('Libp2pService.validateRequestedBlockTxs', request => ({ + @trackSpan('Libp2pService.validateRequestedBlockTxsConsistency', request => ({ [Attributes.BLOCK_ARCHIVE]: request.archiveRoot.toString(), })) - protected async validateRequestedBlockTxs( + protected async validateRequestedBlockTxsConsistency( request: BlockTxsRequest, response: BlockTxsResponse, peerId: PeerId, ): Promise { - const requestedTxValidator = this.createRequestedTxValidator(); - try { if (!response.archiveRoot.equals(request.archiveRoot)) { this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError); @@ -1610,7 +1581,6 @@ export class LibP2PService extends WithTracer implements P2PService { return false; } - await Promise.all(response.txs.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator))); return true; } catch (e: any) { if (e instanceof ValidationError) { @@ -1623,69 +1593,6 @@ export class LibP2PService extends WithTracer implements P2PService { } } - /** - * Validate a collection of txs that has been requested from a peer. - * - * The core component of this validator is that each tx hash MUST match the requested tx hash, - * In order to perform this check, the tx proof must be verified. - * - * Note: This function is called from within `ReqResp.sendRequest` as part of the - * ReqRespSubProtocol.TX subprotocol validation. - * - * @param requestedTxHash - The collection of the txs that was requested. - * @param responseTx - The collection of txs that was received as a response to the request. - * @param peerId - The peer ID of the peer that sent the tx. - * @returns True if the whole collection of txs is valid, false otherwise. - */ - @trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx) => ({ - [Attributes.TX_HASH]: requestedTxHash.toString(), - })) - private async validateRequestedTxs(requestedTxHash: TxHash[], responseTx: Tx[], peerId: PeerId): Promise { - const requested = new Set(requestedTxHash.map(h => h.toString())); - const requestedTxValidator = this.createRequestedTxValidator(); - - //TODO: (mralj) - this is somewhat naive implementation, if single tx is invalid we consider the whole response invalid. - // I think we should still extract the valid txs and return them, so that we can still use the response. - try { - await Promise.all(responseTx.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator, requested))); - return true; - } catch (e: any) { - if (e instanceof ValidationError) { - this.logger.warn(`Failed to validate requested txs from peer ${peerId.toString()}, reason ${e.message}`); - } else { - this.logger.error(`Error during validation of requested txs`, e); - } - - return false; - } - } - - protected async validateRequestedTx( - tx: Tx, - peerId: PeerId, - txValidator: TxValidator, - requested?: Set<`0x${string}`>, - ) { - const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity); - if (requested && !requested.has(tx.getTxHash().toString())) { - penalize(PeerErrorSeverity.MidToleranceError); - throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`); - } - - const { result } = await txValidator.validateTx(tx); - if (result === 'invalid') { - penalize(PeerErrorSeverity.LowToleranceError); - throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`); - } - } - - protected createRequestedTxValidator(): TxValidator { - return createTxValidatorForOnDemandReceivedTxs(this.proofVerifier, { - l1ChainId: this.config.l1ChainId, - rollupVersion: this.config.rollupVersion, - }); - } - private getGasFees(): Promise { return this.blockMinFeesProvider.getCurrentMinFees(); } @@ -1703,6 +1610,7 @@ export class LibP2PService extends WithTracer implements P2PService { proofVerifier: this.proofVerifier, }, peerScoring: this.peerManager, + validateRequestedBlockTxsConsistency: this.validateRequestedBlockTxsConsistency.bind(this), }; } diff --git a/yarn-project/p2p/src/services/reqresp/README.md b/yarn-project/p2p/src/services/reqresp/README.md index 982e00a28e74..fcd67f06899b 100644 --- a/yarn-project/p2p/src/services/reqresp/README.md +++ b/yarn-project/p2p/src/services/reqresp/README.md @@ -46,7 +46,6 @@ Per-protocol size limits checked via preamble before decompression. | Error Type | Severity | |------------|----------| | GOODBYE subprotocol errors | None | -| `CollectiveReqRespTimeoutError` / `InvalidResponseError` | None | | `AbortError` / connection close / muxer closed | None | | `ECONNRESET` / `EPIPE` / `ECONNREFUSED` / `ERR_UNEXPECTED_EOF` | HighToleranceError | | `ERR_UNSUPPORTED_PROTOCOL` | HighToleranceError | @@ -183,19 +182,6 @@ Protected peers (private/trusted/preferred) are always considered "authenticated Conditional registration: BLOCK_TXS handler only registered when `config.disableTransactions` is false. Otherwise peers get `ERR_UNSUPPORTED_PROTOCOL`. -**Requester side via `sendBatchRequest`** (Snappy limit: `max(N, 1) * 512 + 1` KB): - -| Rule | Consequence | File | -|------|-------------|------| -| Archive root must match request | MidToleranceError | `libp2p_service.ts` (`validateRequestedBlockTxs`) | -| BitVector length must match request | MidToleranceError | same | -| No duplicate tx hashes | MidToleranceError | same | -| Tx count within bounds | MidToleranceError | same | -| Local block proposal must exist for archive root | Rejected (no penalty) | same | -| All tx hashes must be in proposal's tx list at allowed indices | LowToleranceError | same | -| Txs in strictly increasing index order | LowToleranceError | same | -| Each tx passes well-formedness (Metadata [4 fields], Size, Data, Proof) | LowToleranceError | same | - **Requester side via `BatchTxRequester`** (separate validation path): | Rule | Consequence | File | diff --git a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.test.ts b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.test.ts index a26e1d79c872..dfbf178e6e78 100644 --- a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.test.ts +++ b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.test.ts @@ -10,7 +10,7 @@ import { sleep } from '@aztec/foundation/sleep'; import { DateProvider } from '@aztec/foundation/timer'; import { type BlockProposal, PeerErrorSeverity } from '@aztec/stdlib/p2p'; import { makeBlockHeader, makeBlockProposal } from '@aztec/stdlib/testing'; -import { Tx, TxArray, TxHash, type TxValidationResult } from '@aztec/stdlib/tx'; +import { Tx, TxArray, TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx'; import { describe, expect, it, jest } from '@jest/globals'; import type { PeerId } from '@libp2p/interface'; @@ -26,16 +26,12 @@ import { BatchTxRequester } from './batch_tx_requester.js'; import { DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD, DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE } from './config.js'; import type { BatchTxRequesterLibP2PService, IPeerPenalizer } from './interface.js'; import { type IPeerCollection, PeerCollection, RATE_LIMIT_EXCEEDED_PEER_CACHE_TTL } from './peer_collection.js'; -import type { IBatchRequestTxValidator } from './tx_validator.js'; /** Mock tx validator for testing that always returns valid */ -class AlwaysValidTxValidator implements IBatchRequestTxValidator { - validateRequestedTx(_tx: Tx): Promise { +class AlwaysValidTxValidator implements TxValidator { + validateTx(_tx: Tx): Promise { return Promise.resolve({ result: 'valid' }); } - validateRequestedTxs(txs: Tx[]): Promise { - return Promise.resolve(txs.map(() => ({ result: 'valid' }))); - } } const TEST_TIMEOUT = 15_000; @@ -49,7 +45,7 @@ describe('BatchTxRequester', () => { let connectionSampler: MockProxy; let reqResp: MockProxy; let mockP2PService: MockProxy; - let txValidator: IBatchRequestTxValidator; + let txValidator: TxValidator; beforeEach(async () => { logger = createLogger('test'); @@ -61,6 +57,7 @@ describe('BatchTxRequester', () => { reqResp, peerScoring, }); + mockP2PService.validateRequestedBlockTxsConsistency.mockResolvedValue(true); txValidator = new AlwaysValidTxValidator(); const signer = Secp256k1Signer.random(); @@ -1190,13 +1187,12 @@ describe('BatchTxRequester', () => { const invalidTxIndices = new Set([2, 3, 7]); // Mark transactions at indices 2, 3, and 7 as invalid - const customValidator: IBatchRequestTxValidator = { - validateRequestedTx: (tx: Tx) => { + const customValidator: TxValidator = { + validateTx: (tx: Tx) => { const txIndex = missing.findIndex(h => h.equals(tx.txHash)); const isInvalid = invalidTxIndices.has(txIndex); return Promise.resolve(isInvalid ? { result: 'invalid', reason: ['test invalid'] } : { result: 'valid' }); }, - validateRequestedTxs: (txs: Tx[]) => Promise.all(txs.map(tx => customValidator.validateRequestedTx(tx))), }; const { mockImplementation } = createRequestLogger(blockProposal, new Set(), peerTransactions); @@ -1270,13 +1266,12 @@ describe('BatchTxRequester', () => { // Validator that rejects transactions at specific indices // Even indices are rejected, odd indices are accepted const invalidTxIndices = new Set([0, 2, 4, 6, 8, 10]); - const mixedValidator: IBatchRequestTxValidator = { - validateRequestedTx: (tx: Tx) => { + const mixedValidator: TxValidator = { + validateTx: (tx: Tx) => { const txIndex = missing.findIndex(h => h.equals(tx.txHash)); const isInvalid = invalidTxIndices.has(txIndex); return Promise.resolve(isInvalid ? { result: 'invalid', reason: ['test invalid'] } : { result: 'valid' }); }, - validateRequestedTxs: (txs: Tx[]) => Promise.all(txs.map(tx => mixedValidator.validateRequestedTx(tx))), }; const { mockImplementation } = createRequestLogger(blockProposal, new Set(), peerTransactions); @@ -1328,8 +1323,8 @@ describe('BatchTxRequester', () => { connectionSampler.getPeerListSortedByConnectionCountAsc.mockReturnValue([peer]); // Validator that throws errors for specific transactions - const throwingValidator: IBatchRequestTxValidator = { - validateRequestedTx: (tx: Tx) => { + const throwingValidator: TxValidator = { + validateTx: (tx: Tx) => { const txIndex = missing.findIndex(h => h.equals(tx.txHash)); // Throw error for transactions at indices 1 and 3 @@ -1344,7 +1339,6 @@ describe('BatchTxRequester', () => { return Promise.resolve({ result: 'valid' }); }, - validateRequestedTxs: (txs: Tx[]) => Promise.all(txs.map(tx => throwingValidator.validateRequestedTx(tx))), }; const peerTransactions = new Map([[peer.toString(), Array.from({ length: txCount }, (_, i) => i)]]); @@ -1697,13 +1691,12 @@ describe('BatchTxRequester', () => { const invalidTxIndices = new Set([1, 6]); // Mark some transactions as invalid - const customValidator: IBatchRequestTxValidator = { - validateRequestedTx: (tx: Tx) => { + const customValidator: TxValidator = { + validateTx: (tx: Tx) => { const txIndex = missing.findIndex(h => h.equals(tx.txHash)); const isInvalid = invalidTxIndices.has(txIndex); return Promise.resolve(isInvalid ? { result: 'invalid', reason: ['test invalid'] } : { result: 'valid' }); }, - validateRequestedTxs: (txs: Tx[]) => Promise.all(txs.map(tx => customValidator.validateRequestedTx(tx))), }; const { mockImplementation } = createRequestLogger(blockProposal, new Set(), peerTransactions); @@ -2019,6 +2012,82 @@ describe('BatchTxRequester', () => { expect(peer0Penalties.length).toBeGreaterThan(0); }); }); + + describe('Response consistency validation', () => { + it('marks peer dumb (without penalising) when validateRequestedBlockTxsConsistency rejects the response', async () => { + const txCount = TX_BATCH_SIZE; + const deadline = 5_000; + const missing = Array.from({ length: txCount }, () => TxHash.random()); + + blockProposal = await makeBlockProposal({ + signer: Secp256k1Signer.random(), + blockHeader: makeBlockHeader(1, { blockNumber: BlockNumber(1) }), + archiveRoot: Fr.random(), + txHashes: missing, + }); + + const peers = await Promise.all([createSecp256k1PeerId(), createSecp256k1PeerId()]); + connectionSampler.getPeerListSortedByConnectionCountAsc.mockReturnValue(peers); + + const peerCollection = new TestPeerCollection( + new PeerCollection(connectionSampler, undefined, new DateProvider()), + ); + + // peer0's responses are rejected by consistency validation; peer1's responses pass. + const consistencyCallPeerIds: string[] = []; + mockP2PService.validateRequestedBlockTxsConsistency.mockImplementation((_req, _resp, peerId) => { + consistencyCallPeerIds.push(peerId.toString()); + return Promise.resolve(peerId.toString() !== peers[0].toString()); + }); + + // Both peers return well-formed responses with the requested txs; + // the consistency mock is what decides whether the response is accepted. + reqResp.sendRequestToPeer.mockImplementation((_peerId: any, _sub: any, data: any) => { + const request = BlockTxsRequest.fromBuffer(data); + const requestedIndices = request.txIndices.getTrueIndices(); + const availableTxs = requestedIndices.map(idx => makeTx(blockProposal.txHashes[idx])); + + return Promise.resolve({ + status: ReqRespStatus.SUCCESS, + data: new BlockTxsResponse( + blockProposal.archive, + new TxArray(...availableTxs), + BitVector.init(txCount, requestedIndices), + ).toBuffer(), + }); + }); + + const requester = new BatchTxRequester( + RequestTracker.create(missing, new Date(Date.now() + deadline)), + blockProposal, + undefined, + mockP2PService, + logger, + new DateProvider(), + { + smartParallelWorkerCount: 0, + dumbParallelWorkerCount: 2, + peerCollection, + txValidator, + }, + ); + + const results = await BatchTxRequester.collectAllTxs(requester.run()); + + // All txs eventually fetched (via peer1). + expect(results).toHaveLength(txCount); + + // Consistency validation was invoked for peer0's response. + expect(consistencyCallPeerIds).toContain(peers[0].toString()); + + // peer0 marked dumb (INTERNAL_ERROR path in handleFailResponseFromPeer)… + expect(peerCollection.peersMarkedDumb).toContain(peers[0].toString()); + + // …but NOT penalised — failed consistency yields INTERNAL_ERROR, not a penalty cause. + const peer0Penalties = peerCollection.peersPenalised.filter(e => e.peerId === peers[0].toString()); + expect(peer0Penalties).toHaveLength(0); + }); + }); }); describe('PeerCollection - Dynamic peer list', () => { diff --git a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts index 77c7f99e2c81..0da0d14b58db 100644 --- a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +++ b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts @@ -4,7 +4,7 @@ import { FifoMemoryQueue, type ISemaphore, Semaphore } from '@aztec/foundation/q import { sleep } from '@aztec/foundation/sleep'; import { DateProvider } from '@aztec/foundation/timer'; import { PeerErrorSeverity } from '@aztec/stdlib/p2p'; -import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx'; +import { Tx, TxArray, TxHash, type TxValidator } from '@aztec/stdlib/tx'; import type { PeerId } from '@libp2p/interface'; @@ -21,7 +21,7 @@ import { import type { BatchTxRequesterLibP2PService, BatchTxRequesterOptions, ITxMetadataCollection } from './interface.js'; import { MissingTxMetadataCollection } from './missing_txs.js'; import { type IPeerCollection, PeerCollection } from './peer_collection.js'; -import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_validator.js'; +import { createBatchRequestTxValidator } from './tx_validator.js'; /* * Tries to fetch all missing transaction until deadline is hit. @@ -51,7 +51,7 @@ export class BatchTxRequester { private readonly txsMetadata: ITxMetadataCollection; private readonly smartRequesterSemaphore: ISemaphore; private readonly txQueue: FifoMemoryQueue; - private readonly txValidator: IBatchRequestTxValidator; + private readonly txValidator: TxValidator; private readonly smartParallelWorkerCount: number; private readonly dumbParallelWorkerCount: number; private readonly txBatchSize: number; @@ -78,7 +78,7 @@ export class BatchTxRequester { this.opts.dumbParallelWorkerCount ?? DEFAULT_BATCH_TX_REQUESTER_DUMB_PARALLEL_WORKER_COUNT; this.txBatchSize = this.opts.txBatchSize ?? DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE; this.txQueue = new FifoMemoryQueue(this.logger); - this.txValidator = this.opts.txValidator ?? new BatchRequestTxValidator(this.p2pService.txValidatorConfig); + this.txValidator = this.opts.txValidator ?? createBatchRequestTxValidator(this.p2pService.txValidatorConfig); if (this.opts.peerCollection) { this.peers = this.opts.peerCollection; @@ -428,6 +428,15 @@ export class BatchTxRequester { } const blockResponse = BlockTxsResponse.fromBuffer(response.data); + + // Validate response. Peers will be penalised by the validator if they send invalid response. + const isValid = await this.p2pService.validateRequestedBlockTxsConsistency(request, blockResponse, peerId); + if (!isValid) { + this.logger.debug(`Peer ${peerId.toString()} sent invalid response`); + this.handleFailResponseFromPeer(peerId, ReqRespStatus.INTERNAL_ERROR); + return; + } + await this.handleSuccessResponseFromPeer(peerId, blockResponse); } catch (err: any) { this.logger.error(`Failed to get valid response from peer ${peerId.toString()}: ${err.message}`, { @@ -445,6 +454,7 @@ export class BatchTxRequester { * Handles failed response form the peer * There are 3 scenarios * - RATE_LIMIT_EXCEEDED: We mark this and don't query this peer again for some_time + * - INTERNAL_ERROR: We use this to cover cases where the request-response consistency validation fails. * - FAILURE and UNKNOWN: We penalise this, if peer has been penalised this way N times they are not queried again * this implies we will query these peers couple of more times and give them a chance to "redeem" themselves before completely ignoring them */ @@ -458,7 +468,8 @@ export class BatchTxRequester { // NOT_FOUND means the peer pruned its block proposal — it can no longer serve // index-based requests, but this is a legitimate state so we don't penalize. - if (responseStatus === ReqRespStatus.NOT_FOUND) { + // We use INTERNAL_ERROR to cover cases where the request-response consistency validation fails. + if (responseStatus === ReqRespStatus.NOT_FOUND || responseStatus === ReqRespStatus.INTERNAL_ERROR) { this.peers.markPeerDumb(peerId); this.txsMetadata.clearPeerData(peerId); return; @@ -485,7 +496,7 @@ export class BatchTxRequester { * Handles received txs. * Transactions are validated and then put on async queue * to be yielded by main running loop - * */ + */ private async handleReceivedTxs(peerId: PeerId, txs: TxArray) { const newTxs = txs.filter(tx => !this.txsMetadata.alreadyFetched(tx.txHash)); @@ -493,12 +504,12 @@ export class BatchTxRequester { return; } - //TODO: this validation can be slow, maybe spawn worker just for validation + // TODO: this validation can be slow, maybe spawn worker just for validation // We could use the async queue for communication. const validationResults = await Promise.allSettled( newTxs.map(async tx => ({ tx, - isValid: (await this.txValidator.validateRequestedTx(tx)).result === 'valid', + isValid: (await this.txValidator.validateTx(tx)).result === 'valid', })), ); diff --git a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/interface.ts b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/interface.ts index f7b503c9dae9..13304adf7cd4 100644 --- a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/interface.ts +++ b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/interface.ts @@ -1,13 +1,14 @@ import type { ISemaphore } from '@aztec/foundation/queue'; import type { PeerErrorSeverity } from '@aztec/stdlib/p2p'; -import type { Tx, TxHash } from '@aztec/stdlib/tx'; +import type { Tx, TxHash, TxValidator } from '@aztec/stdlib/tx'; import type { PeerId } from '@libp2p/interface'; import type { ConnectionSampler } from '../connection-sampler/connection_sampler.js'; +import type { BlockTxsRequest, BlockTxsResponse } from '../index.js'; import type { ReqRespInterface } from '../interface.js'; import type { IPeerCollection } from './peer_collection.js'; -import type { BatchRequestTxValidatorConfig, IBatchRequestTxValidator } from './tx_validator.js'; +import type { BatchRequestTxValidatorConfig } from './tx_validator.js'; export interface IPeerPenalizer { penalizePeer(peerId: PeerId, penalty: PeerErrorSeverity): void; @@ -39,6 +40,12 @@ export interface BatchTxRequesterLibP2PService { txValidatorConfig: BatchRequestTxValidatorConfig; /** Peer scoring for penalizing peers */ peerScoring: IPeerPenalizer; + /** Validate the requested block transactions request-response consistency */ + validateRequestedBlockTxsConsistency: ( + request: BlockTxsRequest, + response: BlockTxsResponse, + peerId: PeerId, + ) => Promise; } export interface BatchTxRequesterOptions { @@ -50,5 +57,5 @@ export interface BatchTxRequesterOptions { semaphore?: ISemaphore; peerCollection?: IPeerCollection; /** Optional tx validator for testing - if not provided, one is created from p2pService.txValidatorConfig */ - txValidator?: IBatchRequestTxValidator; + txValidator?: TxValidator; } diff --git a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/tx_validator.ts b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/tx_validator.ts index db15fda34e01..dd8015a76a8a 100644 --- a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/tx_validator.ts +++ b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/tx_validator.ts @@ -1,5 +1,5 @@ import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server'; -import { Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx'; +import type { TxValidator } from '@aztec/stdlib/tx'; import { createTxValidatorForOnDemandReceivedTxs } from '../../../msg_validators/index.js'; @@ -9,29 +9,9 @@ export interface BatchRequestTxValidatorConfig { proofVerifier: ClientProtocolCircuitVerifier; } -export interface IBatchRequestTxValidator { - validateRequestedTx(tx: Tx): Promise; - validateRequestedTxs(txs: Tx[]): Promise; -} - -export class BatchRequestTxValidator implements IBatchRequestTxValidator { - readonly txValidator: TxValidator; - constructor(private readonly config: BatchRequestTxValidatorConfig) { - this.txValidator = BatchRequestTxValidator.createRequestedTxValidator(this.config); - } - - public async validateRequestedTx(tx: Tx): Promise { - return await this.txValidator.validateTx(tx); - } - - public async validateRequestedTxs(txs: Tx[]): Promise { - return await Promise.all(txs.map(tx => this.validateRequestedTx(tx))); - } - - static createRequestedTxValidator(config: BatchRequestTxValidatorConfig): TxValidator { - return createTxValidatorForOnDemandReceivedTxs(config.proofVerifier, { - l1ChainId: config.l1ChainId, - rollupVersion: config.rollupVersion, - }); - } +export function createBatchRequestTxValidator(config: BatchRequestTxValidatorConfig): TxValidator { + return createTxValidatorForOnDemandReceivedTxs(config.proofVerifier, { + l1ChainId: config.l1ChainId, + rollupVersion: config.rollupVersion, + }); } diff --git a/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.test.ts b/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.test.ts deleted file mode 100644 index 9432ac297e22..000000000000 --- a/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.test.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { describe, expect, it, jest } from '@jest/globals'; -import { createSecp256k1PeerId } from '@libp2p/peer-id-factory'; -import type { Libp2p } from 'libp2p'; - -import { BatchConnectionSampler } from './batch_connection_sampler.js'; -import { ConnectionSampler, type RandomSampler } from './connection_sampler.js'; - -describe('BatchConnectionSampler', () => { - const mockRandomSampler = { - random: jest.fn(), - } as jest.Mocked; - - let peers: Awaited>[]; - let libp2p: jest.Mocked; - let connectionSampler: ConnectionSampler; - - beforeEach(async () => { - jest.clearAllMocks(); - - // Create a set of test peers - peers = await Promise.all(new Array(5).fill(0).map(() => createSecp256k1PeerId())); - - // Mock libp2p to return our test peers - libp2p = { - getPeers: jest.fn().mockImplementation(() => [...peers]), - } as unknown as jest.Mocked; - - // Create a real connection sampler with mocked random sampling - connectionSampler = new ConnectionSampler(libp2p, mockRandomSampler, undefined, { cleanupIntervalMs: 1000 }); - }); - - afterEach(async () => { - await connectionSampler.stop(); - }); - - it('initializes with correct number of peers and request distribution', () => { - // Mock random to return sequential indices - mockRandomSampler.random.mockImplementation(_ => 0); - - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 10, /* maxPeers */ 3); - - expect(sampler.activePeerCount).toBe(3); - expect(sampler.requestsPerBucket).toBe(3); // floor(10/3) = 3 - }); - - it('assigns requests to peers deterministically with wraparound', () => { - // Mock to return first two peers - mockRandomSampler.random.mockImplementation(() => 0); - - // With 5 requests and 2 peers: - // floor(5/2) = 2 requests per peer - // Peer 0: 0,1,4 (gets extra from wraparound) - // Peer 1: 2,3 - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 5, /* maxPeers */ 2); - const assignments = new Array(5).fill(0).map((_, i) => sampler.getPeerForRequest(i)); - - // First peer gets first bucket and wraparound - expect(assignments[0]).toBe(peers[0]); // First bucket - expect(assignments[1]).toBe(peers[0]); // First bucket - expect(assignments[4]).toBe(peers[0]); // Wraparound - - // Second peer gets middle bucket - expect(assignments[2]).toBe(peers[1]); - expect(assignments[3]).toBe(peers[1]); - }); - - it('handles peer removal and replacement', () => { - mockRandomSampler.random.mockImplementation(_ => 0); - - // With 4 requests and 2 peers: - // floor(4/2) = 2 requests per peer - // Initial distribution: - // Peer 0: 0,1 - // Peer 1: 2,3 - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - - const initialPeer = sampler.getPeerForRequest(0); - expect(initialPeer).toBe(peers[0]); - - // Mock random to return the third peer - mockRandomSampler.random.mockImplementation(_ => 2); - sampler.removePeerAndReplace(peers[0]); - - // After replacement: - // Replacement peer should handle the same bucket - const newPeer = sampler.getPeerForRequest(0); - expect(newPeer).toBe(peers[2]); - expect(sampler.getPeerForRequest(1)).toBe(peers[2]); - - // Other peer's bucket remains unchanged - expect(sampler.getPeerForRequest(2)).toBe(peers[1]); - expect(sampler.getPeerForRequest(3)).toBe(peers[1]); - }); - - it('handles peer removal and replacement - no replacement available', () => { - mockRandomSampler.random.mockImplementation(() => 0); - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - - expect(sampler.activePeerCount).toBe(2); - expect(sampler.getPeerForRequest(0)).toBe(peers[0]); - - // Will sample no peers - libp2p.getPeers.mockReturnValue([]); - - // Remove peer 0, its requests will be distributed to peer 1 - sampler.removePeerAndReplace(peers[0]); - // Decrease the number of active peers - expect(sampler.activePeerCount).toBe(1); - - expect(sampler.getPeerForRequest(0)).toBe(peers[1]); - }); - - it('distributes requests according to documentation example', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // Example from doc comment: - // Peers: [P1] [P2] [P3] - // Requests: 0,1,2,9 | 3,4,5 | 6,7,8 - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 10, /* maxPeers */ 3); - - expect(sampler.activePeerCount).toBe(3); - expect(sampler.requestsPerBucket).toBe(3); // floor(10/3) = 3 - - // P1's bucket (0-2) plus wraparound (9) - expect(sampler.getPeerForRequest(0)).toBe(peers[0]); - expect(sampler.getPeerForRequest(1)).toBe(peers[0]); - expect(sampler.getPeerForRequest(2)).toBe(peers[0]); - expect(sampler.getPeerForRequest(9)).toBe(peers[0]); // Wraparound - - // P2's bucket (3-5) - expect(sampler.getPeerForRequest(3)).toBe(peers[1]); - expect(sampler.getPeerForRequest(4)).toBe(peers[1]); - expect(sampler.getPeerForRequest(5)).toBe(peers[1]); - - // P3's bucket (6-8) - expect(sampler.getPeerForRequest(6)).toBe(peers[2]); - expect(sampler.getPeerForRequest(7)).toBe(peers[2]); - expect(sampler.getPeerForRequest(8)).toBe(peers[2]); - }); - - it('same number of requests per peers', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 2, /* maxPeers */ 2); - expect(sampler.requestsPerBucket).toBe(1); - expect(sampler.activePeerCount).toBe(2); - - expect(sampler.getPeerForRequest(0)).toBe(peers[0]); - expect(sampler.getPeerForRequest(1)).toBe(peers[1]); - }); - - it('handles edge cases, 0 peers, smaller batch than max peers', () => { - mockRandomSampler.random.mockImplementation(() => 0); - libp2p.getPeers.mockReturnValue([]); - - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 5, /* maxPeers */ 2); - expect(sampler.activePeerCount).toBe(0); - expect(sampler.getPeerForRequest(0)).toBeUndefined(); - - mockRandomSampler.random.mockImplementation(() => 0); - - libp2p.getPeers.mockImplementation(() => [...peers]); - const samplerWithMorePeers = new BatchConnectionSampler(connectionSampler, /* batchSize */ 2, /* maxPeers */ 3); - expect(samplerWithMorePeers.requestsPerBucket).toBe(1); // floor(2/3) = 0 - // First two requests go to first two peers - expect(samplerWithMorePeers.getPeerForRequest(0)).toBe(peers[0]); - expect(samplerWithMorePeers.getPeerForRequest(1)).toBe(peers[1]); - }); - - it('skips failed peer-index combinations and tries next peer', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // 6 requests across 3 peers (2 per peer) - // Peer 0: 0,1 Peer 1: 2,3 Peer 2: 4,5 - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 6, /* maxPeers */ 3); - - // Initially, request 0 goes to peer 0 - expect(sampler.getPeerForRequest(0)).toBe(peers[0]); - - // Mark peer 0 as failed for index 0 - sampler.markPeerFailedForIndex(peers[0], 0); - - // Now request 0 should go to the next peer (peer 1) - expect(sampler.getPeerForRequest(0)).toBe(peers[1]); - - // Mark peer 1 as also failed for index 0 - sampler.markPeerFailedForIndex(peers[1], 0); - - // Now request 0 should go to peer 2 - expect(sampler.getPeerForRequest(0)).toBe(peers[2]); - - // Request 1 should still go to peer 0 (only index 0 was failed) - expect(sampler.getPeerForRequest(1)).toBe(peers[0]); - }); - - it('samples new peer when all batch peers have failed for an index', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // 4 requests across 2 peers (peers[0] and peers[1]) - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - expect(sampler.activePeerCount).toBe(2); - - // Mark both batch peers as failed for index 0 - sampler.markPeerFailedForIndex(peers[0], 0); - sampler.markPeerFailedForIndex(peers[1], 0); - - // Should sample a new peer (peers[2]) and return it - mockRandomSampler.random.mockImplementation(() => 2); - expect(sampler.getPeerForRequest(0)).toBe(peers[2]); - expect(sampler.activePeerCount).toBe(3); // New peer was added to batch - - // Other indices still work with original peers - expect(sampler.getPeerForRequest(1)).toBe(peers[0]); - expect(sampler.getPeerForRequest(2)).toBe(peers[1]); - }); - - it('returns undefined when all peers exhausted and no new peers available', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // 4 requests across 2 peers - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - - // Mark both peers as failed for index 0 - sampler.markPeerFailedForIndex(peers[0], 0); - sampler.markPeerFailedForIndex(peers[1], 0); - - // No more peers available to sample - libp2p.getPeers.mockReturnValue([peers[0], peers[1]]); // Only return already-used peers - - // No peer available for index 0 - expect(sampler.getPeerForRequest(0)).toBeUndefined(); - }); - - it('failed peer-index tracking survives peer replacement', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // 4 requests across 2 peers - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - - // Mark peer 0 as failed for index 0 - sampler.markPeerFailedForIndex(peers[0], 0); - - // Request 0 now goes to peer 1 - expect(sampler.getPeerForRequest(0)).toBe(peers[1]); - - // Replace peer 0 with peer 2 - mockRandomSampler.random.mockImplementation(() => 2); - sampler.removePeerAndReplace(peers[0]); - - // Request 0 should still go to peer 1 (the replacement peer 2 is now in slot 0, - // but peer 0's failure record should not affect the new peer) - // Actually, the failure is tracked by peer ID, so peer 2 is a fresh peer - // Request 0's primary is now peer 2 (in slot 0), which hasn't failed - expect(sampler.getPeerForRequest(0)).toBe(peers[2]); - }); -}); diff --git a/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.ts b/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.ts deleted file mode 100644 index 42424551e696..000000000000 --- a/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { createLogger } from '@aztec/foundation/log'; - -import type { PeerId } from '@libp2p/interface'; - -import type { ConnectionSampler } from './connection_sampler.js'; - -/** - * Manages batches of peers for parallel request processing. - * Tracks active peers and provides deterministic peer assignment for requests. - * - * Example with 3 peers and 10 requests: - * - * Peers: [P1] [P2] [P3] - * ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ - * Requests: 0,1,2,9 | 3,4,5 | 6,7,8 - * - * Each peer handles a bucket of consecutive requests. - * If a peer fails, it is replaced while maintaining the same bucket. - */ -export class BatchConnectionSampler { - private readonly batch: PeerId[] = []; - private readonly requestsPerPeer: number; - /** Tracks peer-index combinations that returned empty/invalid responses */ - private readonly failedPeerIndices: Map> = new Map(); - - constructor( - private readonly connectionSampler: ConnectionSampler, - batchSize: number, - maxPeers: number, - exclude?: PeerId[], - private readonly logger = createLogger('p2p:reqresp:batch-connection-sampler'), - ) { - if (maxPeers <= 0) { - throw new Error('Max peers cannot be 0'); - } - if (batchSize <= 0) { - throw new Error('Batch size cannot be 0'); - } - - // Calculate how many requests each peer should handle, cannot be 0 - this.requestsPerPeer = Math.max(1, Math.floor(batchSize / maxPeers)); - - // Sample initial peers - const excluding = exclude && new Map(exclude.map(peerId => [peerId.toString(), true] as const)); - this.batch = this.connectionSampler.samplePeersBatch(maxPeers, excluding); - } - - /** - * Gets the peer responsible for handling a specific request index. - * If the primary peer has previously failed for this index, tries other peers. - * If all batch peers have failed, attempts to sample a new peer. - * - * @param index - The request index - * @returns The peer assigned to handle this request, or undefined if no peer available - */ - getPeerForRequest(index: number): PeerId | undefined { - if (this.batch.length === 0) { - return undefined; - } - - // Calculate which peer bucket this index belongs to - const primaryPeerIndex = Math.floor(index / this.requestsPerPeer) % this.batch.length; - - // Try peers starting from primary, wrapping around - for (let offset = 0; offset < this.batch.length; offset++) { - const peerIndex = (primaryPeerIndex + offset) % this.batch.length; - const peer = this.batch[peerIndex]; - const peerKey = peer.toString(); - - const failedIndices = this.failedPeerIndices.get(peerKey); - if (!failedIndices || !failedIndices.has(index)) { - return peer; - } - } - - // All batch peers have failed for this index - try to sample a new peer - const newPeer = this.sampleNewPeer(); - if (newPeer) { - return newPeer; - } - - return undefined; - } - - /** - * Attempts to sample a new peer that isn't already in the batch. - * If successful, adds the peer to the batch. - * - * @returns The new peer if one was sampled, undefined otherwise - */ - private sampleNewPeer(): PeerId | undefined { - // Exclude all current batch peers - const excluding = new Map(this.batch.map(p => [p.toString(), true] as const)); - const newPeer = this.connectionSampler.getPeer(excluding); - - if (newPeer) { - this.batch.push(newPeer); - this.logger.trace('Sampled new peer for exhausted index', { newPeer: newPeer.toString() }); - return newPeer; - } - - return undefined; - } - - /** - * Marks that a peer returned an empty/invalid response for a specific request index. - * The peer will not be assigned this index again. - * - * @param peerId - The peer that failed - * @param index - The request index that failed - */ - markPeerFailedForIndex(peerId: PeerId, index: number): void { - const peerKey = peerId.toString(); - let failedIndices = this.failedPeerIndices.get(peerKey); - if (!failedIndices) { - failedIndices = new Set(); - this.failedPeerIndices.set(peerKey, failedIndices); - } - failedIndices.add(index); - this.logger.trace('Marked peer failed for index', { peerId: peerKey, index }); - } - - /** - * Removes a peer and replaces it with a new one, maintaining the same position - * in the batch array to keep request distribution consistent - * - * @param peerId - The peer to remove and replace - */ - removePeerAndReplace(peerId: PeerId): void { - const index = this.batch.findIndex(p => p === peerId); - if (index === -1) { - return; - } - - const excluding = new Map([[peerId.toString(), true]]); - const newPeer = this.connectionSampler.getPeer(excluding); // Q: Shouldn't we accumulate all excluded peers? Otherwise the sampler could return us a previously excluded peer? - - if (newPeer) { - this.batch[index] = newPeer; - this.logger.trace('Replaced peer', { peerId, newPeer }); - } else { - // If we couldn't get a replacement, remove the peer and compact the array - this.batch.splice(index, 1); - this.logger.trace('Removed peer', { peerId }); - } - } - - /** - * Gets the number of active peers - */ - get activePeerCount(): number { - return this.batch.length; - } - - /** - * Gets the number of requests each peer is assigned to handle - */ - get requestsPerBucket(): number { - return this.requestsPerPeer; - } -} diff --git a/yarn-project/p2p/src/services/reqresp/interface.ts b/yarn-project/p2p/src/services/reqresp/interface.ts index 016525a98919..bcdc58e37a43 100644 --- a/yarn-project/p2p/src/services/reqresp/interface.ts +++ b/yarn-project/p2p/src/services/reqresp/interface.ts @@ -78,23 +78,11 @@ export interface ProtocolRateLimitQuota { globalLimit: RateLimitQuota; } -export const noopValidator = () => Promise.resolve(true); - /** * A type mapping from supprotocol to it's handling function */ export type ReqRespSubProtocolHandlers = Record; -type ResponseValidator = ( - request: RequestIdentifier, - response: Response, - peerId: PeerId, -) => Promise; - -export type ReqRespSubProtocolValidators = { - [S in ReqRespSubProtocol]: ResponseValidator; -}; - /** * Protocols that are always allowed without authentication, even when p2pAllowOnlyValidators is enabled. * These are needed for the handshake and connection management flow. @@ -113,15 +101,6 @@ export const UNAUTHENTICATED_ALLOWED_PROTOCOLS: ReadonlySet */ export type ShouldRejectPeer = (peerId: string) => boolean; -export const DEFAULT_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = { - [ReqRespSubProtocol.PING]: noopValidator, - [ReqRespSubProtocol.STATUS]: noopValidator, - [ReqRespSubProtocol.TX]: noopValidator, - [ReqRespSubProtocol.GOODBYE]: noopValidator, - [ReqRespSubProtocol.AUTH]: noopValidator, - [ReqRespSubProtocol.BLOCK_TXS]: noopValidator, -}; - /* * Helper class to sub-protocol validation error*/ export class ValidationError extends Error { @@ -244,24 +223,9 @@ export const subProtocolSizeCalculators: Record, - subProtocolValidators: ReqRespSubProtocolValidators, - ): Promise; - addSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise; + start(subProtocolHandlers: Partial): Promise; + addSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise; stop(): Promise; - sendBatchRequest( - subProtocol: SubProtocol, - requests: InstanceType[], - pinnedPeer: PeerId | undefined, - timeoutMs?: number, - maxPeers?: number, - maxRetryAttempts?: number, - ): Promise[]>; sendRequestToPeer( peerId: PeerId, subProtocol: ReqRespSubProtocol, diff --git a/yarn-project/p2p/src/services/reqresp/reqresp.test.ts b/yarn-project/p2p/src/services/reqresp/reqresp.test.ts index 2ddf4d9a2cbe..e72926f21c31 100644 --- a/yarn-project/p2p/src/services/reqresp/reqresp.test.ts +++ b/yarn-project/p2p/src/services/reqresp/reqresp.test.ts @@ -1,4 +1,3 @@ -import { times } from '@aztec/foundation/collection'; import { sleep } from '@aztec/foundation/sleep'; import { PeerErrorSeverity } from '@aztec/stdlib/p2p'; import { mockTx } from '@aztec/stdlib/testing'; @@ -18,7 +17,7 @@ import { } from '../../test-helpers/reqresp-nodes.js'; import type { PeerManager } from '../peer-manager/peer_manager.js'; import type { PeerScoring } from '../peer-manager/peer_scoring.js'; -import { type ReqRespResponse, ReqRespSubProtocol, RequestableBuffer } from './interface.js'; +import { type ReqRespResponse, ReqRespSubProtocol } from './interface.js'; import { GoodByeReason, reqGoodbyeHandler } from './protocols/goodbye.js'; import { ReqRespStatus } from './status.js'; @@ -465,133 +464,6 @@ describe('ReqResp', () => { expectSuccess(txResp); }); }); - - describe('Batch requests', () => { - it('should send a batch request between many peers', async () => { - const batchSize = 9; - nodes = await createNodes(peerScoring, 3); - - await startNodes(nodes); - await sleep(500); - await connectToPeers(nodes); - await sleep(500); - - const sendRequestToPeerSpy = jest.spyOn(nodes[0].req, 'sendRequestToPeer'); - - const requests = Array.from({ length: batchSize }, _ => RequestableBuffer.fromBuffer(Buffer.from(`ping`))); - const expectResponses = Array.from({ length: batchSize }, _ => RequestableBuffer.fromBuffer(Buffer.from(`pong`))); - - const res = await nodes[0].req.sendBatchRequest(ReqRespSubProtocol.PING, requests, undefined); - expect(res).toEqual(expectResponses); - - // Expect one request to have been sent to each peer - expect(sendRequestToPeerSpy).toHaveBeenCalledTimes(batchSize); - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ - publicKey: nodes[1].p2p.peerId.publicKey, - }), - ReqRespSubProtocol.PING, - Buffer.from('ping'), - ); - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ - publicKey: nodes[2].p2p.peerId.publicKey, - }), - ReqRespSubProtocol.PING, - Buffer.from('ping'), - ); - }); - - it('should send a batch request with a pinned peer', async () => { - const batchSize = 9; - nodes = await createNodes(peerScoring, 4, { - // Bump rate limits so the pinned peer can respond - [ReqRespSubProtocol.PING]: { - peerLimit: { quotaTimeMs: 1000, quotaCount: 50 }, - globalLimit: { quotaTimeMs: 1000, quotaCount: 50 }, - }, - }); - - await startNodes(nodes); - await sleep(500); - await connectToPeers(nodes); - await sleep(500); - - const sendRequestToPeerSpy = jest.spyOn(nodes[0].req, 'sendRequestToPeer'); - - const requests = times(batchSize, i => RequestableBuffer.fromBuffer(Buffer.from(`ping${i}`))); - const expectResponses = times(batchSize, _ => RequestableBuffer.fromBuffer(Buffer.from(`pong`))); - - const res = await nodes[0].req.sendBatchRequest(ReqRespSubProtocol.PING, requests, nodes[1].p2p.peerId); - expect(res).toEqual(expectResponses); - - // Expect pinned peer to have received all requests - for (let i = 0; i < batchSize; i++) { - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ publicKey: nodes[1].p2p.peerId.publicKey }), - ReqRespSubProtocol.PING, - Buffer.from(`ping${i}`), - ); - } - - // Expect at least one request to have been sent to each other peer - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ publicKey: nodes[2].p2p.peerId.publicKey }), - ReqRespSubProtocol.PING, - expect.any(Buffer), - ); - - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ publicKey: nodes[3].p2p.peerId.publicKey }), - ReqRespSubProtocol.PING, - expect.any(Buffer), - ); - }); - - it('should stop after max retry attempts', async () => { - const batchSize = 12; - const failedIndices = [10, 11]; - nodes = await createNodes(peerScoring, 3); - - await startNodes(nodes); - await sleep(500); - await connectToPeers(nodes); - await sleep(500); - - const requests = Array.from({ length: batchSize }, (_, i) => - RequestableBuffer.fromBuffer(Buffer.from(`ping${i}`)), - ); - - // Mock sendRequestToPeer so that specific requests always fail with RATE_LIMIT_EXCEEDED, - // regardless of which peer they're sent to. This removes the timing dependency on the - // GCRA rate limiter leaking tokens between retries. - const originalSend = nodes[0].req.sendRequestToPeer.bind(nodes[0].req); - const sendSpy = jest - .spyOn(nodes[0].req, 'sendRequestToPeer') - .mockImplementation((peer: PeerId, protocol: ReqRespSubProtocol, buffer: Buffer) => { - const msg = buffer.toString(); - if (failedIndices.some(i => msg === `ping${i}`)) { - return Promise.resolve({ status: ReqRespStatus.RATE_LIMIT_EXCEEDED, data: Buffer.alloc(0) }); - } - return originalSend(peer, protocol, buffer); - }); - - const res = await nodes[0].req.sendBatchRequest(ReqRespSubProtocol.PING, requests, undefined); - - // 10 succeed, 2 permanently fail after all retry attempts are exhausted - const successes = res.filter(r => r !== undefined); - expect(successes).toHaveLength(batchSize - failedIndices.length); - expect(successes).toEqual( - times(batchSize - failedIndices.length, () => RequestableBuffer.fromBuffer(Buffer.from(`pong`))), - ); - - // Verify retries actually happened — those 2 requests were attempted more than once - const failedCalls = sendSpy.mock.calls.filter(([, , buf]) => - failedIndices.some(i => (buf as Buffer).toString() === `ping${i}`), - ); - expect(failedCalls.length).toBeGreaterThan(failedIndices.length); - }); - }); }); function expectSuccess(res: ReqRespResponse): asserts res is { status: ReqRespStatus.SUCCESS; data: Buffer } { diff --git a/yarn-project/p2p/src/services/reqresp/reqresp.ts b/yarn-project/p2p/src/services/reqresp/reqresp.ts index ba3fe8e518f5..efeb51d82a1f 100644 --- a/yarn-project/p2p/src/services/reqresp/reqresp.ts +++ b/yarn-project/p2p/src/services/reqresp/reqresp.ts @@ -1,5 +1,4 @@ // @attribution: lodestar impl for inspiration -import { compactArray } from '@aztec/foundation/collection'; import { AbortError, TimeoutError } from '@aztec/foundation/error'; import { createLogger } from '@aztec/foundation/log'; import { executeTimeout } from '@aztec/foundation/timer'; @@ -11,11 +10,7 @@ import type { Libp2p } from 'libp2p'; import { pipeline } from 'node:stream/promises'; import type { Uint8ArrayList } from 'uint8arraylist'; -import { - CollectiveReqRespTimeoutError, - IndividualReqRespTimeoutError, - InvalidResponseError, -} from '../../errors/reqresp.error.js'; +import { IndividualReqRespTimeoutError } from '../../errors/reqresp.error.js'; import { OversizedSnappyResponseError, SnappyTransform } from '../encoding.js'; import type { PeerScoring } from '../peer-manager/peer_scoring.js'; import { @@ -23,21 +18,16 @@ import { DEFAULT_REQRESP_DIAL_TIMEOUT_MS, type P2PReqRespConfig, } from './config.js'; -import { BatchConnectionSampler } from './connection-sampler/batch_connection_sampler.js'; import { ConnectionSampler, RandomSampler } from './connection-sampler/connection_sampler.js'; import { - DEFAULT_SUB_PROTOCOL_VALIDATORS, type ReqRespInterface, type ReqRespResponse, ReqRespSubProtocol, type ReqRespSubProtocolHandler, type ReqRespSubProtocolHandlers, type ReqRespSubProtocolRateLimits, - type ReqRespSubProtocolValidators, type ShouldRejectPeer, - type SubProtocolMap, UNAUTHENTICATED_ALLOWED_PROTOCOLS, - responseFromBuffer, subProtocolSizeCalculators, } from './interface.js'; import { ReqRespMetrics } from './metrics.js'; @@ -46,13 +36,13 @@ import { RequestResponseRateLimiter, prettyPrintRateLimitStatus, } from './rate-limiter/rate_limiter.js'; -import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqRespStatus } from './status.js'; +import { ReqRespStatus, ReqRespStatusError, parseStatusChunk } from './status.js'; /** * The Request Response Service * * It allows nodes to request specific information from their peers, its use case covers recovering - * information that was missed during a syncronisation or a gossip event. + * information that was missed during a synchronisation or a gossip event. * * This service implements the request response sub protocol, it is heavily inspired from * ethereum implementations of the same name. @@ -67,7 +57,6 @@ export class ReqResp implements ReqRespInterface { private dialTimeoutMs: number = DEFAULT_REQRESP_DIAL_TIMEOUT_MS; private subProtocolHandlers: Partial = {}; - private subProtocolValidators: Partial = {}; private connectionSampler: ConnectionSampler; private rateLimiter: RequestResponseRateLimiter; @@ -130,11 +119,11 @@ export class ReqResp implements ReqRespInterface { /** * Start the reqresp service */ - async start(subProtocolHandlers: ReqRespSubProtocolHandlers, subProtocolValidators: ReqRespSubProtocolValidators) { + async start(subProtocolHandlers: ReqRespSubProtocolHandlers) { Object.assign(this.subProtocolHandlers, subProtocolHandlers); - Object.assign(this.subProtocolValidators, subProtocolValidators); - // Register all protocol handlers + // Register streamHandler with libp2p. + // The streamHandler is responsible for reading the incoming stream, determining the protocol, then triggering the appropriate handler. for (const subProtocol of Object.keys(subProtocolHandlers)) { this.logger.debug(`Registering handler for sub protocol ${subProtocol}`); await this.libp2p.handle( @@ -148,13 +137,8 @@ export class ReqResp implements ReqRespInterface { this.rateLimiter.start(); } - async addSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator: ReqRespSubProtocolValidators[ReqRespSubProtocol] = DEFAULT_SUB_PROTOCOL_VALIDATORS[subProtocol], - ): Promise { + async addSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise { this.subProtocolHandlers[subProtocol] = handler; - this.subProtocolValidators[subProtocol] = validator; this.logger.debug(`Registering handler for sub protocol ${subProtocol}`); await this.libp2p.handle( subProtocol, @@ -188,225 +172,6 @@ export class ReqResp implements ReqRespInterface { // NOTE: We assume libp2p instance is managed by the caller } - /** - * Request multiple messages over the same sub protocol, balancing the requests across peers. - * - * @devnote - * - The function prioritizes sending requests to free peers using a batch sampling strategy. - * - If a peer fails to respond or returns an invalid response, it is removed from the sampling pool and replaced. - * - The function stops retrying once all requests are processed, no active peers remain, or the maximum retry attempts are reached. - * - Responses are validated using a custom validator for the sub-protocol.* - * - * Requests are sent in parallel to each peer, but multiple requests are sent to the same peer in series - * - If a peer fails to respond or returns an invalid response, it is removed from the sampling pool and replaced. - * - The function stops retrying once all requests are processed, no active peers remain, or the maximum retry attempts are reached. - * - Responses are validated using a custom validator for the sub-protocol.* - * - * @param subProtocol - * @param requests - * @param timeoutMs - * @param maxPeers - * @returns - * - * @throws {CollectiveReqRespTimeoutError} - If the request batch exceeds the specified timeout (`timeoutMs`). - */ - @trackSpan( - 'ReqResp.sendBatchRequest', - (subProtocol: ReqRespSubProtocol, requests: InstanceType[]) => ({ - [Attributes.P2P_REQ_RESP_PROTOCOL]: subProtocol, - [Attributes.P2P_REQ_RESP_BATCH_REQUESTS_COUNT]: requests.length, - }), - ) - async sendBatchRequest( - subProtocol: SubProtocol, - requests: InstanceType[], - pinnedPeer: PeerId | undefined, - timeoutMs = 10000, - maxPeers = Math.max(10, Math.ceil(requests.length / 3)), - maxRetryAttempts = 3, - ): Promise[]> { - const responseValidator = this.subProtocolValidators[subProtocol] ?? DEFAULT_SUB_PROTOCOL_VALIDATORS[subProtocol]; - const responses: InstanceType[] = new Array(requests.length); - const requestBuffers = requests.map(req => req.toBuffer()); - const isEmptyResponse = (value: unknown): boolean => { - // Some responses serialize to a non-empty buffer even when they contain no items (e.g., empty TxArray). - if (!value || typeof value !== 'object') { - return false; - } - const length = (value as { length?: number }).length; - return typeof length === 'number' && length === 0; - }; - - const requestFunction = async (signal: AbortSignal) => { - // Track which requests still need to be processed - const pendingRequestIndices = new Set(requestBuffers.map((_, i) => i)); - - // Create batch sampler with the total number of requests and max peers - const batchSampler = new BatchConnectionSampler( - this.connectionSampler, - requests.length, - maxPeers, - compactArray([pinnedPeer]), // Exclude pinned peer from sampling, we will forcefully send all requests to it - createLogger(`${this.logger.module}:batch-connection-sampler`), - ); - - if (batchSampler.activePeerCount === 0 && !pinnedPeer) { - this.logger.warn('No active peers to send requests to'); - return []; - } - - // This is where it gets fun - // The outer loop is the retry loop, we will continue to retry until we process all indices we have - // not received a response for, or we have reached the max retry attempts - - // The inner loop is the batch loop, we will process all requests for each peer in parallel - // We will then process the results of the requests, and resample any peers that failed to respond - // We will continue to retry until we have processed all indices, or we have reached the max retry attempts - - let retryAttempts = 0; - while (pendingRequestIndices.size > 0 && batchSampler.activePeerCount > 0 && retryAttempts < maxRetryAttempts) { - if (signal.aborted) { - throw new AbortError('Batch request aborted'); - } - // Process requests in parallel for each available peer - type BatchEntry = { peerId: PeerId; indices: number[] }; - const requestBatches = new Map(); - - // Group requests by peer - for (const requestIndex of pendingRequestIndices) { - const peer = batchSampler.getPeerForRequest(requestIndex); - if (!peer) { - // No peer available for this specific index (all peers exhausted for it) - // Skip this index for now - it stays in pendingRequestIndices for retry - continue; - } - const peerAsString = peer.toString(); - if (!requestBatches.has(peerAsString)) { - requestBatches.set(peerAsString, { peerId: peer, indices: [] }); - } - requestBatches.get(peerAsString)!.indices.push(requestIndex); - } - - // If there is a pinned peer, we will always send every request to that peer - // We use the default limits for the subprotocol to avoid hitting the rate limiter - if (pinnedPeer) { - const limit = this.rateLimiter.getRateLimits(subProtocol).peerLimit.quotaCount; - requestBatches.set(pinnedPeer.toString(), { - peerId: pinnedPeer, - indices: Array.from(pendingRequestIndices.values()).slice(0, limit), - }); - } - - // If no requests could be assigned (all peers exhausted for all indices), exit early - if (requestBatches.size === 0) { - this.logger.warn('No peers available for any pending request indices, stopping batch request'); - break; - } - - // Make parallel requests for each peer's batch - // A batch entry will look something like this: - // PeerId0: [0, 1, 2, 3] - // PeerId1: [4, 5, 6, 7] - - // Peer Id 0 will send requests 0, 1, 2, 3 in serial - // while simultaneously Peer Id 1 will send requests 4, 5, 6, 7 in serial - - const batchResults = await Promise.all( - Array.from(requestBatches.entries()).map(async ([peerAsString, { peerId: peer, indices }]) => { - try { - const markIndexFailed = (index: number) => batchSampler.markPeerFailedForIndex(peer, index); - // Requests all going to the same peer are sent synchronously - const peerResults: { index: number; response: InstanceType }[] = - []; - let shouldReplacePeer = false; - const handleFailure = (status: ReqRespStatus, index: number) => { - this.logger.warn( - `Request to peer ${peerAsString} failed with status ${prettyPrintReqRespStatus(status)}`, - ); - markIndexFailed(index); - return status === ReqRespStatus.RATE_LIMIT_EXCEEDED; - }; - - for (const index of indices) { - this.logger.trace(`Sending request ${index} to peer ${peerAsString}`); - const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffers[index]); - - // Check the status of the response buffer - if (response.status !== ReqRespStatus.SUCCESS) { - shouldReplacePeer = handleFailure(response.status, index); - if (shouldReplacePeer) { - break; - } - continue; - } - - if (response.data.length === 0) { - markIndexFailed(index); - continue; - } - - const object = responseFromBuffer(subProtocol, response.data); - if (isEmptyResponse(object)) { - markIndexFailed(index); - continue; - } - - const isValid = await responseValidator(requests[index], object, peer); - if (!isValid) { - markIndexFailed(index); - continue; - } - - peerResults.push({ index, response: object }); - } - - // If peer had a hard failure (rate limit), replace it for future iterations - if (shouldReplacePeer) { - this.logger.warn(`Peer ${peerAsString} hit a hard failure, removing from sampler`); - batchSampler.removePeerAndReplace(peer); - } - - return { peer, results: peerResults }; - } catch (error) { - this.logger.warn(`Failed batch request to peer ${peerAsString}:`, error); - batchSampler.removePeerAndReplace(peer); - return { peer, results: [] }; - } - }), - ); - - // Process results - for (const { results } of batchResults) { - for (const { index, response } of results) { - if (response) { - responses[index] = response; - pendingRequestIndices.delete(index); - } - } - } - - retryAttempts++; - } - - if (retryAttempts >= maxRetryAttempts) { - this.logger.warn(`Max retry attempts ${maxRetryAttempts} reached for batch request`); - } - - return responses; - }; - - try { - return await executeTimeout[]>( - requestFunction, - timeoutMs, - () => new CollectiveReqRespTimeoutError(), - ); - } catch (e: any) { - this.logger.warn(`${e.message} | subProtocol: ${subProtocol}`); - return []; - } - } - /** * Sends a request to a specific peer * @@ -757,13 +522,13 @@ export class ReqResp implements ReqRespInterface { ): PeerErrorSeverity | undefined { const logTags = { peerId: peerId.toString(), subProtocol }; - //Punishable error - peer should never send badly formed request + // Punishable error - peer should never send badly formed request if (e instanceof ReqRespStatusError && e.status === ReqRespStatus.BADLY_FORMED_REQUEST) { this.logger.debug(`Punishable error in ${subProtocol}: ${e.cause}`, logTags); return PeerErrorSeverity.LowToleranceError; } - //TODO: (mralj): think if we should penalize peer here based on connection errors + // TODO: (mralj): think if we should penalize peer here based on connection errors return undefined; } @@ -785,12 +550,6 @@ export class ReqResp implements ReqRespInterface { return undefined; } - // We do not punish a collective timeout, as the node triggers this interupt, independent of the peer's behaviour - if (e instanceof CollectiveReqRespTimeoutError || e instanceof InvalidResponseError) { - this.logger.debug(`Non-punishable error in ${subProtocol}: ${e.message}`, logTags); - return undefined; - } - // Invalid status byte: the peer sent a status byte that doesn't match any known status code. // This is a protocol violation, penalize harshly. if (e instanceof ReqRespStatusError) { @@ -810,7 +569,8 @@ export class ReqResp implements ReqRespInterface { /* * Errors specific to connection handling - * These can happen both when sending request and response*/ + * These can happen both when sending request and response. + */ private categorizeConnectionErrors( e: any, peerId: PeerId, diff --git a/yarn-project/p2p/src/services/service.ts b/yarn-project/p2p/src/services/service.ts index e3b7590e83b1..f5428c9a9f19 100644 --- a/yarn-project/p2p/src/services/service.ts +++ b/yarn-project/p2p/src/services/service.ts @@ -17,12 +17,7 @@ import type EventEmitter from 'events'; import type { BatchTxRequesterLibP2PService } from './reqresp/batch-tx-requester/interface.js'; import type { P2PReqRespConfig } from './reqresp/config.js'; import type { StatusMessage } from './reqresp/index.js'; -import type { - ReqRespSubProtocol, - ReqRespSubProtocolHandler, - ReqRespSubProtocolValidators, - SubProtocolMap, -} from './reqresp/interface.js'; +import type { ReqRespSubProtocol, ReqRespSubProtocolHandler } from './reqresp/interface.js'; import type { AuthRequest, AuthResponse } from './reqresp/protocols/auth.js'; export enum PeerDiscoveryState { @@ -100,22 +95,6 @@ export interface P2PService { */ propagate(message: T): Promise; - /** - * Send a batch of requests to peers, and return the responses - * - * @param protocol - The request response protocol to use - * @param requests - The requests to send to the peers - * @returns The responses to the requests - */ - sendBatchRequest( - protocol: Protocol, - requests: InstanceType[], - pinnedPeerId?: PeerId, - timeoutMs?: number, - maxPeers?: number, - maxRetryAttempts?: number, - ): Promise[]>; - // Leaky abstraction: fix https://github.com/AztecProtocol/aztec-packages/issues/7963 registerBlockReceivedCallback(callback: P2PBlockReceivedCallback): void; @@ -150,11 +129,7 @@ export interface P2PService { validateTxsReceivedInBlockProposal(txs: Tx[]): Promise; - addReqRespSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise; + addReqRespSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise; handleAuthRequestFromPeer(authRequest: AuthRequest, peerId: PeerId): Promise; diff --git a/yarn-project/p2p/src/services/tx_collection/config.ts b/yarn-project/p2p/src/services/tx_collection/config.ts index f8f5ceeea81f..68de3db09303 100644 --- a/yarn-project/p2p/src/services/tx_collection/config.ts +++ b/yarn-project/p2p/src/services/tx_collection/config.ts @@ -14,7 +14,7 @@ export type TxCollectionConfig = { txCollectionNodeRpcMaxBatchSize: number; /** A comma-separated list of file store URLs (s3://, gs://, file://, http://) for tx collection */ txCollectionFileStoreUrls: string[]; - /** Delay in ms before file store collection starts after fast collection is triggered */ + /** Delay in ms from reqresp start before file store collection begins */ txCollectionFileStoreFastDelayMs: number; /** Number of concurrent workers for fast file store collection */ txCollectionFileStoreFastWorkerCount: number; @@ -68,7 +68,7 @@ export const txCollectionConfigMappings: ConfigMappingsType }, txCollectionFileStoreFastDelayMs: { env: 'TX_COLLECTION_FILE_STORE_FAST_DELAY_MS', - description: 'Delay before file store collection starts after fast collection', + description: 'Delay in ms from reqresp start before file store collection begins', ...numberConfigHelper(2_000), }, txCollectionFileStoreFastWorkerCount: { diff --git a/yarn-project/p2p/src/services/tx_collection/fast_tx_collection.ts b/yarn-project/p2p/src/services/tx_collection/fast_tx_collection.ts deleted file mode 100644 index 7bcb1366342b..000000000000 --- a/yarn-project/p2p/src/services/tx_collection/fast_tx_collection.ts +++ /dev/null @@ -1,379 +0,0 @@ -import { BlockNumber } from '@aztec/foundation/branded-types'; -import { times } from '@aztec/foundation/collection'; -import { type Logger, createLogger } from '@aztec/foundation/log'; -import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider, elapsed } from '@aztec/foundation/timer'; -import type { L2BlockInfo } from '@aztec/stdlib/block'; -import { type Tx, TxHash } from '@aztec/stdlib/tx'; - -import type { PeerId } from '@libp2p/interface'; - -import { BatchTxRequester } from '../reqresp/batch-tx-requester/batch_tx_requester.js'; -import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js'; -import type { BlockTxsSource } from '../reqresp/index.js'; -import type { TxCollectionConfig } from './config.js'; -import { type IRequestTracker, RequestTracker } from './request_tracker.js'; -import type { FastCollectionRequest, FastCollectionRequestInput } from './tx_collection.js'; -import type { TxAddContext, TxCollectionSink } from './tx_collection_sink.js'; -import type { TxSource } from './tx_source.js'; - -/** - * Collect missing transactions for a block or proposal via reqresp. - * @param requestTracker - The missing transactions tracker - * @param blockTxsSource - The block or proposal containing the transactions - * @param pinnedPeer - Optional peer expected to have the transactions - * @returns The collected transactions - */ -export type IReqRespTxsCollector = ( - requestTracker: IRequestTracker, - blockTxsSource: BlockTxsSource, - pinnedPeer: PeerId | undefined, -) => Promise; - -export class FastTxCollection { - // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections - protected requests: Set = new Set(); - - constructor( - private readonly p2pService: BatchTxRequesterLibP2PService, - private nodes: TxSource[], - private txCollectionSink: TxCollectionSink, - private config: TxCollectionConfig, - private dateProvider: DateProvider = new DateProvider(), - private log: Logger = createLogger('p2p:tx_collection_service'), - protected reqRespTxsCollector?: IReqRespTxsCollector, - ) { - if (!this.reqRespTxsCollector) { - this.reqRespTxsCollector = (requestTracker, blockTxsSource, pinnedPeer) => - BatchTxRequester.collectAllTxs( - new BatchTxRequester( - requestTracker, - blockTxsSource, - pinnedPeer, - this.p2pService, - this.log, - this.dateProvider, - ).run(), - ); - } - } - - public async stop() { - this.requests.forEach(request => { - request.requestTracker.cancel(); - }); - await Promise.resolve(); - } - - public getFastCollectionRequests() { - return this.requests; - } - - public async collectFastFor( - input: FastCollectionRequestInput, - txHashes: TxHash[] | string[], - opts: { deadline: Date; pinnedPeer?: PeerId }, - ) { - const timeout = opts.deadline.getTime() - this.dateProvider.now(); - if (timeout <= 0) { - this.log.warn(`Deadline for fast tx collection is in the past (${timeout}ms)`, { - deadline: opts.deadline.getTime(), - now: this.dateProvider.now(), - }); - return []; - } - - const blockInfo: L2BlockInfo = - input.type === 'proposal' - ? { ...input.blockProposal.toBlockInfo(), blockNumber: input.blockNumber } - : { ...input.block.toBlockInfo() }; - - const request: FastCollectionRequest = { - ...input, - blockInfo, - requestTracker: RequestTracker.create(txHashes, opts.deadline, this.dateProvider), - }; - - const [duration] = await elapsed(() => this.collectFast(request, { ...opts })); - - this.log.verbose( - `Collected ${request.requestTracker.collectedTxs.length} txs out of ${txHashes.length} for ${input.type} at slot ${blockInfo.slotNumber}`, - { - ...blockInfo, - duration, - requestType: input.type, - missingTxs: [...request.requestTracker.missingTxHashes], - }, - ); - return request.requestTracker.collectedTxs; - } - - protected async collectFast(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) { - this.requests.add(request); - const { blockInfo } = request; - - this.log.debug( - `Starting fast collection of ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`, - { ...blockInfo, requestType: request.type, deadline: request.requestTracker.deadline }, - ); - - try { - // Start blasting all nodes for the txs. We give them a little time to respond before we start reqresp. - // We race against the cancellation token to exit as soon as all txs are collected, the deadline expires, - // or the request is externally cancelled. - const nodeCollectionPromise = this.collectFastFromNodes(request); - const waitBeforeReqResp = sleep(this.config.txCollectionFastNodesTimeoutBeforeReqRespMs); - await Promise.race([request.requestTracker.cancellationToken, waitBeforeReqResp]); - - // If we have collected all txs or the request was cancelled, we can stop here. - // Wait for node collection to settle so inner tasks finish before we return. - if (request.requestTracker.checkCancelled()) { - if (request.requestTracker.allFetched()) { - this.log.debug(`All txs collected for slot ${blockInfo.slotNumber} without reqresp`, blockInfo); - } - await nodeCollectionPromise; - return; - } - - // Start blasting reqresp for the remaining txs. Note that node collection keeps running in parallel. - // We stop when we have collected all txs, timed out, or both node collection and reqresp have given up. - // Inner tasks observe requestTracker.checkCancelled() and stop themselves, so this settles shortly after cancellation. - await Promise.allSettled([this.collectFastViaReqResp(request, opts), nodeCollectionPromise]); - } catch (err) { - this.log.error(`Error collecting txs for ${request.type} for slot ${blockInfo.slotNumber}`, err, { - ...blockInfo, - missingTxs: request.requestTracker.missingTxHashes.values().map(txHash => txHash.toString()), - }); - } finally { - // Ensure no unresolved promises and remove the request from the set - request.requestTracker.cancel(); - this.requests.delete(request); - } - } - - /** - * Starts collecting txs from all configured nodes. We send `txCollectionFastMaxParallelRequestsPerNode` requests - * in parallel to each node. We keep track of the number of attempts made to collect each tx, so we can prioritize - * the txs that have been requested less often whenever we need to send a new batch of requests. We ensure that no - * tx is requested more than once at the same time to the same node. - */ - private async collectFastFromNodes(request: FastCollectionRequest): Promise { - if (this.nodes.length === 0) { - return; - } - - // Keep a shared priority queue of all txs pending to be requested, sorted by the number of attempts made to collect them. - const attemptsPerTx = [...request.requestTracker.missingTxHashes].map(txHash => ({ - txHash, - attempts: 0, - found: false, - })); - - // Returns once we have finished all node loops. Each loop finishes when the deadline is hit, or all txs have been collected. - await Promise.allSettled(this.nodes.map(node => this.collectFastFromNode(request, node, attemptsPerTx))); - } - - private async collectFastFromNode( - request: FastCollectionRequest, - node: TxSource, - attemptsPerTx: { txHash: string; attempts: number; found: boolean }[], - ) { - const notFinished = () => !request.requestTracker.checkCancelled(); - - const maxParallelRequests = this.config.txCollectionFastMaxParallelRequestsPerNode; - const maxBatchSize = this.config.txCollectionNodeRpcMaxBatchSize; - const activeRequestsToThisNode = new Set(); // Track the txs being actively requested to this node - - const processBatch = async () => { - while (notFinished()) { - // Pull tx hashes from the attemptsPerTx array, which is sorted by attempts, - // so we prioritize txs that have been requested less often. - const batch = []; - let index = 0; - while (batch.length < maxBatchSize) { - const txToRequest = attemptsPerTx[index++]; - if (!txToRequest) { - // No more txs to process - break; - } else if (!request.requestTracker.isMissing(txToRequest.txHash)) { - // Mark as found if it was found somewhere else, we'll then remove it from the array. - // We don't delete it now since 'array.splice' is pretty expensive, so we do it after sorting. - txToRequest.found = true; - } else if (!activeRequestsToThisNode.has(txToRequest.txHash)) { - // If the tx is not alredy being requested to this node, add it to the current batch and increase attempts. - // Note that we increase the attempts *before* making the request, so the next `collectFastFromNode` that - // needs to grab txs to send, will pick txs that have been requested less often, instead of all requesting - // the same txs at the same time. - batch.push(txToRequest); - activeRequestsToThisNode.add(txToRequest.txHash); - txToRequest.attempts++; - } - } - - // After modifying the array by removing txs or updating attempts, re-sort it and trim the found txs from the end. - attemptsPerTx.sort((a, b) => - a.found === b.found ? a.attempts - b.attempts : Number(a.found) - Number(b.found), - ); - const firstFoundTxIndex = attemptsPerTx.findIndex(tx => tx.found); - if (firstFoundTxIndex !== -1) { - attemptsPerTx.length = firstFoundTxIndex; - } - - // If we see no more txs to request, we can stop this "process" loop - if (batch.length === 0) { - return; - } - - const txHashes = batch.map(({ txHash }) => txHash); - // Collect this batch from the node - await this.txCollectionSink.collect( - async () => { - const result = await node.getTxsByHash(txHashes.map(TxHash.fromString)); - for (const tx of result.validTxs) { - request.requestTracker.markFetched(tx); - } - return result; - }, - txHashes, - { - description: `fast ${node.getInfo()}`, - node: node.getInfo(), - method: 'fast-node-rpc', - ...request.blockInfo, - }, - this.getAddContext(request), - ); - - // Clear from the active requests the txs we just requested - for (const requestedTx of batch) { - activeRequestsToThisNode.delete(requestedTx.txHash); - } - - // Sleep a bit until hitting the node again, but wake up immediately on cancellation - if (notFinished()) { - await Promise.race([ - sleep(this.config.txCollectionFastNodeIntervalMs), - request.requestTracker.cancellationToken, - ]); - } - } - }; - - // Kick off N parallel requests to the node, up to the maxParallelRequests limit - await Promise.all(times(maxParallelRequests, processBatch)); - } - - private async collectFastViaReqResp(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) { - const pinnedPeer = opts.pinnedPeer; - const blockInfo = request.blockInfo; - const slotNumber = blockInfo.slotNumber; - if (request.requestTracker.timeoutMs < 100) { - this.log.warn( - `Not initiating fast reqresp for txs for ${request.type} at slot ${blockInfo.slotNumber} due to timeout`, - { timeoutMs: request.requestTracker.timeoutMs, ...blockInfo }, - ); - return; - } - - this.log.debug( - `Starting fast reqresp for ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`, - { ...blockInfo, timeoutMs: request.requestTracker.timeoutMs, pinnedPeer }, - ); - - try { - await this.txCollectionSink.collect( - async () => { - let blockTxsSource: BlockTxsSource; - if (request.type === 'proposal') { - blockTxsSource = request.blockProposal; - } else if (request.type === 'block') { - blockTxsSource = { - txHashes: request.block.body.txEffects.map(e => e.txHash), - archive: request.block.archive.root, - }; - } else { - throw new Error(`Unknown request type: ${(request as { type: string }).type}`); - } - - const result = await this.reqRespTxsCollector!(request.requestTracker, blockTxsSource, pinnedPeer); - return { validTxs: result, invalidTxHashes: [] }; - }, - Array.from(request.requestTracker.missingTxHashes), - { description: `reqresp for slot ${slotNumber}`, method: 'fast-req-resp', ...opts, ...request.blockInfo }, - this.getAddContext(request), - ); - } catch (err) { - this.log.error(`Error sending fast reqresp request for txs`, err, { - txs: [...request.requestTracker.missingTxHashes], - ...blockInfo, - }); - } - } - - /** Returns the TxAddContext for the given request, used by the sink to add txs to the pool correctly. */ - private getAddContext(request: FastCollectionRequest): TxAddContext { - if (request.type === 'proposal') { - return { type: 'proposal', blockHeader: request.blockProposal.blockHeader }; - } else { - return { type: 'mined', block: request.block }; - } - } - - /** - * Handle txs by marking them as found for the requests that are waiting for them, and resolves the request if all its txs have been found. - * Called internally and from the main tx collection manager whenever the tx pool emits a tx-added event. - */ - public foundTxs(txs: Tx[]) { - for (const request of this.requests) { - for (const tx of txs) { - const txHash = tx.txHash.toString(); - // Remove the tx hash from the missing set, and add it to the found set. - if (request.requestTracker.markFetched(tx)) { - this.log.trace(`Found tx ${txHash} for fast collection request`, { - ...request.blockInfo, - txHash: tx.txHash.toString(), - type: request.type, - }); - if (request.requestTracker.allFetched()) { - this.log.trace(`All txs found for fast collection request`, { - ...request.blockInfo, - type: request.type, - }); - break; - } - } - } - } - } - - /** Returns the tx hashes that are still missing (from all requests). */ - public getMissingTxHashes(): TxHash[] { - return Array.from(this.requests.values()).flatMap(request => - Array.from(request.requestTracker.missingTxHashes).map(TxHash.fromString), - ); - } - - /** - * Stop collecting all txs for blocks less than or requal to the block number specified. - * To be called when we no longer care about gathering txs up to a certain block, eg when they become proven or finalized. - */ - public stopCollectingForBlocksUpTo(blockNumber: BlockNumber): void { - for (const request of this.requests) { - if (request.blockInfo.blockNumber <= blockNumber) { - request.requestTracker.cancel(); - } - } - } - - /** - * Stop collecting all txs for blocks greater than the block number specified. - * To be called when there is a chain prune and previously mined txs are no longer relevant. - */ - public stopCollectingForBlocksAfter(blockNumber: BlockNumber): void { - for (const request of this.requests) { - if (request.blockInfo.blockNumber > blockNumber) { - request.requestTracker.cancel(); - } - } - } -} diff --git a/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.test.ts b/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.test.ts index eacef127cfb2..f41512a1dbca 100644 --- a/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.test.ts +++ b/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.test.ts @@ -12,6 +12,7 @@ import { type MockProxy, mock } from 'jest-mock-extended'; import type { TxPoolV2 } from '../../mem_pools/tx_pool_v2/interfaces.js'; import { type FileStoreCollectionConfig, FileStoreTxCollection } from './file_store_tx_collection.js'; import type { FileStoreTxSource } from './file_store_tx_source.js'; +import { type IRequestTracker, RequestTracker } from './request_tracker.js'; import { type TxAddContext, TxCollectionSink } from './tx_collection_sink.js'; describe('FileStoreTxCollection', () => { @@ -26,6 +27,11 @@ describe('FileStoreTxCollection', () => { let txs: Tx[]; let txHashes: TxHash[]; + let requestTracker: IRequestTracker; + + // Track in-flight startCollecting invocations so afterEach can shut them down cleanly. + let activeTrackers: IRequestTracker[]; + let activePromises: Promise[]; const makeFileStoreSource = (name: string) => { const source = mock(); @@ -49,6 +55,14 @@ describe('FileStoreTxCollection', () => { }); }; + /** Spawns a collection run and registers it for afterEach cleanup. */ + const startCollecting = (tracker: IRequestTracker, ctx: TxAddContext): Promise => { + activeTrackers.push(tracker); + const promise = fileStoreCollection.startCollecting(tracker, ctx); + activePromises.push(promise); + return promise; + }; + /** Waits for the sink to emit txs-added events for the expected number of txs. */ const waitForTxsAdded = (expectedCount: number) => { const { promise, resolve } = promiseWithResolvers(); @@ -102,33 +116,38 @@ describe('FileStoreTxCollection', () => { const block = await L2Block.random(BlockNumber(1)); context = { type: 'mined', block }; deadline = new Date(dateProvider.now() + 60 * 60 * 1000); + requestTracker = RequestTracker.create(txHashes, deadline, dateProvider); + + activeTrackers = []; + activePromises = []; }); afterEach(async () => { - await fileStoreCollection.stop(); + for (const t of activeTrackers) { + t.cancel(); + } + await Promise.allSettled(activePromises); jest.restoreAllMocks(); }); it('downloads txs when startCollecting is called', async () => { setFileStoreTxs(fileStoreSources[0], txs); - fileStoreCollection.start(); - const txsAddedPromise = waitForTxsAdded(txs.length); - fileStoreCollection.startCollecting(txHashes, context, deadline); + void startCollecting(requestTracker, context); await txsAddedPromise; expect(fileStoreSources[0].getTxsByHash).toHaveBeenCalled(); expect(txPool.addMinedTxs).toHaveBeenCalled(); }); - it('skips txs marked as found', async () => { + it('skips txs already marked fetched on the tracker', async () => { setFileStoreTxs(fileStoreSources[0], txs); - fileStoreCollection.start(); + // Mark first tx as found before queueing so it's never queued in the first place + requestTracker.markFetched(txs[0]); - fileStoreCollection.startCollecting(txHashes, context, deadline); - fileStoreCollection.foundTxs([txs[0]]); + void startCollecting(requestTracker, context); const txsAddedPromise = waitForTxsAdded(2); await txsAddedPromise; @@ -145,53 +164,25 @@ describe('FileStoreTxCollection', () => { // Pin random so we always start at source 0, ensuring we test the fallback to source 1 jest.spyOn(Math, 'random').mockReturnValue(0); - fileStoreCollection.start(); - + const tracker = RequestTracker.create([txHashes[0]], deadline, dateProvider); const txsAddedPromise = waitForTxsAdded(1); - fileStoreCollection.startCollecting([txHashes[0]], context, deadline); + void startCollecting(tracker, context); await txsAddedPromise; // Both stores should have been tried expect(fileStoreSources[0].getTxsByHash).toHaveBeenCalled(); expect(fileStoreSources[1].getTxsByHash).toHaveBeenCalled(); expect(txPool.addMinedTxs).toHaveBeenCalled(); - - jest.restoreAllMocks(); }); - it('does not start workers if no file store sources are configured', () => { + it('does not start workers if no file store sources are configured', async () => { const log = createLogger('test'); fileStoreCollection = new FileStoreTxCollection([], txCollectionSink, config, dateProvider, log); - fileStoreCollection.start(); - fileStoreCollection.startCollecting(txHashes, context, deadline); - - // With no sources, start() is a no-op (no workers spawned) and startCollecting() returns - // immediately, so no calls should have been made synchronously. - expect(fileStoreSources[0].getTxsByHash).not.toHaveBeenCalled(); - }); - - it('does not re-queue txs that are already pending', async () => { - setFileStoreTxs(fileStoreSources[0], txs); - setFileStoreTxs(fileStoreSources[1], txs); - - // Use single worker for deterministic behavior - const log = createLogger('test'); - config = { workerCount: 1, backoffBaseMs: 1000, backoffMaxMs: 5000 }; - fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); - - fileStoreCollection.start(); - - const txsAddedPromise = waitForTxsAdded(txs.length); - fileStoreCollection.startCollecting(txHashes, context, deadline); - fileStoreCollection.startCollecting(txHashes, context, deadline); // Duplicate call + // With no sources, startCollecting resolves immediately without making any calls. + await startCollecting(requestTracker, context); - await txsAddedPromise; - - // With 1 worker processing sequentially, each tx should be found on the first source. - // Duplicate startCollecting should not create extra entries. - const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); - expect(allCalls.length).toBe(txHashes.length); + expect(fileStoreSources[0].getTxsByHash).not.toHaveBeenCalled(); }); it('retries across sources when tx is not found initially', async () => { @@ -200,10 +191,9 @@ describe('FileStoreTxCollection', () => { config = { workerCount: 1, backoffBaseMs: 100, backoffMaxMs: 500 }; fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); - fileStoreCollection.start(); - // Initially both sources return empty - fileStoreCollection.startCollecting([txHashes[0]], context, deadline); + const tracker = RequestTracker.create([txHashes[0]], deadline, dateProvider); + void startCollecting(tracker, context); // Wait for first full cycle (2 sources = 2 calls) await waitForSourceCalls(fileStoreSources, 2); @@ -220,88 +210,54 @@ describe('FileStoreTxCollection', () => { expect(txPool.addMinedTxs).toHaveBeenCalled(); }); - it('expires entries past deadline', async () => { - const log = createLogger('test'); - config = { workerCount: 1, backoffBaseMs: 50, backoffMaxMs: 100 }; - fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); - - // Set a very short deadline - const shortDeadline = new Date(dateProvider.now() + 100); - - fileStoreCollection.start(); - fileStoreCollection.startCollecting([txHashes[0]], context, shortDeadline); - - // Wait for first full cycle (2 sources = 2 calls) - await waitForSourceCalls(fileStoreSources, 2); - - // Advance time past the deadline - dateProvider.setTime(dateProvider.now() + 200); - - // Clear mocks so we can distinguish new calls from old ones - jest.clearAllMocks(); - - // Add a new entry with a valid deadline and set up source to return it. - // This proves the worker is alive and the expired entry was cleaned up. - setFileStoreTxs(fileStoreSources[0], [txs[1]]); - const txsAddedPromise = waitForTxsAdded(1); - fileStoreCollection.startCollecting([txHashes[1]], context, deadline); - await txsAddedPromise; - - // Only txHashes[1] should have been requested after clearing mocks - const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); - const requestedHashes = allCalls.flat().flat(); - expect(requestedHashes).not.toContainEqual(txHashes[0]); - expect(requestedHashes).toContainEqual(txHashes[1]); - }); - - it('does not start collecting if deadline is in the past', () => { - const pastDeadline = new Date(dateProvider.now() - 1000); + it('does not start collecting if tracker is already cancelled', async () => { + requestTracker.cancel(); - fileStoreCollection.start(); - fileStoreCollection.startCollecting(txHashes, context, pastDeadline); + await startCollecting(requestTracker, context); - // startCollecting returns immediately without adding entries when deadline is past + // startCollecting returns immediately without spawning workers when tracker is cancelled expect(fileStoreSources[0].getTxsByHash).not.toHaveBeenCalled(); }); - it('foundTxs stops retry for found txs', async () => { + it('stops trying for txs marked fetched on the tracker after queuing', async () => { const log = createLogger('test'); config = { workerCount: 1, backoffBaseMs: 50, backoffMaxMs: 100 }; fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); setFileStoreTxs(fileStoreSources[0], [txs[1]]); - fileStoreCollection.start(); - fileStoreCollection.startCollecting(txHashes, context, deadline); + void startCollecting(requestTracker, context); - // Mark first tx as found - fileStoreCollection.foundTxs([txs[0]]); + // Externally mark tx[0] as found via the tracker (simulating node/reqresp/gossip finding it). + // startCollecting yields before spawning workers, so this runs before any source call is made. + requestTracker.markFetched(txs[0]); const txsAddedPromise = waitForTxsAdded(1); await txsAddedPromise; - // tx[0] should never have been attempted + // tx[0] should never have been attempted by the file store const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); const requestedHashes = allCalls.flat().flat(); expect(requestedHashes).not.toContainEqual(txHashes[0]); }); - it('clearPending removes all entries', async () => { - fileStoreCollection.start(); - fileStoreCollection.startCollecting(txHashes, context, deadline); - fileStoreCollection.clearPending(); + it('workers exit when tracker is cancelled', async () => { + // Long backoff so workers spend most of their time sleeping after a single attempt + const log = createLogger('test'); + config = { workerCount: 2, backoffBaseMs: 60_000, backoffMaxMs: 60_000 }; + fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); + + // Pre-set the tracker timer so a cancellation does not require real-time deadline expiry + const tracker = RequestTracker.create(txHashes, deadline, dateProvider); + const promise = startCollecting(tracker, context); - // Verify workers are alive but the cleared entries are gone by adding - // a new entry and confirming only it gets processed. - setFileStoreTxs(fileStoreSources[0], [txs[0]]); - const txsAddedPromise = waitForTxsAdded(1); - fileStoreCollection.startCollecting([txHashes[0]], context, deadline); - await txsAddedPromise; + // Let workers do at least one round of attempts + await waitForSourceCalls(fileStoreSources, 2); - // Only the newly added tx[0] should have been requested, not all 3 original txs - const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); - const requestedHashes = allCalls.flat().flat(); - expect(requestedHashes).not.toContainEqual(txHashes[1]); - expect(requestedHashes).not.toContainEqual(txHashes[2]); + tracker.cancel(); + + // The startCollecting promise resolves once all workers settle. Without this guarantee, the + // test would either hang or leak workers — both are caught by Jest's default timeout. + await promise; }); }); diff --git a/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.ts b/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.ts index 165ba3d9928a..abaf1b64ad6e 100644 --- a/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.ts +++ b/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.ts @@ -1,10 +1,11 @@ +import { times } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; -import { type PromiseWithResolvers, promiseWithResolvers } from '@aztec/foundation/promise'; import { sleep } from '@aztec/foundation/sleep'; import { DateProvider } from '@aztec/foundation/timer'; -import { Tx, TxHash } from '@aztec/stdlib/tx'; +import { TxHash } from '@aztec/stdlib/tx'; import type { FileStoreTxSource } from './file_store_tx_source.js'; +import type { IRequestTracker } from './request_tracker.js'; import type { TxAddContext, TxCollectionSink } from './tx_collection_sink.js'; /** Configuration for a FileStoreTxCollection instance. */ @@ -16,8 +17,6 @@ export type FileStoreCollectionConfig = { type FileStoreTxEntry = { txHash: string; - context: TxAddContext; - deadline: Date; attempts: number; lastAttemptTime: number; nextSourceIndex: number; @@ -25,96 +24,60 @@ type FileStoreTxEntry = { /** * Collects txs from file stores as a fallback after P2P methods have been tried. - * Uses a shared worker pool that pulls entries with priority (fewest attempts first), - * retries with round-robin across sources, and applies exponential backoff between - * full cycles through all sources. + * Each call to startCollecting spins up its own worker pool which pulls entries with priority + * (fewest attempts first), retries with round-robin across sources, and applies exponential + * backoff between full cycles through all sources. Workers self-terminate when the request + * tracker is cancelled (deadline / all-fetched / external) or when there is nothing left to do. */ export class FileStoreTxCollection { - /** Map from tx hash string to entry for all pending downloads. */ - private entries = new Map(); - - /** Worker promises for the shared worker pool. */ - private workers: Promise[] = []; - - /** Whether the worker pool is running. */ - private running = false; - - /** Signal used to wake sleeping workers when new entries arrive or stop is called. */ - private wakeSignal: PromiseWithResolvers; - constructor( private readonly sources: FileStoreTxSource[], private readonly txCollectionSink: TxCollectionSink, private readonly config: FileStoreCollectionConfig, private readonly dateProvider: DateProvider = new DateProvider(), private readonly log: Logger = createLogger('p2p:file_store_tx_collection'), - ) { - this.wakeSignal = promiseWithResolvers(); - } - - /** Starts the shared worker pool. */ - public start(): void { - if (this.sources.length === 0) { - this.log.debug('No file store sources configured'); - return; - } - this.running = true; - for (let i = 0; i < this.config.workerCount; i++) { - this.workers.push(this.workerLoop()); - } - } - - /** Stops all workers and clears state. */ - public async stop(): Promise { - this.running = false; - this.wake(); - await Promise.all(this.workers); - this.workers = []; - this.entries.clear(); - } - - /** Adds entries to the shared map and wakes workers. */ - public startCollecting(txHashes: TxHash[], context: TxAddContext, deadline: Date): void { - if (this.sources.length === 0 || txHashes.length === 0) { - return; - } - if (+deadline <= this.dateProvider.now()) { + ) {} + + /** + * Spins up workers to download all txs still missing from the tracker, racing across the + * configured file store sources. Resolves once all workers settle. + */ + public async startCollecting(requestTracker: IRequestTracker, context: TxAddContext): Promise { + if (this.sources.length === 0 || requestTracker.checkCancelled()) { return; } - for (const txHash of txHashes) { - const hashStr = txHash.toString(); - if (!this.entries.has(hashStr)) { - this.entries.set(hashStr, { - txHash: hashStr, - context, - deadline, - attempts: 0, - lastAttemptTime: 0, - nextSourceIndex: Math.floor(Math.random() * this.sources.length), - }); - } + // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + const entries: Set = new Set(); + for (const hashStr of requestTracker.missingTxHashes) { + entries.add({ + txHash: hashStr, + attempts: 0, + lastAttemptTime: 0, + nextSourceIndex: Math.floor(Math.random() * this.sources.length), + }); } - this.wake(); - } - /** Removes entries for txs that have been found elsewhere. */ - public foundTxs(txs: Tx[]): void { - for (const tx of txs) { - this.entries.delete(tx.getTxHash().toString()); + // Yield before spawning so the synchronous caller can finish any follow-up (eg. marking a tx + // as fetched on the tracker, or cancelling it) before workers begin scanning entries. + await Promise.resolve(); + if (requestTracker.checkCancelled()) { + return; } - } - /** Clears all pending entries. */ - public clearPending(): void { - this.entries.clear(); + await Promise.allSettled(times(this.config.workerCount, () => this.workerLoop(entries, requestTracker, context))); } - private async workerLoop(): Promise { - while (this.running) { - const action = this.getNextAction(); + private async workerLoop( + // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + entries: Set, + requestTracker: IRequestTracker, + context: TxAddContext, + ): Promise { + while (!requestTracker.checkCancelled() && entries.size > 0) { + const action = this.getNextAction(entries, requestTracker); if (action.type === 'sleep') { - await action.promise; + await Promise.race([sleep(action.ms), requestTracker.cancellationToken]); continue; } @@ -133,10 +96,10 @@ export class FileStoreTxCollection { method: 'file-store', fileStore: source.getInfo(), }, - entry.context, + context, ); if (result.txs.length > 0) { - this.entries.delete(entry.txHash); + entries.delete(entry); } } catch (err) { this.log.trace(`Error downloading tx ${entry.txHash} from ${source.getInfo()}`, { err }); @@ -144,15 +107,20 @@ export class FileStoreTxCollection { } } - /** Single-pass scan: removes expired entries, finds the best ready entry, or computes sleep time. */ - private getNextAction(): { type: 'process'; entry: FileStoreTxEntry } | { type: 'sleep'; promise: Promise } { + /** Single-pass scan: removes stale entries, finds the best ready entry, or computes sleep time. */ + private getNextAction( + // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + entries: Set, + requestTracker: IRequestTracker, + ): { type: 'process'; entry: FileStoreTxEntry } | { type: 'sleep'; ms: number } { const now = this.dateProvider.now(); let best: FileStoreTxEntry | undefined; let earliestReadyAt = Infinity; - for (const [key, entry] of this.entries) { - if (+entry.deadline <= now) { - this.entries.delete(key); + for (const entry of entries) { + // Drop entries whose tx was already found via another collection path. + if (!requestTracker.isMissing(entry.txHash)) { + entries.delete(entry); continue; } const backoffMs = this.getBackoffMs(entry); @@ -169,10 +137,9 @@ export class FileStoreTxCollection { if (best) { return { type: 'process', entry: best }; } - if (earliestReadyAt < Infinity) { - return { type: 'sleep', promise: this.sleepOrWake(earliestReadyAt - now) }; - } - return { type: 'sleep', promise: this.waitForWake() }; + // earliestReadyAt is finite whenever there are surviving entries; if entries became empty, + // the outer worker loop will exit on its next iteration via entries.size === 0. + return { type: 'sleep', ms: earliestReadyAt === Infinity ? 0 : earliestReadyAt - now }; } /** Computes backoff for an entry. Backoff applies after a full cycle through all sources. */ @@ -183,20 +150,4 @@ export class FileStoreTxCollection { } return Math.min(this.config.backoffBaseMs * Math.pow(2, fullCycles - 1), this.config.backoffMaxMs); } - - /** Resolves the current wake signal and creates a new one. */ - private wake(): void { - this.wakeSignal.resolve(); - this.wakeSignal = promiseWithResolvers(); - } - - /** Waits until the wake signal is resolved. */ - private async waitForWake(): Promise { - await this.wakeSignal.promise; - } - - /** Sleeps for the given duration or until the wake signal is resolved. */ - private async sleepOrWake(ms: number): Promise { - await Promise.race([sleep(ms), this.wakeSignal.promise]); - } } diff --git a/yarn-project/p2p/src/services/tx_collection/index.ts b/yarn-project/p2p/src/services/tx_collection/index.ts index 4f151c32e27f..293ebdde7ab3 100644 --- a/yarn-project/p2p/src/services/tx_collection/index.ts +++ b/yarn-project/p2p/src/services/tx_collection/index.ts @@ -1,4 +1,3 @@ -export { TxCollection, type FastCollectionRequestInput } from './tx_collection.js'; -export { type IReqRespTxsCollector } from './fast_tx_collection.js'; +export { TxCollection, type FastCollectionRequestInput, type IReqRespTxsCollector } from './tx_collection.js'; export { type TxSource, createNodeRpcTxSources, NodeRpcTxSource } from './tx_source.js'; export { FileStoreTxSource, createFileStoreTxSources } from './file_store_tx_source.js'; diff --git a/yarn-project/p2p/src/services/tx_collection/tx_collection.test.ts b/yarn-project/p2p/src/services/tx_collection/tx_collection.test.ts index 750e09e34fb3..5cb61cbeedd9 100644 --- a/yarn-project/p2p/src/services/tx_collection/tx_collection.test.ts +++ b/yarn-project/p2p/src/services/tx_collection/tx_collection.test.ts @@ -16,9 +16,8 @@ import type { TxPoolV2, TxPoolV2Events } from '../../mem_pools/tx_pool_v2/interf import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js'; import type { BlockTxsSource } from '../reqresp/protocols/block_txs/block_txs_reqresp.js'; import { type TxCollectionConfig, txCollectionConfigMappings } from './config.js'; -import { FastTxCollection, type IReqRespTxsCollector } from './fast_tx_collection.js'; import type { FileStoreTxSource } from './file_store_tx_source.js'; -import { type FastCollectionRequest, TxCollection } from './tx_collection.js'; +import { type FastCollectionRequest, type IReqRespTxsCollector, TxCollection } from './tx_collection.js'; import type { TxSource } from './tx_source.js'; describe('TxCollection', () => { @@ -95,7 +94,7 @@ describe('TxCollection', () => { const setReqRespResponse = (promise: Promise) => { let lastArgs: Parameters | undefined; - txCollection.fastCollection.reqRespTxsCollector = jest.fn().mockImplementation((...x) => { + txCollection.reqRespTxsCollector = jest.fn().mockImplementation((...x) => { lastArgs = x; return promise; }); @@ -147,16 +146,16 @@ describe('TxCollection', () => { setReqRespTxs([]); }); - afterEach(async () => { - await txCollection.stop(); + afterEach(() => { + txCollection.stop(); }); - describe('fast collection', () => { + describe('fast tx collection', () => { it('collects txs from nodes only', async () => { setNodeTxs(nodes[0], txs); const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); expect(nodes[0].getTxsByHash).toHaveBeenCalledWith(txHashes); - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); expectTxsMinedInPool(txs); expect(collected).toEqual(txs); }); @@ -191,7 +190,7 @@ describe('TxCollection', () => { const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); expect(nodes[0].getTxsByHash).toHaveBeenCalledWith(txHashes); expect(nodes[1].getTxsByHash).toHaveBeenCalledWith(txHashes); - expect(txCollection.fastCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); + expect(txCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); expectLastReqRespCollectorArgs(argsGetter); expectTxsMinedInPool([txs[0]]); expectTxsMinedInPool([txs[1]]); @@ -203,12 +202,26 @@ describe('TxCollection', () => { txCollection = new TestTxCollection(mockP2PService, [], constants, txPool, config, [], dateProvider); const argsGetter = setReqRespTxs(txs); const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); - expect(txCollection.fastCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); + expect(txCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); expectLastReqRespCollectorArgs(argsGetter); expectTxsMinedInPool(txs); expect(collected).toEqual(txs); }); + it('starts reqresp immediately when no nodes are configured', async () => { + // Large initial wait — if reqresp were gated by it, the collection would take ~10s. + config = { ...config, txCollectionFastNodesTimeoutBeforeReqRespMs: 10_000 }; + txCollection = new TestTxCollection(mockP2PService, [], constants, txPool, config, [], dateProvider); + setReqRespTxs(txs); + + const startTime = dateProvider.now(); + const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); + + expect(txCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); + expect(dateProvider.now() - startTime).toBeLessThan(1000); + expect(collected).toEqual(txs); + }); + it('keeps retrying txs not found until deadline', async () => { deadline = new Date(dateProvider.now() + 2000); setNodeTxs(nodes[0], [txs[0]]); @@ -219,7 +232,7 @@ describe('TxCollection', () => { expect(dateProvider.now()).toBeGreaterThanOrEqual(+deadline - 5); expect(nodes[0].getTxsByHash).toHaveBeenCalledWith(txHashes); expect(nodes[0].getTxsByHash).toHaveBeenCalledWith([txHashes[2]]); - expect(txCollection.fastCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); + expect(txCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); expectLastReqRespCollectorArgs(argsGetter); expectTxsMinedInPool([txs[0]]); expectTxsMinedInPool([txs[1]]); @@ -274,15 +287,15 @@ describe('TxCollection', () => { const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); expect(collected).toEqual([]); expect(nodes[0].getTxsByHash).not.toHaveBeenCalled(); - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); }); describe('cancellation signals', () => { /** Captures the FastCollectionRequest during collectFast, before it's removed in finally. */ const captureRequest = () => { let captured: FastCollectionRequest | undefined; - const origCollectFast = txCollection.fastCollection.collectFast.bind(txCollection.fastCollection); - jest.spyOn(txCollection.fastCollection, 'collectFast').mockImplementation((request, opts) => { + const origCollectFast = txCollection.collectFast.bind(txCollection); + jest.spyOn(txCollection, 'collectFast').mockImplementation((request, opts) => { captured = request; return origCollectFast(request, opts); }); @@ -319,7 +332,7 @@ describe('TxCollection', () => { setReqRespTxs([]); const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); expect(collected).toEqual(txs); }); @@ -332,7 +345,7 @@ describe('TxCollection', () => { const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); expect(dateProvider.now()).toBeGreaterThanOrEqual(+deadline - 5); expect(collected).toEqual([]); }); @@ -382,13 +395,13 @@ describe('TxCollection', () => { const request = getRequest(); expect(request).toBeDefined(); // Reqresp should not have started yet — we're still in the initial wait - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); request.requestTracker.cancel(); await collectionPromise; // Should have exited without ever starting reqresp - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); expect(dateProvider.now()).toBeLessThan(+deadline); }); @@ -406,7 +419,7 @@ describe('TxCollection', () => { const collectionPromise = txCollection.collectFastForBlock(block, txHashes, { deadline }); await sleep(200); - expect(txCollection.fastCollection.reqRespTxsCollector).toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).toHaveBeenCalled(); getRequest().requestTracker.cancel(); collectorPromise.resolve([]); @@ -439,7 +452,7 @@ describe('TxCollection', () => { expect(request).toBeDefined(); expect(request.requestTracker.checkCancelled()).toBe(false); - await txCollection.stop(); + txCollection.stop(); expect(request.requestTracker.checkCancelled()).toBe(true); collectorPromise.resolve([]); @@ -489,13 +502,13 @@ describe('TxCollection', () => { const collectionPromise = txCollection.collectFastForBlock(block, txHashes, { deadline }); await sleep(100); - expect(txCollection.fastCollection.requests.size).toBe(1); + expect(txCollection.requests.size).toBe(1); txCollection.stopCollectingForBlocksUpTo(block.number); collectorPromise.resolve([]); await collectionPromise; - expect(txCollection.fastCollection.requests.size).toBe(0); + expect(txCollection.requests.size).toBe(0); }); }); }); @@ -529,17 +542,15 @@ describe('TxCollection', () => { it('collects txs from file store after configured delay', async () => { setFileStoreTxs(fileStoreSources[0], txs); - await txCollection.start(); - deadline = new Date(dateProvider.now() + 500); + // Long deadline so the collection ends when file store finds the txs (not when deadline fires) + deadline = new Date(dateProvider.now() + 5000); const collectionPromise = txCollection.collectFastForBlock(block, txHashes, { deadline }); - // File store should not have been called yet (delay hasn't elapsed) + // File store should not have been called yet (delays haven't elapsed) expect(fileStoreSources[0].getTxsByHash).not.toHaveBeenCalled(); - // Advance time past the configured file store delay - dateProvider.setTime(dateProvider.now() + 200); - // Allow the async sleep resolution and worker processing to complete - await sleep(200); + // Wait for: node wait (200ms default) + file store delay (100ms) + worker processing + await sleep(500); await collectionPromise; // File store should now have been called for each tx @@ -549,34 +560,28 @@ describe('TxCollection', () => { it('does not download txs from file store if found via P2P before delay expires', async () => { setFileStoreTxs(fileStoreSources[0], txs); - await txCollection.start(); - deadline = new Date(dateProvider.now() + 500); + // Long deadline so the collection ends when all txs are found (not when deadline fires) + deadline = new Date(dateProvider.now() + 5000); const collectionPromise = txCollection.collectFastForBlock(block, txHashes, { deadline }); - // Simulate all txs found via P2P before delay expires + // Simulate all txs found via P2P before delay expires — this cancels the tracker immediately txCollection.handleTxsAddedToPool({ txs, source: 'test' }); - // Now advance time past the delay - dateProvider.setTime(dateProvider.now() + 200); await sleep(100); await collectionPromise; - // File store should not have downloaded any txs because they were all found + // File store should not have downloaded any txs because they were all found before the delay const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); expect(allCalls.length).toBe(0); }); }); }); -class TestFastTxCollection extends FastTxCollection { +class TestTxCollection extends TxCollection { // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections declare requests: Set; - declare collectFast: (request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) => Promise; - declare reqRespTxsCollector?: IReqRespTxsCollector; -} - -class TestTxCollection extends TxCollection { - declare fastCollection: TestFastTxCollection; declare fileStoreFastCollection: TxCollection['fileStoreFastCollection']; declare handleTxsAddedToPool: TxPoolV2Events['txs-added']; + declare collectFast: (request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) => Promise; + declare reqRespTxsCollector?: IReqRespTxsCollector; } diff --git a/yarn-project/p2p/src/services/tx_collection/tx_collection.ts b/yarn-project/p2p/src/services/tx_collection/tx_collection.ts index 9a609fb408a3..30814392650c 100644 --- a/yarn-project/p2p/src/services/tx_collection/tx_collection.ts +++ b/yarn-project/p2p/src/services/tx_collection/tx_collection.ts @@ -1,7 +1,8 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; +import { times } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider } from '@aztec/foundation/timer'; +import { DateProvider, elapsed } from '@aztec/foundation/timer'; import type { L2Block, L2BlockInfo } from '@aztec/stdlib/block'; import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; import type { BlockProposal } from '@aztec/stdlib/p2p'; @@ -12,12 +13,13 @@ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-clien import type { PeerId } from '@libp2p/interface'; import type { TxPoolV2, TxPoolV2Events } from '../../mem_pools/tx_pool_v2/interfaces.js'; +import { BatchTxRequester } from '../reqresp/batch-tx-requester/batch_tx_requester.js'; import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js'; +import type { BlockTxsSource } from '../reqresp/index.js'; import type { TxCollectionConfig } from './config.js'; -import { FastTxCollection } from './fast_tx_collection.js'; import { FileStoreTxCollection } from './file_store_tx_collection.js'; import type { FileStoreTxSource } from './file_store_tx_source.js'; -import type { IRequestTracker } from './request_tracker.js'; +import { type IRequestTracker, RequestTracker } from './request_tracker.js'; import { type TxAddContext, TxCollectionSink } from './tx_collection_sink.js'; import type { TxSource } from './tx_source.js'; @@ -32,20 +34,36 @@ export type FastCollectionRequest = FastCollectionRequestInput & { blockInfo: L2BlockInfo; }; +/** + * Collect missing transactions for a block or proposal via reqresp. + * @param requestTracker - The missing transactions tracker + * @param blockTxsSource - The block or proposal containing the transactions + * @param pinnedPeer - Optional peer expected to have the transactions + * @returns The collected transactions + */ +export type IReqRespTxsCollector = ( + requestTracker: IRequestTracker, + blockTxsSource: BlockTxsSource, + pinnedPeer: PeerId | undefined, +) => Promise; + /** * Coordinates tx collection from remote RPC nodes, reqresp, and file store. * - * The fast collection methods quickly gather txs from RPC nodes and reqresp, usually for attesting - * to block proposals or preparing to prove an epoch. A delayed file-store fallback can also fetch - * txs if configured. Both paths send txs to the collection sink, which handles metrics and adds - * them to the tx pool. Whenever a tx is added to either the sink or the pool, this service is - * notified via events and stops collecting that tx across all in-flight requests. + * Runs a sequential pipeline: node RPC → reqresp → file store. Node collection starts immediately, + * reqresp starts after a configured delay, and file store (if configured) starts after a further + * delay. All paths send txs to the collection sink, which handles metrics and adds them to the + * tx pool. Whenever a tx is added to the sink or the pool, this service is notified and stops + * collecting that tx across all in-flight requests. */ export class TxCollection { - /** Fast collection methods */ - protected readonly fastCollection: FastTxCollection; + // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + protected requests: Set = new Set(); - /** File store collection for fast (proposal/proving) path */ + /** The collector for txs via reqresp */ + protected reqRespTxsCollector?: IReqRespTxsCollector; + + /** File store collection for the fast (proposal/proving) path */ protected readonly fileStoreFastCollection: FileStoreTxCollection; /** Handles txs found by collection paths before adding to the pool */ @@ -57,12 +75,6 @@ export class TxCollection { /** Handler for the txs-added event from the tx collection sink */ protected readonly handleTxsFound: TxPoolV2Events['txs-added']; - /** Whether the service has been started. */ - private started = false; - - /** Whether file store sources are configured. */ - private readonly hasFileStoreSources: boolean; - constructor( private readonly p2pService: BatchTxRequesterLibP2PService, private readonly nodes: TxSource[], @@ -76,16 +88,18 @@ export class TxCollection { ) { this.txCollectionSink = new TxCollectionSink(this.txPool, telemetryClient, this.log); - this.fastCollection = new FastTxCollection( - this.p2pService, - this.nodes, - this.txCollectionSink, - this.config, - this.dateProvider, - this.log, - ); + this.reqRespTxsCollector = (requestTracker, blockTxsSource, pinnedPeer) => + BatchTxRequester.collectAllTxs( + new BatchTxRequester( + requestTracker, + blockTxsSource, + pinnedPeer, + this.p2pService, + this.log, + this.dateProvider, + ).run(), + ); - this.hasFileStoreSources = fileStoreSources.length > 0; this.fileStoreFastCollection = new FileStoreTxCollection( fileStoreSources, this.txCollectionSink, @@ -112,19 +126,11 @@ export class TxCollection { this.txPool.on('txs-added', this.handleTxsAddedToPool); } - /** Starts all collection loops. */ - public start(): Promise { - this.started = true; - this.fileStoreFastCollection.start(); - - // TODO(palla/txs): Collect mined unproven tx hashes for txs we dont have in the pool and populate missingTxs on startup - return Promise.resolve(); - } - - /** Stops all activity. */ - public async stop() { - this.started = false; - await Promise.all([this.fastCollection.stop(), this.fileStoreFastCollection.stop()]); + /** Stops all activity. Cancels in-flight requests; file store workers self-terminate. */ + public stop() { + this.requests.forEach(request => { + request.requestTracker.cancel(); + }); this.txPool.removeListener('txs-added', this.handleTxsAddedToPool); this.txCollectionSink.removeListener('txs-added', this.handleTxsFound); @@ -145,48 +151,295 @@ export class TxCollection { } /** Collects the set of txs for the given proposal or block as fast as possible */ - public collectFastFor( + public async collectFastFor( input: FastCollectionRequestInput, txHashes: TxHash[] | string[], opts: { deadline: Date; pinnedPeer?: PeerId }, ) { + const timeout = opts.deadline.getTime() - this.dateProvider.now(); + if (timeout <= 0) { + this.log.warn(`Deadline for fast tx collection is in the past (${timeout}ms)`, { + deadline: opts.deadline.getTime(), + now: this.dateProvider.now(), + }); + return []; + } + const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : h)); - // Delay file store collection to give P2P methods time to find txs first - if (this.hasFileStoreSources) { - const context = this.getAddContextForInput(input); - sleep(this.config.txCollectionFileStoreFastDelayMs) - .then(() => { - if (!this.started) { - return; - } + const blockInfo: L2BlockInfo = + input.type === 'proposal' + ? { ...input.blockProposal.toBlockInfo(), blockNumber: input.blockNumber } + : { ...input.block.toBlockInfo() }; + + const request: FastCollectionRequest = { + ...input, + blockInfo, + requestTracker: RequestTracker.create(hashes, opts.deadline, this.dateProvider), + }; + + const [duration] = await elapsed(() => this.collectFast(request, { pinnedPeer: opts.pinnedPeer })); + + this.log.verbose( + `Collected ${request.requestTracker.collectedTxs.length} txs out of ${hashes.length} for ${input.type} at slot ${blockInfo.slotNumber}`, + { + ...blockInfo, + duration, + requestType: input.type, + missingTxs: [...request.requestTracker.missingTxHashes], + }, + ); + return request.requestTracker.collectedTxs; + } + + protected async collectFast(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) { + this.requests.add(request); + const { blockInfo } = request; + + this.log.debug( + `Starting fast collection of ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`, + { ...blockInfo, requestType: request.type, deadline: request.requestTracker.deadline }, + ); + + try { + // 1. Start node collection in the background. + // Note: this will be a noop if no nodes are configured. + const nodeCollectionPromise = this.collectFastFromNodes(request); + + // 2. Wait before starting reqresp, interruptible by cancellation or node exhaustion. + await Promise.race([ + request.requestTracker.cancellationToken, + sleep(this.config.txCollectionFastNodesTimeoutBeforeReqRespMs), + nodeCollectionPromise, // If node collection has finished (or if there are no nodes configured), we can exit early. + ]); + + // 3. Start reqresp in the background (runs in parallel with node collection). + // Note: this will be a noop if all TXs were already found. + const reqRespPromise = this.collectFastViaReqResp(request, opts); + + // 4. Wait before starting file store, interruptible by cancellation. + await Promise.race([ + request.requestTracker.cancellationToken, + sleep(this.config.txCollectionFileStoreFastDelayMs), + reqRespPromise, // If reqresp has finished, we can exit early. + ]); + + // 5. Start file store collection in the background. Self-terminates on tracker cancel / all-found. + // Note: this will be a noop if all TXs were already found. + const fileStorePromise = this.fileStoreFastCollection.startCollecting( + request.requestTracker, + this.getAddContext(request), + ); + + // 6. Wait for all paths to settle. + // NOTE: The request will automatically be cancelled after `opt.deadline` is reached. + await Promise.allSettled([reqRespPromise, nodeCollectionPromise, fileStorePromise]); + } catch (err) { + this.log.error(`Error collecting txs for ${request.type} for slot ${blockInfo.slotNumber}`, err, { + ...blockInfo, + missingTxs: request.requestTracker.missingTxHashes.values().map(txHash => txHash.toString()), + }); + } finally { + request.requestTracker.cancel(); + this.requests.delete(request); + } + } - // Only queue txs that are still missing after the delay. - const missingTxHashStrings = new Set(this.fastCollection.getMissingTxHashes().map(hash => hash.toString())); - const missingTxHashesToCollect = hashes.filter(hash => missingTxHashStrings.has(hash.toString())); - if (missingTxHashesToCollect.length > 0) { - this.fileStoreFastCollection.startCollecting(missingTxHashesToCollect, context, opts.deadline); + /** + * Starts collecting txs from all configured nodes. We send `txCollectionFastMaxParallelRequestsPerNode` requests + * in parallel to each node. We keep track of the number of attempts made to collect each tx, so we can prioritize + * the txs that have been requested less often whenever we need to send a new batch of requests. We ensure that no + * tx is requested more than once at the same time to the same node. + */ + private async collectFastFromNodes(request: FastCollectionRequest): Promise { + if (this.nodes.length === 0) { + return; + } + + // Keep a shared priority queue of all txs pending to be requested, sorted by the number of attempts made to collect them. + const attemptsPerTx = [...request.requestTracker.missingTxHashes].map(txHash => ({ + txHash, + attempts: 0, + found: false, + })); + + // Returns once we have finished all node loops. Each loop finishes when the deadline is hit, or all txs have been collected. + await Promise.allSettled(this.nodes.map(node => this.collectFastFromNode(request, node, attemptsPerTx))); + } + + private async collectFastFromNode( + request: FastCollectionRequest, + node: TxSource, + attemptsPerTx: { txHash: string; attempts: number; found: boolean }[], + ) { + const notFinished = () => !request.requestTracker.checkCancelled(); + + const maxParallelRequests = this.config.txCollectionFastMaxParallelRequestsPerNode; + const maxBatchSize = this.config.txCollectionNodeRpcMaxBatchSize; + const activeRequestsToThisNode = new Set(); // Track the txs being actively requested to this node + + const processBatch = async () => { + while (notFinished()) { + // Pull tx hashes from the attemptsPerTx array, which is sorted by attempts, + // so we prioritize txs that have been requested less often. + const batch = []; + let index = 0; + while (batch.length < maxBatchSize) { + const txToRequest = attemptsPerTx[index++]; + if (!txToRequest) { + // No more txs to process + break; + } else if (!request.requestTracker.isMissing(txToRequest.txHash)) { + // Mark as found if it was found somewhere else, we'll then remove it from the array. + // We don't delete it now since 'array.splice' is pretty expensive, so we do it after sorting. + txToRequest.found = true; + } else if (!activeRequestsToThisNode.has(txToRequest.txHash)) { + // If the tx is not already being requested to this node, add it to the current batch and increase attempts. + // Note that we increase the attempts *before* making the request, so the next `collectFastFromNode` that + // needs to grab txs to send, will pick txs that have been requested less often, instead of all requesting + // the same txs at the same time. + batch.push(txToRequest); + activeRequestsToThisNode.add(txToRequest.txHash); + txToRequest.attempts++; } - }) - .catch(err => this.log.error('Error in file store fast delay', err)); + } + + // After modifying the array by removing txs or updating attempts, re-sort it and trim the found txs from the end. + attemptsPerTx.sort((a, b) => + a.found === b.found ? a.attempts - b.attempts : Number(a.found) - Number(b.found), + ); + const firstFoundTxIndex = attemptsPerTx.findIndex(tx => tx.found); + if (firstFoundTxIndex !== -1) { + attemptsPerTx.length = firstFoundTxIndex; + } + + // If we see no more txs to request, we can stop this "process" loop + if (batch.length === 0) { + return; + } + + const txHashes = batch.map(({ txHash }) => txHash); + // Collect this batch from the node + await this.txCollectionSink.collect( + async () => { + const result = await node.getTxsByHash(txHashes.map(TxHash.fromString)); + for (const tx of result.validTxs) { + request.requestTracker.markFetched(tx); + } + return result; + }, + txHashes, + { + description: `fast ${node.getInfo()}`, + node: node.getInfo(), + method: 'fast-node-rpc', + ...request.blockInfo, + }, + this.getAddContext(request), + ); + + // Clear from the active requests the txs we just requested + for (const requestedTx of batch) { + activeRequestsToThisNode.delete(requestedTx.txHash); + } + + // Sleep a bit until hitting the node again, but wake up immediately on cancellation + if (notFinished()) { + await Promise.race([ + sleep(this.config.txCollectionFastNodeIntervalMs), + request.requestTracker.cancellationToken, + ]); + } + } + }; + + // Kick off N parallel requests to the node, up to the maxParallelRequests limit + await Promise.all(times(maxParallelRequests, processBatch)); + } + + private async collectFastViaReqResp(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) { + const pinnedPeer = opts.pinnedPeer; + const blockInfo = request.blockInfo; + const slotNumber = blockInfo.slotNumber; + if (request.requestTracker.timeoutMs < 100) { + this.log.warn( + `Not initiating fast reqresp for txs for ${request.type} at slot ${blockInfo.slotNumber} due to timeout`, + { timeoutMs: request.requestTracker.timeoutMs, ...blockInfo }, + ); + return; + } + + if (request.requestTracker.checkCancelled()) { + this.log.debug(`No txs to collect via reqresp for ${request.type} at slot ${blockInfo.slotNumber}`, { + ...blockInfo, + }); + return; } - return this.fastCollection.collectFastFor(input, txHashes, opts); + this.log.debug( + `Starting fast reqresp for ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`, + { ...blockInfo, timeoutMs: request.requestTracker.timeoutMs, pinnedPeer }, + ); + + try { + await this.txCollectionSink.collect( + async () => { + let blockTxsSource: BlockTxsSource; + if (request.type === 'proposal') { + blockTxsSource = request.blockProposal; + } else if (request.type === 'block') { + blockTxsSource = { + txHashes: request.block.body.txEffects.map(e => e.txHash), + archive: request.block.archive.root, + }; + } else { + throw new Error(`Unknown request type: ${(request as { type: string }).type}`); + } + + const result = await this.reqRespTxsCollector!(request.requestTracker, blockTxsSource, pinnedPeer); + return { validTxs: result, invalidTxHashes: [] }; + }, + Array.from(request.requestTracker.missingTxHashes), + { description: `reqresp for slot ${slotNumber}`, method: 'fast-req-resp', ...opts, ...request.blockInfo }, + this.getAddContext(request), + ); + } catch (err) { + this.log.error(`Error sending fast reqresp request for txs`, err, { + txs: [...request.requestTracker.missingTxHashes], + ...blockInfo, + }); + } } - /** Returns the TxAddContext for the given fast collection request input */ - private getAddContextForInput(input: FastCollectionRequestInput): TxAddContext { - if (input.type === 'proposal') { - return { type: 'proposal', blockHeader: input.blockProposal.blockHeader }; + /** Returns the TxAddContext for the given request, used by the sink to add txs to the pool correctly. */ + private getAddContext(request: FastCollectionRequest): TxAddContext { + if (request.type === 'proposal') { + return { type: 'proposal', blockHeader: request.blockProposal.blockHeader }; } else { - return { type: 'mined', block: input.block }; + return { type: 'mined', block: request.block }; } } - /** Mark the given txs as found. Stops collecting them. */ + /** Mark the given txs as found. Stops collecting them across all in-flight requests. */ private foundTxs(txs: Tx[]) { - this.fastCollection.foundTxs(txs); - this.fileStoreFastCollection.foundTxs(txs); + for (const request of this.requests) { + for (const tx of txs) { + if (request.requestTracker.markFetched(tx)) { + this.log.trace(`Found tx ${tx.txHash.toString()} for fast collection request`, { + ...request.blockInfo, + txHash: tx.txHash.toString(), + type: request.type, + }); + if (request.requestTracker.allFetched()) { + this.log.trace(`All txs found for fast collection request`, { + ...request.blockInfo, + type: request.type, + }); + break; + } + } + } + } } /** @@ -194,8 +447,11 @@ export class TxCollection { * To be called when we no longer care about gathering txs up to a certain block, eg when they become proven or finalized. */ public stopCollectingForBlocksUpTo(blockNumber: BlockNumber): void { - this.fastCollection.stopCollectingForBlocksUpTo(blockNumber); - this.fileStoreFastCollection.clearPending(); + for (const request of this.requests) { + if (request.blockInfo.blockNumber <= blockNumber) { + request.requestTracker.cancel(); + } + } } /** @@ -203,7 +459,10 @@ export class TxCollection { * To be called when there is a chain prune and previously mined txs are no longer relevant. */ public stopCollectingForBlocksAfter(blockNumber: BlockNumber): void { - this.fastCollection.stopCollectingForBlocksAfter(blockNumber); - this.fileStoreFastCollection.clearPending(); + for (const request of this.requests) { + if (request.blockInfo.blockNumber > blockNumber) { + request.requestTracker.cancel(); + } + } } } diff --git a/yarn-project/p2p/src/services/tx_file_store/tx_file_store.ts b/yarn-project/p2p/src/services/tx_file_store/tx_file_store.ts index 063c6256680f..25b7d995c63e 100644 --- a/yarn-project/p2p/src/services/tx_file_store/tx_file_store.ts +++ b/yarn-project/p2p/src/services/tx_file_store/tx_file_store.ts @@ -1,3 +1,4 @@ +import { FifoSet } from '@aztec/foundation/fifo-set'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { RunningPromise } from '@aztec/foundation/promise'; import { makeBackoff, retry } from '@aztec/foundation/retry'; @@ -10,6 +11,8 @@ import type { TxPoolV2 } from '../../mem_pools/index.js'; import type { TxFileStoreConfig } from './config.js'; import { TxFileStoreInstrumentation } from './instrumentation.js'; +const MAX_RECENT_UPLOADS = 1000; + /** * Uploads validated transactions to a file store as a fallback retrieval mechanism. * Listens to TxPool txs-added events and uploads txs asynchronously with bounded concurrency. @@ -21,9 +24,7 @@ export class TxFileStore { private readonly handleTxsAdded: (args: { txs: Tx[]; source?: string }) => void; /** Recently uploaded tx hashes for deduplication. */ - private recentUploads: Set = new Set(); - private recentUploadsOrder: string[] = []; - private readonly maxRecentUploads = 1000; + private recentUploads = FifoSet.withLimit(MAX_RECENT_UPLOADS); private constructor( private readonly fileStore: FileStore, @@ -127,24 +128,11 @@ export class TxFileStore { const path = `${this.basePath}/txs/${txHash}.bin`; const timer = new Timer(); - if (this.recentUploads.has(txHash)) { + if (!this.recentUploads.addIfAbsent(txHash)) { return; } try { - this.recentUploads.add(txHash); - this.recentUploadsOrder.push(txHash); - - if (this.recentUploadsOrder.length > this.maxRecentUploads) { - // delete old entries in recentUploads - for (const txHashToRemove of this.recentUploadsOrder.splice( - 0, - this.recentUploadsOrder.length - this.maxRecentUploads, - )) { - this.recentUploads.delete(txHashToRemove); - } - } - await retry( () => this.fileStore.save(path, tx.toBuffer(), { compress: true }), `Uploading tx ${txHash}`, diff --git a/yarn-project/p2p/src/services/tx_provider.ts b/yarn-project/p2p/src/services/tx_provider.ts index 311e31162351..5004ba6eb532 100644 --- a/yarn-project/p2p/src/services/tx_provider.ts +++ b/yarn-project/p2p/src/services/tx_provider.ts @@ -32,6 +32,11 @@ export class TxProvider implements ITxProvider { this.instrumentation = new TxProviderInstrumentation(client, 'TxProvider'); } + /** Returns whether each tx hash is currently in the local tx pool. */ + public hasTxs(txHashes: TxHash[]): Promise { + return this.txPool.hasTxs(txHashes); + } + /** Returns txs from the tx pool given their hashes.*/ public async getAvailableTxs(txHashes: TxHash[]): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> { const response = await this.txPool.getTxsByHash(txHashes); diff --git a/yarn-project/p2p/src/test-helpers/mock-pubsub.ts b/yarn-project/p2p/src/test-helpers/mock-pubsub.ts index a537a25c5e35..ac1f1109b9ac 100644 --- a/yarn-project/p2p/src/test-helpers/mock-pubsub.ts +++ b/yarn-project/p2p/src/test-helpers/mock-pubsub.ts @@ -23,15 +23,12 @@ import type { MemPools } from '../mem_pools/interface.js'; import { DummyPeerDiscoveryService, DummyPeerManager, LibP2PService } from '../services/index.js'; import type { P2PReqRespConfig } from '../services/reqresp/config.js'; import type { ConnectionSampler } from '../services/reqresp/connection-sampler/connection_sampler.js'; -import { - type ReqRespInterface, - type ReqRespResponse, - type ReqRespSubProtocol, - type ReqRespSubProtocolHandler, - type ReqRespSubProtocolHandlers, - type ReqRespSubProtocolValidators, - type SubProtocolMap, - responseFromBuffer, +import type { + ReqRespInterface, + ReqRespResponse, + ReqRespSubProtocol, + ReqRespSubProtocolHandler, + ReqRespSubProtocolHandlers, } from '../services/reqresp/interface.js'; import { ReqRespStatus } from '../services/reqresp/status.js'; import { GossipSubEvent } from '../types/index.js'; @@ -89,8 +86,8 @@ export function getMockPubSubP2PServiceFactory( /** * Mock implementation of ReqRespInterface that routes requests to other peers' handlers through the mock network. - * When a peer calls sendBatchRequest, the mock iterates over network peers and invokes their registered handler - * for the sub-protocol, simulating the request-response protocol without actual libp2p streams. + * When a peer calls sendRequestToPeer, the mock looks up the target peer's registered handler for the + * sub-protocol and invokes it, simulating the request-response protocol without actual libp2p streams. */ class MockReqResp implements ReqRespInterface { private handlers: Partial = {}; @@ -106,19 +103,12 @@ class MockReqResp implements ReqRespInterface { updateConfig(_config: Partial): void {} setShouldRejectPeer(): void {} - start( - subProtocolHandlers: Partial, - _subProtocolValidators: ReqRespSubProtocolValidators, - ): Promise { + start(subProtocolHandlers: Partial): Promise { Object.assign(this.handlers, subProtocolHandlers); return Promise.resolve(); } - addSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { + addSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise { this.handlers[subProtocol] = handler; return Promise.resolve(); } @@ -132,46 +122,6 @@ class MockReqResp implements ReqRespInterface { return this.handlers[subProtocol]; } - async sendBatchRequest( - subProtocol: SubProtocol, - requests: InstanceType[], - pinnedPeer: PeerId | undefined, - _timeoutMs?: number, - _maxPeers?: number, - _maxRetryAttempts?: number, - ): Promise[]> { - const responses: InstanceType[] = []; - const peers = this.network.getReqRespPeers().filter(p => !p.peerId.equals(this.peerId)); - const targetPeers = pinnedPeer ? peers.filter(p => p.peerId.equals(pinnedPeer)) : peers; - const delayMs = this.network.getPropagationDelayMs(); - - if (delayMs > 0) { - await sleep(delayMs); - } - - for (const request of requests) { - const requestBuffer = request.toBuffer(); - for (const peer of targetPeers) { - const handler = peer.getHandler(subProtocol); - if (!handler) { - continue; - } - try { - const responseBuffer = await handler(this.peerId, requestBuffer); - if (responseBuffer.length > 0) { - const response = responseFromBuffer(subProtocol, responseBuffer); - responses.push(response as InstanceType); - break; - } - } catch (err) { - this.logger.debug(`Mock reqresp handler error from peer ${peer.peerId}`, { err }); - } - } - } - - return responses; - } - async sendRequestToPeer( peerId: PeerId, subProtocol: ReqRespSubProtocol, diff --git a/yarn-project/p2p/src/test-helpers/reqresp-nodes.ts b/yarn-project/p2p/src/test-helpers/reqresp-nodes.ts index 8c6d75faa637..8f9bbbbda460 100644 --- a/yarn-project/p2p/src/test-helpers/reqresp-nodes.ts +++ b/yarn-project/p2p/src/test-helpers/reqresp-nodes.ts @@ -43,8 +43,6 @@ import { ReqRespSubProtocol, type ReqRespSubProtocolHandlers, type ReqRespSubProtocolRateLimits, - type ReqRespSubProtocolValidators, - noopValidator, } from '../services/reqresp/interface.js'; import { pingHandler } from '../services/reqresp/protocols/index.js'; import { ReqResp } from '../services/reqresp/reqresp.js'; @@ -199,17 +197,6 @@ export const MOCK_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers = { [ReqRespSubProtocol.BLOCK_TXS]: (_msg: any) => Promise.resolve(Buffer.from('block_txs')), }; -// By default, all requests are valid -// If you want to test an invalid response, you can override the validator -export const MOCK_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = { - [ReqRespSubProtocol.PING]: noopValidator, - [ReqRespSubProtocol.STATUS]: noopValidator, - [ReqRespSubProtocol.TX]: noopValidator, - [ReqRespSubProtocol.GOODBYE]: noopValidator, - [ReqRespSubProtocol.AUTH]: noopValidator, - [ReqRespSubProtocol.BLOCK_TXS]: noopValidator, -}; - /** * @param numberOfNodes - the number of nodes to create * @returns An array of the created nodes @@ -222,13 +209,9 @@ export const createNodes = ( return timesParallel(numberOfNodes, () => createReqResp(peerScoring, rateLimits)); }; -export const startNodes = async ( - nodes: ReqRespNode[], - subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS, - subProtocolValidators = MOCK_SUB_PROTOCOL_VALIDATORS, -) => { +export const startNodes = async (nodes: ReqRespNode[], subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS) => { for (const node of nodes) { - await node.req.start(subProtocolHandlers, subProtocolValidators); + await node.req.start(subProtocolHandlers); } }; diff --git a/yarn-project/p2p/src/test-helpers/test_tx_provider.ts b/yarn-project/p2p/src/test-helpers/test_tx_provider.ts index 20ae98e634f2..6e4ae3a9b91a 100644 --- a/yarn-project/p2p/src/test-helpers/test_tx_provider.ts +++ b/yarn-project/p2p/src/test-helpers/test_tx_provider.ts @@ -31,6 +31,11 @@ export class TestTxProvider implements ITxProvider { return this.getTxsByHashes(txHashes); } + /** Returns whether each tx hash is in the seeded collection. */ + hasTxs(txHashes: TxHash[]): Promise { + return Promise.resolve(txHashes.map(h => this.txs.has(h.toString()))); + } + /** Get txs for a block proposal, returning any seeded txs that match the requested hashes. */ getTxsForBlockProposal( blockProposal: BlockProposal, diff --git a/yarn-project/p2p/src/test-helpers/testbench-utils.ts b/yarn-project/p2p/src/test-helpers/testbench-utils.ts index 17bd755a724c..2c1d982f92fb 100644 --- a/yarn-project/p2p/src/test-helpers/testbench-utils.ts +++ b/yarn-project/p2p/src/test-helpers/testbench-utils.ts @@ -4,12 +4,7 @@ import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; import type { Logger } from '@aztec/foundation/log'; import type { L2Block, L2BlockId } from '@aztec/stdlib/block'; import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import type { - BlockProposal, - CheckpointAttestation, - CheckpointProposal, - CheckpointProposalCore, -} from '@aztec/stdlib/p2p'; +import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore } from '@aztec/stdlib/p2p'; import { type BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx'; import EventEmitter from 'events'; @@ -215,6 +210,7 @@ export class InMemoryTxPool extends EventEmitter implements TxPoolV2 { */ export class InMemoryAttestationPool { private proposals = new Map(); + private checkpoints = new Map(); tryAddBlockProposal(blockProposal: BlockProposal): Promise { const id = blockProposal.archive.toString(); @@ -230,12 +226,25 @@ export class InMemoryAttestationPool { return Promise.resolve(this.proposals.get(id)); } - tryAddCheckpointProposal(_proposal: CheckpointProposal): Promise { + tryAddCheckpointProposal(proposal: CheckpointProposalCore): Promise { + const proposals = this.checkpoints.get(proposal.slotNumber) ?? []; + proposals.push(proposal); + this.checkpoints.set(proposal.slotNumber, proposals); return Promise.resolve({ added: true, alreadyExists: false, count: 1 }); } - getCheckpointProposal(_slot: SlotNumber): Promise { - return Promise.resolve(undefined); + getCheckpointProposal(slot: SlotNumber): Promise { + return Promise.resolve(this.checkpoints.get(slot)?.[0]); + } + + getProposalsForSlot(slot: SlotNumber): Promise<{ + blockProposals: BlockProposal[]; + checkpointProposals: CheckpointProposalCore[]; + }> { + return Promise.resolve({ + blockProposals: [...this.proposals.values()].filter(proposal => proposal.slotNumber === slot), + checkpointProposals: this.checkpoints.get(slot) ?? [], + }); } async addOwnCheckpointAttestations(_attestations: CheckpointAttestation[]): Promise {} @@ -262,11 +271,12 @@ export class InMemoryAttestationPool { } isEmpty(): Promise { - return Promise.resolve(this.proposals.size === 0); + return Promise.resolve(this.proposals.size === 0 && this.checkpoints.size === 0); } resetState(): void { this.proposals.clear(); + this.checkpoints.clear(); } } diff --git a/yarn-project/p2p/src/testbench/p2p_client_testbench_worker.ts b/yarn-project/p2p/src/testbench/p2p_client_testbench_worker.ts index 0ad602106c6a..274c86272f13 100644 --- a/yarn-project/p2p/src/testbench/p2p_client_testbench_worker.ts +++ b/yarn-project/p2p/src/testbench/p2p_client_testbench_worker.ts @@ -23,7 +23,7 @@ import type { DataStoreConfig } from '@aztec/stdlib/kv-store'; import { type BlockProposal, P2PMessage } from '@aztec/stdlib/p2p'; import { ChonkProof } from '@aztec/stdlib/proofs'; import { makeAztecAddress, makeBlockHeader, makeBlockProposal, mockTx } from '@aztec/stdlib/testing'; -import { Tx, TxHash, type TxValidationResult } from '@aztec/stdlib/tx'; +import { Tx, TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx'; import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client'; import type { Message, PeerId } from '@libp2p/interface'; @@ -38,7 +38,6 @@ import { LibP2PService } from '../services/index.js'; import type { PeerManager } from '../services/peer-manager/peer_manager.js'; import { BatchTxRequester } from '../services/reqresp/batch-tx-requester/batch_tx_requester.js'; import type { BatchTxRequesterLibP2PService } from '../services/reqresp/batch-tx-requester/interface.js'; -import type { IBatchRequestTxValidator } from '../services/reqresp/batch-tx-requester/tx_validator.js'; import { RateLimitStatus } from '../services/reqresp/rate-limiter/rate_limiter.js'; import type { ReqResp } from '../services/reqresp/reqresp.js'; import type { PeerDiscoveryService } from '../services/service.js'; @@ -276,10 +275,8 @@ async function runAggregatorBenchmark( } } - const noopTxValidator: IBatchRequestTxValidator = { - validateRequestedTx: (_tx: Tx): Promise => Promise.resolve({ result: 'valid' }), - validateRequestedTxs: (txs: Tx[]): Promise => - Promise.resolve(txs.map(() => ({ result: 'valid' }))), + const noopTxValidator: TxValidator = { + validateTx: (_tx: Tx): Promise => Promise.resolve({ result: 'valid' }), }; timer = new Timer(); diff --git a/yarn-project/protocol-contracts/fixtures/ContractClassPublishedEventData.hex b/yarn-project/protocol-contracts/fixtures/ContractClassPublishedEventData.hex index 6619699e7cb2..efa62eb0bde0 100644 --- a/yarn-project/protocol-contracts/fixtures/ContractClassPublishedEventData.hex +++ b/yarn-project/protocol-contracts/fixtures/ContractClassPublishedEventData.hex @@ -1 +1 @@ -000000000000000000000000000000000000000000000000000000000000000320f5895a4e837356c2d551743df6bf642756dcd93cd31cbd37c556c90bf7f2441c2459719688b73599862bb4192cf567006eaf1fd7382d84f842a6f3616b326c0000000000000000000000000000000000000000000000000000000000000001237dfcd925241181677bde88f3ea51653dd144811eda2d9f208eee7c6b42f50a07be998ba5208ae3c3c9329157a2c586b26d7489a3e4be5af66e6a1b70e4357a0000000000000000000000000000000000000000000000000000000000000e04002700020401280000010480472700000447250000004127020304012702040400001f0a0003000400462d0846022500000075270202044727020304003b0e00000300022c0000430030644e72e131a029b85045b68181585d2833e84879b970009143e1f593f00000002900004404ffffffff2700450403262902000300324d00e62f0a2a02030427020504002702070403002a0507062d080103000801060100270303040100220302062d0e050600220602062d0e05062702060403002a030006052702050401270206040227020704002702080101270209010027020a0000002902000b00c732f9772b02000c0000000000000000020000000000000000002b02000d00000000000000000300000000000000002902000e00d9b5157824000200040000012323000006202d08010427020f04030008010f01270304040100002204020f1f3a00060005000f002a04050f2d0b0f0f002a0406102d0b1010001e020004001e020011001e020011002d080112270213040300080113012703001204010022120213360e0011001300002a1205132d0b1313002a1206142d0b0014141c0a131200042a12141524020013000001b027021204003c0612012d080001122702130403000801130127031204010022120213360e0011001302002a001205112d0b1111002a1206132d0b13131c0a111200042a1213142402001100000001fc27021204003c0612012d0801112702120402000801120127031104010000221102121f3a000500070012002a1105122d0b12121c0a1213041c0a131100002d08011227021304030008011301270312040100221202131f3a00060005000013002a1205132d0b1313002a1206162d0b16162902001200d52de36b2d0800011727021804050008011801270317040100221702182d0a18192d0e12190000221902192d0e131900221902192d0e161900221902192d0e0d192d08011227000213040500080113012703120401002217021300221202163f0f0013001600002a1205132d0b1313290200120016f8af272d0801162702170405000801170100270316040100221602172d0a17182d0e121800221802182d0e11180022180200182d0e131800221802182d0e0d182d08011127021204050008011201270311000401002216021200221102133f0f00120013002a1105122d0b12120a2a1412001124020011000003532500000d540a2a150a111e020012010a22124313160a0013141c0a141600042a1612140a2a130912240200120000038627021604003c000616010a2a151412122a111213240200130000039d2500000d662d0801112700021204040008011201270311040100221102122d0a12132d0e0e130022130200132d0e0f1300221302132d0e1013002211020f390320004400440004004500000f200200042102000f2d080111270210040000221102132d0b1313270214040003002a111412223a000f000700122d0a0f13270311040100221102142d0e13001400221402142d0e13142702150403002a131514000801140127021404002d000a131506221502150a2a1014162d0a1510240200160000045a2d0a10102402000016000004740a2a10151724020017000004742500000d782402000400000400aa23000004812d0b110400220402042d0e0411002211020f2d0b0f0f270212000403002a1112043c0e0f0423000004aa0a2a10070424020004000004c02702000f04003c060f011e020004002d08010f2702100403000801100127030f04010000220f0210360e0004001002002a0f05102d0b1010002a0f06112d0b11111c000a100f00042a0f1112240200100000051127020f04003c060f012902000f0000ede022762d08011027021104050008011101270310040100221002112d0a1100132d0e0f1300221302132d0e041300221302132d0e121300221302132d0e0d00132d08010427020f04050008010f012703040401002210020f00220402113f000f000f0011002a04050f2d0b0f0f3402000f1e020004002d08010f270210040005000801100127030f040100220f02102d0a10112d0e0b1100221102112d0e00041100221102112d0e0a1100221102112d0e0c112d0801042702100405000800011001270304040100220f021000220402113f0f00100011002a04050f2d0b000f0f3402000f2d0b030400220402042d0e0403002203020f2d0b0f0f270210000403002a0310043b0e000f0004230000062029020004005bd9f2da0a2a0204000f27020400022902001000ef52534d2402000f00000649230000083a2d0801000f2702110403000801110127030f040100220f02111f3a000600050011002a000f05112d0b1111002a0f06122d0b12121e02000f001e02000f001e02000f00002d08011327021404050008011401270313040100221302142d0a14152d0e0b001500221502152d0e0f1500221502152d0e0a1500221502152d0e0c152d0801000f2702140405000801140127030f0401002213021400220f02153f0f0014000015002a0f05132d0b13131e02000f002902001400036d527f2d0801152702160004050008011601270315040100221502162d0a16172d0e141700221702172d000e0f1700221702172d0e131700221702172d0e0d172d08010f270213040500000801130127030f0401002215021300220f02143f0f00130014002a0f05132d000b1313330a0013000f2402000f000007792500000d8a2d08010f270213040500000801130127030f040100220f02132d0a13142d0e101400221402142d0e04001400221402142d0e111400221402142d0e0d142d0801112702130405000801001301270311040100220f021300221102143f0f00130014002a11050f2d0b0f000f0a2a0f0a110a2a11091324020013000007f72500000d9c1e020011002f2a00000f00110013002a131211300a0011000f2d0b030f00220f020f2d0e0f030000220302112d0b11112702120403002a03120f3b0e0011000f230000083a0a2a00020e0f2402000f0000084c23000009492d08010e27020f04030008010f012700030e040100220e020f1f3a00060005000f002a0e050f2d0b0f0f002a0e0611002d0b11111e020006001e020006002d08010627020e04050008010e01270306000401002206020e2d0a0e122d0e101200221202122d0e041200221202122d0e000f1200221202122d0e0d122d08010e27020f04050008010f0127030e040100002206020f00220e02123f0f000f0012002a0e05062d0b06060a2a060a0e0a2a000e090f2402000f000009062500000d9c1e02000e002f2a0006000e000f002a000f110e300a000e00062d0b030600220602062d0e0603002203020e2d0b0e0e0027020f0403002a030f063b0e000e000623000009492902000600bb19097e0a002a02060e2402000e000009642300000a932d08010627020e04020008010e01002703060401002206020e1f3a00050005000e002a06050e2d0b0e0e1e02000600001e020006001e0200060924020006000009a92500000dae2d08010627020f0004050008010f012703060401002206020f2d0a0f112d0e101100221102112d000e041100221102112d0e0e1100221102112d0e0d112d08010427020d0405000008010d012703040401002206020d002204020e3f0f000d000e002a0405062d000b06060a2a060a040a2a04090d2402000d00000a272500000d9c1e02000400002f2a00060004000d270206040127020f0403002a060f0e2d0801040008010e00012703040401002204020e2d0e060e00220e020e2d0e060e27020e0403002a00040e062d0a060e2d0e0d0e002204020d2d0b0d0d27020e0403002a040e063b000e000d00062300000a932902000400ee21e57b0a2a0204062402000600000a00ae2300000b8e1e020004010a22044306160a060d1c0a0d0e00042a0e040d0a002a0609042402000400000adc27020e04003c060e011e020004000a2a0d0406002402000600000af32500000dc01e020004002d08010627020d04050008010d00012703060401002206020d2d0a0d0e2d0e0b0e00220e020e2d0e040e00220e00020e2d0e0a0e00220e020e2d0e0c0e2d08010427020a04050008010a01270300040401002206020a002204020b3f0f000a000b002a0405062d0b060634020000062d0b030400220402042d0e040300220302052d0b05052702060403002a030006043b0e000500042300000b8e2702030255270204026e270205026b27020600026f270207027727020a022027020b027327020c026527020d026c27020e02006327020f02742702100272270211027b270212027d2d080113270214041c000008011401270313040100221302142d0a14152d0e031500221502152d0e04150000221502152d0e051500221502152d0e041500221502152d0e06150022150200152d0e071500221502152d0e041500221502152d0e0a1500221502152d0e0b001500221502152d0e0c1500221502152d0e0d1500221502152d0e0c150022150002152d0e0e1500221502152d0e0f1500221502152d0e061500221502152d0e00101500221502152d0e0a1500221502152d0e111500221502152d0e0b150022001502152d0e0c1500221502152d0e0d1500221502152d0e0c1500221502152d000e0e1500221502152d0e0f1500221502152d0e061500221502152d0e10150000221502152d0e121527020300010a2a0908042402000400000d54270205041e002d080106270207041e00080107012d0a06072a030007059b5bbff74a5bff19000022070207002213020a27020b041b2d020a032d0207042d020b052500000d00d227020a041b002a070a072d0e030700220702072d0e020700220702073c0e0005062a010001058a553a2c2b67c8ef3c040201262a01000105c80d73736ecd00b4e13c040201262a0100010575fef108377c8a4f3c040201262a010001050600613b3d0b9dbd333c040201262a01000105babb21d7823318643c040201262a0001000105c5cc62b50ed35c303c040201262a010001052ab9ecbeb3430ae13c000402012600000305072d0003082d0004092300000df62d0108062d04060900000008020800000902090c0008070a2400000a00000de42600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a \ No newline at end of file +000000000000000000000000000000000000000000000000000000000000000320f5895a4e837356c2d551743df6bf642756dcd93cd31cbd37c556c90bf7f244135e3e6dff88ef7e69c592472939cddff00850a0886c416e47720573cf94db4c000000000000000000000000000000000000000000000000000000000000000124c6b040ea6c3ec2ecf9d6b0c0c709239696f66ea8d27d3bc064852a8bfb579c10b89e84a594728151d2054d9e41999f109fca6895e8bec7894445886adaa5c10000000000000000000000000000000000000000000000000000000000000e1c0027000204012800000104804d270000044d250000004127020304012702040400001f0a00030004004c2d084c0225000000b7270202044d27020304003b0e00000300022c0000430030644e72e131a029b85045b68181585d2833e84879b970009143e1f593f00000002900004404ffffffff2700450403270046000027004700010127004804012900004900c732f9772b00004a0000000000000000020000000000000000002b00004b000000000000000003000000000000000026290200000300324de62f0a2a02030427020504002702070403002a0507062d080103000008010601270303040100220302062d0e050600220602062d0e0506270206040003002a0306052702050402270206040027020701002902000800d9b5157824000200040000012323000006202d0801042702090403000801090127030404010000220402091f3200050048000900220448092d0b0909002a04050a2d0b0a0a001e020004001e02000b001e02000b002d08010c27020d04030008010d012703000c040100220c020d360e000b000d0000220c480d2d0b0d0d002a0c050e2d0b000e0e1c0a0d0c00042a0c0e0f2402000d000001b027020c04003c060c012d0800010c27020d04030008010d0127030c040100220c020d360e000b000d020022000c480b2d0b0b0b002a0c050d2d0b0d0d1c0a0b0c00042a0c0d0e2402000b00000001fc27020c04003c060c012d08010b27020c04020008010c0127030b04010000220b020c1f3800480006000c00220b480c2d0b0c0c1c0a0c0d041c0a0d0b00002d08010c27020d04030008010d0127030c040100220c020d1f320005004800000d00220c480d2d0b0d0d002a0c05102d0b10102902000c00d52de36b2d0800011127021204050008011201270311040100221102122d0a12132d0e0c130000221302132d0e0d1300221302132d0e101300221302132d0c4b132d08010c2700020d04050008010d0127030c0401002211020d00220c02103f0f000d00100000220c480d2d0b0d0d2902000c0016f8af272d0801102702110405000801110100270310040100221002112d0a11122d0e0c1200221202122d0e0b120022120200122d0e0d1200221202122d0c4b122d08010b27020c04050008010c0127030b000401002210020c00220b020d3f0f000c000d00220b480c2d0b0c0c0a2a0e0c000b2402000b000003532500000c770a220f460b1e02000c010a220c430d160a000d0e1c0a0e1000042a100c0e0a2a0d070c2402000c0000038627021004003c000610010a2a0f0e0c122a0b0c0d2402000d0000039d2500000c892d08010b2700020c04040008010c0127030b040100220b020c2d0a0c0d2d0e080d00220d02000d2d0e090d00220d020d2d0e0a0d00220b0209390320004400440004004500000920020004210200092d08010b27020a040000220b020d2d0b0d0d27020e040003002a0b0e0c223a00090006000c2d0a090d27030b040100220b020e2d0e0d000e00220e020e2d0e0d0e27020f0403002a0d0f0e0008010e0127020e04002d000a0d0f06220f020f0a2a0a0e102d0a0f0a240200100000045a2d0a0a0a2402000010000004740a2a0a0f1124020011000004742500000c9b2402000400000400aa23000004812d0b0b0400220402042d0e040b00220b02092d0b090927020c000403002a0b0c043c0e090423000004aa0a2a0a060424020004000004c02702000904003c0609011e020004002d08010927020a04030008010a01270309040100002209020a360e0004000a02002209480a2d0b0a0a002a09050b2d0b0b0b1c000a0a0900042a090b0c2402000a0000051127020904003c060901290200090000ede022762d08010a27020b04050008010b0127030a040100220a020b2d0a0b000d2d0e090d00220d020d2d0e040d00220d020d2d0e0c0d00220d020d2d0c4b000d2d08010427020904050008010901270304040100220a0209002204020b3f000f0009000b00220448092d0b0909340200091e020004002d08010927020a0400050008010a012703090401002209020a2d0a0a0b2d0c490b00220b020b2d0e00040b00220b020b2d0c460b00220b020b2d0c4a0b2d08010427020a0405000800010a012703040401002209020a002204020b3f0f000a000b00220448092d0b000909340200092d0b030400220402042d0e040300220302092d0b090927020a000403002a030a043b0e00090004230000062029020004005bd9f2da0a2a0204000927020400022902000a00ef52534d2402000900000649230000075d2d0801000927020b04030008010b012703090401002209020b1f3200050048000b00220009480b2d0b0b0b002a09050c2d0b0c0c1e020009001e02000900270209040d002d08000d00080009002500000cad2d0200002d08010927020d04050008010d00012703090401002209020d2d0a0d0e2d0e0a0e00220e020e2d0e040e00220e00020e2d0e0b0e00220e020e2d0c4b0e2d08010b27020d04050008010d012703000b0401002209020d00220b020e3f0f000d000e00220b48092d0b09090a220900460b0a2a0b070d2402000d0000071a2500000da21e02000b002f2a0009000b00000d002a0d0c0b300a000b00092d0b030900220902092d0e0903002203020b002d0b0b0b27020c0403002a030c093b0e000b0009230000075d0a2a02080924000200090000076f230000086c2d0801082702090403000801090127030804010000220802091f3200050048000900220848092d0b0909002a08050b2d0b0b0b001e020005001e020005002d0801052702080405000801080127030504010022000502082d0a080c2d0e0a0c00220c020c2d0e040c00220c020c2d0e090c0022000c020c2d0c4b0c2d080108270209040500080109012703080401002205020900002208020c3f0f0009000c00220848052d0b05050a220546080a2a0807092400020009000008292500000da21e020008002f2a000500080009002a090b0830000a000800052d0b030500220502052d0e050300220302082d0b0808270209040003002a0309053b0e00080005230000086c2902000500bb19097e0a2a02050800240200080000088723000009b62d0801052702080402000801080127030504000100220502081f3000480048000800220548082d0b08081e020005001e02000005001e0200050924020005000008cc2500000db42d0801052702090405000800010901270305040100220502092d0a090b2d0e0a0b00220b020b2d0e040b0000220b020b2d0e080b00220b020b2d0c4b0b2d08010427020804050008010801002703040401002205020800220402093f0f0008000900220448052d0b05050a00220546040a2a040708240200080000094a2500000da21e020004002f2a00050000040008270205040127020a0403002a050a092d080104000801090127030400040100220402092d0e050900220902092d0e05092702090403002a0409052d000a05092d0e080900220402082d0b08082702090403002a0409053b0e000800000523000009b62902000400ee21e57b0a2a02040524020005000009d1230000000ab11e020004010a22044305160a05081c0a080900042a0904080a2a0507040024020004000009ff27020904003c0609011e020004000a2a080405240200050000000a162500000dc61e020004002d0801052702080405000801080127030500040100220502082d0a08092d0c490900220902092d0e040900220902092d0c00460900220902092d0c4a092d08010427020804050008010801270304040100002205020800220402093f0f0008000900220448052d0b0505340200052d0b03000400220402042d0e040300220302052d0b05052702080403002a0308043b0e00000500042300000ab12702030255270204026e270205026b270206026f270200080277270209022027020a027327020b026527020c026c27020d026327020e00027427020f0272270210027b270211027d2d080112270213041c000801130100270312040100221202132d0a13142d0e031400221402142d0e04140022140200142d0e051400221402142d0e041400221402142d0e061400221402142d0e08001400221402142d0e041400221402142d0e091400221402142d0e0a140022140002142d0e0b1400221402142d0e0c1400221402142d0e0b1400221402142d0e000d1400221402142d0e0e1400221402142d0e061400221402142d0e0f140022001402142d0e091400221402142d0e101400221402142d0e0a1400221402142d000e0b1400221402142d0e0c1400221402142d0e0b1400221402142d0e0d140000221402142d0e0e1400221402142d0e061400221402142d0e0f140022140214002d0e111427020300010a220747042402000400000c77270205041e2d08010600270208041e00080108012d0a06082a030008059b5bbff74a5bff19002208020008002212020927020a041b2d0209032d0208042d020a052500000dd827020900041b002a0809082d0e030800220802082d0e020800220802083c0e05062a01000001058a553a2c2b67c8ef3c040201262a01000105c80d73736ecdb4e13c04000201262a0100010575fef108377c8a4f3c040201261e020002002d0801032700020404050008010401270303040100220302042d0a04052d0c49050022050200052d0e020500220502052d0c460500220502052d0c4a052d08010227020404000500080104012703020401002203020400220202053f0f000400050022024800032d0b03031e020002002902000400036d527f2d0801052702060405000801000601270305040100220502062d0a06072d0e040700220702072d0e02070022000702072d0e030700220702072d0c4b072d08010227020304050008010301270003020401002205020300220202043f0f0003000400220248032d0b0303330a00000300022402000200000da12500000e0a262a01000105babb21d782331864003c040201262a01000105c5cc62b50ed35c303c040201262a010001052ab9ec00beb3430ae13c0402012600000305072d0003082d0004092300000dfc2d010800062d040609000008020800000902090c0008070a2400000a00000dea262a010000010506613b3d0b9dbd333c04020126000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b \ No newline at end of file diff --git a/yarn-project/protocol-contracts/fixtures/ContractInstancePublishedEventData.hex b/yarn-project/protocol-contracts/fixtures/ContractInstancePublishedEventData.hex index 91be7f65a8fd..8c62e70d96ce 100644 --- a/yarn-project/protocol-contracts/fixtures/ContractInstancePublishedEventData.hex +++ b/yarn-project/protocol-contracts/fixtures/ContractInstancePublishedEventData.hex @@ -1 +1 @@ -1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a821e212810f887382b564c453919235ecc04ff03f9c5127ac9a630a3fc62cfbbb0000000000000000000000000000000000000000000000000000000000000001108abf493e0af91750b53cd462defc3373f1a522e982af55b0c8ec7d20cf03931c2459719688b73599862bb4192cf567006eaf1fd7382d84f842a6f3616b326c0fb36d433fc86c98e17d214b1024303def3bb1e8fa412bc6e796eb1366b5f55b1366c504bbb3b3bb5d7246d9e082468eae37d93c38705b9eb4ef8bb76dc9b98005c6d6a962e4d7a458aa232dab86841ebcfe4d342556f270f6b2452fd87581bb1e415b163a4af0578cf70ab19e836504a74de9ea3e0c94373ca781436155bfc31fe218da6de686b7a39b092364894c6c2246fee50d0ff9832294cd6b792b8f421aa402e7eafa5c5d6ed9454c794e744eabf3b0c5ed84a35567fbe7509552181808afab9b331786e21a60f1f237a7a0f5457ce547160b82ace9a58a800b170fc1289752f4904779a603001cd6fab021079a04e18f0740eb0e1009088199178d1f26814d31374c3e5c551e28a5467feb67155bb2be160d80ca851babfa60501e61000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f \ No newline at end of file +1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a81a0d9f0f131e602239f499207c271b6319cb33a45b8f917a7c35d8a52a60d2cb00000000000000000000000000000000000000000000000000000000000000022d906f112c4a0f17792dbb184f229b5e5fe22d3ae04eb78736ce9ae0e35e49fc14cc2f3a2417ec81f84c15b1517cef38654c29ace9d54f5a4a22ce1709cc5fc90dad6f31fca9cac105434c9d0071a24a38da659700aee09d285b5ceae94ff5fe00000000000000000000000000000000000000000000000000000000000000002f6b4b954efabd4f61fe64c1704e82f62760c1a0b5ec1ab88e272fae2f3f0d6c21f72071d5882ea13df29918cbaad0d60a11f61309ece108e61d7102b62ec1b50460480b46dcfd5c3262004f191fecf11f321d74618d761e6bcadc691078b4210c0e28c4de1167675c811c52defc32dae2245315682dd349b26ef9c3161b1f96222398ec917e21cb0cbac7050610c2bcb0c2fedfc637bf03d59094b7fd9ce18600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d \ No newline at end of file diff --git a/yarn-project/protocol-contracts/src/class-registry/__snapshots__/contract_class_published_event.test.ts.snap b/yarn-project/protocol-contracts/src/class-registry/__snapshots__/contract_class_published_event.test.ts.snap index 82c511c761eb..7a1833ae133f 100644 --- a/yarn-project/protocol-contracts/src/class-registry/__snapshots__/contract_class_published_event.test.ts.snap +++ b/yarn-project/protocol-contracts/src/class-registry/__snapshots__/contract_class_published_event.test.ts.snap @@ -2,10 +2,10 @@ exports[`ContractClassPublishedEvent parses an event as emitted by the ContractClassRegistry 1`] = ` ContractClassPublishedEvent { - "artifactHash": Fr<0x237dfcd925241181677bde88f3ea51653dd144811eda2d9f208eee7c6b42f50a>, - "contractClassId": Fr<0x1c2459719688b73599862bb4192cf567006eaf1fd7382d84f842a6f3616b326c>, - "packedPublicBytecode": Buffer<0x27000204012800000104804727000004472500000041270203040127020404001f0a0003000400462d0846022500000075270202044727020304003b0e000300022c0000430030644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000002900004404ffffffff2700450403262902000300324de62f0a2a02030427020504002702070403002a0507062d0801030008010601270303040100220302062d0e050600220602062d0e05062702060403002a0306052702050401270206040227020704002702080101270209010027020a00002902000b00c732f9772b02000c00000000000000000200000000000000002b02000d00000000000000000300000000000000002902000e00d9b51578240200040000012323000006202d08010427020f04030008010f012703040401002204020f1f3a00060005000f002a04050f2d0b0f0f002a0406102d0b10101e020004001e020011001e020011002d0801122702130403000801130127031204010022120213360e0011001300002a1205132d0b1313002a1206142d0b14141c0a131200042a12141524020013000001b027021204003c0612012d0801122702130403000801130127031204010022120213360e0011001302002a1205112d0b1111002a1206132d0b13131c0a111200042a12131424020011000001fc27021204003c0612012d08011127021204020008011201270311040100221102121f3a000500070012002a1105122d0b12121c0a1213041c0a1311002d08011227021304030008011301270312040100221202131f3a000600050013002a1205132d0b1313002a1206162d0b16162902001200d52de36b2d08011727021804050008011801270317040100221702182d0a18192d0e121900221902192d0e131900221902192d0e161900221902192d0e0d192d080112270213040500080113012703120401002217021300221202163f0f00130016002a1205132d0b1313290200120016f8af272d08011627021704050008011701270316040100221602172d0a17182d0e121800221802182d0e111800221802182d0e131800221802182d0e0d182d080111270212040500080112012703110401002216021200221102133f0f00120013002a1105122d0b12120a2a14121124020011000003532500000d540a2a150a111e020012010a22124313160a13141c0a141600042a1612140a2a130912240200120000038627021604003c0616010a2a151412122a111213240200130000039d2500000d662d08011127021204040008011201270311040100221102122d0a12132d0e0e1300221302132d0e0f1300221302132d0e1013002211020f3903200044004400040045000f200200042102000f2d080111270210040000221102132d0b13132702140403002a111412223a000f000700122d0a0f13270311040100221102142d0e131400221402142d0e13142702150403002a131514000801140127021404002d0a131506221502150a2a1014162d0a1510240200160000045a2d0a101024020016000004740a2a10151724020017000004742500000d7824020004000004aa23000004812d0b110400220402042d0e0411002211020f2d0b0f0f2702120403002a1112043c0e0f0423000004aa0a2a10070424020004000004c027020f04003c060f011e020004002d08010f2702100403000801100127030f040100220f0210360e0004001002002a0f05102d0b1010002a0f06112d0b11111c0a100f00042a0f1112240200100000051127020f04003c060f012902000f00ede022762d08011027021104050008011101270310040100221002112d0a11132d0e0f1300221302132d0e041300221302132d0e121300221302132d0e0d132d08010427020f04050008010f012703040401002210020f00220402113f0f000f0011002a04050f2d0b0f0f3402000f1e020004002d08010f2702100405000801100127030f040100220f02102d0a10112d0e0b1100221102112d0e041100221102112d0e0a1100221102112d0e0c112d08010427021004050008011001270304040100220f021000220402113f0f00100011002a04050f2d0b0f0f3402000f2d0b030400220402042d0e0403002203020f2d0b0f0f2702100403002a0310043b0e000f0004230000062029020004005bd9f2da0a2a02040f27020400022902001000ef52534d2402000f00000649230000083a2d08010f2702110403000801110127030f040100220f02111f3a000600050011002a0f05112d0b1111002a0f06122d0b12121e02000f001e02000f001e02000f002d08011327021404050008011401270313040100221302142d0a14152d0e0b1500221502152d0e0f1500221502152d0e0a1500221502152d0e0c152d08010f2702140405000801140127030f0401002213021400220f02153f0f00140015002a0f05132d0b13131e02000f002902001400036d527f2d08011527021604050008011601270315040100221502162d0a16172d0e141700221702172d0e0f1700221702172d0e131700221702172d0e0d172d08010f2702130405000801130127030f0401002215021300220f02143f0f00130014002a0f05132d0b1313330a0013000f2402000f000007792500000d8a2d08010f2702130405000801130127030f040100220f02132d0a13142d0e101400221402142d0e041400221402142d0e111400221402142d0e0d142d08011127021304050008011301270311040100220f021300221102143f0f00130014002a11050f2d0b0f0f0a2a0f0a110a2a11091324020013000007f72500000d9c1e020011002f2a000f00110013002a131211300a0011000f2d0b030f00220f020f2d0e0f0300220302112d0b11112702120403002a03120f3b0e0011000f230000083a0a2a020e0f2402000f0000084c23000009492d08010e27020f04030008010f0127030e040100220e020f1f3a00060005000f002a0e050f2d0b0f0f002a0e06112d0b11111e020006001e020006002d08010627020e04050008010e012703060401002206020e2d0a0e122d0e101200221202122d0e041200221202122d0e0f1200221202122d0e0d122d08010e27020f04050008010f0127030e0401002206020f00220e02123f0f000f0012002a0e05062d0b06060a2a060a0e0a2a0e090f2402000f000009062500000d9c1e02000e002f2a0006000e000f002a0f110e300a000e00062d0b030600220602062d0e0603002203020e2d0b0e0e27020f0403002a030f063b0e000e000623000009492902000600bb19097e0a2a02060e2402000e000009642300000a932d08010627020e04020008010e012703060401002206020e1f3a00050005000e002a06050e2d0b0e0e1e020006001e020006001e0200060924020006000009a92500000dae2d08010627020f04050008010f012703060401002206020f2d0a0f112d0e101100221102112d0e041100221102112d0e0e1100221102112d0e0d112d08010427020d04050008010d012703040401002206020d002204020e3f0f000d000e002a0405062d0b06060a2a060a040a2a04090d2402000d00000a272500000d9c1e020004002f2a00060004000d270206040127020f0403002a060f0e2d0801040008010e012703040401002204020e2d0e060e00220e020e2d0e060e27020e0403002a040e062d0a060e2d0e0d0e002204020d2d0b0d0d27020e0403002a040e063b0e000d00062300000a932902000400ee21e57b0a2a0204062402000600000aae2300000b8e1e020004010a22044306160a060d1c0a0d0e00042a0e040d0a2a0609042402000400000adc27020e04003c060e011e020004000a2a0d04062402000600000af32500000dc01e020004002d08010627020d04050008010d012703060401002206020d2d0a0d0e2d0e0b0e00220e020e2d0e040e00220e020e2d0e0a0e00220e020e2d0e0c0e2d08010427020a04050008010a012703040401002206020a002204020b3f0f000a000b002a0405062d0b0606340200062d0b030400220402042d0e040300220302052d0b05052702060403002a0306043b0e000500042300000b8e2702030255270204026e270205026b270206026f270207027727020a022027020b027327020c026527020d026c27020e026327020f02742702100272270211027b270212027d2d080113270214041c0008011401270313040100221302142d0a14152d0e031500221502152d0e041500221502152d0e051500221502152d0e041500221502152d0e061500221502152d0e071500221502152d0e041500221502152d0e0a1500221502152d0e0b1500221502152d0e0c1500221502152d0e0d1500221502152d0e0c1500221502152d0e0e1500221502152d0e0f1500221502152d0e061500221502152d0e101500221502152d0e0a1500221502152d0e111500221502152d0e0b1500221502152d0e0c1500221502152d0e0d1500221502152d0e0c1500221502152d0e0e1500221502152d0e0f1500221502152d0e061500221502152d0e101500221502152d0e121527020300010a2a0908042402000400000d54270205041e2d080106270207041e00080107012d0a06072a030007059b5bbff74a5bff190022070207002213020a27020b041b2d020a032d0207042d020b052500000dd227020a041b002a070a072d0e030700220702072d0e020700220702073c0e05062a010001058a553a2c2b67c8ef3c040201262a01000105c80d73736ecdb4e13c040201262a0100010575fef108377c8a4f3c040201262a0100010506613b3d0b9dbd333c040201262a01000105babb21d7823318643c040201262a01000105c5cc62b50ed35c303c040201262a010001052ab9ecbeb3430ae13c0402012600000305072d0003082d0004092300000df62d0108062d040609000008020800000902090c0008070a2400000a00000de426>, - "privateFunctionsRoot": Fr<0x07be998ba5208ae3c3c9329157a2c586b26d7489a3e4be5af66e6a1b70e4357a>, + "artifactHash": Fr<0x24c6b040ea6c3ec2ecf9d6b0c0c709239696f66ea8d27d3bc064852a8bfb579c>, + "contractClassId": Fr<0x135e3e6dff88ef7e69c592472939cddff00850a0886c416e47720573cf94db4c>, + "packedPublicBytecode": Buffer<0x27000204012800000104804d270000044d2500000041270203040127020404001f0a00030004004c2d084c0225000000b7270202044d27020304003b0e000300022c0000430030644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000002900004404ffffffff27004504032700460000270047010127004804012900004900c732f9772b00004a00000000000000000200000000000000002b00004b0000000000000000030000000000000000262902000300324de62f0a2a02030427020504002702070403002a0507062d0801030008010601270303040100220302062d0e050600220602062d0e05062702060403002a0306052702050402270206040027020701002902000800d9b51578240200040000012323000006202d08010427020904030008010901270304040100220402091f3200050048000900220448092d0b0909002a04050a2d0b0a0a1e020004001e02000b001e02000b002d08010c27020d04030008010d0127030c040100220c020d360e000b000d0000220c480d2d0b0d0d002a0c050e2d0b0e0e1c0a0d0c00042a0c0e0f2402000d000001b027020c04003c060c012d08010c27020d04030008010d0127030c040100220c020d360e000b000d0200220c480b2d0b0b0b002a0c050d2d0b0d0d1c0a0b0c00042a0c0d0e2402000b000001fc27020c04003c060c012d08010b27020c04020008010c0127030b040100220b020c1f3800480006000c00220b480c2d0b0c0c1c0a0c0d041c0a0d0b002d08010c27020d04030008010d0127030c040100220c020d1f3200050048000d00220c480d2d0b0d0d002a0c05102d0b10102902000c00d52de36b2d08011127021204050008011201270311040100221102122d0a12132d0e0c1300221302132d0e0d1300221302132d0e101300221302132d0c4b132d08010c27020d04050008010d0127030c0401002211020d00220c02103f0f000d001000220c480d2d0b0d0d2902000c0016f8af272d08011027021104050008011101270310040100221002112d0a11122d0e0c1200221202122d0e0b1200221202122d0e0d1200221202122d0c4b122d08010b27020c04050008010c0127030b0401002210020c00220b020d3f0f000c000d00220b480c2d0b0c0c0a2a0e0c0b2402000b000003532500000c770a220f460b1e02000c010a220c430d160a0d0e1c0a0e1000042a100c0e0a2a0d070c2402000c0000038627021004003c0610010a2a0f0e0c122a0b0c0d2402000d0000039d2500000c892d08010b27020c04040008010c0127030b040100220b020c2d0a0c0d2d0e080d00220d020d2d0e090d00220d020d2d0e0a0d00220b02093903200044004400040045000920020004210200092d08010b27020a040000220b020d2d0b0d0d27020e0403002a0b0e0c223a00090006000c2d0a090d27030b040100220b020e2d0e0d0e00220e020e2d0e0d0e27020f0403002a0d0f0e0008010e0127020e04002d0a0d0f06220f020f0a2a0a0e102d0a0f0a240200100000045a2d0a0a0a24020010000004740a2a0a0f1124020011000004742500000c9b24020004000004aa23000004812d0b0b0400220402042d0e040b00220b02092d0b090927020c0403002a0b0c043c0e090423000004aa0a2a0a060424020004000004c027020904003c0609011e020004002d08010927020a04030008010a012703090401002209020a360e0004000a02002209480a2d0b0a0a002a09050b2d0b0b0b1c0a0a0900042a090b0c2402000a0000051127020904003c0609012902000900ede022762d08010a27020b04050008010b0127030a040100220a020b2d0a0b0d2d0e090d00220d020d2d0e040d00220d020d2d0e0c0d00220d020d2d0c4b0d2d08010427020904050008010901270304040100220a0209002204020b3f0f0009000b00220448092d0b0909340200091e020004002d08010927020a04050008010a012703090401002209020a2d0a0a0b2d0c490b00220b020b2d0e040b00220b020b2d0c460b00220b020b2d0c4a0b2d08010427020a04050008010a012703040401002209020a002204020b3f0f000a000b00220448092d0b0909340200092d0b030400220402042d0e040300220302092d0b090927020a0403002a030a043b0e00090004230000062029020004005bd9f2da0a2a02040927020400022902000a00ef52534d2402000900000649230000075d2d08010927020b04030008010b012703090401002209020b1f3200050048000b002209480b2d0b0b0b002a09050c2d0b0c0c1e020009001e02000900270209040d2d08000d00080009002500000cad2d0200002d08010927020d04050008010d012703090401002209020d2d0a0d0e2d0e0a0e00220e020e2d0e040e00220e020e2d0e0b0e00220e020e2d0c4b0e2d08010b27020d04050008010d0127030b0401002209020d00220b020e3f0f000d000e00220b48092d0b09090a2209460b0a2a0b070d2402000d0000071a2500000da21e02000b002f2a0009000b000d002a0d0c0b300a000b00092d0b030900220902092d0e0903002203020b2d0b0b0b27020c0403002a030c093b0e000b0009230000075d0a2a020809240200090000076f230000086c2d08010827020904030008010901270308040100220802091f3200050048000900220848092d0b0909002a08050b2d0b0b0b1e020005001e020005002d08010527020804050008010801270305040100220502082d0a080c2d0e0a0c00220c020c2d0e040c00220c020c2d0e090c00220c020c2d0c4b0c2d0801082702090405000801090127030804010022050209002208020c3f0f0009000c00220848052d0b05050a220546080a2a08070924020009000008292500000da21e020008002f2a000500080009002a090b08300a000800052d0b030500220502052d0e050300220302082d0b08082702090403002a0309053b0e00080005230000086c2902000500bb19097e0a2a020508240200080000088723000009b62d08010527020804020008010801270305040100220502081f3000480048000800220548082d0b08081e020005001e020005001e0200050924020005000008cc2500000db42d08010527020904050008010901270305040100220502092d0a090b2d0e0a0b00220b020b2d0e040b00220b020b2d0e080b00220b020b2d0c4b0b2d080104270208040500080108012703040401002205020800220402093f0f0008000900220448052d0b05050a220546040a2a040708240200080000094a2500000da21e020004002f2a000500040008270205040127020a0403002a050a092d0801040008010901270304040100220402092d0e050900220902092d0e05092702090403002a0409052d0a05092d0e080900220402082d0b08082702090403002a0409053b0e0008000523000009b62902000400ee21e57b0a2a02040524020005000009d12300000ab11e020004010a22044305160a05081c0a080900042a0904080a2a05070424020004000009ff27020904003c0609011e020004000a2a0804052402000500000a162500000dc61e020004002d08010527020804050008010801270305040100220502082d0a08092d0c490900220902092d0e040900220902092d0c460900220902092d0c4a092d080104270208040500080108012703040401002205020800220402093f0f0008000900220448052d0b0505340200052d0b030400220402042d0e040300220302052d0b05052702080403002a0308043b0e000500042300000ab12702030255270204026e270205026b270206026f2702080277270209022027020a027327020b026527020c026c27020d026327020e027427020f0272270210027b270211027d2d080112270213041c0008011301270312040100221202132d0a13142d0e031400221402142d0e041400221402142d0e051400221402142d0e041400221402142d0e061400221402142d0e081400221402142d0e041400221402142d0e091400221402142d0e0a1400221402142d0e0b1400221402142d0e0c1400221402142d0e0b1400221402142d0e0d1400221402142d0e0e1400221402142d0e061400221402142d0e0f1400221402142d0e091400221402142d0e101400221402142d0e0a1400221402142d0e0b1400221402142d0e0c1400221402142d0e0b1400221402142d0e0d1400221402142d0e0e1400221402142d0e061400221402142d0e0f1400221402142d0e111427020300010a220747042402000400000c77270205041e2d080106270208041e00080108012d0a06082a030008059b5bbff74a5bff190022080208002212020927020a041b2d0209032d0208042d020a052500000dd8270209041b002a0809082d0e030800220802082d0e020800220802083c0e05062a010001058a553a2c2b67c8ef3c040201262a01000105c80d73736ecdb4e13c040201262a0100010575fef108377c8a4f3c040201261e020002002d08010327020404050008010401270303040100220302042d0a04052d0c490500220502052d0e020500220502052d0c460500220502052d0c4a052d080102270204040500080104012703020401002203020400220202053f0f0004000500220248032d0b03031e020002002902000400036d527f2d08010527020604050008010601270305040100220502062d0a06072d0e040700220702072d0e020700220702072d0e030700220702072d0c4b072d080102270203040500080103012703020401002205020300220202043f0f0003000400220248032d0b0303330a000300022402000200000da12500000e0a262a01000105babb21d7823318643c040201262a01000105c5cc62b50ed35c303c040201262a010001052ab9ecbeb3430ae13c0402012600000305072d0003082d0004092300000dfc2d0108062d040609000008020800000902090c0008070a2400000a00000dea262a0100010506613b3d0b9dbd333c04020126>, + "privateFunctionsRoot": Fr<0x10b89e84a594728151d2054d9e41999f109fca6895e8bec7894445886adaa5c1>, "version": 1, } `; diff --git a/yarn-project/protocol-contracts/src/instance-registry/__snapshots__/contract_instance_published_event.test.ts.snap b/yarn-project/protocol-contracts/src/instance-registry/__snapshots__/contract_instance_published_event.test.ts.snap index f74640794bf0..fc855b12b4a2 100644 --- a/yarn-project/protocol-contracts/src/instance-registry/__snapshots__/contract_instance_published_event.test.ts.snap +++ b/yarn-project/protocol-contracts/src/instance-registry/__snapshots__/contract_instance_published_event.test.ts.snap @@ -2,17 +2,18 @@ exports[`ContractInstancePublishedEvent parses an event as emitted by the ClassInstanceRegistry 1`] = ` ContractInstancePublishedEvent { - "address": "0x21e212810f887382b564c453919235ecc04ff03f9c5127ac9a630a3fc62cfbbb", - "contractClassId": "0x1c2459719688b73599862bb4192cf567006eaf1fd7382d84f842a6f3616b326c", + "address": "0x1a0d9f0f131e602239f499207c271b6319cb33a45b8f917a7c35d8a52a60d2cb", + "contractClassId": "0x14cc2f3a2417ec81f84c15b1517cef38654c29ace9d54f5a4a22ce1709cc5fc9", "deployer": "0x0000000000000000000000000000000000000000000000000000000000000000", - "initializationHash": "0x0fb36d433fc86c98e17d214b1024303def3bb1e8fa412bc6e796eb1366b5f55b", + "immutablesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "initializationHash": "0x0dad6f31fca9cac105434c9d0071a24a38da659700aee09d285b5ceae94ff5fe", "publicKeys": PublicKeys { - "masterIncomingViewingPublicKey": "0x1e415b163a4af0578cf70ab19e836504a74de9ea3e0c94373ca781436155bfc31fe218da6de686b7a39b092364894c6c2246fee50d0ff9832294cd6b792b8f42", - "masterNullifierPublicKey": "0x1366c504bbb3b3bb5d7246d9e082468eae37d93c38705b9eb4ef8bb76dc9b98005c6d6a962e4d7a458aa232dab86841ebcfe4d342556f270f6b2452fd87581bb", - "masterOutgoingViewingPublicKey": "0x1aa402e7eafa5c5d6ed9454c794e744eabf3b0c5ed84a35567fbe7509552181808afab9b331786e21a60f1f237a7a0f5457ce547160b82ace9a58a800b170fc1", - "masterTaggingPublicKey": "0x289752f4904779a603001cd6fab021079a04e18f0740eb0e1009088199178d1f26814d31374c3e5c551e28a5467feb67155bb2be160d80ca851babfa60501e61", + "ivpkM": "0x21f72071d5882ea13df29918cbaad0d60a11f61309ece108e61d7102b62ec1b50460480b46dcfd5c3262004f191fecf11f321d74618d761e6bcadc691078b421", + "npkMHash": "0x2f6b4b954efabd4f61fe64c1704e82f62760c1a0b5ec1ab88e272fae2f3f0d6c", + "ovpkMHash": "0x0c0e28c4de1167675c811c52defc32dae2245315682dd349b26ef9c3161b1f96", + "tpkMHash": "0x222398ec917e21cb0cbac7050610c2bcb0c2fedfc637bf03d59094b7fd9ce186", }, - "salt": "0x108abf493e0af91750b53cd462defc3373f1a522e982af55b0c8ec7d20cf0393", - "version": 1, + "salt": "0x2d906f112c4a0f17792dbb184f229b5e5fe22d3ae04eb78736ce9ae0e35e49fc", + "version": 2, } `; diff --git a/yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts b/yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts index 35857a0f852b..d69ae3c2b683 100644 --- a/yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts +++ b/yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts @@ -15,6 +15,7 @@ export class ContractInstancePublishedEvent { public readonly salt: Fr, public readonly contractClassId: Fr, public readonly initializationHash: Fr, + public readonly immutablesHash: Fr, public readonly publicKeys: PublicKeys, public readonly deployer: AztecAddress, ) {} @@ -31,6 +32,7 @@ export class ContractInstancePublishedEvent { const salt = reader.readObject(Fr); const contractClassId = reader.readObject(Fr); const initializationHash = reader.readObject(Fr); + const immutablesHash = reader.readObject(Fr); const publicKeys = reader.readObject(PublicKeys); const deployer = reader.readObject(AztecAddress); @@ -40,13 +42,14 @@ export class ContractInstancePublishedEvent { salt, contractClassId, initializationHash, + immutablesHash, publicKeys, deployer, ); } toContractInstance(): ContractInstanceWithAddress { - if (this.version !== 1) { + if (this.version !== 2) { throw new Error(`Unexpected contract instance version ${this.version}`); } @@ -56,6 +59,7 @@ export class ContractInstancePublishedEvent { currentContractClassId: this.contractClassId, originalContractClassId: this.contractClassId, initializationHash: this.initializationHash, + immutablesHash: this.immutablesHash, publicKeys: this.publicKeys, salt: this.salt, deployer: this.deployer, diff --git a/yarn-project/protocol-contracts/src/make_protocol_contract.ts b/yarn-project/protocol-contracts/src/make_protocol_contract.ts index 87215bcb3c20..d921be733ef2 100644 --- a/yarn-project/protocol-contracts/src/make_protocol_contract.ts +++ b/yarn-project/protocol-contracts/src/make_protocol_contract.ts @@ -1,3 +1,4 @@ +import { Fr } from '@aztec/foundation/curves/bn254'; import type { ContractArtifact } from '@aztec/stdlib/abi'; import { PublicKeys } from '@aztec/stdlib/keys'; @@ -34,10 +35,11 @@ export function makeProtocolContract(name: ProtocolContractName, artifact: Contr }; const instance = { - version: 1 as const, + version: 2 as const, currentContractClassId: classId, originalContractClassId: classId, initializationHash, + immutablesHash: Fr.ZERO, // Protocol Contracts Have No Immutables publicKeys: PublicKeys.default(), salt, deployer: address, diff --git a/yarn-project/protocol-contracts/src/scripts/generate_data.ts b/yarn-project/protocol-contracts/src/scripts/generate_data.ts index 58b8d8aa14c7..9bd43ff78210 100644 --- a/yarn-project/protocol-contracts/src/scripts/generate_data.ts +++ b/yarn-project/protocol-contracts/src/scripts/generate_data.ts @@ -89,10 +89,11 @@ async function computeContractData(artifact: NoirCompiledContract, deployer: Azt const constructorArtifact = loaded.functions.find(f => f.name === 'constructor'); const initializationHash = await computeInitializationHash(constructorArtifact, []); const instance = { - version: 1 as const, + version: 2 as const, currentContractClassId: contractClass.id, originalContractClassId: contractClass.id, initializationHash, + immutablesHash: Fr.ZERO, // Protocol Contracts Have No Immutables publicKeys: PublicKeys.default(), salt, deployer, diff --git a/yarn-project/prover-client/package.json b/yarn-project/prover-client/package.json index 1340a4433c20..d55946bd264a 100644 --- a/yarn-project/prover-client/package.json +++ b/yarn-project/prover-client/package.json @@ -28,7 +28,7 @@ "clean": "rm -rf ./dest .tsbuildinfo", "bb": "node --no-warnings ./dest/bb/index.js", "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --testTimeout=3500000", - "test:debug": "LOG_LEVEL=debug NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --testTimeout=1500000 --testNamePattern prover/bb_prover/parity" + "test:debug": "LOG_LEVEL=\"debug; info: json-rpc, simulator\" NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --testTimeout=1500000 --testNamePattern prover/bb_prover/parity" }, "jest": { "moduleNameMapper": { diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.ts index 2fb617696015..19951893c916 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.ts @@ -89,7 +89,7 @@ export class ProvingOrchestrator extends TopTreeProvingScheduler implements Epoc protected provingPromise: Promise | undefined = undefined; private metrics: ProvingOrchestratorMetrics; - // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + private dbs: Map = new Map(); constructor( diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts b/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts index 34fc09fe7b06..4652413271d4 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts @@ -856,7 +856,7 @@ describe.each([ await assertJobTransition(id, 'in-progress', 'in-queue'); }); - it('cancel stale jobs that time out', async () => { + it('cleans up stale in-progress jobs before deleting their epoch database', async () => { const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, @@ -887,10 +887,9 @@ describe.each([ inputsUri: makeInputsUri(), }); - // advance time again so job times out. Since the job was in-progress, it won't be cleaned up as stale - // but will be rejected when it times out - await sleep(jobTimeoutMs + brokerIntervalMs); - await assertJobStatus(id, 'rejected'); + // the epoch-1 database is old enough to delete, so the broker closes any remaining epoch-1 jobs + await (broker as any).cleanupPass(); + await assertJobStatus(id, 'not-found'); }); it('rejects jobs that time out more than maxRetries times', async () => { @@ -1070,13 +1069,15 @@ describe.each([ inputsUri: makeInputsUri(), }); - await sleep(brokerIntervalMs); + await (broker as any).cleanupPass(); + await assertJobStatus(id, 'not-found'); - // job was in-progress so it won't be cleaned up as stale, but will be rejected on error + // the epoch-1 database has been deleted, so late worker reports are ignored + jest.spyOn(database, 'setProvingJobError'); await broker.reportProvingJobError(id, 'test error', true); + expect(database.setProvingJobError).not.toHaveBeenCalled(); await expect(broker.getProvingJobStatus(id)).resolves.toEqual({ - status: 'rejected', - reason: 'test error', + status: 'not-found', }); }); }); diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker.ts b/yarn-project/prover-client/src/proving_broker/proving_broker.ts index decb4835eff3..27364938d5e1 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker.ts @@ -319,6 +319,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr } private cleanUpProvingJobState(ids: ProvingJobId[]) { + const idsToClean = new Set(ids); for (const id of ids) { this.jobsCache.delete(id); const deferred = this.promises.get(id); @@ -331,6 +332,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr this.retries.delete(id); this.enqueuedAt.delete(id); } + this.completedJobNotifications = this.completedJobNotifications.filter(id => !idsToClean.has(id)); } #getProvingJobStatus(id: ProvingJobId): ProvingJobStatus { @@ -598,21 +600,21 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr } private async cleanupPass() { - this.cleanupStaleJobs(); this.reEnqueueExpiredJobs(); const oldestEpochToKeep = this.oldestEpochToKeep(); if (oldestEpochToKeep > 0) { + this.cleanupJobsOlderThanEpoch(EpochNumber(oldestEpochToKeep)); await this.database.deleteAllProvingJobsOlderThanEpoch(EpochNumber(oldestEpochToKeep)); this.logger.trace(`Deleted all epochs older than ${oldestEpochToKeep}`); } } - private cleanupStaleJobs() { + private cleanupJobsOlderThanEpoch(epochNumber: EpochNumber) { const jobIds = Array.from(this.jobsCache.keys()); const jobsToClean: ProvingJobId[] = []; for (const id of jobIds) { const job = this.jobsCache.get(id)!; - if (this.isJobStale(job) && !this.inProgress.has(id) && !this.resultsCache.has(id)) { + if (job.epochNumber < epochNumber) { jobsToClean.push(id); } } diff --git a/yarn-project/prover-node/src/job/epoch-proving-job.test.ts b/yarn-project/prover-node/src/job/epoch-proving-job.test.ts index d6b6fcd8739f..cc6c7b6f7aa0 100644 --- a/yarn-project/prover-node/src/job/epoch-proving-job.test.ts +++ b/yarn-project/prover-node/src/job/epoch-proving-job.test.ts @@ -26,6 +26,12 @@ import type { EpochProvingJobData } from './epoch-proving-job-data.js'; import { EpochProvingJob } from './epoch-proving-job.js'; describe('epoch-proving-job', () => { + const mockFork = () => { + const fork = mock(); + fork[Symbol.asyncDispose].mockImplementation(() => fork.close()); + return fork; + }; + // Dependencies let prover: MockProxy; let publisher: MockProxy; @@ -86,7 +92,7 @@ describe('epoch-proving-job', () => { l2BlockSource = mock(); worldState = mock(); publicProcessorFactory = mock(); - db = mock(); + db = mockFork(); publicProcessor = mock(); metrics = new ProverNodeJobMetrics( getTelemetryClient().getMeter('EpochProvingJob'), @@ -199,6 +205,62 @@ describe('epoch-proving-job', () => { expect(publisher.submitEpochProof).not.toHaveBeenCalled(); }); + it('waits for in-flight checkpoint processing to settle after a block processing failure', async () => { + const forkDbs = times(NUM_BLOCKS, () => mockFork()); + let nextFork = 0; + worldState.fork.mockImplementation(() => Promise.resolve(forkDbs[nextFork++])); + prover.startNewBlock.mockResolvedValue(undefined); + + let processCalls = 0; + let resolveSecondProcessStarted!: () => void; + const secondProcessStarted = new Promise(resolve => { + resolveSecondProcessStarted = resolve; + }); + let releaseSecondProcess!: () => void; + const secondProcessMayFinish = new Promise(resolve => { + releaseSecondProcess = resolve; + }); + + publicProcessorFactory.create.mockImplementation(() => { + const processor = mock(); + processor.process.mockImplementation(async txs => { + const txsArray = await toArray(txs); + processCalls++; + + if (processCalls === 1) { + await secondProcessStarted; + throw new Error('Failed to process tx'); + } + + if (processCalls === 2) { + resolveSecondProcessStarted(); + await secondProcessMayFinish; + } + + const processedTxs = await Promise.all(txsArray.map(tx => mock({ hash: tx.getTxHash() }))); + return [processedTxs, [], txsArray, [], []]; + }); + return processor; + }); + + const job = createJob({ parallelBlockLimit: 2 }); + const runPromise = job.run(); + + await secondProcessStarted; + const runResolvedBeforeSecondProcessFinished = await Promise.race([ + runPromise.then(() => true), + sleep(50).then(() => false), + ]); + + releaseSecondProcess(); + await runPromise; + + expect(runResolvedBeforeSecondProcessFinished).toBe(false); + expect(job.getState()).toEqual('failed'); + expect(forkDbs[1].close).toHaveBeenCalled(); + expect(publisher.submitEpochProof).not.toHaveBeenCalled(); + }); + it('times out if deadline is hit', async () => { prover.startNewBlock.mockImplementation(() => sleep(200)); const deadline = new Date(Date.now() + 100); @@ -219,6 +281,42 @@ describe('epoch-proving-job', () => { expect(publisher.submitEpochProof).not.toHaveBeenCalled(); }); + it('aborts public processing when stopped externally', async () => { + prover.startNewBlock.mockResolvedValue(undefined); + + let processStarted!: () => void; + const processStartedPromise = new Promise(resolve => { + processStarted = resolve; + }); + let abortSignal: AbortSignal | undefined; + + publicProcessor.process.mockImplementation(async (txs, opts) => { + const signal = opts?.signal; + if (!signal) { + throw new Error('Expected public processor abort signal'); + } + abortSignal = signal; + processStarted(); + await new Promise(resolve => signal.addEventListener('abort', () => resolve(), { once: true })); + + const txsArray = await toArray(txs); + const processedTxs = await Promise.all(txsArray.map(tx => mock({ hash: tx.getTxHash() }))); + return [processedTxs, [], txsArray, [], []]; + }); + + const job = createJob({ parallelBlockLimit: 1 }); + const runPromise = job.run(); + + await processStartedPromise; + await job.stop(); + await runPromise; + + expect(abortSignal?.aborted).toBe(true); + expect(job.getState()).toEqual('stopped'); + expect(prover.addTxs).not.toHaveBeenCalled(); + expect(publisher.submitEpochProof).not.toHaveBeenCalled(); + }); + it('halts if a new block for the epoch is found', async () => { const newHeaders = times(NUM_BLOCKS + 1, i => BlockHeader.random({ blockNumber: BlockNumber(i + 1) })); l2BlockSource.getBlocksData.mockResolvedValue(newHeaders.map(h => ({ header: h }) as any)); diff --git a/yarn-project/prover-node/src/job/epoch-proving-job.ts b/yarn-project/prover-node/src/job/epoch-proving-job.ts index 73cb5dfb5d12..88b8fad06dda 100644 --- a/yarn-project/prover-node/src/job/epoch-proving-job.ts +++ b/yarn-project/prover-node/src/job/epoch-proving-job.ts @@ -46,6 +46,7 @@ export class EpochProvingJob implements Traceable { private uuid: string; private runPromise: Promise | undefined; + private abortController = new AbortController(); private epochCheckPromise: RunningPromise | undefined; private deadlineTimeoutHandler: NodeJS.Timeout | undefined; @@ -170,7 +171,7 @@ export class EpochProvingJob implements Traceable { ? AVM_MAX_CONCURRENT_SIMULATIONS : this.checkpoints.length; - await asyncPool(parallelism, this.checkpoints, async checkpoint => { + await this.processCheckpoints(parallelism, async checkpoint => { this.checkState(); const checkpointTimer = new Timer(); @@ -228,22 +229,26 @@ export class EpochProvingJob implements Traceable { // Process public fns. L1 to L2 messages are only inserted for the first block of a checkpoint, // as the fork for subsequent blocks already includes them from the previous block's synced state. - const db = await this.createFork( - BlockNumber(block.number - 1), - blockIndex === 0 ? l1ToL2Messages : undefined, - ); - const config = PublicSimulatorConfig.from({ - proverId: this.prover.getProverId().toField(), - skipFeeEnforcement: false, - collectDebugLogs: false, - collectHints: true, - collectPublicInputs: true, - collectStatistics: false, - }); - const publicProcessor = this.publicProcessorFactory.create(db, globalVariables, config); - const processed = await this.processTxs(publicProcessor, txs); - await this.prover.addTxs(processed); - await db.close(); + { + await using db = await this.createFork( + BlockNumber(block.number - 1), + blockIndex === 0 ? l1ToL2Messages : undefined, + ); + this.checkState(); + const config = PublicSimulatorConfig.from({ + proverId: this.prover.getProverId().toField(), + skipFeeEnforcement: false, + collectDebugLogs: false, + collectHints: true, + collectPublicInputs: true, + collectStatistics: false, + }); + const publicProcessor = this.publicProcessorFactory.create(db, globalVariables, config); + const processed = await this.processTxs(publicProcessor, txs); + this.checkState(); + await this.prover.addTxs(processed); + } + this.checkState(); this.log.verbose(`Processed all ${txs.length} txs for block ${block.number}`, { blockNumber: block.number, blockHash: (await block.hash()).toString(), @@ -337,7 +342,9 @@ export class EpochProvingJob implements Traceable { */ private async createFork(blockNumber: BlockNumber, l1ToL2Messages: Fr[] | undefined) { this.log.verbose(`Creating fork at ${blockNumber}`, { blockNumber }); - const db = await this.dbProvider.fork(blockNumber); + // temporary stack to control fork lifetime + await using cleanup = new AsyncDisposableStack(); + const db = cleanup.use(await this.dbProvider.fork(blockNumber)); if (l1ToL2Messages !== undefined) { this.log.verbose(`Inserting ${l1ToL2Messages.length} L1 to L2 messages in fork`, { @@ -347,9 +354,44 @@ export class EpochProvingJob implements Traceable { await appendL1ToL2MessagesToTree(db, l1ToL2Messages); } + // everything run succesfully so we can release this stack and give control of the fork's lifetime to the caller + cleanup.move(); return db; } + private async processCheckpoints( + parallelism: number, + processCheckpoint: (checkpoint: Checkpoint) => Promise, + ): Promise { + let hasError = false; + let firstError: unknown; + + await asyncPool(Math.max(parallelism, 1), this.checkpoints, async checkpoint => { + if (hasError || this.abortController.signal.aborted) { + return; + } + + try { + this.checkState(); + await processCheckpoint(checkpoint); + } catch (err) { + if (!hasError) { + hasError = true; + firstError = err; + this.failProcessing(); + } + } + }); + + if (hasError) { + throw firstError; + } + + if (this.abortController.signal.aborted) { + this.checkState(); + } + } + private progressState(state: EpochProvingJobState) { this.checkState(); this.state = state; @@ -363,12 +405,24 @@ export class EpochProvingJob implements Traceable { public async stop(state: EpochProvingJobTerminalState = 'stopped') { this.state = state; - this.prover.cancel(); + this.interruptProcessing(); if (this.runPromise) { await this.runPromise; } } + private failProcessing() { + if (!EpochProvingJobTerminalState.includes(this.state)) { + this.state = 'failed'; + } + this.interruptProcessing(); + } + + private interruptProcessing() { + this.abortController.abort(); + this.prover.cancel(); + } + private scheduleDeadlineStop() { const deadline = this.deadline; if (deadline) { @@ -444,7 +498,11 @@ export class EpochProvingJob implements Traceable { private async processTxs(publicProcessor: PublicProcessor, txs: Tx[]): Promise { const { deadline } = this; - const [processedTxs, failedTxs] = await publicProcessor.process(txs, { deadline }); + const [processedTxs, failedTxs] = await publicProcessor.process(txs, { + deadline, + signal: this.abortController.signal, + }); + this.checkState(); if (failedTxs.length) { const failedTxHashes = await Promise.all(failedTxs.map(({ tx }) => tx.getTxHash())); diff --git a/yarn-project/prover-node/src/prover-node-publisher.test.ts b/yarn-project/prover-node/src/prover-node-publisher.test.ts index f7a22a777829..31d035b37d9e 100644 --- a/yarn-project/prover-node/src/prover-node-publisher.test.ts +++ b/yarn-project/prover-node/src/prover-node-publisher.test.ts @@ -188,6 +188,82 @@ describe('prover-node-publisher', () => { }, ); + it('waits until the proven checkpoint reaches the checkpoint before the proof start', async () => { + const checkpoints = Array.from({ length: 100 }, () => RootRollupPublicInputs.random()); + const fromCheckpoint = CheckpointNumber(33); + const toCheckpoint = CheckpointNumber(64); + + rollup.getTips + .mockResolvedValueOnce({ + pending: CheckpointNumber(65), + proven: CheckpointNumber(31), + }) + .mockResolvedValueOnce({ + pending: CheckpointNumber(65), + proven: CheckpointNumber(32), + }) + .mockResolvedValue({ + pending: CheckpointNumber(65), + proven: CheckpointNumber(32), + }); + rollup.getRollupConstants.mockResolvedValue({ + l1StartBlock: 0n, + l1GenesisTime: BigInt(Math.floor(Date.now() / 1000)), + slotDuration: 1, + epochDuration: 1, + proofSubmissionEpochs: 100, + targetCommitteeSize: 48, + rollupManaLimit: Number.MAX_SAFE_INTEGER, + }); + + rollup.getCheckpoint.mockImplementation((checkpointNumber: CheckpointNumber) => + Promise.resolve({ + archive: checkpoints[checkpointNumber - 1].endArchiveRoot, + attestationsHash: Buffer32.ZERO, + payloadDigest: Buffer32.ZERO, + headerHash: Buffer32.ZERO, + blobCommitmentsHash: Buffer32.ZERO, + outHash: '0x', + slotNumber: SlotNumber(0), + feeHeader: { + excessMana: 0n, + manaUsed: 0n, + ethPerFeeAsset: 0n, + congestionCost: 0n, + proverCost: 0n, + }, + }), + ); + + const ourPublicInputs = RootRollupPublicInputs.random(); + ourPublicInputs.previousArchiveRoot = checkpoints[fromCheckpoint - 2].endArchiveRoot; + ourPublicInputs.endArchiveRoot = checkpoints[toCheckpoint - 1].endArchiveRoot; + + const ourBatchedBlob = new BatchedBlob( + ourPublicInputs.blobPublicInputs.blobCommitmentsHash, + ourPublicInputs.blobPublicInputs.z, + ourPublicInputs.blobPublicInputs.y, + ourPublicInputs.blobPublicInputs.c, + ourPublicInputs.blobPublicInputs.c.negate(), + ); + + rollup.getEpochProofPublicInputs.mockResolvedValue(ourPublicInputs.toFields()); + + await publisher.submitEpochProof({ + epochNumber: EpochNumber(2), + fromCheckpoint, + toCheckpoint, + publicInputs: ourPublicInputs, + proof: Proof.empty(), + batchedBlobInputs: ourBatchedBlob, + attestations: [], + }); + + expect(rollup.getRollupConstants).toHaveBeenCalled(); + expect(rollup.getTips).toHaveBeenCalledTimes(3); + expect(l1Utils.sendAndMonitorTransaction).toHaveBeenCalled(); + }); + it('analyzeEpochProofSubmission validates, estimates, and does not send tx', async () => { const fromCheckpoint = 33; const toCheckpoint = 64; diff --git a/yarn-project/prover-node/src/prover-node-publisher.ts b/yarn-project/prover-node/src/prover-node-publisher.ts index b1ec554523cb..5c7bfeab2460 100644 --- a/yarn-project/prover-node/src/prover-node-publisher.ts +++ b/yarn-project/prover-node/src/prover-node-publisher.ts @@ -8,11 +8,13 @@ import { areArraysEqual } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log'; +import { retryUntil } from '@aztec/foundation/retry'; import type { Tuple } from '@aztec/foundation/serialize'; import { Timer } from '@aztec/foundation/timer'; import { RollupAbi } from '@aztec/l1-artifacts'; import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client'; import { CommitteeAttestation, CommitteeAttestationsAndSigners } from '@aztec/stdlib/block'; +import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers'; import type { Proof } from '@aztec/stdlib/proofs'; import type { FeeRecipient, RootRollupPublicInputs } from '@aztec/stdlib/rollup'; import type { L1PublishProofStats } from '@aztec/stdlib/stats'; @@ -101,6 +103,11 @@ export class ProverNodePublisher { const ctx = { epochNumber, fromCheckpoint, toCheckpoint }; if (!this.interrupted) { + if (!(await this.waitUntilStartBuildsOnProven(args))) { + this.log.verbose('Checkpoint data syncing interrupted', ctx); + return false; + } + const timer = new Timer(); // Validate epoch proof range and hashes are correct before submitting await this.validateEpochProofSubmission(args); @@ -147,6 +154,53 @@ export class ProverNodePublisher { return false; } + private async waitUntilStartBuildsOnProven(args: { epochNumber: EpochNumber; fromCheckpoint: CheckpointNumber }) { + const { epochNumber, fromCheckpoint } = args; + const provenCheckpoint = await this.getProvenCheckpoint(); + if (this.isStartBuildingOnProven(fromCheckpoint, provenCheckpoint)) { + return true; + } + + const timeout = await this.getSecondsUntilProofSubmissionWindowEnd(epochNumber); + this.log.info(`Waiting for proven checkpoint to reach proof start`, { + epochNumber, + fromCheckpoint, + provenCheckpoint, + timeout, + }); + + await retryUntil( + async () => { + if (this.interrupted) { + return true; + } + + const proven = await this.getProvenCheckpoint(); + this.log.verbose(`Proven checkpoint is at ${proven} (waiting for ${fromCheckpoint - 1})`, { epochNumber }); + return this.isStartBuildingOnProven(fromCheckpoint, proven) ? true : undefined; + }, + `proven checkpoint to reach ${fromCheckpoint - 1}`, + timeout, + 4, + ); + + return !this.interrupted; + } + + private async getProvenCheckpoint() { + return (await this.rollupContract.getTips()).proven; + } + + private isStartBuildingOnProven(fromCheckpoint: CheckpointNumber, provenCheckpoint: CheckpointNumber) { + return fromCheckpoint - 1 <= provenCheckpoint; + } + + private async getSecondsUntilProofSubmissionWindowEnd(epochNumber: EpochNumber) { + const deadline = getProofSubmissionDeadlineTimestamp(epochNumber, await this.rollupContract.getRollupConstants()); + const now = BigInt(Math.floor(Date.now() / 1000)); + return Math.max(Number(deadline - now), 0.001); + } + private async validateEpochProofSubmission(args: { fromCheckpoint: CheckpointNumber; toCheckpoint: CheckpointNumber; diff --git a/yarn-project/prover-node/src/prover-node.ts b/yarn-project/prover-node/src/prover-node.ts index 92db38ae492b..dbcf9b906e63 100644 --- a/yarn-project/prover-node/src/prover-node.ts +++ b/yarn-project/prover-node/src/prover-node.ts @@ -166,10 +166,10 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable async stop() { this.log.info('Stopping ProverNode'); await this.epochsMonitor.stop(); - await this.prover.stop(); - await tryStop(this.publisherFactory); this.publisher?.interrupt(); await Promise.all(Array.from(this.jobs.values()).map(job => job.stop())); + await this.prover.stop(); + await tryStop(this.publisherFactory); this.rewardsMetrics.stop(); this.l1Metrics.stop(); await this.telemetryClient.stop(); diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts index 0a3fffe870bf..4bd1b749fd88 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts @@ -225,6 +225,7 @@ export class Oracle { instance.deployer, instance.currentContractClassId, instance.initializationHash, + instance.immutablesHash, ...instance.publicKeys.toFields(), ].map(toACVMField); } @@ -314,10 +315,26 @@ export class Oracle { // with two fields: `some` (a boolean) and `value` (a field array in this case). if (result === undefined) { // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size. - return [toACVMField(0), Array(13).fill(toACVMField(0))]; + // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, partial_address] = 6 fields. + return [toACVMField(0), Array(6).fill(toACVMField(0))]; } else { // Data was found so we set `some` to 1 and return it along with `value`. - return [toACVMField(1), [...result.publicKeys.toFields(), result.partialAddress].map(toACVMField)]; + // The Noir side hand-decodes a `[Field; 6]` here (see aztec-nr/aztec/src/oracle/keys.nr), so we + // emit the 5-field PublicKeys shape + partial_address explicitly + // rather than going through `publicKeys.toFields()` (which is the struct-flattened 6-field + // wire for oracle returns that decode via struct shape). + const { publicKeys, partialAddress } = result; + return [ + toACVMField(1), + [ + publicKeys.npkMHash, + publicKeys.ivpkM.x, + publicKeys.ivpkM.y, + publicKeys.ovpkMHash, + publicKeys.tpkMHash, + partialAddress, + ].map(toACVMField), + ]; } } diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts index f37e686891ef..2288551091e8 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts @@ -337,40 +337,40 @@ describe('Private Execution test suite', () => { keyStore.getAccounts.mockResolvedValue([owner, recipient, senderForTags]); - keyStore.accountHasKey.mockImplementation(async (account: AztecAddress, pkMHash: Fr) => { + keyStore.accountHasKey.mockImplementation((account: AztecAddress, pkMHash: Fr) => { if (account.equals(owner)) { - return pkMHash.equals(await ownerCompleteAddress.publicKeys.masterNullifierPublicKey.hash()); + return Promise.resolve(pkMHash.equals(ownerCompleteAddress.publicKeys.npkMHash)); } if (account.equals(recipient)) { - return pkMHash.equals(await recipientCompleteAddress.publicKeys.masterNullifierPublicKey.hash()); + return Promise.resolve(pkMHash.equals(recipientCompleteAddress.publicKeys.npkMHash)); } if (account.equals(senderForTags)) { - return pkMHash.equals(await senderForTagsCompleteAddress.publicKeys.masterNullifierPublicKey.hash()); + return Promise.resolve(pkMHash.equals(senderForTagsCompleteAddress.publicKeys.npkMHash)); } - return false; + return Promise.resolve(false); }); keyStore.getKeyValidationRequest.mockImplementation(async (pkMHash: Fr, contractAddress: AztecAddress) => { - if (pkMHash.equals(await ownerCompleteAddress.publicKeys.masterNullifierPublicKey.hash())) { + if (pkMHash.equals(ownerCompleteAddress.publicKeys.npkMHash)) { return Promise.resolve( new KeyValidationRequest( - ownerCompleteAddress.publicKeys.masterNullifierPublicKey, + ownerCompleteAddress.publicKeys.npkMHash, await computeAppNullifierHidingKey(ownerNhkM, contractAddress), ), ); } - if (pkMHash.equals(await recipientCompleteAddress.publicKeys.masterNullifierPublicKey.hash())) { + if (pkMHash.equals(recipientCompleteAddress.publicKeys.npkMHash)) { return Promise.resolve( new KeyValidationRequest( - recipientCompleteAddress.publicKeys.masterNullifierPublicKey, + recipientCompleteAddress.publicKeys.npkMHash, await computeAppNullifierHidingKey(recipientNhkM, contractAddress), ), ); } - if (pkMHash.equals(await senderForTagsCompleteAddress.publicKeys.masterNullifierPublicKey.hash())) { + if (pkMHash.equals(senderForTagsCompleteAddress.publicKeys.npkMHash)) { return Promise.resolve( new KeyValidationRequest( - senderForTagsCompleteAddress.publicKeys.masterNullifierPublicKey, + senderForTagsCompleteAddress.publicKeys.npkMHash, await computeAppNullifierHidingKey(senderForTagsNhkM, contractAddress), ), ); @@ -1265,7 +1265,7 @@ describe('Private Execution test suite', () => { // Generate a partial address, pubkey, and resulting address const completeAddress = await CompleteAddress.random(); const args = [completeAddress.address]; - const pubKey = completeAddress.publicKeys.masterIncomingViewingPublicKey; + const pubKey = completeAddress.publicKeys.ivpkM; addressStore.getCompleteAddress.mockResolvedValue(completeAddress); const { entrypoint: result } = await runSimulator({ diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution.test.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution.test.ts index 47d684aa7850..b9cd370c147a 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution.test.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution.test.ts @@ -1,7 +1,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; import { Grumpkin } from '@aztec/foundation/crypto/grumpkin'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin'; +import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin'; import type { KeyStore } from '@aztec/key-store'; import { StatefulTestContractArtifact } from '@aztec/noir-test-contracts.js/StatefulTest'; import { WASMSimulator } from '@aztec/simulator/client'; @@ -14,7 +14,7 @@ import { computeContractAddressFromInstance, } from '@aztec/stdlib/contract'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { PublicKeys, deriveKeys } from '@aztec/stdlib/keys'; +import { PublicKeys, deriveKeys, hashPublicKey } from '@aztec/stdlib/keys'; import { MessageContext } from '@aztec/stdlib/logs'; import { Note, NoteDao } from '@aztec/stdlib/note'; import { makeL2Tips } from '@aztec/stdlib/testing'; @@ -150,12 +150,13 @@ describe('Utility Execution test suite', () => { // The initializer nullifier check requires the instance to be a valid preimage of the contract address, so we // can't use a random contract address here. const instanceFields = { - version: 1 as const, + version: 2 as const, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: new Fr(42), originalContractClassId: new Fr(42), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), }; const contractAddress = await computeContractAddressFromInstance(instanceFields); @@ -242,12 +243,13 @@ describe('Utility Execution test suite', () => { const expectedSum = new Fr(9); const instanceFields = { - version: 1 as const, + version: 2 as const, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: new Fr(42), originalContractClassId: new Fr(42), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), }; const contractAddress = await computeContractAddressFromInstance(instanceFields); @@ -489,11 +491,12 @@ describe('Utility Execution test suite', () => { // Derive keys so we can mock getMasterSecretKey (used by getSharedSecrets) const { masterIncomingViewingSecretKey: ownerIvskM } = await deriveKeys(ownerSecretKey); - keyStore.getMasterSecretKey.mockImplementation((publicKey: Point) => { - if (publicKey.equals(ownerCompleteAddress.publicKeys.masterIncomingViewingPublicKey)) { + const ownerIvpkMHash = await hashPublicKey(ownerCompleteAddress.publicKeys.ivpkM); + keyStore.getMasterSecretKey.mockImplementation((pkMHash: Fr) => { + if (pkMHash.equals(ownerIvpkMHash)) { return Promise.resolve(ownerIvskM); } - throw new Error(`Unknown public key ${publicKey}`); + throw new Error(`Unknown pk_m_hash ${pkMHash}`); }); const contractAddressA = await AztecAddress.random(); diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts index e03a4ee93c19..3e252d028380 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts @@ -3,7 +3,6 @@ import type { BlockNumber } from '@aztec/foundation/branded-types'; import { uniqueBy } from '@aztec/foundation/collection'; import { Aes128 } from '@aztec/foundation/crypto/aes128'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import { LogLevels, type Logger, createLogger } from '@aztec/foundation/log'; import type { MembershipWitness } from '@aztec/foundation/trees'; import type { KeyStore } from '@aztec/key-store'; @@ -23,7 +22,7 @@ import type { CompleteAddress, ContractInstance, PartialAddress } from '@aztec/s import { siloNullifier } from '@aztec/stdlib/hash'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; import type { KeyValidationRequest } from '@aztec/stdlib/kernel'; -import { type PublicKeys, computeAddressSecret } from '@aztec/stdlib/keys'; +import { PublicKey, type PublicKeys, computeAddressSecret, hashPublicKey } from '@aztec/stdlib/keys'; import { MessageContext, deriveAppSiloedSharedSecret } from '@aztec/stdlib/logs'; import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging'; import type { NoteStatus } from '@aztec/stdlib/note'; @@ -720,15 +719,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra ); } const recipientCompleteAddress = await this.getCompleteAddressOrFail(address); - const ivskM = await this.keyStore.getMasterSecretKey( - recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey, - ); + const ivpkMHash = await hashPublicKey(recipientCompleteAddress.publicKeys.ivpkM); + const ivskM = await this.keyStore.getMasterSecretKey(ivpkMHash); const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM); const ephPkFields = this.ephemeralArrayService.readArrayAt(ephPksSlot); const secrets = await Promise.all( ephPkFields.map(fields => - deriveAppSiloedSharedSecret(addressSecret, Point.fromFields(fields), this.contractAddress), + deriveAppSiloedSharedSecret(addressSecret, PublicKey.fromFields(fields), this.contractAddress), ), ); diff --git a/yarn-project/pxe/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts b/yarn-project/pxe/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts index 9b4c5542d145..149dea355274 100644 --- a/yarn-project/pxe/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +++ b/yarn-project/pxe/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts @@ -68,7 +68,7 @@ async function getMasterSecretKeysAndKeyTypeDomainSeparators( const numRequestsToProcess = Math.min(keyValidationRequests.claimedLength, numRequestsToVerify); const keysHints = await Promise.all( keyValidationRequests.array.slice(0, numRequestsToProcess).map(async ({ request }) => { - const secretKeys = await oracle.getMasterSecretKey(request.request.pkM); + const secretKeys = await oracle.getMasterSecretKey(request.request.pkMHash); return new KeyValidationHint(secretKeys); }), ); diff --git a/yarn-project/pxe/src/private_kernel/hints/test_utils.ts b/yarn-project/pxe/src/private_kernel/hints/test_utils.ts index be5bf7a66f7c..9a1fba6009ed 100644 --- a/yarn-project/pxe/src/private_kernel/hints/test_utils.ts +++ b/yarn-project/pxe/src/private_kernel/hints/test_utils.ts @@ -14,7 +14,6 @@ import { } from '@aztec/constants'; import { makeTuple } from '@aztec/foundation/array'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import type { Serializable } from '@aztec/foundation/serialize'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { @@ -130,10 +129,7 @@ export class PrivateKernelCircuitPublicInputsBuilder { const addr = opts?.contractAddress ?? this.contractAddress; this.keyValidationRequests.push( new ScopedKeyValidationRequestAndSeparator( - new KeyValidationRequestAndSeparator( - new KeyValidationRequest(new Point(Fr.random(), Fr.random(), false), Fr.random()), - Fr.random(), - ), + new KeyValidationRequestAndSeparator(new KeyValidationRequest(Fr.random(), Fr.random()), Fr.random()), addr, ), ); @@ -253,10 +249,7 @@ export class PrivateCircuitPublicInputsBuilder { /** Adds a key validation request. */ addKeyValidationRequest(): this { this.keyValidationRequests.push( - new KeyValidationRequestAndSeparator( - new KeyValidationRequest(new Point(Fr.random(), Fr.random(), false), Fr.random()), - Fr.random(), - ), + new KeyValidationRequestAndSeparator(new KeyValidationRequest(Fr.random(), Fr.random()), Fr.random()), ); return this; } diff --git a/yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts b/yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts index e16dab33ec23..a44bab2ad2fc 100644 --- a/yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts +++ b/yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts @@ -130,12 +130,13 @@ describe('Private Kernel Sequencer', () => { oracle.getMasterSecretKey.mockResolvedValue(Fr.random() as any); oracle.getContractAddressPreimage.mockResolvedValue({ - version: 1 as const, + version: 2 as const, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), address: await AztecAddress.random(), saltedInitializationHash: Fr.random(), diff --git a/yarn-project/pxe/src/private_kernel/private_kernel_oracle.ts b/yarn-project/pxe/src/private_kernel/private_kernel_oracle.ts index e04720182409..cce48341341e 100644 --- a/yarn-project/pxe/src/private_kernel/private_kernel_oracle.ts +++ b/yarn-project/pxe/src/private_kernel/private_kernel_oracle.ts @@ -6,7 +6,7 @@ import { VK_TREE_HEIGHT, } from '@aztec/constants'; import type { Fr } from '@aztec/foundation/curves/bn254'; -import type { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin'; +import type { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin'; import { MembershipWitness } from '@aztec/foundation/trees'; import type { KeyStore } from '@aztec/key-store'; import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/vk-tree'; @@ -103,14 +103,14 @@ export class PrivateKernelOracle { } /** - * Retrieves the sk_m corresponding to the pk_m. - * @throws If the provided public key is not associated with any of the registered accounts. - * @param masterPublicKey - The master public key to get secret key for. + * Retrieves the sk_m corresponding to the pk_m hash. + * @throws If the provided hash is not associated with any of the registered accounts. + * @param masterPublicKeyHash - The master public key hash to get secret key for. * @returns A Promise that resolves to sk_m. * @dev Used when feeding the sk_m to the kernel circuit for keys verification. */ - public getMasterSecretKey(masterPublicKey: Point): Promise { - return this.keyStore.getMasterSecretKey(masterPublicKey); + public getMasterSecretKey(masterPublicKeyHash: Fr): Promise { + return this.keyStore.getMasterSecretKey(masterPublicKeyHash); } /** Use debug data to get the function name corresponding to a selector. */ diff --git a/yarn-project/pxe/src/storage/address_store/address_store.test.ts b/yarn-project/pxe/src/storage/address_store/address_store.test.ts index 40cea7d0f9f3..51e52319a6c2 100644 --- a/yarn-project/pxe/src/storage/address_store/address_store.test.ts +++ b/yarn-project/pxe/src/storage/address_store/address_store.test.ts @@ -1,4 +1,5 @@ import { timesParallel } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/curves/bn254'; import { Point } from '@aztec/foundation/curves/grumpkin'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import { CompleteAddress } from '@aztec/stdlib/contract'; @@ -30,7 +31,7 @@ describe('addresses', () => { const address = await CompleteAddress.random(); const otherAddress = await CompleteAddress.create( address.address, - new PublicKeys(await Point.random(), await Point.random(), await Point.random(), await Point.random()), + new PublicKeys(Fr.random(), await Point.random(), Fr.random(), Fr.random()), address.partialAddress, ); diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json index f2e80f8f02f2..ead6b82ef58e 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json @@ -2,21 +2,21 @@ "complete_addresses": [ { "index": 0, - "value": "0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a214c7a24ddf501afc8734c7379ee502296289eb24cd8cd03cd435e128c06be0000987721e0963b4a5bd81ee862e2740d8849fd90537569064d3d3a4640e858d219e95c05f09cb86d1a6257572f9082ca15d4a02373c4d8c9cee23dc61a4c2a882f9017d51bca6616102d8a1d4dba89e4ce12881a2414576f01d2fec9492814a22c19ff0b089b07da436e6f7be6b26cdc17b9cee504a528c071ef6a416299683d0b369479d6e50504702d0b56bb56e4e8e0e77171429896651d0c11621e82ebc32fcdd0d194adafd753dc0ed279f5cfb54ddcce1dd581d4631cf343ba9ee6c1ab2858abca6c00da3def156b1f12a6464384e326d5fa724c2fc2ff2b7f3fc8ad5f0000000000000000000000000000000000000000000000000000000000000003" + "value": "179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db13ad6965d11a533a663d07507319f74ac3305325f6f72423c0b24aa1193268bb19e95c05f09cb86d1a6257572f9082ca15d4a02373c4d8c9cee23dc61a4c2a882f9017d51bca6616102d8a1d4dba89e4ce12881a2414576f01d2fec9492814a22a1b054e998835d166711839b515d434b1fbc207ad4fdb5b2b43d6ac6b400871019f5bb255e87523d43da83ebc9fa95169b653d4abef902e011e9eac620fc45b0000000000000000000000000000000000000000000000000000000000000003" }, { "index": 1, - "value": "2bc83a7fe553d4b649228410040c130a782f86f9b54813f4d847d0c3eeba065a156832f7840991767f448681237ef8bce6895fc79e5d9d0dedd89dccfd9d59ce215403719ea86d38909507bba0ba2d191f72dc1991a5dfc17da8bf7e8c1f1f4f267e526a2e6e9adf6a026989be005bd50d1aea76d20816b9843bc95557696f9f16c3eb259ba3e3eb27b7fe3abc36e87923990bf5c265cb0d57790eda2a4432f1237296442bbb36cc3632af0578ad4b7d5d69d52e05937a1d3e2fe295ac9af98628737df05bb727d77dd52691d42566eb22e529f9f404a2f9bc2e1982956ba09c1df52a95111bd76680a4356951e68a20c3e51cbddb7d1536c572b416bd342e3204aa15eaf393bb18695ddee077d52be6489ed510f357a90003099ce337e6232c0000000000000000000000000000000000000000000000000000000000000007" + "value": "0bc042bac587b8ff4785ff5b6def422de3ad558e37ec89b6494ff8c5dae0aa5d17c2df1b7355bb4c4494aa4ec85d15ff8881cea1b34691f0cc558e8aef3f3f4c267e526a2e6e9adf6a026989be005bd50d1aea76d20816b9843bc95557696f9f16c3eb259ba3e3eb27b7fe3abc36e87923990bf5c265cb0d57790eda2a4432f105a5449624125d37f10cd4c68ffd57b0dc0cdaa916cb37840be1db9bf88e3c5f0e81754454e3b12035b13448a9fe3b980bf31a9808cb93e146628fb06fa1b46f0000000000000000000000000000000000000000000000000000000000000007" } ], "complete_address_index": [ { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a", - "value": "num:0" + "key": "utf8:0x0bc042bac587b8ff4785ff5b6def422de3ad558e37ec89b6494ff8c5dae0aa5d", + "value": "num:1" }, { - "key": "utf8:0x2bc83a7fe553d4b649228410040c130a782f86f9b54813f4d847d0c3eeba065a", - "value": "num:1" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db", + "value": "num:0" } ] } diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json index 6de71bb8c2e4..e52777ac981c 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json @@ -22,7 +22,7 @@ "contracts_instances": [ { "key": "utf8:0x0000000000000000000000000000000000000000000000000000000000000065", - "value": "010000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000430000000000000000000000000000000000000000000000000000000000000047" + "value": "020000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000043" } ] } diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json index 7164be86011a..24f383496aa2 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json @@ -1,51 +1,51 @@ { "key_store": [ { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ivpk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ivpk_m", "value": "19e95c05f09cb86d1a6257572f9082ca15d4a02373c4d8c9cee23dc61a4c2a882f9017d51bca6616102d8a1d4dba89e4ce12881a2414576f01d2fec9492814a2" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ivpk_m_hash", - "value": "2c8a04047c06c447dcf1011ddd80c1d03dc9f70a5fa4645722d086fe82504d76" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ivpk_m_hash", + "value": "1fd17152d394f6a43b527c531590888d610d1bcb9aa71a02498ce820bbf4dc62" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ivsk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ivsk_m", "value": "1fb01c42d1aaa2662041b899c77cb19e08192193acc5a94405f1b43c974eba7a" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-nhk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-nhk_m", "value": "2dd30220767969b10044b1322585bb4c4df4e0c5d9b4d7b3045a879a8e3e91d2" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-npk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-npk_m", "value": "214c7a24ddf501afc8734c7379ee502296289eb24cd8cd03cd435e128c06be0000987721e0963b4a5bd81ee862e2740d8849fd90537569064d3d3a4640e858d2" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-npk_m_hash", - "value": "0df588690e44b50e4ca694d25b494039b60f09451eaea7aaba97bd4cf8001710" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-npk_m_hash", + "value": "13ad6965d11a533a663d07507319f74ac3305325f6f72423c0b24aa1193268bb" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ovpk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ovpk_m", "value": "2c19ff0b089b07da436e6f7be6b26cdc17b9cee504a528c071ef6a416299683d0b369479d6e50504702d0b56bb56e4e8e0e77171429896651d0c11621e82ebc3" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ovpk_m_hash", - "value": "2cbd8a987ad7dc81814feabc55abdf40b810161611ad89b705db92f32cf94603" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ovpk_m_hash", + "value": "2a1b054e998835d166711839b515d434b1fbc207ad4fdb5b2b43d6ac6b400871" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ovsk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ovsk_m", "value": "279fe6ef7dd2477b919327b1ebab7497c41b9a7ccfa9d5d52e32698e3b85293b" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-tpk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-tpk_m", "value": "2fcdd0d194adafd753dc0ed279f5cfb54ddcce1dd581d4631cf343ba9ee6c1ab2858abca6c00da3def156b1f12a6464384e326d5fa724c2fc2ff2b7f3fc8ad5f" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-tpk_m_hash", - "value": "2a0b3526801cd5edcaf6b4ba6e1f0a378b6d78d42a62410e86202fb66b44dd53" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-tpk_m_hash", + "value": "019f5bb255e87523d43da83ebc9fa95169b653d4abef902e011e9eac620fc45b" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-tsk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-tsk_m", "value": "183cb61099458d1564aa57c90c7091ac623a14092ab314150c9cfbb416810320" } ] diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json index 2ee17beb3c62..8a55a9c4c66f 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json @@ -1,5 +1,5 @@ { - "schemaVersion": 5, + "schemaVersion": 6, "stores": [ { "name": "address_book", diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts b/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts index 91b2c2d90ef1..d54678092928 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts @@ -2,7 +2,6 @@ import { CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants'; import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import { EthAddress } from '@aztec/foundation/eth-address'; import type { Tuple } from '@aztec/foundation/serialize'; import { KeyStore } from '@aztec/key-store'; @@ -15,7 +14,7 @@ import { BlockHash, Body, GENESIS_BLOCK_HEADER_HASH, L2Block } from '@aztec/stdl import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; import { CompleteAddress, SerializableContractInstance } from '@aztec/stdlib/contract'; import { GasFees } from '@aztec/stdlib/gas'; -import { PublicKeys } from '@aztec/stdlib/keys'; +import { PublicKey, PublicKeys } from '@aztec/stdlib/keys'; import { ContractClassLog, ContractClassLogFields, @@ -187,18 +186,17 @@ export const SCHEMA_TESTS: readonly SchemaTest[] = [ await contractStore.addContractInstance( new SerializableContractInstance({ - version: 1, + version: 2, salt: new Fr(73n), deployer: AztecAddress.fromBigInt(79n), currentContractClassId: new Fr(83n), originalContractClassId: new Fr(89n), initializationHash: new Fr(97n), - publicKeys: new PublicKeys( - new Point(new Fr(41n), new Fr(43n), false), - new Point(new Fr(47n), new Fr(53n), false), - new Point(new Fr(59n), new Fr(61n), false), - new Point(new Fr(67n), new Fr(71n), false), - ), + immutablesHash: new Fr(103n), + // Only `ivpk_m` is exposed as a curve point; the other three master keys + // are exposed as `hash_public_key` digests. Constructor signature is now + // `(npkMHash, ivpkM, ovpkMHash, tpkMHash)`. + publicKeys: new PublicKeys(new Fr(41n), new PublicKey(new Fr(47n), new Fr(53n)), new Fr(59n), new Fr(67n)), }).withAddress(AztecAddress.fromBigInt(101n)), ); }, diff --git a/yarn-project/pxe/src/storage/metadata.ts b/yarn-project/pxe/src/storage/metadata.ts index aa63404894b5..b828fac62539 100644 --- a/yarn-project/pxe/src/storage/metadata.ts +++ b/yarn-project/pxe/src/storage/metadata.ts @@ -1 +1 @@ -export const PXE_DATA_SCHEMA_VERSION = 5; +export const PXE_DATA_SCHEMA_VERSION = 6; diff --git a/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts b/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts index b2800582f02d..6c9e4a430d33 100644 --- a/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts +++ b/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts @@ -494,7 +494,7 @@ describe('SenderTaggingStore', () => { describe('finalizePendingIndexesOfAPartiallyRevertedTx', () => { function makeTxEffect(txHash: TxHash, siloedTags: SiloedTag[]): TxEffect { return new TxEffect( - RevertCode.APP_LOGIC_REVERTED, + RevertCode.REVERTED, txHash, Fr.ZERO, [Fr.random()], // noteHashes (at least 1 nullifier required below, not here) diff --git a/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts b/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts index d2020a61218b..db241763b58e 100644 --- a/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts +++ b/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts @@ -467,12 +467,12 @@ describe('syncSenderTaggingIndexes', () => { ); }); - // Mock getTxReceipt to return FINALIZED with APP_LOGIC_REVERTED + // Mock getTxReceipt to return FINALIZED with REVERTED aztecNode.getTxReceipt.mockResolvedValue( new TxReceipt( revertedTxHash, TxStatus.FINALIZED, - TxExecutionResult.APP_LOGIC_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, @@ -482,7 +482,7 @@ describe('syncSenderTaggingIndexes', () => { // Mock getTxEffect to return a TxEffect where only the tag at index 4 survived (non-revertible phase) const txEffect = new TxEffect( - RevertCode.APP_LOGIC_REVERTED, + RevertCode.REVERTED, revertedTxHash, Fr.ZERO, [Fr.random()], // noteHashes diff --git a/yarn-project/pxe/src/tagging/sender_sync/utils/get_status_change_of_pending.test.ts b/yarn-project/pxe/src/tagging/sender_sync/utils/get_status_change_of_pending.test.ts index 676b491d8910..2842a8554eb7 100644 --- a/yarn-project/pxe/src/tagging/sender_sync/utils/get_status_change_of_pending.test.ts +++ b/yarn-project/pxe/src/tagging/sender_sync/utils/get_status_change_of_pending.test.ts @@ -55,7 +55,7 @@ describe('getStatusChangeOfPending', () => { new TxReceipt( hash, TxStatus.FINALIZED, - TxExecutionResult.APP_LOGIC_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, @@ -67,7 +67,7 @@ describe('getStatusChangeOfPending', () => { new TxReceipt( hash, TxStatus.FINALIZED, - TxExecutionResult.TEARDOWN_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, @@ -79,7 +79,7 @@ describe('getStatusChangeOfPending', () => { new TxReceipt( hash, TxStatus.FINALIZED, - TxExecutionResult.BOTH_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, diff --git a/yarn-project/sequencer-client/README.md b/yarn-project/sequencer-client/README.md index dcd133ab02e5..6738e8cb168d 100644 --- a/yarn-project/sequencer-client/README.md +++ b/yarn-project/sequencer-client/README.md @@ -4,13 +4,13 @@ The sequencer client is the proposer-side counterpart to the [validator client]( A single instance owns the entire proposer flow for one slot: deciding whether to propose, building several L2 blocks one after another, signing them, gossiping them, collecting attestations from the committee, and submitting the final checkpoint to L1 in one Multicall3 transaction together with governance and slashing votes. -The sequencer does **not** decide what is in the next block on its own. It composes the work of several other subsystems: the [tx pool](../p2p/README.md) supplies transactions, the [validator client](../validator-client/README.md) owns the operator keys and signs proposals, the `CheckpointBuilder` (defined in `@aztec/validator-client`, but constructed and held by the sequencer's `CheckpointProposalJob`) executes the txs, the [archiver](../archiver/README.md) provides the L2 chain state needed to anchor each block, the [epoch cache](../epoch-cache/README.md) answers proposer/committee lookups, and the [slasher](../slasher/README.md) supplies offenses to vote on. +The sequencer does **not** decide what is in the next block on its own. It composes the work of several other subsystems: the [tx pool](../p2p/README.md) supplies transactions, the [validator client](../validator-client/README.md) owns operator keys and contains the `CheckpointBuilder` that actually executes them, the [archiver](../archiver/README.md) provides the L2 chain state needed to anchor each block, the [epoch cache](../epoch-cache/README.md) answers proposer/committee lookups, and the [slasher](../slasher/README.md) supplies offenses to vote on. ## Key Concepts ### Slots, Blocks, and Checkpoints -The Aztec design splits each Aztec slot into multiple L2 blocks: +The Aztec consensus design splits each Aztec slot into multiple L2 blocks. This is the design originally called [building in chunks](https://github.com/AztecProtocol/engineering-designs/blob/main/docs/building-in-chunks/index.md). - **Slot** — a fixed time window (e.g. 72 s) during which one proposer is allowed to build. - **Block** — a single batch of transactions, executed and validated as a unit, with its own header. @@ -26,13 +26,11 @@ There are two tips the sequencer cares about: - The **proposed chain** is the set of blocks that have been broadcast over p2p but not yet committed to L1. Both the sequencer and validators push these blocks into the archiver so the rest of the node can serve them. - The **checkpointed chain** is the set of checkpoints that have landed on L1, recovered from `CheckpointProposed` events. -Within a slot, the proposer adds blocks to the proposed chain as it goes. At the end of its slot, it sends a `CheckpointProposal` that committee members attest to; intermediate blocks are accepted onto the proposed chain by virtue of the proposer's signature alone, and every node that wants to follow the proposed chain re-executes them. See the [validator client README](../validator-client/README.md) for the consumer side. +Within a slot, the proposer adds blocks to the proposed chain as it goes. Only the last block within the slot is bundled with a `CheckpointProposal` that committee members attest to; intermediate blocks are accepted onto the proposed chain by virtue of the proposer's signature alone, and every node that wants to follow the proposed chain re-executes them. See the [validator client README](../validator-client/README.md) for the consumer side. ### Proposer Pipelining -The legacy non-pipelined flow had the proposer for slot `N` build, attest, and publish inside slot `N`; so the proposer spent most of `N` collecting attestations and waiting for the L1 transaction to be mined, leaving a long idle window. - -Pipelining removes that idle window: the proposer for slot `N` builds blocks during slot `N - 1`, finishes attestation collection before the slot boundary, and submits the L1 transaction at the start of slot `N`. +The legacy ("non-pipelined") flow has the proposer for slot `N` build, attest, and publish inside slot `N`. The proposer spends most of `N` collecting attestations and waiting for the L1 transaction to be mined, leaving a long idle window. Pipelining, [proposed in this discussion](https://github.com/AztecProtocol/governance/discussions/8), removes that idle window: the proposer for slot `N` builds blocks during slot `N - 1`, finishes attestation collection before the slot boundary, and submits the L1 transaction at the start of slot `N`. Pipelining shifts the work like this: @@ -45,35 +43,44 @@ Pipelining shifts the work like this: \* The pipelined timing model reserves enough end-of-slot budget for attestations to be in hand by the slot boundary, but the enforced deadline (`checkpointAttestationDeadline`) actually extends to `2 * aztecSlotDuration - l1PublishingTime`, so a late attestation can still spill into the target slot. -The non-pipelined mode is being removed; this README treats pipelining as the default. The toggle still exists for lingering tests. +In practice, "non-pipelined mode" is being removed; this README treats pipelining as the default. The toggle still exists (`enableProposerPipelining`) because `EpochCache` consults it when looking up the proposer for the next L1 slot — when pipelining is enabled, the sequencer asks the cache for the proposer of `slot + 1` rather than `slot`. + +The pipelining flow introduces two failure modes that block building has to handle: -Note that, under pipelining, if the parent checkpoint we built on top of fails to land cleanly on L1, the next proposer's work is discarded (`pipelined-checkpoint-discarded` event). +- **Pipeline depth** is bounded to 2 (`checkpointNumber ≤ confirmedCheckpoint + 2`). Building further ahead would require trusting more in-flight parent proposals than the design allows. +- **Pipelined parent invalidation**: if the parent checkpoint we built on top of fails to land cleanly on L1, the next proposer's work is discarded (`pipelined-checkpoint-discarded` event) and an `invalidate` request is enqueued for the parent. ## Architecture -```mermaid -flowchart TD - Seq["Sequencer
state machine, one slot at a time
work() → prepareCheckpointProposal() → CheckpointProposalJob"] - - VC["ValidatorClient
operator keys, HA signer
signs block + checkpoint proposals"] - EC["EpochCache
proposer + committee lookup"] - CB["CheckpointBuilder
forked world state
per-block execution via PublicProcessor"] - Pub["SequencerPublisher
Multicall3 L1 tx
with preChecks"] - - P2P["p2pClient"] - TP["TxProvider
(tx pool)"] - Arc["Archiver
L2 tips, addBlock"] - L1["L1 Rollup Contract"] - - Seq -->|signs proposals| VC - Seq -->|proposer / committee| EC - Seq -->|builds blocks| CB - Seq -->|enqueues actions| Pub - - Seq -->|broadcast block + checkpoint proposals| P2P - Seq -->|push to proposed chain| Arc - CB -->|pull txs| TP - Pub -->|submit Multicall3| L1 +``` + ┌──────────────────────────────────────────────────────────────┐ + │ Sequencer │ + │ (state machine, one slot at a time) │ + │ │ + │ work() ──► prepareCheckpointProposal() ──► proposal job │ + └─────┬────────────────┬──────────────────┬──────────────────┬─┘ + │ │ │ │ + ▼ ▼ ▼ ▼ + ┌──────────────────┐ ┌──────────┐ ┌──────────────────┐ ┌────────────────┐ + │ ValidatorClient │ │ Epoch │ │ CheckpointBuilder│ │ Sequencer │ + │ (owns keys, │ │ Cache │ │ (forked world │ │ Publisher │ + │ HA signer, │ │ (proposer│ │ state, per-block│ │ (Multicall3 │ + │ signs the │ │ + │ │ execution via │ │ L1 tx, with │ + │ proposals) │ │ comm.) │ │ PublicProcessor)│ │ pre-checks) │ + └──────────────────┘ └──────────┘ └──────────────────┘ └────────────────┘ + │ │ │ + │ block + checkpoint │ pull txs │ + │ proposals over p2p ▼ ▼ + │ ┌──────────┐ ┌────────────┐ + ├────────────────────────► │ Tx │ │ L1 Rollup │ + │ │ Provider │ │ Contract │ + │ push blocks to └──────────┘ └────────────┘ + ▼ proposed chain + ┌──────────────────┐ + │ Archiver │ + │ (l2 tips, │ + │ addBlock) │ + └──────────────────┘ ``` `SequencerClient.new(config, deps)` is the entrypoint and is constructed by the full node. It reads L1 constants (`l1GenesisTime`, `slotDuration`, `rollupManaLimit`) from the rollup contract, builds the publisher factory, validator client wiring, and timetable, then instantiates the `Sequencer`. See `src/client/sequencer-client.ts`. @@ -108,20 +115,18 @@ The sequencer is a `TypedEventEmitter`. The most useful events | `pipelined-checkpoint-discarded` | Pipelined parent failed to land; this slot's work is thrown away. | | `checkpoint-error` | Catch-all: an exception escaped `work()`. | -State enum (`src/sequencer/utils.ts`). The happy-path slot cycle is: +State enum (`src/sequencer/utils.ts`): ``` -IDLE → SYNCHRONIZING → PROPOSER_CHECK - → INITIALIZING_CHECKPOINT - → (WAITING_FOR_TXS ↔ CREATING_BLOCK ↔ WAITING_UNTIL_NEXT_BLOCK)* - → ASSEMBLING_CHECKPOINT - → COLLECTING_ATTESTATIONS - → PUBLISHING_CHECKPOINT - → IDLE +STOPPED → STOPPING → IDLE → SYNCHRONIZING → PROPOSER_CHECK + → INITIALIZING_CHECKPOINT + → (WAITING_FOR_TXS ↔ CREATING_BLOCK ↔ WAITING_UNTIL_NEXT_BLOCK)* + → ASSEMBLING_CHECKPOINT + → COLLECTING_ATTESTATIONS + → PUBLISHING_CHECKPOINT + → IDLE ``` -Lifecycle transitions sit outside the cycle: `start()` moves `STOPPED → IDLE`, and `stop()` moves the current state through `STOPPING → STOPPED`. - ### CheckpointProposalJob `CheckpointProposalJob` (`src/sequencer/checkpoint_proposal_job.ts`) is the per-slot unit of work. It owns the lifecycle from "we have decided to propose" through "the L1 transaction has been submitted". The contract is: @@ -214,6 +219,7 @@ Key entry points: | `GlobalVariableBuilder` | `src/global_variable_builder/` | Computes `CheckpointGlobalVariables` and predicts the per-slot fee asset price modifier. See its [README](src/global_variable_builder/README.md). | | `L1TxFailedStore` | `src/publisher/l1_tx_failed_store/` | Persists actions that returned a revert reason so they aren't retried in the same form on the next slot. | | `ChainStateOverrides` | `src/sequencer/chain_state_overrides.ts` | Builds the L1 `eth_call` overrides used during the pipelined parent + invalidation simulations. | +| `AutomineSequencer` | `src/sequencer/automine/` | Minimal queue-driven sequencer for single-sequencer e2e tests. Bypasses consensus, pipelining, and timetable enforcement. See [`src/sequencer/automine/README.md`](src/sequencer/automine/README.md). | ## Configuration @@ -227,11 +233,11 @@ The configuration object is `SequencerConfig` (`src/sequencer/config.ts` + `src/ | `minValidTxsPerBlock` | falls back to `minTxsPerBlock` | After execution, discard the block if fewer txs validated. | | `maxTxsPerBlock` / `SEQ_MAX_TX_PER_BLOCK` | unset | Hard per-block tx cap (capped at `maxTxsPerCheckpoint` at startup). | | `maxTxsPerCheckpoint` / `SEQ_MAX_TX_PER_CHECKPOINT` | unset | Total tx cap across the checkpoint. Enables redistribution when set. | -| `maxBlocksPerCheckpoint` / `MAX_BLOCKS_PER_CHECKPOINT` | 24 | Absolute ceiling on blocks per checkpoint, applied on top of the timetable's `maxNumberOfBlocks`. Also caps the `indexWithinCheckpoint` accepted on inbound block proposals. | +| `maxBlocksPerCheckpoint` / `MAX_BLOCKS_PER_CHECKPOINT` | 24 | Hard ceiling beyond what the timetable allows. Also caps the `indexWithinCheckpoint` accepted on inbound block proposals. | | `maxL2BlockGas` / `SEQ_MAX_L2_BLOCK_GAS` | unset | Per-block mana cap, capped at `rollupManaLimit`. | | `maxDABlockGas` / `SEQ_MAX_DA_BLOCK_GAS` | unset | Per-block DA gas cap, capped at `MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT`. | | `perBlockAllocationMultiplier` / `SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER` | 1.2 | Multiplier passed to the checkpoint builder so early blocks can use slightly more than their even share. | -| `redistributeCheckpointBudget` / `SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET` | true | Legacy flag, kept for back-compat. Has no effect on proposal building — redistribution is always on. | +| `redistributeCheckpointBudget` / `SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET` | true | Legacy flag. Redistribution is always on during proposal building. | ### Timing @@ -242,7 +248,7 @@ The configuration object is `SequencerConfig` (`src/sequencer/config.ts` + `src/ | `attestationPropagationTime` / `SEQ_ATTESTATION_PROPAGATION_TIME` | 2 s | One-way p2p estimate fed to the timetable. | | `l1PublishingTime` / `SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT` | full L1 slot | Time reserved for the L1 tx to land. | | `sequencerPollingIntervalMS` / `SEQ_POLLING_INTERVAL_MS` | 500 | Work-loop tick rate. | -| `enableProposerPipelining` / `SEQ_ENABLE_PROPOSER_PIPELINING` | false | When true, the sequencer builds for `slot + 1`. The flag lives in shared `PipelineConfig`; both the sequencer's timetable and `EpochCache`'s proposer-of-next-slot lookup read it. | +| `enableProposerPipelining` / `SEQ_ENABLE_PROPOSER_PIPELINING` | false | When true, the sequencer builds for `slot + 1`. The flag lives in shared `PipelineConfig` and is read by `EpochCache`, not by the sequencer directly. | ### Behavior @@ -254,8 +260,8 @@ The configuration object is `SequencerConfig` (`src/sequencer/config.ts` + `src/ | `coinbase` / `COINBASE` | proposer addr | Recipient of block rewards. | | `feeRecipient` / `FEE_RECIPIENT` | proposer addr | Recipient of tx fees. | | `governanceProposerPayload` / `GOVERNANCE_PROPOSER_PAYLOAD_ADDRESS` | unset | Payload signaled in the governance vote each slot. | -| `secondsBeforeInvalidatingBlockAsCommitteeMember` / `SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_COMMITTEE_MEMBER` | 144 | When *not* the proposer, committee members may invalidate a stuck checkpoint after this many seconds into the slot. | -| `secondsBeforeInvalidatingBlockAsNonCommitteeMember` / `SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_NON_COMMITTEE_MEMBER` | 432 | Same for any node — last resort. | +| `secondsBeforeInvalidatingBlockAsCommitteeMember` | 144 | When *not* the proposer, committee members may invalidate a stuck checkpoint after this many seconds into the slot. | +| `secondsBeforeInvalidatingBlockAsNonCommitteeMember` | 432 | Same for any node — last resort. | The full list (including test/fault-injection hooks like `pauseProposingForSlots` and `skipPublishingCheckpointsPercent`) lives in `src/config.ts`. diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index 34c14f2a509f..16f703bccc9c 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -53,6 +53,7 @@ export const DefaultSequencerConfig = { skipCollectingAttestations: false, skipInvalidateBlockAsProposer: false, broadcastInvalidBlockProposal: false, + broadcastInvalidCheckpointProposalOnly: false, injectFakeAttestation: false, injectHighSValueAttestation: false, injectUnrecoverableSignatureAttestation: false, @@ -191,6 +192,15 @@ export const sequencerConfigMappings: ConfigMappingsType = { description: 'Broadcast invalid block proposals with corrupted state (for testing only)', ...booleanConfigHelper(DefaultSequencerConfig.broadcastInvalidBlockProposal), }, + invalidBlockProposalIndexWithinCheckpoint: { + description: 'Broadcast an invalid block proposal only at this indexWithinCheckpoint (for testing only)', + ...optionalNumberConfigHelper(), + }, + broadcastInvalidCheckpointProposalOnly: { + description: + 'Broadcast invalid checkpoint proposals while keeping the underlying block proposals valid (for testing only). When unset, the checkpoint follows broadcastInvalidBlockProposal.', + ...booleanConfigHelper(DefaultSequencerConfig.broadcastInvalidCheckpointProposalOnly), + }, injectFakeAttestation: { description: 'Inject a fake attestation (for testing only)', ...booleanConfigHelper(DefaultSequencerConfig.injectFakeAttestation), diff --git a/yarn-project/sequencer-client/src/index.ts b/yarn-project/sequencer-client/src/index.ts index 2375b9013a90..7b156d567f79 100644 --- a/yarn-project/sequencer-client/src/index.ts +++ b/yarn-project/sequencer-client/src/index.ts @@ -1,7 +1,16 @@ export * from './client/index.js'; export * from './config.js'; export * from './publisher/index.js'; -export { Sequencer, SequencerState, type SequencerEvents } from './sequencer/index.js'; +export { + AutomineSequencer, + type AutomineSequencerConstants, + type AutomineSequencerDeps, + createAutomineSequencer, + type CreateAutomineSequencerArgs, + Sequencer, + SequencerState, + type SequencerEvents, +} from './sequencer/index.js'; // Used by the node to simulate public parts of transactions. Should these be moved to a shared library? // ISSUE(#9832) diff --git a/yarn-project/sequencer-client/src/publisher/sequencer-bundle-simulator.ts b/yarn-project/sequencer-client/src/publisher/sequencer-bundle-simulator.ts new file mode 100644 index 000000000000..5ae7c1647117 --- /dev/null +++ b/yarn-project/sequencer-client/src/publisher/sequencer-bundle-simulator.ts @@ -0,0 +1,253 @@ +import type { EpochCache } from '@aztec/epoch-cache'; +import { Multicall3, type RollupContract, buildSimulationOverridesStateOverride } from '@aztec/ethereum/contracts'; +import { type L1TxUtils, MAX_L1_TX_LIMIT } from '@aztec/ethereum/l1-tx-utils'; +import { formatViemError } from '@aztec/ethereum/utils'; +import type { SlotNumber } from '@aztec/foundation/branded-types'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; + +import type { Hex, StateOverride } from 'viem'; + +import type { RequestWithExpiry } from './sequencer-publisher.js'; + +/** A request that was dropped by bundle simulation, with the decoded revert reason. */ +export type DroppedRequest = { + request: RequestWithExpiry; + revertReason: string | undefined; + returnData: Hex | undefined; +}; + +/** + * Result of {@link SequencerBundleSimulator.simulate}. + * + * - `success`: simulation succeeded. `requests` is the filtered survivor list, `gasLimit` is + * the bumped gas limit derived from `gasUsed` (plus blob evaluation gas). `droppedRequests` + * lists the entries that were observed to revert in simulation. + * - `fallback`: the node does not support eth_simulateV1 (or the simulate call threw). The + * caller should send `requests` as-is with a safe gas limit (e.g. {@link MAX_L1_TX_LIMIT}). + * `droppedRequests` carries any entries that the first pass already proved reverted, so the + * caller does not re-include them when the second pass falls back. + * - `aborted`: the bundle cannot be sent. `droppedRequests` contains only entries that were + * actually observed to revert (so they can be reported as simulation failures); it is empty + * when the abort was caused by an empty input bundle. + */ +export type BundleSimulateResult = + | { kind: 'success'; requests: RequestWithExpiry[]; gasLimit: bigint; droppedRequests: DroppedRequest[] } + | { kind: 'fallback'; requests: RequestWithExpiry[]; droppedRequests: DroppedRequest[] } + | { kind: 'aborted'; reason: AbortReason; droppedRequests: DroppedRequest[] }; + +export type AbortReason = 'empty-bundle' | 'all-reverted' | 'second-pass-reverts'; + +type SimulatePassResult = + | { kind: 'decoded'; survivors: RequestWithExpiry[]; droppedRequests: DroppedRequest[]; gasUsed: bigint } + | { kind: 'fallback' }; + +/** + * Bundle-level simulator for the aggregate3 payload that `SequencerPublisher` is about to send. + * + * Runs `eth_simulateV1` against `Multicall3.aggregate3`, drops entries that revert, and returns + * a gasLimit for the survivors. When `eth_simulateV1` is unavailable, signals fallback to the + * caller so it can send the bundle as-is with a conservative gas limit. + */ +export class SequencerBundleSimulator { + private readonly log: Logger; + + constructor( + private readonly deps: { + getL1TxUtils: () => L1TxUtils; + rollupContract: RollupContract; + epochCache: EpochCache; + log?: Logger; + }, + ) { + this.log = deps.log ?? createLogger('sequencer:publisher:bundle-simulator'); + } + + /** + * Simulates the given bundle at the target slot's start timestamp and filters out entries + * that revert. + * + * - If all entries pass on the first pass, returns `success` with the gasLimit. + * - If some entries revert, re-simulates the survivors. If the second pass is clean, returns + * `success` with the survivors and dropped entries. If the second pass surfaces any revert, + * returns `aborted` — we refuse to send a bundle whose composition still has internal + * reverts after one round of filtering. + * - If eth_simulateV1 is unavailable, returns `fallback`. The caller is expected to send the + * bundle as-is with a safe gas limit. + * + * The simulation `block.timestamp` is always the target L2 slot's start timestamp, since + * propose's `validateHeader` and EIP-712 signature checks both derive a slot from + * `block.timestamp` and compare against the slot the validator signed for. + * + * Known limitation: on networks where L1 is mining behind cadence (missed L1 slots, anvil with + * overridden timestamps), the actual `block.timestamp` at send time can land in the prior L2 + * slot. In that case `propose` would revert silently inside the multicall. The simulator does + * not detect this case because it simulates AT the target timestamp — the prior implementation + * used `min(predictedNextL1Ts, targetTimestamp)` to surface this failure mode at simulate time. + */ + public async simulate(validRequests: RequestWithExpiry[], targetSlot: SlotNumber): Promise { + if (validRequests.length === 0) { + return { kind: 'aborted', reason: 'empty-bundle', droppedRequests: [] }; + } + // Pin the publisher we'll use across the whole simulate call so that the publisher's rotation + // can't change l1TxUtils mid-flight. + const l1TxUtils = this.deps.getL1TxUtils(); + + const proposeRequest = validRequests.find(r => r.action === 'propose'); + const simulateTimestamp = getTimestampForSlot(targetSlot, this.deps.epochCache.getL1Constants()); + const firstPassOverrides = await this.buildStateOverrides(!!proposeRequest); + + const firstPass = await this.simulateAndDecode(l1TxUtils, validRequests, simulateTimestamp, firstPassOverrides); + + if (firstPass.kind === 'fallback') { + this.log.warn('Bundle simulate fallback (eth_simulateV1 unavailable); caller will send bundle as-is', { + actions: validRequests.map(r => r.action), + }); + return { kind: 'fallback', requests: validRequests, droppedRequests: [] }; + } + + if (firstPass.survivors.length === 0) { + this.log.warn('All bundle entries dropped in simulation; aborting send', { + actions: validRequests.map(r => r.action), + }); + return { kind: 'aborted', reason: 'all-reverted', droppedRequests: firstPass.droppedRequests }; + } + + if (firstPass.droppedRequests.length === 0) { + return this.buildSuccessResult(l1TxUtils, firstPass.survivors, [], firstPass.gasUsed, proposeRequest); + } + + this.log.warn('Some bundle entries reverted; re-simulating reduced bundle', { + droppedActions: firstPass.droppedRequests.map(d => d.request.action), + remainingActions: firstPass.survivors.map(r => r.action), + }); + + // Rebuild overrides for the reduced bundle: if propose was dropped, we no longer need the blob-check override + const proposeSurvived = proposeRequest !== undefined && firstPass.survivors.includes(proposeRequest); + const secondPassOverrides = proposeSurvived ? firstPassOverrides : await this.buildStateOverrides(false); + const secondPass = await this.simulateAndDecode( + l1TxUtils, + firstPass.survivors, + simulateTimestamp, + secondPassOverrides, + ); + + if (secondPass.kind === 'fallback') { + this.log.warn( + 'Bundle simulate errored on second pass (eth_simulateV1 unavailable); sending first-pass survivors as-is', + { + actions: firstPass.survivors.map(r => r.action), + droppedActions: firstPass.droppedRequests.map(d => d.request.action), + }, + ); + return { kind: 'fallback', requests: firstPass.survivors, droppedRequests: firstPass.droppedRequests }; + } + + // We refuse to chase reverts through repeated trimming: anything other than a clean second pass aborts the whole send + if (secondPass.droppedRequests.length > 0) { + this.log.error('Re-simulate surfaced reverts; aborting send', { + secondPassDroppedActions: secondPass.droppedRequests.map(d => d.request.action), + }); + return { + kind: 'aborted', + reason: 'second-pass-reverts', + droppedRequests: [...firstPass.droppedRequests, ...secondPass.droppedRequests], + }; + } + + return this.buildSuccessResult( + l1TxUtils, + secondPass.survivors, + firstPass.droppedRequests, + secondPass.gasUsed, + proposeRequest, + ); + } + + private buildSuccessResult( + l1TxUtils: L1TxUtils, + survivors: RequestWithExpiry[], + droppedRequests: DroppedRequest[], + bundleGasUsed: bigint, + proposeRequest: RequestWithExpiry | undefined, + ): BundleSimulateResult { + const proposeSurvived = proposeRequest !== undefined && survivors.includes(proposeRequest); + const blobEvaluationGas = proposeSurvived ? (proposeRequest?.blobEvaluationGas ?? 0n) : 0n; + const gasLimit = this.computeGasLimit(l1TxUtils, bundleGasUsed, blobEvaluationGas); + this.log.debug('Bundle simulate complete', { + survivingRequests: survivors.length, + bundleGasUsed, + gasLimit, + actions: survivors.map(r => r.action), + }); + return { kind: 'success', requests: survivors, gasLimit, droppedRequests }; + } + + /** + * `gasLimit = bumpGasLimit(ceil(gasUsed * 64 / 63))`, plus blob evaluation gas if a propose + * survived, capped at the L1 block gas limit. + */ + private computeGasLimit(l1TxUtils: L1TxUtils, bundleGasUsed: bigint, blobEvaluationGas: bigint): bigint { + const gasUsedWithEip150 = (bundleGasUsed * 64n + 62n) / 63n; + const gasLimit = l1TxUtils.bumpGasLimit(gasUsedWithEip150) + blobEvaluationGas; + return gasLimit > MAX_L1_TX_LIMIT ? MAX_L1_TX_LIMIT : gasLimit; + } + + /** + * eth_simulateV1 cannot carry blob sidecar data, so disable the rollup's on-chain blob check + * when a propose is in the bundle. + */ + private buildStateOverrides(hasProposeAction: boolean): Promise { + return buildSimulationOverridesStateOverride( + this.deps.rollupContract, + hasProposeAction ? { disableBlobCheck: true } : undefined, + ); + } + + private async simulateAndDecode( + l1TxUtils: L1TxUtils, + requests: RequestWithExpiry[], + simulateTimestamp: bigint, + stateOverrides: StateOverride, + ): Promise { + let simResult: Awaited>; + try { + simResult = await Multicall3.simulateAggregate3( + requests.map(r => ({ to: r.request.to! as Hex, data: r.request.data! as Hex, abi: r.request.abi })), + l1TxUtils, + { + blockOverrides: { time: simulateTimestamp, gasLimit: MAX_L1_TX_LIMIT * 2n }, + stateOverrides, + gas: MAX_L1_TX_LIMIT, + fallbackGasEstimate: MAX_L1_TX_LIMIT, + }, + ); + } catch (err) { + this.log.warn('Bundle simulate threw; treating as fallback', { + err: formatViemError(err), + actions: requests.map(r => r.action), + }); + return { kind: 'fallback' }; + } + + if (simResult.kind === 'fallback') { + return { kind: 'fallback' }; + } + + const survivors: RequestWithExpiry[] = []; + const droppedRequests: DroppedRequest[] = []; + for (let i = 0; i < requests.length; i++) { + const entry = simResult.entries[i]; + if (entry.success) { + survivors.push(requests[i]); + continue; + } + droppedRequests.push({ + request: requests[i], + revertReason: entry.revertReason, + returnData: entry.returnData, + }); + } + return { kind: 'decoded', survivors, droppedRequests, gasUsed: simResult.gasUsed }; + } +} diff --git a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts index ce8479609636..2a9bac671e44 100644 --- a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts +++ b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts @@ -5,19 +5,17 @@ import type { L1ContractsConfig } from '@aztec/ethereum/config'; import { type GovernanceProposerContract, Multicall3, + MulticallForwarderRevertedError, type RollupContract, - type SimulationOverridesPlan, type SlashingProposerContract, } from '@aztec/ethereum/contracts'; import { - type GasPrice, type L1TxUtils, type L1TxUtilsConfig, + MAX_L1_TX_LIMIT, defaultL1TxUtilsConfig, } from '@aztec/ethereum/l1-tx-utils'; -import { FormattedViemError } from '@aztec/ethereum/utils'; -import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; -import { Fr } from '@aztec/foundation/curves/bn254'; +import { BlockNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { TimeoutError } from '@aztec/foundation/error'; import { EthAddress } from '@aztec/foundation/eth-address'; import { sleep } from '@aztec/foundation/sleep'; @@ -33,9 +31,12 @@ import { type MockProxy, mock } from 'jest-mock-extended'; import { type GetCodeReturnType, type GetTransactionReceiptReturnType, + type Hex, type PrivateKeyAccount, type TransactionReceipt, encodeFunctionData, + encodeFunctionResult, + multicall3Abi, toHex, } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; @@ -168,10 +169,13 @@ describe('SequencerPublisher', () => { (l1TxUtils as any).estimateGas.mockResolvedValue(GAS_GUESS); (l1TxUtils as any).simulate.mockResolvedValue({ gasUsed: 1_000_000n, result: '0x' }); (l1TxUtils as any).bumpGasLimit.mockImplementation((val: bigint) => val + (val * 20n) / 100n); + l1TxUtils.getSenderBalance.mockResolvedValue(10_000_000_000_000_000_000n); // 10 ETH, sufficient for all tests (l1TxUtils as any).client = { account: { address: '0x1234567890123456789012345678901234567890', }, + getGasPrice: () => Promise.resolve(1n), + getBlock: () => Promise.resolve({ timestamp: 0n }), }; const currentL2Slot = publisher.getCurrentL2Slot(); @@ -230,7 +234,8 @@ describe('SequencerPublisher', () => { forwardSpy.mockResolvedValue({ receipt: proposeTxReceipt, - errorMsg: undefined, + stats: undefined, + multicallData: '0x', }); await publisher.sendRequests(); @@ -274,8 +279,7 @@ describe('SequencerPublisher', () => { expect.objectContaining({ blobs: expect.any(Array), }), - mockRollupAddress, - expect.anything(), // the logger + { gasLimitRequired: true }, ); expect(forwardSpy.mock.calls[0][2]?.gasLimit).toBeGreaterThan(2_000_000n); @@ -291,7 +295,8 @@ describe('SequencerPublisher', () => { it('errors if forwarder tx fails', async () => { forwardSpy.mockRejectedValueOnce(new Error()).mockResolvedValueOnce({ receipt: proposeTxReceipt, - errorMsg: undefined, + stats: undefined, + multicallData: '0x', }); await publisher.enqueueProposeCheckpoint( @@ -312,7 +317,14 @@ describe('SequencerPublisher', () => { secondL1TxUtils = mock(); secondL1TxUtils.getBlockNumber.mockResolvedValue(1n); secondL1TxUtils.getSenderAddress.mockReturnValue(EthAddress.random()); - secondL1TxUtils.getSenderBalance.mockResolvedValue(1000n); + secondL1TxUtils.getSenderBalance.mockResolvedValue(10_000_000_000_000_000_000n); // 10 ETH + (secondL1TxUtils as any).client = { + account: { address: EthAddress.random().toString() }, + getGasPrice: () => Promise.resolve(1n), + }; + (secondL1TxUtils as any).bumpGasLimit = (val: bigint) => val + (val * 20n) / 100n; + (secondL1TxUtils as any).simulate = () => Promise.resolve({ gasUsed: 1_000_000n, result: '0x' }); + (secondL1TxUtils as any).getBlockNumber = () => Promise.resolve(1n); getNextPublisher = jest.fn(); @@ -352,7 +364,7 @@ describe('SequencerPublisher', () => { it('rotates to next publisher when forward throws and retries successfully', async () => { forwardSpy .mockRejectedValueOnce(new Error('RPC error')) - .mockResolvedValueOnce({ receipt: proposeTxReceipt, errorMsg: undefined }); + .mockResolvedValueOnce({ receipt: proposeTxReceipt, stats: undefined, multicallData: '0x' }); getNextPublisher.mockResolvedValueOnce(secondL1TxUtils); await rotatingPublisher.enqueueProposeCheckpoint( @@ -371,7 +383,6 @@ describe('SequencerPublisher', () => { expect.anything(), expect.anything(), expect.anything(), - expect.anything(), ); expect(forwardSpy).toHaveBeenNthCalledWith( 2, @@ -380,7 +391,6 @@ describe('SequencerPublisher', () => { expect.anything(), expect.anything(), expect.anything(), - expect.anything(), ); expect(getNextPublisher).toHaveBeenCalledWith([l1TxUtils.getSenderAddress()]); // Result is defined (rotation succeeded and tx was sent) @@ -424,152 +434,232 @@ describe('SequencerPublisher', () => { expect(result).toBeUndefined(); }); - it('does not rotate when forward returns a revert (on-chain failure)', async () => { - forwardSpy.mockResolvedValue({ receipt: { ...proposeTxReceipt, status: 'reverted' }, errorMsg: 'revert reason' }); - + it('does not enter the rotation loop when txTimeoutAt is already in the past', async () => { + const pastTimeout = new Date(Date.now() - 1000); await rotatingPublisher.enqueueProposeCheckpoint( new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + { txTimeoutAt: pastTimeout }, ); const result = await rotatingPublisher.sendRequests(); - expect(forwardSpy).toHaveBeenCalledTimes(1); + expect(result).toBeUndefined(); + expect(forwardSpy).not.toHaveBeenCalled(); expect(getNextPublisher).not.toHaveBeenCalled(); - // Result contains the reverted receipt (no rotation) - expect(result?.result).toMatchObject({ receipt: { status: 'reverted' } }); }); - }); - it('does not send propose tx if rollup validation fails', async () => { - l1TxUtils.simulate.mockRejectedValueOnce(new Error('Test error')); + it('stops rotating once txTimeoutAt elapses mid-rotation', async () => { + // First forward throws; getNextPublisher rotates to a new publisher; but by then the + // deadline has elapsed and the rotation loop should bail before the second forward call. + // Use jest fake timers to control `Date.now()` deterministically — the rotation loop + // checks the deadline via `new Date() > txConfig.txTimeoutAt`, so faking the system clock + // is the cleanest way to model "deadline elapses mid-rotation" without racing wall-clock + // setTimeout against CI host speed. + jest.useFakeTimers({ doNotFake: ['nextTick', 'queueMicrotask', 'setImmediate'] }); + try { + jest.setSystemTime(new Date('2026-01-01T00:00:00Z')); + const futureTimeout = new Date(Date.now() + 1000); + forwardSpy.mockImplementationOnce(() => { + // Simulate enough wall-clock advance during the forward to push past the deadline, + // so the loop's next deadline check bails before the second attempt. + jest.setSystemTime(Date.now() + 5000); + return Promise.reject(new Error('RPC error on first')); + }); + getNextPublisher.mockResolvedValueOnce(secondL1TxUtils); + + await rotatingPublisher.enqueueProposeCheckpoint( + new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), + CommitteeAttestationsAndSigners.empty(testSignatureContext), + Signature.empty(), + { txTimeoutAt: futureTimeout }, + ); + const result = await rotatingPublisher.sendRequests(); + + expect(result).toBeUndefined(); + // forward was attempted exactly once (the first publisher); rotation was aborted before + // the second attempt because the deadline had passed. + expect(forwardSpy).toHaveBeenCalledTimes(1); + } finally { + jest.useRealTimers(); + } + }); + + it('does not rotate when forward throws MulticallForwarderRevertedError (on-chain failure)', async () => { + forwardSpy.mockRejectedValueOnce( + new MulticallForwarderRevertedError({ ...proposeTxReceipt, status: 'reverted' }), + ); - await expect( - publisher.enqueueProposeCheckpoint( + await rotatingPublisher.enqueueProposeCheckpoint( new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), - ), - ).rejects.toThrow(); - - expect(l1TxUtils.simulate).toHaveBeenCalledTimes(1); + ); + const result = await rotatingPublisher.sendRequests(); - const result = await publisher.sendRequests(); - expect(result).toEqual(undefined); - expect(forwardSpy).not.toHaveBeenCalled(); + expect(forwardSpy).toHaveBeenCalledTimes(1); + expect(getNextPublisher).not.toHaveBeenCalled(); + expect(result).toBeUndefined(); + }); }); - it('preCheck closure uses preCheckSimulationOverridesPlan, not the enqueue-time plan', async () => { - (publisher.epochCache.isProposerPipeliningEnabled as jest.Mock).mockReturnValue(true); - - const validateSpy = jest.spyOn(publisher, 'validateCheckpointForSubmission').mockResolvedValue(undefined); - - const enqueuePlan: SimulationOverridesPlan = { - chainTipsOverride: { pending: CheckpointNumber(7) }, - pendingCheckpointState: { archive: Fr.random() }, - }; - const preCheckPlan: SimulationOverridesPlan = { - chainTipsOverride: { pending: CheckpointNumber(8) }, - }; - + it('does not send propose tx if rollup validation fails', async () => { await publisher.enqueueProposeCheckpoint( new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), - { simulationOverridesPlan: enqueuePlan, preCheckSimulationOverridesPlan: preCheckPlan }, ); - // Enqueue-time validation called with the enqueue plan (plus withoutBlobCheck applied). - expect(validateSpy).toHaveBeenCalledTimes(1); - expect(validateSpy.mock.calls[0][3]).toMatchObject({ - chainTipsOverride: { pending: CheckpointNumber(7) }, - disableBlobCheck: true, + // Simulate the bundle-level validate returning a failed entry for the propose call. + // When all entries fail, bundleSimulate returns undefined and sendRequests returns undefined. + const failedResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [{ success: false, returnData: '0x' }], }); + (l1TxUtils as any).simulate.mockResolvedValueOnce({ gasUsed: 0n, result: failedResult }); - // The pending preCheck request should now run the preCheck closure with the preCheck plan. - const requests: { preCheck?: () => Promise }[] = (publisher as any).requests; - expect(requests).toHaveLength(1); - const preCheck = requests[0].preCheck; - expect(preCheck).toBeDefined(); - - validateSpy.mockClear(); - await preCheck!(); - - expect(validateSpy).toHaveBeenCalledTimes(1); - expect(validateSpy.mock.calls[0][3]).toMatchObject({ - chainTipsOverride: { pending: CheckpointNumber(8) }, - disableBlobCheck: true, - }); - // And not the enqueue plan's archive override. - expect(validateSpy.mock.calls[0][3]?.pendingCheckpointState).toBeUndefined(); + const result = await publisher.sendRequests(); + expect(result).toEqual(undefined); + expect(forwardSpy).not.toHaveBeenCalled(); + expect(l1TxUtils.simulate).toHaveBeenCalledTimes(1); }); - it('preCheck does not fall back to the enqueue plan when preCheckSimulationOverridesPlan is omitted', async () => { - (publisher.epochCache.isProposerPipeliningEnabled as jest.Mock).mockReturnValue(true); + describe('bundleSimulate second-pass re-decode', () => { + const addTwoRequests = () => { + const currentL2Slot = publisher.getCurrentL2Slot(); + publisher.addRequest({ + action: 'invalidate-by-invalid-attestation', + request: { to: mockRollupAddress, data: '0xdeadbeef' }, + lastValidL2Slot: SlotNumber(Number(currentL2Slot) + 2), + checkSuccess: () => true, + }); + publisher.addRequest({ + action: 'propose', + request: { + to: mockRollupAddress, + data: encodeFunctionData({ + abi: EmpireBaseAbi, + functionName: 'signal', + args: [EthAddress.random().toString()], + }), + }, + lastValidL2Slot: SlotNumber(Number(currentL2Slot) + 2), + checkSuccess: () => true, + }); + }; - const validateSpy = jest.spyOn(publisher, 'validateCheckpointForSubmission').mockResolvedValue(undefined); + it('drops an entry that still reverts in the second-pass re-simulate', async () => { + addTwoRequests(); + + // First simulate: invalidate succeeds, propose fails. + const firstResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [ + { success: true, returnData: '0x' }, + { success: false, returnData: '0x' }, + ], + }); + // Second simulate (reduced bundle with only invalidate): that entry also fails. + const secondResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [{ success: false, returnData: '0x' }], + }); - const enqueuePlan: SimulationOverridesPlan = { - chainTipsOverride: { pending: CheckpointNumber(7) }, - pendingCheckpointState: { archive: Fr.random() }, - }; + (l1TxUtils as any).simulate + .mockResolvedValueOnce({ gasUsed: 500_000n, result: firstResult }) + .mockResolvedValueOnce({ gasUsed: 0n, result: secondResult }); - await publisher.enqueueProposeCheckpoint( - new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), - CommitteeAttestationsAndSigners.empty(testSignatureContext), - Signature.empty(), - { simulationOverridesPlan: enqueuePlan }, - ); + const result = await publisher.sendRequests(); - expect(validateSpy).toHaveBeenCalledTimes(1); - expect(validateSpy.mock.calls[0][3]).toMatchObject({ - chainTipsOverride: { pending: CheckpointNumber(7) }, - disableBlobCheck: true, + // Both passes dropped everything — should abort. + expect(result).toBeUndefined(); + expect(forwardSpy).not.toHaveBeenCalled(); + expect(l1TxUtils.simulate).toHaveBeenCalledTimes(2); }); - const requests: { preCheck?: () => Promise }[] = (publisher as any).requests; - expect(requests).toHaveLength(1); - const preCheck = requests[0].preCheck; - expect(preCheck).toBeDefined(); + it('sends only survivors after second-pass re-simulate filters additional failures', async () => { + addTwoRequests(); + + // First simulate: both succeed initially. + // (Simulate a case where second-pass further trims — to test the path where + // first pass survivors differ from second pass survivors.) + const firstResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [ + { success: true, returnData: '0x' }, + { success: false, returnData: '0x' }, + ], + }); + // Second simulate (reduced bundle with only invalidate): that one succeeds. + const secondResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [{ success: true, returnData: '0x' }], + }); - validateSpy.mockClear(); - await preCheck!(); + (l1TxUtils as any).simulate + .mockResolvedValueOnce({ gasUsed: 500_000n, result: firstResult }) + .mockResolvedValueOnce({ gasUsed: 300_000n, result: secondResult }); - expect(validateSpy).toHaveBeenCalledTimes(1); - const preCheckArg = validateSpy.mock.calls[0][3]; - expect(preCheckArg?.disableBlobCheck).toBe(true); - expect(preCheckArg?.chainTipsOverride).toBeUndefined(); - expect(preCheckArg?.pendingCheckpointState).toBeUndefined(); - }); + forwardSpy.mockResolvedValue({ receipt: proposeTxReceipt, stats: undefined, multicallData: '0x' }); - it('returns errorMsg if forwarder tx reverts', async () => { - forwardSpy.mockResolvedValue({ - receipt: { ...proposeTxReceipt, status: 'reverted' }, - errorMsg: 'Test error', + const result = await publisher.sendRequests(); + + expect(result).toBeDefined(); + // Only the invalidate survivor was sent. + expect(result?.sentActions).toEqual(['invalidate-by-invalid-attestation']); + expect(forwardSpy).toHaveBeenCalledTimes(1); + expect(l1TxUtils.simulate).toHaveBeenCalledTimes(2); }); - await publisher.enqueueProposeCheckpoint( - new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), - CommitteeAttestationsAndSigners.empty(testSignatureContext), - Signature.empty(), - ); - const result = await publisher.sendRequests(); + it('preserves first-pass survivors when second-pass simulate returns fallback', async () => { + addTwoRequests(); + + // First simulate: propose fails, invalidate survives. + const firstResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [ + { success: true, returnData: '0x' }, + { success: false, returnData: '0x' }, + ], + }); + // Second simulate: fallback (eth_simulateV1 not supported on the reduced bundle). + (l1TxUtils as any).simulate + .mockResolvedValueOnce({ gasUsed: 500_000n, result: firstResult }) + .mockResolvedValueOnce({ gasUsed: 1_000_000n, result: '0x' }); + + forwardSpy.mockResolvedValue({ receipt: proposeTxReceipt, stats: undefined, multicallData: '0x' }); + + const result = await publisher.sendRequests(); - expect(result).not.toBeInstanceOf(FormattedViemError); - if (result instanceof FormattedViemError) { - fail('Not Expected result to be a FormattedViemError'); - } else { - expect((result as any).result.errorMsg).toEqual('Test error'); - } + // Second-pass fallback must NOT re-include the propose entry that first-pass dropped. + expect(result).toBeDefined(); + expect(result?.sentActions).toEqual(['invalidate-by-invalid-attestation']); + expect(result?.failedActions).toEqual(['propose']); + expect(forwardSpy).toHaveBeenCalledTimes(1); + expect(forwardSpy.mock.calls[0][2]?.gasLimit).toEqual(MAX_L1_TX_LIMIT); + // The forwarded bundle should only contain the survivor. + expect(forwardSpy.mock.calls[0][0]).toHaveLength(1); + expect(l1TxUtils.simulate).toHaveBeenCalledTimes(2); + }); }); it('does not send requests if interrupted', async () => { forwardSpy.mockImplementationOnce( () => - sleep(10, { receipt: proposeTxReceipt, gasPrice: { maxFeePerGas: 1n, maxPriorityFeePerGas: 1n } }) as Promise<{ + sleep(10, { + receipt: proposeTxReceipt, + stats: undefined, + multicallData: '0x', + }) as Promise<{ receipt: TransactionReceipt; - gasPrice: GasPrice; - errorMsg: undefined; + stats: undefined; + multicallData: Hex; }>, ); await publisher.enqueueProposeCheckpoint( @@ -586,64 +676,6 @@ describe('SequencerPublisher', () => { expect((publisher as any).requests.length).toEqual(0); }); - it('discards only the request whose preCheck fails before sending', async () => { - const currentL2Slot = publisher.getCurrentL2Slot(); - const keptRequest = { - to: mockGovernanceProposerAddress, - data: encodeFunctionData({ - abi: EmpireBaseAbi, - functionName: 'signal', - args: [EthAddress.random().toString()], - }), - }; - const failedRequest = { - to: mockRollupAddress, - data: encodeFunctionData({ - abi: EmpireBaseAbi, - functionName: 'signal', - args: [EthAddress.random().toString()], - }), - }; - - const keptPreCheck = jest.fn(() => Promise.resolve()); - const failedPreCheck = jest.fn(() => Promise.reject(new Error('preCheck failed'))); - - publisher.addRequest({ - action: 'vote-offenses', - request: keptRequest, - lastValidL2Slot: currentL2Slot, - preCheck: keptPreCheck, - checkSuccess: () => true, - }); - publisher.addRequest({ - action: 'governance-signal', - request: failedRequest, - lastValidL2Slot: currentL2Slot, - preCheck: failedPreCheck, - checkSuccess: () => true, - }); - - forwardSpy.mockResolvedValue({ - receipt: proposeTxReceipt, - errorMsg: undefined, - }); - - const result = await publisher.sendRequestsAt(new Date((publisher as any).dateProvider.now())); - - expect(keptPreCheck).toHaveBeenCalledTimes(1); - expect(failedPreCheck).toHaveBeenCalledTimes(1); - expect(result?.sentActions).toEqual(['vote-offenses']); - expect(forwardSpy).toHaveBeenCalledTimes(1); - expect(forwardSpy).toHaveBeenCalledWith( - [keptRequest], - l1TxUtils, - { gasLimit: undefined, txTimeoutAt: undefined }, - undefined, - mockRollupAddress, - expect.anything(), - ); - }); - it('does not send requests if no valid requests are found', async () => { publisher.addRequest({ action: 'propose', @@ -704,15 +736,18 @@ describe('SequencerPublisher', () => { forwardSpy.mockResolvedValue({ receipt: proposeTxReceipt, - errorMsg: undefined, + stats: undefined, + multicallData: '0x', }); await publisher.sendRequests(); expect(forwardSpy).toHaveBeenCalledTimes(1); - // The gas config should only include the valid request's gas (100_000), not the expired one (500_000) + // The expired request (500_000) is filtered before bundle simulate. + // Bundle simulate returns '0x' (fallback), so gasLimit comes from MAX_L1_TX_LIMIT, + // not from per-request gasConfig — the expired request's gasLimit has no effect. const txConfig = forwardSpy.mock.calls[0][2]; - expect(txConfig?.gasLimit).toEqual(100_000n); + expect(txConfig?.gasLimit).toEqual(MAX_L1_TX_LIMIT); }); it('does not signal for payload when quorum is reached', async () => { @@ -737,8 +772,8 @@ describe('SequencerPublisher', () => { it('does not signal for payload with empty code', async () => { const { govPayload } = mockGovernancePayload(); - l1TxUtils.getCode.mockReturnValue(Promise.resolve(undefined)); - ``; + // isPayloadEmpty now lives on GovernanceProposerContract, not L1TxUtils. + governanceProposerContract.isPayloadEmpty.mockResolvedValue(true); expect( await publisher.enqueueGovernanceCastSignal( diff --git a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts index 47819bcb1221..cf4146867c7e 100644 --- a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts @@ -7,12 +7,10 @@ import { type GovernanceProposerContract, MULTI_CALL_3_ADDRESS, Multicall3, - RollupContract, - SimulationOverridesBuilder, + MulticallForwarderRevertedError, + type RollupContract, type SimulationOverridesPlan, type SlashingProposerContract, - type ViemCommitteeAttestations, - type ViemHeader, buildSimulationOverridesStateOverride, } from '@aztec/ethereum/contracts'; import { type L1FeeAnalysisResult, L1FeeAnalyzer } from '@aztec/ethereum/l1-fee-analysis'; @@ -25,46 +23,67 @@ import { type TransactionStats, WEI_CONST, } from '@aztec/ethereum/l1-tx-utils'; -import { FormattedViemError, formatViemError, mergeAbis, tryExtractEvent } from '@aztec/ethereum/utils'; -import { sumBigint } from '@aztec/foundation/bigint'; +import { + FormattedViemError, + formatViemError, + mergeAbis, + tryDecodeRevertReason, + tryExtractEvent, +} from '@aztec/ethereum/utils'; import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { trimmedBytesLength } from '@aztec/foundation/buffer'; import { pick } from '@aztec/foundation/collection'; import type { Fr } from '@aztec/foundation/curves/bn254'; import { TimeoutError } from '@aztec/foundation/error'; import { EthAddress } from '@aztec/foundation/eth-address'; -import { Signature, type ViemSignature } from '@aztec/foundation/eth-signature'; +import { Signature } from '@aztec/foundation/eth-signature'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { InterruptibleSleep } from '@aztec/foundation/sleep'; import { bufferToHex } from '@aztec/foundation/string'; import { type DateProvider, Timer } from '@aztec/foundation/timer'; -import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts'; +import { EmpireBaseAbi, ErrorsAbi, RollupAbi, SlashingProposerAbi } from '@aztec/l1-artifacts'; import { type ProposerSlashAction, encodeSlashConsensusVotes } from '@aztec/slasher'; import { CommitteeAttestationsAndSigners, type ValidateCheckpointResult } from '@aztec/stdlib/block'; import type { Checkpoint } from '@aztec/stdlib/checkpoint'; -import { getLastL1SlotTimestampForL2Slot, getNextL1SlotTimestamp } from '@aztec/stdlib/epoch-helpers'; +import { getNextL1SlotTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import type { CheckpointHeader } from '@aztec/stdlib/rollup'; import type { L1PublishCheckpointStats } from '@aztec/stdlib/stats'; import { type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client'; import { + type Abi, type Hex, type TransactionReceipt, type TypedDataDefinition, encodeFunctionData, keccak256, - multicall3Abi, toHex, } from 'viem'; import type { SequencerPublisherConfig } from './config.js'; import { type FailedL1Tx, type L1TxFailedStore, createL1TxFailedStore } from './l1_tx_failed_store/index.js'; +import { type DroppedRequest, SequencerBundleSimulator } from './sequencer-bundle-simulator.js'; import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js'; +/** + * Returns true if the receipt indicates a successful send AND the expected event was emitted + * by the target contract. Both pieces are required: an aggregate3 entry that reverted will + * have receipt.status === 'success' but no event log. + */ +function extractEventSuccess( + receipt: TransactionReceipt | undefined, + opts: { address: string; abi: Abi; eventName: string }, +): boolean { + if (!receipt || receipt.status !== 'success') { + return false; + } + return !!tryExtractEvent(receipt.logs, opts.address.toString() as Hex, opts.abi, opts.eventName); +} + /** Result of a sendRequests call, returned by both sendRequests() and sendRequestsAt(). */ export type SendRequestsResult = { - /** The L1 transaction receipt or error from the bundled multicall. */ - result: { receipt: TransactionReceipt; errorMsg?: string } | FormattedViemError; + /** The L1 transaction receipt from the bundled multicall. */ + result: { receipt: TransactionReceipt }; /** Actions that expired (past their deadline) before the request was sent. */ expiredActions: Action[]; /** Actions that were included in the sent L1 transaction. */ @@ -119,24 +138,16 @@ export type InvalidateCheckpointRequest = { type EnqueueProposeCheckpointOpts = { txTimeoutAt?: Date; - simulationOverridesPlan?: SimulationOverridesPlan; - /** - * Overrides to apply to the preCheck simulation right before L1 submission. - * Intentionally separate from `simulationOverridesPlan`: enqueue-time validation - * may need pipelined-parent / pretend-proof-landed overrides, but preCheck must - * reflect real L1 state to catch state drift between build and submission. - */ - preCheckSimulationOverridesPlan?: SimulationOverridesPlan; }; -interface RequestWithExpiry { +export interface RequestWithExpiry { action: Action; request: L1TxRequest; lastValidL2Slot: SlotNumber; gasConfig?: Pick; blobConfig?: L1BlobInputs; - /** Optional pre-send validation. If it rejects, the request is discarded. */ - preCheck?: () => Promise; + /** Gas consumed by validateBlobs; stashed for the bundle simulate at send time. */ + blobEvaluationGas?: bigint; checkSuccess: ( request: L1TxRequest, result?: { receipt: TransactionReceipt; stats?: TransactionStats; errorMsg?: string }, @@ -146,16 +157,19 @@ interface RequestWithExpiry { export class SequencerPublisher { private interrupted = false; private metrics: SequencerPublisherMetrics; + private bundleSimulator: SequencerBundleSimulator; public epochCache: EpochCache; private failedTxStore?: Promise; - protected governanceLog = createLogger('sequencer:publisher:governance'); - protected slashingLog = createLogger('sequencer:publisher:slashing'); + /** + * ABI used to decode raw revert payloads from dropped bundle entries when the original + * request did not carry an abi (e.g. the propose request). Merges every contract the + * publisher can route to so any of their custom errors decode against it. + */ + private readonly revertDecoderAbi: Abi = mergeAbis([RollupAbi, SlashingProposerAbi, EmpireBaseAbi, ErrorsAbi]); protected lastActions: Partial> = {}; - private isPayloadEmptyCache: Map = new Map(); - protected log: Logger; protected ethereumSlotDuration: bigint; protected aztecSlotDuration: bigint; @@ -165,9 +179,6 @@ export class SequencerPublisher { private blobClient: BlobClientInterface; - /** Address to use for simulations in fisherman mode (actual proposer's address) */ - private proposerAddressForSimulation?: EthAddress; - /** Optional callback to obtain a replacement publisher when the current one fails to send. */ private getNextPublisher?: (excludeAddresses: EthAddress[]) => Promise; @@ -180,12 +191,6 @@ export class SequencerPublisher { /** Interruptible sleep used by sendRequestsAt to wait until a target timestamp. */ private readonly interruptibleSleep = new InterruptibleSleep(); - // A CALL to a cold address is 2700 gas - public static MULTICALL_OVERHEAD_GAS_GUESS = 5000n; - - // Gas report for VotingWithSigTest shows a max gas of 100k, but we've seen it cost 700k+ in testnet - public static VOTE_GAS_GUESS: bigint = 800_000n; - public l1TxUtils: L1TxUtils; public rollupContract: RollupContract; public govProposerContract: GovernanceProposerContract; @@ -244,7 +249,7 @@ export class SequencerPublisher { this.l1FeeAnalyzer = new L1FeeAnalyzer( this.l1TxUtils.client, deps.dateProvider, - createLogger('sequencer:publisher:fee-analyzer'), + this.log.createChild('fee-analyzer'), ); } @@ -252,11 +257,18 @@ export class SequencerPublisher { this.feeAssetPriceOracle = new FeeAssetPriceOracle( this.l1TxUtils.client, this.rollupContract, - createLogger('sequencer:publisher:price-oracle'), + this.log.createChild('price-oracle'), ); // Initialize failed L1 tx store (optional, for test networks) this.failedTxStore = createL1TxFailedStore(config.l1TxFailedStore, this.log); + + this.bundleSimulator = new SequencerBundleSimulator({ + getL1TxUtils: () => this.l1TxUtils, + rollupContract: this.rollupContract, + epochCache: this.epochCache, + log: this.log.createChild('bundle-simulator'), + }); } /** @@ -308,14 +320,6 @@ export class SequencerPublisher { return this.l1FeeAnalyzer; } - /** - * Sets the proposer address to use for simulations in fisherman mode. - * @param proposerAddress - The actual proposer's address to use for balance lookups in simulations - */ - public setProposerAddressForSimulation(proposerAddress: EthAddress | undefined) { - this.proposerAddressForSimulation = proposerAddress; - } - public addRequest(request: RequestWithExpiry) { this.requests.push(request); } @@ -393,23 +397,26 @@ export class SequencerPublisher { /** * Sends all requests that are still valid. + * @param targetSlot - The target L2 slot for this send. When provided (pipelined path via + * sendRequestsAt), it is threaded into bundleSimulate so the block.timestamp override + * matches the slot the propose is built for. When omitted, falls back to + * getCurrentL2Slot() for the non-pipelined callers in Sequencer.doWork. * @returns one of: * - A receipt and stats if the tx succeeded * - a receipt and errorMsg if it failed on L1 * - undefined if no valid requests are found OR the tx failed to send. */ @trackSpan('SequencerPublisher.sendRequests') - public async sendRequests(): Promise { + public async sendRequests(targetSlot?: SlotNumber): Promise { const requestsToProcess = [...this.requests]; this.requests = []; if (this.interrupted || requestsToProcess.length === 0) { return undefined; } - const currentL2Slot = this.getCurrentL2Slot(); + const currentL2Slot = targetSlot ?? this.getCurrentL2Slot(); this.log.debug(`Sending requests on L2 slot ${currentL2Slot}`); const validRequests = requestsToProcess.filter(request => request.lastValidL2Slot >= currentL2Slot); - const validActions = validRequests.map(x => x.action); const expiredActions = requestsToProcess .filter(request => request.lastValidL2Slot < currentL2Slot) .map(x => x.action); @@ -432,70 +439,58 @@ export class SequencerPublisher { return undefined; } - // @note - we can only have one blob config per bundle - // find requests with gas and blob configs - // See https://github.com/AztecProtocol/aztec-packages/issues/11513 + // Collect earliest txTimeoutAt across all requests. const gasConfigs = validRequests.filter(request => request.gasConfig).map(request => request.gasConfig); - const blobConfigs = validRequests.filter(request => request.blobConfig).map(request => request.blobConfig); - - if (blobConfigs.length > 1) { - throw new Error('Multiple blob configs found'); - } - - const blobConfig = blobConfigs[0]; - - // Merge gasConfigs. Yields the sum of gasLimits, and the earliest txTimeoutAt, or undefined if no gasConfig sets them. - const gasLimits = gasConfigs.map(g => g?.gasLimit).filter((g): g is bigint => g !== undefined); - let gasLimit = gasLimits.length > 0 ? sumBigint(gasLimits) : undefined; // sum - // Cap at L1 block gas limit so the node accepts the tx ("gas limit too high" otherwise). - const maxGas = MAX_L1_TX_LIMIT; - if (gasLimit !== undefined && gasLimit > maxGas) { - this.log.debug('Capping bundled tx gas limit to L1 max', { - requested: gasLimit, - capped: maxGas, - }); - gasLimit = maxGas; - } const txTimeoutAts = gasConfigs.map(g => g?.txTimeoutAt).filter((g): g is Date => g !== undefined); - const txTimeoutAt = txTimeoutAts.length > 0 ? new Date(Math.min(...txTimeoutAts.map(g => g.getTime()))) : undefined; // earliest - const txConfig: RequestWithExpiry['gasConfig'] = { gasLimit, txTimeoutAt }; + const txTimeoutAt = txTimeoutAts.length > 0 ? new Date(Math.min(...txTimeoutAts.map(g => g.getTime()))) : undefined; // Sort the requests so that proposals always go first // This ensures the committee gets precomputed correctly validRequests.sort((a, b) => compareActions(a.action, b.action)); try { - // Capture context for failed tx backup before sending - const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); - const multicallData = encodeFunctionData({ - abi: multicall3Abi, - functionName: 'aggregate3', - args: [ - validRequests.map(r => ({ - target: r.request.to!, - callData: r.request.data!, - allowFailure: true, - })), - ], - }); - const blobDataHex = blobConfig?.blobs?.map(b => toHex(b)) as Hex[] | undefined; + // Bundle-level eth_simulateV1: filters out entries that revert and derives the gasLimit. + const bundleResult = await this.bundleSimulator.simulate(validRequests, currentL2Slot); - const txContext = { multicallData, blobData: blobDataHex, l1BlockNumber }; + if (bundleResult.kind === 'aborted') { + this.logDroppedInSim(bundleResult.droppedRequests); + void this.backupDroppedInSim(bundleResult.droppedRequests); + return undefined; + } + + const { requests, droppedRequests, gasLimit } = + bundleResult.kind === 'fallback' + ? { + requests: bundleResult.requests, + droppedRequests: bundleResult.droppedRequests, + gasLimit: MAX_L1_TX_LIMIT, + } + : bundleResult; + + this.logDroppedInSim(droppedRequests); + + // Compute blobConfig from survivors (not original validRequests) so that if the propose + // entry was dropped by bundleSimulate we don't attach a blob-typed config to a non-blob tx. + const [blobConfig] = requests.filter(r => r.blobConfig).map(r => r.blobConfig); + const txConfig: RequestWithExpiry['gasConfig'] = { gasLimit, txTimeoutAt }; this.log.debug('Forwarding transactions', { - validRequests: validRequests.map(request => request.action), + requests: requests.map(request => request.action), txConfig, }); - const result = await this.forwardWithPublisherRotation(validRequests, txConfig, blobConfig); + const result = await this.forwardWithPublisherRotation(requests, txConfig, blobConfig); if (result === undefined) { return undefined; } - const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions( - validRequests, + const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions(requests, result); + const allFailedActions = [...failedActions, ...droppedRequests.map(d => d.request.action)]; + return { result, - txContext, - ); - return { result, expiredActions, sentActions: validActions, successfulActions, failedActions }; + expiredActions, + sentActions: requests.map(x => x.action), + successfulActions, + failedActions: allFailedActions, + }; } catch (err) { const viemError = formatViemError(err); this.log.error(`Failed to publish bundled transactions`, viemError); @@ -512,6 +507,40 @@ export class SequencerPublisher { } } + /** Logs entries dropped by bundle simulation as warnings on the publisher's logger. */ + private logDroppedInSim(dropped: DroppedRequest[]): void { + for (const drop of dropped) { + const revertReasonDecoded = drop.revertReason ?? tryDecodeRevertReason(drop.returnData, this.revertDecoderAbi); + this.log.warn('Bundle entry dropped: action reverted in sim', { + action: drop.request.action, + revertReason: revertReasonDecoded ?? drop.returnData, + revertReasonDecoded, + returnData: drop.returnData, + }); + } + } + + /** Backs up entries dropped by bundle simulation, one record per dropped action. */ + private async backupDroppedInSim(dropped: DroppedRequest[]): Promise { + if (dropped.length === 0) { + return; + } + const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); + for (const { request: req } of dropped) { + this.backupFailedTx({ + id: keccak256(req.request.data!), + failureType: 'simulation', + request: { to: req.request.to! as Hex, data: req.request.data! }, + l1BlockNumber: l1BlockNumber.toString(), + error: { message: 'Bundle entry dropped: action reverted in sim' }, + context: { + actions: [req.action], + sender: this.getSenderAddress().toString(), + }, + }); + } + } + /** * Forwards transactions via Multicall3, rotating to the next available publisher if a send * failure occurs (i.e. the tx never reached the chain). @@ -522,19 +551,30 @@ export class SequencerPublisher { txConfig: RequestWithExpiry['gasConfig'], blobConfig: L1BlobInputs | undefined, ) { + if (!txConfig?.gasLimit) { + throw new Error('gasLimit is required for bundled transactions'); + } + const txConfigWithGasLimit = txConfig as L1TxConfig & { gasLimit: bigint }; + const triedAddresses: EthAddress[] = []; let currentPublisher = this.l1TxUtils; while (true) { + if (txConfig.txTimeoutAt && new Date() > txConfig.txTimeoutAt) { + this.log.warn(`Tx timeout (${txConfig.txTimeoutAt.toISOString()}) elapsed; stopping publisher rotation`, { + triedAddresses: triedAddresses.map(a => a.toString()), + }); + return undefined; + } triedAddresses.push(currentPublisher.getSenderAddress()); + try { const result = await Multicall3.forward( validRequests.map(r => r.request), currentPublisher, - txConfig, + txConfigWithGasLimit, blobConfig, - this.rollupContract.address, - this.log, + { gasLimitRequired: true }, ); this.l1TxUtils = currentPublisher; return result; @@ -542,6 +582,12 @@ export class SequencerPublisher { if (err instanceof TimeoutError) { throw err; } + if (err instanceof MulticallForwarderRevertedError) { + this.log.error('Forwarder transaction reverted on-chain; not rotating publisher', err, { + transactionHash: err.receipt.transactionHash, + }); + return undefined; + } const viemError = formatViemError(err); if (!this.getNextPublisher) { this.log.error('Failed to publish bundled transactions', viemError); @@ -553,7 +599,11 @@ export class SequencerPublisher { ); const nextPublisher = await this.getNextPublisher([...triedAddresses]); if (!nextPublisher) { - this.log.error('All available publishers exhausted, failed to publish bundled transactions'); + this.log.error( + `All available publishers exhausted (tried ${triedAddresses.length}), failed to publish bundled transactions`, + viemError, + { triedAddresses: triedAddresses.map(a => a.toString()) }, + ); return undefined; } currentPublisher = nextPublisher; @@ -562,112 +612,59 @@ export class SequencerPublisher { } /* - * Schedules sending all enqueued requests at (or after) the given timestamp. + * Schedules sending all enqueued requests at (or after) the start of the given L2 slot. + * Sleeps until one L1 slot before the L2 slot boundary so the tx has a chance of being + * picked up by the first L1 block of the L2 slot. + * NB: there is a known correctness risk — being included in the L1 block right before the + * L2 slot starts would revert propose with HeaderLib__InvalidSlotNumber. * Uses InterruptibleSleep so it can be cancelled via interrupt(). - * Returns the promise for the L1 response (caller should NOT await this in the work loop). */ - public async sendRequestsAt(submitAfter: Date): Promise { - const ms = submitAfter.getTime() - this.dateProvider.now(); - if (ms > 0) { - this.log.debug(`Sleeping ${ms}ms before sending requests`, { submitAfter }); - await this.interruptibleSleep.sleep(ms); + public async sendRequestsAt(targetSlot: SlotNumber): Promise { + const l1Constants = this.epochCache.getL1Constants(); + // Start of the target L2 slot, in ms (getTimestampForSlot returns seconds). + const startOfTargetSlotMs = Number(getTimestampForSlot(targetSlot, l1Constants)) * 1000; + // Aim to be in the mempool one L1 slot before the L2 slot starts, so we have a chance of + // being picked up by the first L1 block of the L2 slot. + const submitAfterMs = startOfTargetSlotMs - Number(this.ethereumSlotDuration) * 1000; + const sleepMs = submitAfterMs - this.dateProvider.now(); + if (sleepMs > 0) { + this.log.debug(`Sleeping ${sleepMs}ms before sending requests`, { + targetSlot, + submitAfterMs, + }); + await this.interruptibleSleep.sleep(sleepMs); } if (this.interrupted) { return undefined; } - - // Re-validate enqueued requests after the sleep (state may have changed, e.g. prune or L1 reorg) - const validRequests: RequestWithExpiry[] = []; - for (const request of this.requests) { - if (!request.preCheck) { - validRequests.push(request); - continue; - } - - try { - await request.preCheck(); - validRequests.push(request); - } catch (err) { - this.log.warn(`Pre-send validation failed for ${request.action}, discarding request`, err); - } - } - - this.requests = validRequests; - if (this.requests.length === 0) { - return undefined; - } - - return this.sendRequests(); + return this.sendRequests(targetSlot); } private callbackBundledTransactions( requests: RequestWithExpiry[], - result: { receipt: TransactionReceipt; errorMsg?: string } | FormattedViemError | undefined, - txContext: { multicallData: Hex; blobData?: Hex[]; l1BlockNumber: bigint }, + result: { receipt: TransactionReceipt; multicallData: Hex }, ) { const actionsListStr = requests.map(r => r.action).join(', '); - if (result instanceof FormattedViemError) { - this.log.error(`Failed to publish bundled transactions (${actionsListStr})`, result); - this.backupFailedTx({ - id: keccak256(txContext.multicallData), - failureType: 'send-error', - request: { to: MULTI_CALL_3_ADDRESS, data: txContext.multicallData }, - blobData: txContext.blobData, - l1BlockNumber: txContext.l1BlockNumber.toString(), - error: { message: result.message, name: result.name }, - context: { - actions: requests.map(r => r.action), - requests: requests.map(r => ({ action: r.action, to: r.request.to! as Hex, data: r.request.data! })), - sender: this.getSenderAddress().toString(), - }, - }); - return { failedActions: requests.map(r => r.action) }; - } else { - this.log.verbose(`Published bundled transactions (${actionsListStr})`, { - result, - requests: requests.map(r => ({ - ...r, - // Avoid logging large blob data - blobConfig: r.blobConfig - ? { ...r.blobConfig, blobs: r.blobConfig.blobs.map(b => ({ size: trimmedBytesLength(b) })) } - : undefined, - })), - }); - const successfulActions: Action[] = []; - const failedActions: Action[] = []; - for (const request of requests) { - if (request.checkSuccess(request.request, result)) { - successfulActions.push(request.action); - } else { - failedActions.push(request.action); - } - } - // Single backup for the whole reverted tx - if (failedActions.length > 0 && result?.receipt?.status === 'reverted') { - this.backupFailedTx({ - id: result.receipt.transactionHash, - failureType: 'revert', - request: { to: MULTI_CALL_3_ADDRESS, data: txContext.multicallData }, - blobData: txContext.blobData, - l1BlockNumber: result.receipt.blockNumber.toString(), - receipt: { - transactionHash: result.receipt.transactionHash, - blockNumber: result.receipt.blockNumber.toString(), - gasUsed: (result.receipt.gasUsed ?? 0n).toString(), - status: 'reverted', - }, - error: { message: result.errorMsg ?? 'Transaction reverted' }, - context: { - actions: failedActions, - requests: requests - .filter(r => failedActions.includes(r.action)) - .map(r => ({ action: r.action, to: r.request.to! as Hex, data: r.request.data! })), - sender: this.getSenderAddress().toString(), - }, - }); + this.log.verbose(`Published bundled transactions (${actionsListStr})`, { + result, + requests: requests.map(r => ({ + ...r, + // Avoid logging large blob data + blobConfig: r.blobConfig + ? { ...r.blobConfig, blobs: r.blobConfig.blobs.map(b => ({ size: trimmedBytesLength(b) })) } + : undefined, + })), + }); + const successfulActions: Action[] = []; + const failedActions: Action[] = []; + for (const request of requests) { + if (request.checkSuccess(request.request, result)) { + successfulActions.push(request.action); + } else { + failedActions.push(request.action); } - return { successfulActions, failedActions }; } + return { successfulActions, failedActions }; } /** @@ -677,7 +674,11 @@ export class SequencerPublisher { */ public async canProposeAt(tipArchive: Fr, msgSender: EthAddress, simulationOverridesPlan?: SimulationOverridesPlan) { // TODO: #14291 - should loop through multiple keys to check if any of them can propose - const ignoredErrors = ['SlotAlreadyInChain', 'InvalidProposer', 'InvalidArchive']; + // These errors are expected when we cannot actually propose right now — usually because our + // local view of the chain is ahead of L1 (proposed parent hasn't landed yet, or someone + // else has just landed the slot, or the archive override doesn't match). We log a warn and + // skip the proposal; we do NOT treat these as bugs. + const expectedErrors = ['SlotAlreadyInChain', 'InvalidProposer', 'InvalidArchive']; const pipelined = this.epochCache.isProposerPipeliningEnabled(); const slotOffset = pipelined ? this.aztecSlotDuration : 0n; @@ -691,8 +692,8 @@ export class SequencerPublisher { await buildSimulationOverridesStateOverride(this.rollupContract, simulationOverridesPlan), ) .catch(err => { - if (err instanceof FormattedViemError && ignoredErrors.find(e => err.message.includes(e))) { - this.log.warn(`Failed canProposeAtTime check with ${ignoredErrors.find(e => err.message.includes(e))}`, { + if (err instanceof FormattedViemError && expectedErrors.find(e => err.message.includes(e))) { + this.log.warn(`Failed canProposeAtTime check with ${expectedErrors.find(e => err.message.includes(e))}`, { error: err.message, }); } else { @@ -725,7 +726,8 @@ export class SequencerPublisher { flags, ] as const; - const ts = this.getSimulationTimestamp(header.slotNumber); + const l1Constants = this.epochCache.getL1Constants(); + const ts = getTimestampForSlot(header.slotNumber, l1Constants); const stateOverrides = await buildSimulationOverridesStateOverride(this.rollupContract, simulationOverridesPlan); let balance = 0n; if (this.config.fishermanMode) { @@ -879,35 +881,6 @@ export class SequencerPublisher { } } - /** Simulates `propose` to make sure that the checkpoint is valid for submission */ - @trackSpan('SequencerPublisher.validateCheckpointForSubmission') - public async validateCheckpointForSubmission( - checkpoint: Checkpoint, - attestationsAndSigners: CommitteeAttestationsAndSigners, - attestationsAndSignersSignature: Signature, - simulationOverridesPlan?: SimulationOverridesPlan, - ): Promise { - const blobFields = checkpoint.toBlobFields(); - const blobs = await getBlobsPerL1Block(blobFields); - const blobInput = getPrefixedEthBlobCommitments(blobs); - - const args = [ - { - header: checkpoint.header.toViem(), - archive: toHex(checkpoint.archive.root.toBuffer()), - oracleInput: { - feeAssetPriceModifier: checkpoint.feeAssetPriceModifier, - }, - }, - attestationsAndSigners.getPackedAttestations(), - attestationsAndSigners.getSigners().map(signer => signer.toString()), - attestationsAndSignersSignature.toViemSignature(), - blobInput, - ] as const; - - await this.simulateProposeTx(args, simulationOverridesPlan); - } - private async enqueueCastSignalHelper( slotNumber: SlotNumber, signalType: GovernanceSignalAction, @@ -938,7 +911,7 @@ export class SequencerPublisher { return false; } - if (await this.isPayloadEmpty(payload)) { + if (await base.isPayloadEmpty(payload)) { this.log.warn(`Skipping vote cast for payload with empty code`); return false; } @@ -981,45 +954,19 @@ export class SequencerPublisher { lastValidL2Slot: slotNumber, }); - const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); - const timestamp = this.getSimulationTimestamp(slotNumber); - - try { - await this.l1TxUtils.simulate(request, { time: timestamp }, [], mergeAbis([request.abi ?? [], ErrorsAbi])); - this.log.debug(`Simulation for ${action} at slot ${slotNumber} succeeded`, { request }); - } catch (err) { - const viemError = formatViemError(err); - this.log.error(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, viemError, { - simulationTimestamp: timestamp, - l1BlockNumber, - }); - this.backupFailedTx({ - id: keccak256(request.data!), - failureType: 'simulation', - request: { to: request.to!, data: request.data!, value: request.value?.toString() }, - l1BlockNumber: l1BlockNumber.toString(), - error: { message: viemError.message, name: viemError.name }, - context: { - actions: [action], - slot: slotNumber, - sender: this.getSenderAddress().toString(), - }, - }); - // Yes, we enqueue the request anyway, in case there was a bug with the simulation itself - } - // TODO(palla/slash): All votes (governance and slashing) should txTimeoutAt at the end of the slot. this.addRequest({ - gasConfig: { gasLimit: SequencerPublisher.VOTE_GAS_GUESS }, action, request, lastValidL2Slot: slotNumber, checkSuccess: (_request, result) => { const success = result && - result.receipt && - result.receipt.status === 'success' && - tryExtractEvent(result.receipt.logs, base.address.toString(), EmpireBaseAbi, 'SignalCast'); + extractEventSuccess(result.receipt, { + address: base.address.toString(), + abi: EmpireBaseAbi, + eventName: 'SignalCast', + }); const logData = { ...result, slotNumber, round, payload: payload.toString() }; if (!success) { @@ -1041,17 +988,6 @@ export class SequencerPublisher { return true; } - private async isPayloadEmpty(payload: EthAddress): Promise { - const key = payload.toString(); - const cached = this.isPayloadEmptyCache.get(key); - if (cached) { - return cached; - } - const isEmpty = !(await this.l1TxUtils.getCode(payload)); - this.isPayloadEmptyCache.set(key, isEmpty); - return isEmpty; - } - /** * Enqueues a governance castSignal transaction to cast a signal for a given slot number. * @param slotNumber - The slot number to cast a signal for. @@ -1100,10 +1036,14 @@ export class SequencerPublisher { } const votes = bufferToHex(encodeSlashConsensusVotes(action.votes)); const request = await this.slashingProposerContract.buildVoteRequestFromSigner(votes, slotNumber, signer); - await this.simulateAndEnqueueRequest( + this.enqueueRequest( 'vote-offenses', request, - (receipt: TransactionReceipt) => !!this.slashingProposerContract!.tryExtractVoteCastEvent(receipt.logs), + { + address: this.slashingProposerContract.address.toString(), + abi: SlashingProposerAbi, + eventName: 'VoteCast', + }, slotNumber, ); break; @@ -1123,11 +1063,14 @@ export class SequencerPublisher { action.round, action.committees, ); - await this.simulateAndEnqueueRequest( + this.enqueueRequest( 'execute-slash', executeRequest, - (receipt: TransactionReceipt) => - !!this.slashingProposerContract!.tryExtractRoundExecutedEvent(receipt.logs), + { + address: this.slashingProposerContract.address.toString(), + abi: SlashingProposerAbi, + eventName: 'RoundExecuted', + }, slotNumber, ); break; @@ -1143,7 +1086,7 @@ export class SequencerPublisher { return true; } - /** Simulates and enqueues a proposal for a checkpoint on L1 */ + /** Enqueues a proposal for a checkpoint on L1 */ public async enqueueProposeCheckpoint( checkpoint: Checkpoint, attestationsAndSigners: CommitteeAttestationsAndSigners, @@ -1164,61 +1107,11 @@ export class SequencerPublisher { feeAssetPriceModifier: checkpoint.feeAssetPriceModifier, }; - const simulationOverridesPlan = SimulationOverridesBuilder.from(opts.simulationOverridesPlan) - .withoutBlobCheck() - .build(); - - const preCheckSimulationOverridesPlan = SimulationOverridesBuilder.from(opts.preCheckSimulationOverridesPlan) - .withoutBlobCheck() - .build(); - - try { - // @note This will make sure that we are passing the checks for our header ASSUMING that the data is also made available - // This means that we can avoid the simulation issues in later checks. - // By simulation issue, I mean the fact that the block.timestamp is equal to the last block, not the next, which - // make time consistency checks break. - // TODO(palla): Check whether we're validating twice, once here and once within addProposeTx, since we call simulateProposeTx in both places. - await this.validateCheckpointForSubmission( - checkpoint, - attestationsAndSigners, - attestationsAndSignersSignature, - simulationOverridesPlan, - ); - } catch (err: any) { - this.log.error(`Checkpoint validation failed. ${err instanceof Error ? err.message : 'No error message'}`, err, { - ...checkpoint.getStats(), - slotNumber: checkpoint.header.slotNumber, - simulationOverridesPlan, - }); - throw err; - } - - // Build a pre-check callback that re-validates the checkpoint before L1 submission. - // During pipelining this catches stale proposals due to prunes or L1 reorgs that occur during the pipeline sleep. - let preCheck = undefined; - if (this.epochCache.isProposerPipeliningEnabled()) { - preCheck = async () => { - this.log.debug(`Re-validating checkpoint ${checkpoint.number} before L1 submission`); - await this.validateCheckpointForSubmission( - checkpoint, - attestationsAndSigners, - attestationsAndSignersSignature, - preCheckSimulationOverridesPlan, - ); - }; - } - this.log.verbose(`Enqueuing checkpoint propose transaction`, { ...checkpoint.toCheckpointInfo(), txTimeoutAt: opts.txTimeoutAt, - simulationOverridesPlan, }); - await this.addProposeTx( - checkpoint, - proposeTxArgs, - { txTimeoutAt: opts.txTimeoutAt, simulationOverridesPlan }, - preCheck, - ); + await this.addProposeTx(checkpoint, proposeTxArgs, { txTimeoutAt: opts.txTimeoutAt }); } public enqueueInvalidateCheckpoint( @@ -1229,23 +1122,22 @@ export class SequencerPublisher { return; } - // We issued the simulation against the rollup contract, so we need to account for the overhead of the multicall3 - const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil((Number(request.gasUsed) * 64) / 63))); - const { gasUsed, checkpointNumber } = request; - const logData = { gasUsed, checkpointNumber, gasLimit, opts }; + const logData = { gasUsed, checkpointNumber, opts }; this.log.verbose(`Enqueuing invalidate checkpoint request`, logData); this.addRequest({ action: `invalidate-by-${request.reason}`, request: request.request, - gasConfig: { gasLimit, txTimeoutAt: opts.txTimeoutAt }, + gasConfig: opts.txTimeoutAt ? { txTimeoutAt: opts.txTimeoutAt } : undefined, lastValidL2Slot: SlotNumber(this.getCurrentL2Slot() + 2), checkSuccess: (_req, result) => { const success = result && - result.receipt && - result.receipt.status === 'success' && - tryExtractEvent(result.receipt.logs, this.rollupContract.address, RollupAbi, 'CheckpointInvalidated'); + extractEventSuccess(result.receipt, { + address: this.rollupContract.address, + abi: RollupAbi, + eventName: 'CheckpointInvalidated', + }); if (!success) { this.log.warn(`Invalidate checkpoint ${request.checkpointNumber} failed`, { ...result, ...logData }); } else { @@ -1256,73 +1148,36 @@ export class SequencerPublisher { }); } - private async simulateAndEnqueueRequest( + /** + * Dedup-checked enqueue helper for actions that are simulated at bundle-send time rather + * than at enqueue time. Validates the (action, slot) dedup key, sets `lastActions`, and + * enqueues without a gasLimit so the bundle simulate sets the only gasLimit that matters. + */ + private enqueueRequest( action: Action, request: L1TxRequest, - checkSuccess: (receipt: TransactionReceipt) => boolean | undefined, + eventOpts: { address: string; abi: Abi; eventName: string }, slotNumber: SlotNumber, - ) { - const timestamp = this.getSimulationTimestamp(slotNumber); - const logData = { slotNumber, timestamp, gasLimit: undefined as bigint | undefined }; + ): boolean { if (this.lastActions[action] && this.lastActions[action] === slotNumber) { this.log.debug(`Skipping duplicate action ${action} for slot ${slotNumber}`); return false; } - const cachedLastActionSlot = this.lastActions[action]; this.lastActions[action] = slotNumber; - this.log.debug(`Simulating ${action} for slot ${slotNumber}`, logData); - - const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); - - let gasUsed: bigint; - const simulateAbi = mergeAbis([request.abi ?? [], ErrorsAbi]); - - try { - ({ gasUsed } = await this.l1TxUtils.simulate(request, { time: timestamp }, [], simulateAbi)); - this.log.verbose(`Simulation for ${action} succeeded`, { ...logData, request, gasUsed }); - } catch (err) { - const viemError = formatViemError(err, simulateAbi); - this.log.error(`Simulation for ${action} at ${slotNumber} failed`, viemError, logData); - - this.backupFailedTx({ - id: keccak256(request.data!), - failureType: 'simulation', - request: { to: request.to!, data: request.data!, value: request.value?.toString() }, - l1BlockNumber: l1BlockNumber.toString(), - error: { message: viemError.message, name: viemError.name }, - context: { - actions: [action], - slot: slotNumber, - sender: this.getSenderAddress().toString(), - }, - }); - - return false; - } - - // We issued the simulation against the rollup contract, so we need to account for the overhead of the multicall3 - const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil((Number(gasUsed) * 64) / 63))); - logData.gasLimit = gasLimit; - - // Store the ABI used for simulation on the request so Multicall3.forward can decode errors - // when the tx is sent and a revert is diagnosed via simulation. - const requestWithAbi = { ...request, abi: simulateAbi }; - - this.log.debug(`Enqueuing ${action}`, logData); + this.log.debug(`Enqueuing ${action}`, { slotNumber }); this.addRequest({ action, - request: requestWithAbi, - gasConfig: { gasLimit }, + request, lastValidL2Slot: slotNumber, - checkSuccess: (_req, result) => { - const success = result && result.receipt && result.receipt.status === 'success' && checkSuccess(result.receipt); + checkSuccess: (_request, result) => { + const success = result && extractEventSuccess(result.receipt, eventOpts); if (!success) { - this.log.warn(`Action ${action} at ${slotNumber} failed`, { ...result, ...logData }); + this.log.warn(`Action ${action} at ${slotNumber} failed`, { ...result, slotNumber }); this.lastActions[action] = cachedLastActionSlot; } else { - this.log.info(`Action ${action} at ${slotNumber} succeeded`, { ...result, ...logData }); + this.log.info(`Action ${action} at ${slotNumber} succeeded`, { ...result, slotNumber }); } return !!success; }, @@ -1348,7 +1203,7 @@ export class SequencerPublisher { this.l1TxUtils.restart(); } - private async prepareProposeTx(encodedData: L1ProcessArgs, simulationOverridesPlan?: SimulationOverridesPlan) { + private async prepareProposeTx(encodedData: L1ProcessArgs) { const kzg = Blob.getViemKzgInstance(); const blobInput = getPrefixedEthBlobCommitments(encodedData.blobs); this.log.debug('Validating blob input', { blobInput }); @@ -1361,7 +1216,11 @@ export class SequencerPublisher { blobEvaluationGas = BigInt(encodedData.blobs.length) * 21_000n; this.log.debug(`Using fixed blob evaluation gas estimate in fisherman mode: ${blobEvaluationGas}`); } else { - // Normal mode - use estimateGas with blob inputs + // We call validateBlobs via estimateGas with real blob+kzg sidecars as a consistency check + // that our locally-built blob commitments match the blob data. The bundle simulate at send + // time uses eth_simulateV1, which cannot carry blob inputs, so the rollup's on-chain blob + // check is forced off there — making this the only pre-flight detector of a commitment/data + // mismatch. The returned gas estimate is stashed on the request for the bundle path to read. blobEvaluationGas = await this.l1TxUtils .estimateGas( this.getSenderAddress().toString(), @@ -1419,119 +1278,21 @@ export class SequencerPublisher { blobInput, ] as const; - const { rollupData, simulationResult } = await this.simulateProposeTx(args, simulationOverridesPlan); - - return { args, blobEvaluationGas, rollupData, simulationResult }; - } - - /** - * Simulates the propose tx with eth_simulateV1 - * @param args - The propose tx args - * @returns The simulation result - */ - private async simulateProposeTx( - args: readonly [ - { - readonly header: ViemHeader; - readonly archive: `0x${string}`; - readonly oracleInput: { - readonly feeAssetPriceModifier: bigint; - }; - }, - ViemCommitteeAttestations, - `0x${string}`[], // Signers - ViemSignature, - `0x${string}`, - ], - simulationOverridesPlan?: SimulationOverridesPlan, - ) { - const rollupData = encodeFunctionData({ - abi: RollupAbi, - functionName: 'propose', - args, - }); - - const stateOverrides = await buildSimulationOverridesStateOverride(this.rollupContract, simulationOverridesPlan); - // In fisherman mode, simulate as the proposer but with sufficient balance - if (this.proposerAddressForSimulation) { - stateOverrides.push({ - address: this.proposerAddressForSimulation.toString(), - balance: 10n * WEI_CONST * WEI_CONST, // 10 ETH - }); - } + const rollupData = encodeFunctionData({ abi: RollupAbi, functionName: 'propose', args }); - const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); - const simTs = this.getSimulationTimestamp(SlotNumber.fromBigInt(args[0].header.slotNumber)); - - const simulationResult = await this.l1TxUtils - .simulate( - { - to: this.rollupContract.address, - data: rollupData, - gas: MAX_L1_TX_LIMIT, - ...(this.proposerAddressForSimulation && { from: this.proposerAddressForSimulation.toString() }), - }, - { - time: simTs, - // @note reth should have a 30m gas limit per block but throws errors that this tx is beyond limit so we increase here - gasLimit: MAX_L1_TX_LIMIT * 2n, - }, - stateOverrides, - RollupAbi, - { - // @note fallback gas estimate to use if the node doesn't support simulation API - fallbackGasEstimate: MAX_L1_TX_LIMIT, - }, - ) - .catch(err => { - // In fisherman mode, we expect ValidatorSelection__MissingProposerSignature since fisherman doesn't have proposer signature - const viemError = formatViemError(err); - if (this.config.fishermanMode && viemError.message?.includes('ValidatorSelection__MissingProposerSignature')) { - this.log.debug(`Ignoring expected ValidatorSelection__MissingProposerSignature error in fisherman mode`); - // Return a minimal simulation result with the fallback gas estimate - return { - gasUsed: MAX_L1_TX_LIMIT, - logs: [], - }; - } - this.log.error(`Failed to simulate propose tx`, viemError, { simulationTimestamp: simTs }); - this.backupFailedTx({ - id: keccak256(rollupData), - failureType: 'simulation', - request: { to: this.rollupContract.address, data: rollupData }, - l1BlockNumber: l1BlockNumber.toString(), - error: { message: viemError.message, name: viemError.name }, - context: { - actions: ['propose'], - slot: Number(args[0].header.slotNumber), - sender: this.getSenderAddress().toString(), - }, - }); - throw err; - }); - - return { rollupData, simulationResult }; + return { args, blobEvaluationGas, rollupData }; } private async addProposeTx( checkpoint: Checkpoint, encodedData: L1ProcessArgs, opts: EnqueueProposeCheckpointOpts = {}, - preCheck?: () => Promise, ): Promise { const slot = checkpoint.header.slotNumber; const timer = new Timer(); const kzg = Blob.getViemKzgInstance(); - const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx( - encodedData, - opts.simulationOverridesPlan, - ); + const { rollupData, blobEvaluationGas } = await this.prepareProposeTx(encodedData); const startBlock = await this.l1TxUtils.getBlockNumber(); - const gasLimit = this.l1TxUtils.bumpGasLimit( - BigInt(Math.ceil((Number(simulationResult.gasUsed) * 64) / 63)) + - blobEvaluationGas + - SequencerPublisher.MULTICALL_OVERHEAD_GAS_GUESS, // We issue the simulation against the rollup contract, so we need to account for the overhead of the multicall3 - ); // Send the blobs to the blob client preemptively. This helps in tests where the sequencer mistakingly thinks that the propose // tx fails but it does get mined. We make sure that the blobs are sent to the blob client regardless of the tx outcome. @@ -1548,8 +1309,8 @@ export class SequencerPublisher { data: rollupData, }, lastValidL2Slot: checkpoint.header.slotNumber, - gasConfig: { txTimeoutAt: opts.txTimeoutAt, gasLimit }, - preCheck, + gasConfig: { txTimeoutAt: opts.txTimeoutAt, gasLimit: undefined }, + blobEvaluationGas, blobConfig: { blobs: encodedData.blobs.map(b => b.data), kzg, @@ -1559,10 +1320,11 @@ export class SequencerPublisher { return false; } const { receipt, stats, errorMsg } = result; - const success = - receipt && - receipt.status === 'success' && - tryExtractEvent(receipt.logs, this.rollupContract.address, RollupAbi, 'CheckpointProposed'); + const success = extractEventSuccess(receipt, { + address: this.rollupContract.address, + abi: RollupAbi, + eventName: 'CheckpointProposed', + }); if (success) { const endBlock = receipt.blockNumber; @@ -1603,13 +1365,6 @@ export class SequencerPublisher { }); } - /** Returns the timestamp of the last L1 slot within a given L2 slot. Used as the simulation timestamp - * for eth_simulateV1 calls, since it's guaranteed to be greater than any L1 block produced during the slot. */ - private getSimulationTimestamp(slot: SlotNumber): bigint { - const l1Constants = this.epochCache.getL1Constants(); - return getLastL1SlotTimestampForL2Slot(slot, l1Constants); - } - /** Returns the timestamp of the next L1 slot boundary after now. */ private getNextL1SlotTimestamp(): bigint { const l1Constants = this.epochCache.getL1Constants(); diff --git a/yarn-project/sequencer-client/src/sequencer/README.md b/yarn-project/sequencer-client/src/sequencer/README.md index e2d94a1878c9..fc3692c33ce1 100644 --- a/yarn-project/sequencer-client/src/sequencer/README.md +++ b/yarn-project/sequencer-client/src/sequencer/README.md @@ -2,11 +2,11 @@ This document covers how the sequencer schedules its work within a slot. See the [package README](../../README.md) for the high-level architecture; this one focuses on the timing math and the state-machine deadlines. -The model described here is for **proposer pipelining**, the standard mode in production. Non-pipelined scheduling existed historically. +The model described here is for **proposer pipelining**, the standard mode in production. Non-pipelined scheduling existed historically and is in the process of being removed. ## Overview -Block production runs on a cadence of fixed-length **slots** (e.g. 72 s). Each slot has a single elected proposer who is allowed to build during that slot. The proposer can build several blocks within the slot, but all those blocks are part of the same **checkpoint** and commit to the same L2 slot: +Block production runs on three nested clocks: - A **slot** is a fixed window (e.g. 72 s) during which one elected proposer is allowed to build. - A slot contains several equal-length **sub-slots** (e.g. 8 s). Each sub-slot owns the budget for one L2 block and has a deadline fixed relative to the slot start. @@ -192,7 +192,7 @@ Block 1 has 7 s of build time instead of 8 s. Still well above `minExecutionTime ### Very slow initialization (8 s) -Sub-slot 1's deadline (9 s) is less than `minExecutionTime` (2 s) away, so it is skipped entirely. The first attempted block runs in sub-slot 2 with the usual budget. The checkpoint will have one fewer block. +Sub-slot 1's deadline (9 s) is closer than `minExecutionTime` (2 s), so it is skipped entirely. The first attempted block runs in sub-slot 2 with the usual budget. The checkpoint will have one fewer block. ### Block takes longer than its budget @@ -208,7 +208,7 @@ The current sub-slot is dropped without committing anything. The loop retries on ### Build slot ends before attestations arrive -`waitForAttestations` enforces `checkpointAttestationDeadline` (`2 * aztecSlotDuration - l1PublishingTime`) and returns `undefined` if the quorum is not in by then. The proposal stays on the proposed chain but no `propose` call is enqueued for L1; governance and slashing votes still go out via `sendRequestsAt`. The publishing-state deadline allows spillover into the target slot precisely to absorb a small overrun while the quorum is still arriving. +`assertTimeLeft` will reject `PUBLISHING_CHECKPOINT` if the attestation deadline has passed; the slot is abandoned, and `checkpoint-publish-failed` is emitted. The `PUBLISHING_CHECKPOINT` deadline allows spillover into the target slot (`2 * aztecSlotDuration - l1PublishingTime`) precisely to absorb a small overrun. ### Pipelined parent fails on L1 @@ -228,6 +228,6 @@ aztecSlotDuration ≥ checkpointInitializationTime + blockDuration // last-block re-execution window ``` -If `blockDuration` is set below `minExecutionTime`, the timing model normalizes `minExecutionTime` down to `blockDuration` rather than rejecting the config (see `normalizeCheckpointTimingConfig` in `stdlib/src/timetable/index.ts`). `p2pPropagationTime` should be measured against the deployment's actual p2p latency: it directly determines how much of each slot is spent on the cooldown. +Block duration should be ≥ `minExecutionTime` (otherwise no sub-slot ever has enough headroom). `p2pPropagationTime` should be measured against the deployment's actual p2p latency: it directly determines how much of each slot is spent on the cooldown. `l1PublishingTime` should fit inside the Ethereum slot the target slot maps to. The default of 12 s lines up with one Ethereum slot; congested deployments may need to increase it (which only affects the `PUBLISHING_CHECKPOINT` deadline, not the number of blocks built). diff --git a/yarn-project/sequencer-client/src/sequencer/automine/README.md b/yarn-project/sequencer-client/src/sequencer/automine/README.md new file mode 100644 index 000000000000..baabfd7aaf53 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/automine/README.md @@ -0,0 +1,46 @@ +# AutomineSequencer + +A minimal, deterministic, queue-driven sequencer for e2e tests that do not exercise block-building or consensus mechanics (e.g. `e2e_token`, `e2e_amm`, `e2e_authwit`). + +## When to use it + +Use `AutomineSequencer` (via `AUTOMINE_E2E_OPTS`) for single-sequencer tests that care about contract logic, not about proposer selection, attestations, pipelining, or multi-validator coordination. It bypasses all of that machinery. + +Use the production `Sequencer` (via `PIPELINING_SETUP_OPTS` or the default) for tests that explicitly exercise consensus, validator rotation, P2P gossip, slashing, or multi-node behavior. + +**Requirement**: the deployed rollup must have `aztecTargetCommitteeSize == 0`. This causes `Rollup.verifyProposer` / `verifyAttestations` on L1 to short-circuit and accept an empty `CommitteeAttestationsAndSigners`, which is what `AutomineSequencer` always sends. + +## What it omits + +Compared to the production `Sequencer`: + +- No proposer-turn check (single sequencer, always proposes). +- No sync check, no pipelining, no timetable enforcement. +- No validator orchestration, attestation collection, or P2P proposal gossip. +- No slashing, no governance votes, no `SequencerEvents`. + +Consumers (archiver, world-state, `EpochTestSettler`) observe L1 and the archiver tip directly rather than listening for sequencer events. + +## Serial-queue invariant + +Every operation — mempool-driven block builds, explicit empty-block builds, time warps, and reorgs — is serialized through a single `SerialQueue`. They never interleave. + +Public entry points: + +| Method | Description | +| --- | --- | +| `buildIfPending()` | Enqueues a mempool-driven build. Coalesces bursts into one job. | +| `buildEmptyBlock()` | Enqueues a forced empty-block build. | +| `warpTo(ts)` / `warpBy(delta)` | Advances L1 time to a slot boundary. | +| `revertToCheckpoint(n)` | Rolls L1 back to the block that published checkpoint `n`, then resets archiver, world-state, and P2P pool. | +| `syncPoint()` | Awaits the queue reaching idle. | + +## Entry points + +**Factory** — `createAutomineSequencer` in `automine_factory.ts` wires up all dependencies (publisher manager, keystore, cheat codes, etc.), starts the `PublisherManager`, and returns an unstarted `AutomineSequencer`. The caller (`AztecNodeService.createAndSync` in `aztec-node/src/aztec-node/server.ts`) invokes `AutomineSequencer.start()` separately. It is called by the full node when `aztecTargetCommitteeSize == 0`. + +**Test fixture** — `AUTOMINE_E2E_OPTS` in `end-to-end/src/fixtures/fixtures.ts` is the test-side entry point. Pass it to `setup()` to get a node + `AutomineSequencer` instead of the production sequencer stack. + +## Epoch proving caveat + +Epoch proving remains manual under `AUTOMINE_E2E_OPTS`. The e2e `setup()` fixture does NOT wire an `EpochTestSettler` — that observer is only attached in `local-network.ts`. Tests that cross epoch boundaries must therefore advance the proven anchor explicitly via `cheatCodes.rollup.markAsProven(...)`. See `e2e_lending_contract.test.ts` (which calls `progressSlots` in `simulators/lending_simulator.ts`) and `e2e_pruned_blocks.test.ts` for real examples. diff --git a/yarn-project/sequencer-client/src/sequencer/automine/automine_factory.ts b/yarn-project/sequencer-client/src/sequencer/automine/automine_factory.ts new file mode 100644 index 000000000000..a67a8ff85102 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/automine/automine_factory.ts @@ -0,0 +1,145 @@ +import type { Archiver } from '@aztec/archiver'; +import type { BlobClientInterface } from '@aztec/blob-client/client'; +import type { EpochCache } from '@aztec/epoch-cache'; +import { GovernanceProposerContract, type RollupContract } from '@aztec/ethereum/contracts'; +import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils'; +import { PublisherManager } from '@aztec/ethereum/publisher-manager'; +import { EthCheatCodes } from '@aztec/ethereum/test'; +import type { ViemPublicClient } from '@aztec/ethereum/types'; +import type { Logger } from '@aztec/foundation/log'; +import type { DateProvider } from '@aztec/foundation/timer'; +import type { KeystoreManager } from '@aztec/node-keystore'; +import type { P2PClient as ConcreteP2PClient, P2P } from '@aztec/p2p'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import type { ChainConfig } from '@aztec/stdlib/config'; +import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; +import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { TelemetryClient } from '@aztec/telemetry-client'; +import { type FullNodeCheckpointsBuilder, NodeKeystoreAdapter, type ValidatorClient } from '@aztec/validator-client'; + +import { type SequencerClientConfig, getPublisherConfigFromSequencerConfig } from '../../config.js'; +import type { GlobalVariableBuilder } from '../../global_variable_builder/global_builder.js'; +import { SequencerPublisherFactory } from '../../publisher/sequencer-publisher-factory.js'; +import { AutomineSequencer } from './automine_sequencer.js'; + +/** Arguments for {@link createAutomineSequencer}. */ +export type CreateAutomineSequencerArgs = { + config: SequencerClientConfig & Pick; + l1TxUtils: L1TxUtils[]; + funderL1TxUtils: L1TxUtils | undefined; + publicClient: ViemPublicClient; + rollupContract: RollupContract; + epochCache: EpochCache; + blobClient: BlobClientInterface | undefined; + telemetry: TelemetryClient; + dateProvider: DateProvider; + keyStoreManager: KeystoreManager; + validatorClient: ValidatorClient; + checkpointsBuilder: FullNodeCheckpointsBuilder; + globalVariableBuilder: GlobalVariableBuilder; + worldStateSynchronizer: WorldStateSynchronizer; + archiver: L2BlockSource & + L1ToL2MessageSource & + Pick; + p2pClient: P2P & Pick; + l1Constants: { l1GenesisTime: bigint; slotDuration: number; ethereumSlotDuration: number; rollupManaLimit: number }; + log: Logger; +}; + +/** + * Builds an {@link AutomineSequencer} for use in single-sequencer e2e tests. + * + * Constructs the PublisherManager, GovernanceProposerContract, SequencerPublisherFactory, + * looks up the attestor/coinbase/feeRecipient from the keystore, wires EthCheatCodes, + * and starts the publisher manager before returning. + */ +export async function createAutomineSequencer({ + config, + l1TxUtils, + funderL1TxUtils, + publicClient, + rollupContract, + epochCache, + blobClient, + telemetry, + dateProvider, + keyStoreManager, + validatorClient, + checkpointsBuilder, + globalVariableBuilder, + worldStateSynchronizer, + archiver, + p2pClient, + l1Constants, + log, +}: CreateAutomineSequencerArgs): Promise { + const publisherManager = new PublisherManager(l1TxUtils, getPublisherConfigFromSequencerConfig(config), { + bindings: log.getBindings(), + funder: funderL1TxUtils, + }); + const governanceProposerContract = new GovernanceProposerContract( + publicClient, + config.governanceProposerAddress.toString(), + ); + const publisherFactory = new SequencerPublisherFactory(config, { + telemetry, + blobClient: blobClient!, + epochCache, + governanceProposerContract, + rollupContract, + dateProvider, + publisherManager, + nodeKeyStore: NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager), + logger: log, + }); + const attestorAddresses = NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager).getAttesterAddresses(); + const attestor = attestorAddresses[0]; + if (!attestor) { + throw new Error('AutomineSequencer requires at least one attestor address in the keystore'); + } + const coinbase = validatorClient.getCoinbaseForAttestor(attestor); + const feeRecipient = validatorClient.getFeeRecipientForAttestor(attestor); + const ethCheatCodes = new EthCheatCodes(config.l1RpcUrls, dateProvider, log.createChild('eth-cheat-codes')); + + // Include the funder's L1TxUtils in the reorg reset list so funding-tx nonces don't + // go stale after L1 rollbacks. Dedupe by sender address in case the funder reuses a + // publisher's signer. + const reorgResetL1TxUtils = (() => { + if (!funderL1TxUtils) { + return l1TxUtils; + } + const funderAddress = funderL1TxUtils.getSenderAddress().toString(); + const alreadyIncluded = l1TxUtils.some(utils => utils.getSenderAddress().toString() === funderAddress); + return alreadyIncluded ? l1TxUtils : [...l1TxUtils, funderL1TxUtils]; + })(); + + const automineSequencer = new AutomineSequencer({ + publisherFactory, + checkpointsBuilder, + globalsBuilder: globalVariableBuilder, + worldState: worldStateSynchronizer, + l2BlockSource: archiver, + l1ToL2MessageSource: archiver, + p2pClient, + ethCheatCodes, + dateProvider: dateProvider as any, // TestDateProvider; verified at construction in fixture + l1Constants: { + l1GenesisTime: l1Constants.l1GenesisTime, + slotDuration: l1Constants.slotDuration, + ethereumSlotDuration: l1Constants.ethereumSlotDuration, + rollupManaLimit: l1Constants.rollupManaLimit, + epochDuration: config.aztecEpochDuration, + }, + coinbase, + feeRecipient, + signatureContext: { chainId: config.l1ChainId, rollupAddress: config.rollupAddress }, + config, + archiver, + l1TxUtils: reorgResetL1TxUtils, + stopExtras: () => publisherManager.stop(), + log: log.createChild('automine-sequencer'), + }); + + await publisherManager.start(); + return automineSequencer; +} diff --git a/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts b/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts new file mode 100644 index 000000000000..805b507adff4 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts @@ -0,0 +1,592 @@ +import type { Archiver } from '@aztec/archiver'; +import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils'; +import type { EthCheatCodes } from '@aztec/ethereum/test'; +import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import type { EthAddress } from '@aztec/foundation/eth-address'; +import { Signature } from '@aztec/foundation/eth-signature'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { SerialQueue } from '@aztec/foundation/queue'; +import { RunningPromise } from '@aztec/foundation/running-promise'; +import type { TestDateProvider } from '@aztec/foundation/timer'; +import { isErrorClass } from '@aztec/foundation/types'; +import type { P2PClient as ConcreteP2PClient, P2P } from '@aztec/p2p'; +import type { AztecAddress } from '@aztec/stdlib/aztec-address'; +import { CommitteeAttestationsAndSigners, type L2Block, type L2BlockSource } from '@aztec/stdlib/block'; +import { getPreviousCheckpointOutHashes } from '@aztec/stdlib/checkpoint'; +import type { ChainConfig } from '@aztec/stdlib/config'; +import { + type L1RollupConstants, + getEpochAtSlot, + getSlotAtTimestamp, + getTimestampForSlot, +} from '@aztec/stdlib/epoch-helpers'; +import { InsufficientValidTxsError, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; +import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import type { FailedTx, Tx } from '@aztec/stdlib/tx'; +import type { + BuildBlockInCheckpointResult, + CheckpointBuilder, + FullNodeCheckpointsBuilder, +} from '@aztec/validator-client'; + +import type { GlobalVariableBuilder } from '../../global_variable_builder/global_builder.js'; +import type { SequencerPublisherFactory } from '../../publisher/sequencer-publisher-factory.js'; +import type { SequencerPublisher } from '../../publisher/sequencer-publisher.js'; +import type { SequencerConfig } from '../config.js'; + +/** + * L1 rollup constants needed by the AutomineSequencer. Same as SequencerRollupConstants + * plus `epochDuration` for the epoch-based checkpoint out-hash lookup. + */ +export type AutomineSequencerConstants = Pick< + L1RollupConstants, + 'ethereumSlotDuration' | 'l1GenesisTime' | 'slotDuration' | 'rollupManaLimit' | 'epochDuration' +>; + +/** Dependencies for the AutomineSequencer. */ +export type AutomineSequencerDeps = { + publisherFactory: SequencerPublisherFactory; + checkpointsBuilder: FullNodeCheckpointsBuilder; + globalsBuilder: GlobalVariableBuilder; + worldState: WorldStateSynchronizer; + l2BlockSource: L2BlockSource; + l1ToL2MessageSource: L1ToL2MessageSource; + /** P2P client; must also expose `sync()` for post-rollback pool recovery. */ + p2pClient: P2P & Pick; + ethCheatCodes: EthCheatCodes; + dateProvider: TestDateProvider; + l1Constants: AutomineSequencerConstants; + coinbase: EthAddress; + feeRecipient: AztecAddress; + signatureContext: CoordinationSignatureContext; + config: SequencerConfig & Pick; + /** + * Archiver used to push locally-built blocks and proposed checkpoints into the in-memory + * store, force an immediate L1 sync after publishing, and roll back state during reorgs. + */ + archiver: Pick; + /** L1 tx utils whose cached nonces must be reset after an L1 reorg. */ + l1TxUtils: Pick[]; + /** + * Optional extra cleanup hook awaited inside {@link AutomineSequencer.stop}. Used by the + * factory to shut down the PublisherManager funding loop after the queue and poller drain. + */ + stopExtras?: () => Promise; + /** How often to poll the mempool for new txs while running. Defaults to 50ms. */ + pollIntervalMs?: number; + log?: Logger; +}; + +/** + * Minimal, deterministic, queue-driven sequencer for e2e tests that don't exercise + * block-building or consensus (e.g. e2e_token, e2e_amm, e2e_authwit). + * + * Differences from the production `Sequencer`: + * - No proposer-turn check (single sequencer). + * - No sync check, no pipelining, no validator orchestration, no attestations, + * no slashing, no votes, no P2P proposal gossip, no timetable enforcement. + * - No event emission — consumers (archiver, world-state, `EpochTestSettler`) observe + * L1 and the archiver tip rather than sequencer events. + * - All test-driven time control (warp / mine empty block) goes through a single + * serial queue alongside mempool-driven builds; the three never interleave. + * + * Requires `aztecTargetCommitteeSize == 0` on the deployed rollup so that the + * L1 `verifyProposer` / `verifyAttestations` short-circuits accept an empty + * `CommitteeAttestationsAndSigners` (see + * `l1-contracts/src/core/libraries/rollup/ValidatorSelectionLib.sol:244`). + */ +export class AutomineSequencer { + private readonly log: Logger; + private readonly queue: SerialQueue; + private readonly pollIntervalMs: number; + private readonly deps: AutomineSequencerDeps; + + private running = false; + private stopped = false; + private paused = false; + private mempoolPoller?: RunningPromise; + private publisher?: SequencerPublisher; + private attestorAddress?: EthAddress; + + /** Set while a mempool-driven build is queued but not yet run; used to coalesce. */ + private buildQueued: Promise | undefined = undefined; + + /** Last L2 slot we published a checkpoint for (-1 means none yet). */ + private lastBuiltSlot: number = -1; + + constructor(deps: AutomineSequencerDeps) { + this.deps = deps; + this.log = deps.log ?? createLogger('sequencer:automine'); + this.queue = new SerialQueue(); + this.pollIntervalMs = deps.pollIntervalMs ?? 50; + } + + /** + * Starts the sequencer. Switches anvil into automine mode (no interval mining), + * acquires a publisher, and begins polling the mempool for pending txs. + */ + public async start(): Promise { + if (this.running) { + return; + } + this.running = true; + + await this.deps.ethCheatCodes.setIntervalMining(0, { silent: true }); + await this.deps.ethCheatCodes.setAutomine(true, { silent: true }); + + const { publisher, attestorAddress } = await this.deps.publisherFactory.create(); + this.publisher = publisher; + this.attestorAddress = attestorAddress; + this.log.info(`AutomineSequencer started`, { + publisher: this.publisher.getSenderAddress().toString(), + attestor: this.attestorAddress.toString(), + }); + + this.queue.start(); + + // Fallback poller that triggers a build if we discover pending txs without an explicit + // notification. Tests can also call `buildIfPending()` directly to skip the poll wait. + this.mempoolPoller = new RunningPromise(() => this.maybeEnqueueBuild(), this.log, this.pollIntervalMs); + this.mempoolPoller.start(); + } + + /** + * Stops the sequencer. Drains the queue, unsubscribes the mempool poller, and runs any + * registered {@link AutomineSequencerDeps.stopExtras} hook (e.g. the PublisherManager's + * funding loop). Idempotent: subsequent calls return without re-running cleanup. + */ + public async stop(): Promise { + if (this.stopped) { + return; + } + this.stopped = true; + this.running = false; + await this.mempoolPoller?.stop(); + await this.queue.end(); + await this.deps.stopExtras?.(); + this.log.info('AutomineSequencer stopped'); + } + + /** + * Enqueues a mempool-driven build. Coalesces consecutive calls so a burst of new txs + * collapses into one build job. Returns the built block (or undefined if nothing was built + * or the sequencer is paused). + */ + public buildIfPending(): Promise { + if (!this.running || this.paused) { + return Promise.resolve(undefined); + } + if (this.buildQueued) { + // A build is already queued; coalesce. The pending build will pick up the new txs. + return this.buildQueued; + } + this.buildQueued = this.queue.put(async () => { + try { + return await this.runBuild({ allowEmpty: false }); + } finally { + this.buildQueued = undefined; + } + }); + return this.buildQueued; + } + + /** + * Pauses mempool-driven block production. Pending txs accumulate in the pool without being + * mined. Explicit test-harness operations (`buildEmptyBlock`, `warpTo`, `revertToCheckpoint`) + * continue to work; this only gates the mempool poller and `buildIfPending`. + */ + public pause(): void { + if (this.paused) { + return; + } + this.paused = true; + this.log.info('AutomineSequencer paused'); + } + + /** Resumes mempool-driven block production after a previous {@link pause}. */ + public resume(): void { + if (!this.paused) { + return; + } + this.paused = false; + this.log.info('AutomineSequencer resumed'); + } + + /** + * Updates the in-memory sequencer config. Mirrors {@link SequencerClient.updateConfig} so that + * `AztecNode.setConfig` (e.g. tests bumping `minTxsPerBlock` to bundle multiple txs into one + * block) propagates to the AutomineSequencer's gating logic in {@link runBuild}. + */ + public updateConfig(config: Partial): void { + Object.assign(this.deps.config, config); + } + + /** Returns a snapshot of the current sequencer config (used by pause/resume bookkeeping). */ + public getConfig(): SequencerConfig { + return this.deps.config; + } + + /** Enqueues an empty-block build. Resolves to the built block. */ + public buildEmptyBlock(): Promise { + return this.queue.put(async () => { + const block = await this.runBuild({ allowEmpty: true }); + if (!block) { + throw new Error('buildEmptyBlock: runBuild returned undefined'); + } + return block; + }); + } + + /** + * Warps L1 timestamp to `targetTimestampSec`. Rounded up to the next aztec-slot + * boundary so the next build lands on a fresh slot. Atomic with respect to builds — + * the queue ensures no build is in flight while the warp executes. + */ + public warpTo(targetTimestampSec: number): Promise { + return this.queue.put(() => this.runWarp(targetTimestampSec)); + } + + /** Warps L1 timestamp forward by `deltaSec` seconds from the current L1 time. */ + public warpBy(deltaSec: number): Promise { + return this.queue.put(async () => { + const current = await this.deps.ethCheatCodes.lastBlockTimestamp(); + await this.runWarp(current + deltaSec); + }); + } + + /** + * Reorgs L1 so that every L1 block strictly after the one that published + * `targetCheckpoint` is removed. The archiver, world-state, and date provider + * are all brought back in sync before the promise resolves. + * + * Runs inside the serial queue so it never interleaves with a build or warp. + */ + public revertToCheckpoint(targetCheckpoint: number): Promise { + return this.queue.put(() => this.runRevert(targetCheckpoint)); + } + + /** Awaits the queue draining to a fully idle state. */ + public syncPoint(): Promise { + return this.queue.syncPoint(); + } + + /** Called from the mempool poller. Enqueues a build if there are pending txs. */ + private async maybeEnqueueBuild(): Promise { + if (!this.running || this.paused || this.buildQueued) { + return; + } + try { + const pending = await this.deps.p2pClient.getPendingTxCount(); + if (pending > 0) { + // Fire-and-forget; the build result is delivered via `buildIfPending()` callers, + // not via the poller. + void this.buildIfPending().catch(err => { + this.log.error('Mempool-driven build failed', err); + }); + } + } catch (err) { + this.log.warn('Failed to poll mempool', { err: err instanceof Error ? err.message : String(err) }); + } + } + + /** Builds one checkpoint with a single block, publishes it, syncs the date provider. */ + private async runBuild({ allowEmpty }: { allowEmpty: boolean }): Promise { + if (!this.running || !this.publisher || !this.attestorAddress) { + return undefined; + } + + const txCount = await this.deps.p2pClient.getPendingTxCount(); + // For mempool-driven builds, wait for at least `minTxsPerBlock` pending txs (or 1 if not set) + // before building. This mirrors the production sequencer's `waitForMinTxs` behavior, and is + // required for tests that bundle multiple txs into one block via `setConfig({ minTxsPerBlock })`. + // Explicit empty-block / warp paths pass `allowEmpty: true` and bypass this gate. + const minRequired = allowEmpty ? 0 : Math.max(this.deps.config.minTxsPerBlock ?? 1, 1); + if (txCount < minRequired) { + return undefined; + } + + // Decide target slot from the pending block's timestamp — picks up any prior + // `setNextBlockTimestamp` call (e.g. queued by runWarp) instead of assuming +1 over + // the last mined block. + const pendingBlockTs = await this.deps.ethCheatCodes.nextBlockTimestamp(); + let targetSlot = Number(getSlotAtTimestamp(BigInt(pendingBlockTs), this.deps.l1Constants)); + if (targetSlot <= this.lastBuiltSlot) { + // Pending block doesn't reach a new slot yet; advance to the next slot we own. + targetSlot = this.lastBuiltSlot + 1; + } + const slotBoundaryTs = Number(getTimestampForSlot(SlotNumber(targetSlot), this.deps.l1Constants)); + + // Pre-set anvil's next block timestamp only if the slot boundary is past what's already + // scheduled. setNextBlockTimestamp rejects values not strictly greater than the last block's + // timestamp, and pendingBlockTs is always > lastBlockTimestamp, so this guard is sufficient. + if (slotBoundaryTs > pendingBlockTs) { + await this.deps.ethCheatCodes.setNextBlockTimestamp(slotBoundaryTs); + } + + const tips = await this.deps.l2BlockSource.getL2Tips(); + const syncedToBlockNumber = tips.proposed.number; + + // Ensure world state has processed the archiver's tip before forking. Without this, + // world state may still be at the previous block (since it syncs asynchronously from + // the archiver), and `fork(syncedToBlockNumber)` would fail with + // "Unable to initialize from future block". + await this.deps.worldState.syncImmediate(BlockNumber(syncedToBlockNumber)); + + const nextBlockNumber = BlockNumber(syncedToBlockNumber + 1); + const checkpointNumber = CheckpointNumber(tips.proposedCheckpoint.checkpoint.number + 1); + const targetEpoch = getEpochAtSlot(SlotNumber(targetSlot), this.deps.l1Constants); + + this.log.verbose(`Building automine checkpoint`, { + checkpointNumber, + blockNumber: nextBlockNumber, + slot: targetSlot, + slotTimestamp: slotBoundaryTs, + txCount, + allowEmpty, + }); + + const checkpointGlobals = await this.deps.globalsBuilder.buildCheckpointGlobalVariables( + this.deps.coinbase, + this.deps.feeRecipient, + SlotNumber(targetSlot), + ); + + const l1ToL2Messages = await this.deps.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber); + + const previousCheckpointOutHashes = await getPreviousCheckpointOutHashes({ + blockSource: this.deps.l2BlockSource, + epoch: targetEpoch, + checkpointNumber, + l1Constants: this.deps.l1Constants, + pipeliningEnabled: false, + log: this.log, + }); + + const feeAssetPriceModifier = await this.publisher.getFeeAssetPriceModifier(); + + await using fork = await this.deps.worldState.fork(syncedToBlockNumber, { closeDelayMs: 0 }); + + const checkpointBuilder = await this.deps.checkpointsBuilder.startCheckpoint( + checkpointNumber, + checkpointGlobals, + feeAssetPriceModifier, + l1ToL2Messages, + previousCheckpointOutHashes, + fork, + this.log.getBindings(), + ); + + const pendingTxs = this.deps.p2pClient.iterateEligiblePendingTxs(); + + const buildResult = await this.tryBuildBlock( + checkpointBuilder, + pendingTxs, + nextBlockNumber, + checkpointGlobals.timestamp, + allowEmpty, + checkpointNumber, + ); + if (!buildResult) { + return undefined; + } + + const checkpoint = await checkpointBuilder.completeCheckpoint(); + + // Empty CommitteeAttestationsAndSigners is accepted on-chain when committee size is 0. + const emptyAttestations = CommitteeAttestationsAndSigners.empty(this.deps.signatureContext); + const emptyAttestationsSignature = Signature.empty(); + + // Push the block and proposed checkpoint into the archiver locally BEFORE publishing to L1. + // This avoids racing the archiver's L1 polling: if the L1 publish happened first, polling + // could surface the checkpoint and reject our subsequent local push as duplicate. Pushing + // first means the archiver already has the proposed entry when L1 polling fires; the L1 + // sync path then promotes the existing proposed checkpoint via promoteProposedToCheckpointed + // rather than re-adding it. + await this.deps.archiver.addBlock(buildResult.block); + await this.deps.archiver.addProposedCheckpoint({ + header: checkpoint.header, + checkpointNumber, + startBlock: BlockNumber(buildResult.block.number), + blockCount: 1, + totalManaUsed: checkpoint.header.totalManaUsed.toBigInt(), + feeAssetPriceModifier, + }); + + await this.publisher.enqueueProposeCheckpoint(checkpoint, emptyAttestations, emptyAttestationsSignature); + const result = await this.publisher.sendRequests(SlotNumber(targetSlot)); + + const successful = result?.successfulActions?.find(a => a === 'propose'); + if (!successful) { + this.log.error('Propose action did not succeed under automine', { + slot: targetSlot, + checkpointNumber, + successful: result?.successfulActions, + failed: result?.failedActions, + }); + throw new Error(`AutomineSequencer: propose did not succeed for slot ${targetSlot}`); + } + + // Force one full L1-sync cycle synchronously. The local addBlock/addProposedCheckpoint + // above advances the proposed tip, but tips.checkpointed and the L1->L2 inbox tree state + // only advance when the archiver observes the L1-confirmed checkpoint via its sync loop. + await this.deps.archiver.syncImmediate(); + + // Sync the date provider to the L1 block timestamp we just mined. + const newL1Ts = await this.deps.ethCheatCodes.lastBlockTimestamp(); + this.deps.dateProvider.setTime(newL1Ts * 1000); + + this.lastBuiltSlot = targetSlot; + + this.log.verbose(`Automine checkpoint published`, { + checkpointNumber, + blockNumber: nextBlockNumber, + slot: targetSlot, + l1Timestamp: newL1Ts, + txCount: buildResult.numTxs, + }); + + return buildResult.block; + } + + /** + * Warps L1 timestamp to (or past) `targetTimestampSec`, rounded up to the next aztec-slot + * boundary, by queuing an empty-checkpoint build at that slot. Mines exactly one L1 block + * (the propose tx auto-mined under anvil's automine mode), with the timestamp pre-set so + * the mined block lands on the slot boundary. + */ + private async runWarp(targetTimestampSec: number): Promise { + const currentL1Ts = await this.deps.ethCheatCodes.lastBlockTimestamp(); + if (targetTimestampSec <= currentL1Ts) { + this.log.debug(`Warp target ${targetTimestampSec} is not in the future of current L1 ts ${currentL1Ts}`); + return; + } + + // Round up to the next aztec-slot boundary so the next build naturally lands on a new slot. + const targetSlot = Number(getSlotAtTimestamp(BigInt(targetTimestampSec), this.deps.l1Constants)); + const slotBoundaryTs = Number(getTimestampForSlot(SlotNumber(targetSlot + 1), this.deps.l1Constants)); + + // Queue the next L1 block at the slot boundary timestamp, then build (and publish) an + // empty L2 checkpoint. The propose tx auto-mines a single L1 block at slotBoundaryTs, + // and `runBuild` syncs the date provider to the new L1 timestamp. + await this.deps.ethCheatCodes.setNextBlockTimestamp(slotBoundaryTs); + await this.runBuild({ allowEmpty: true }); + + this.log.verbose(`Warped L1 to slot boundary`, { slot: targetSlot + 1, timestamp: slotBoundaryTs }); + } + + /** + * Rolls L1 back to the block that published `targetCheckpoint`, drops the archiver's + * in-memory state to match, and resets internal slot bookkeeping. + */ + private async runRevert(targetCheckpoint: number): Promise { + const checkpointData = await this.deps.l2BlockSource.getCheckpointData({ + number: CheckpointNumber(targetCheckpoint), + }); + if (!checkpointData) { + throw new Error(`AutomineSequencer: checkpoint ${targetCheckpoint} not found in archiver`); + } + + const targetL1Block = Number(checkpointData.l1.blockNumber); + this.log.verbose(`Reverting to checkpoint ${targetCheckpoint}`, { + targetCheckpoint, + targetL1Block, + checkpointSlot: checkpointData.header.slotNumber, + }); + + // Roll the archiver back to the last block of targetCheckpoint before the L1 reorg, + // since the archiver needs to fetch the target checkpoint's L1 block hash during rollback. + const lastBlockInCheckpoint = BlockNumber(checkpointData.startBlock + checkpointData.blockCount - 1); + await this.deps.archiver.rollbackTo(lastBlockInCheckpoint); + + // Force the P2P block stream to run one cycle immediately so it processes the + // chain-pruned event triggered by the archiver rollback above. Without this, the + // P2P pool may not have restored rolled-back txs to pending by the time the next + // build runs. + await this.deps.p2pClient.sync(); + + // Force world-state to process the archiver's prune event immediately, so the next build + // doesn't try to insert nullifiers that were already in the pruned checkpoints. + await this.deps.worldState.syncImmediate(); + + // Remove all L1 blocks strictly after the target checkpoint's publish block so that + // the propose txs for later checkpoints are gone from L1. We use reorg(depth) directly + // to keep targetL1Block itself as the new chain tip. + const currentL1Block = await this.deps.ethCheatCodes.publicClient.getBlockNumber(); + const depth = Number(currentL1Block) - targetL1Block; + if (depth > 0) { + await this.deps.ethCheatCodes.reorg(depth); + } + + // anvil_rollback re-queues the rolled-back txs into the mempool. Clear them so they + // don't get re-mined, then reset the publisher nonce tracker so the next propose tx + // uses the correct nonce for the post-reorg chain state. + await this.deps.ethCheatCodes.rpcCall('anvil_dropAllTransactions', []); + this.deps.l1TxUtils.forEach(utils => utils.resetNonce()); + + // Reset slot bookkeeping so the next build picks up at the correct slot. + this.lastBuiltSlot = Number(checkpointData.header.slotNumber); + + this.log.verbose(`Reverted to checkpoint ${targetCheckpoint}`, { + targetCheckpoint, + targetL1Block, + }); + } + + /** + * Wraps `checkpointBuilder.buildBlock` with the failed-tx handling shared by both error + * and success paths: drops the failed txs from the P2P mempool, and returns `undefined` + * when `InsufficientValidTxsError` aborts the build (so the caller skips publishing). + */ + private async tryBuildBlock( + checkpointBuilder: CheckpointBuilder, + pendingTxs: AsyncIterableIterator, + nextBlockNumber: BlockNumber, + timestamp: bigint, + allowEmpty: boolean, + checkpointNumber: CheckpointNumber, + ): Promise { + let buildResult: BuildBlockInCheckpointResult; + try { + buildResult = await checkpointBuilder.buildBlock(pendingTxs, nextBlockNumber, timestamp, { + maxTransactions: this.deps.config.maxTxsPerBlock, + // Allow empty for explicit-empty builds; require at least 1 valid tx otherwise. + minValidTxs: allowEmpty ? 0 : 1, + isBuildingProposal: true, + maxBlocksPerCheckpoint: 1, + perBlockAllocationMultiplier: 1, + }); + } catch (err) { + // Mirrors production's checkpoint_proposal_job: if every pending tx failed execution and + // we didn't reach minValidTxs, drop the failed txs from the mempool so they don't block + // the poller forever, then abort this build with no checkpoint published. + if (isErrorClass(err, InsufficientValidTxsError)) { + await this.dropFailedTxsFromP2P(err.failedTxs); + this.log.verbose(`AutomineSequencer: insufficient valid txs, skipping build`, { + checkpointNumber, + processedCount: err.processedCount, + minRequired: err.minRequired, + failedCount: err.failedTxs.length, + }); + return undefined; + } + throw err; + } + + // Drop any txs that failed execution but didn't trigger InsufficientValidTxsError, so we + // don't re-pick them up on the next build. + await this.dropFailedTxsFromP2P(buildResult.failedTxs); + + return buildResult; + } + + /** Removes txs that failed execution from the P2P mempool so they don't get retried. */ + private async dropFailedTxsFromP2P(failedTxs: FailedTx[]): Promise { + if (failedTxs.length === 0) { + return; + } + const failedTxHashes = failedTxs.map(fail => fail.tx.getTxHash()); + this.log.verbose(`Dropping failed txs ${failedTxHashes.join(', ')}`); + await this.deps.p2pClient.handleFailedExecution(failedTxHashes); + } +} diff --git a/yarn-project/sequencer-client/src/sequencer/chain_state_overrides.ts b/yarn-project/sequencer-client/src/sequencer/chain_state_overrides.ts index 412f1562d461..60c588faa974 100644 --- a/yarn-project/sequencer-client/src/sequencer/chain_state_overrides.ts +++ b/yarn-project/sequencer-client/src/sequencer/chain_state_overrides.ts @@ -1,135 +1,162 @@ import { RollupContract, SimulationOverridesBuilder, type SimulationOverridesPlan } from '@aztec/ethereum/contracts'; import { CheckpointNumber } from '@aztec/foundation/branded-types'; -import type { Fr } from '@aztec/foundation/curves/bn254'; import type { Logger } from '@aztec/foundation/log'; -import { computeCheckpointPayloadDigest } from '@aztec/stdlib/checkpoint'; -import type { ProposedCheckpointData } from '@aztec/stdlib/checkpoint'; +import { type ProposedCheckpointData, computeCheckpointPayloadDigest } from '@aztec/stdlib/checkpoint'; import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; -type PipelinedParentSimulationOverridesPlanInput = { - checkpointNumber: CheckpointNumber; - proposedCheckpointData?: ProposedCheckpointData; +type CheckpointSimulationOverridesPlanInput = { + /** Target rollup contract. */ rollup: RollupContract; - signatureContext: CoordinationSignatureContext; + /** Checkpoint number to be proposed. */ + checkpointNumber: CheckpointNumber; + /** Logger instance. */ log: Logger; /** - * Whether proposer pipelining is enabled. Controls only the parent pending/fee-header - * portion of the plan — the proven override below is independent of pipelining because - * the boundary build needs it for globals and enqueue-time validation regardless. + * The proposed parent checkpoint when pipelining. Its `checkpointNumber` must equal + * `checkpointNumber - 1`; the helper enforces this. Mutually exclusive with + * `invalidateToPendingCheckpointNumber`. + */ + proposedCheckpointData?: ProposedCheckpointData; + /** + * The pending checkpoint number we'll end up at after invalidation lands. Mutually exclusive + * with `proposedCheckpointData`. */ - pipeliningEnabled: boolean; - /** If set, also overrides `tips.proven` so `canPruneAtTime` returns false at the simulation timestamp. */ - prunePending?: { provenOverride: CheckpointNumber }; -}; - -type SubmissionSimulationOverridesPlanInput = { - pipelinedParentPlan?: SimulationOverridesPlan; invalidateToPendingCheckpointNumber?: CheckpointNumber; - lastArchiveRoot: Fr; - pipeliningEnabled: boolean; + /** + * The real on-chain pending checkpoint number (typically `syncedTo.checkpointedCheckpointNumber`). + * Used as the snapshot we pin both `pending` and `proven` to avoid prunes in simulation. + */ + checkpointedCheckpointNumber: CheckpointNumber; + /** + * Chain-level consensus signature context. Used to recompute the parent's `payloadDigest` for the + * pipelined simulation override so it matches what `propose` will write into `tempCheckpointLogs[parent]` + * once the parent lands. + */ + signatureContext: CoordinationSignatureContext; }; /** - * Builds the simulated chain view used while constructing a checkpoint proposal. May carry: - * - A pending parent override + fee header (only when pipelining is enabled). - * - A proven override (whenever `prunePending` is set, even with pipelining off — the boundary - * build needs it for the globals builder's mana-min-fee lookup and the enqueue-time - * submission simulation regardless of pipelining). + * Builds the SimulationOverridesPlan describing the simulated L1 rollup state for a checkpoint's + * enqueue-time simulations: `canProposeAt` (in Sequencer.doWork) and the propose-related sims + * (validateBlockHeader, simulateProposeTx). The plan reflects "as if our pipelined parent + * checkpoint has landed and any required invalidation has executed" — the gap that needs to be + * bridged at enqueue time. + * + * Pipelining (`proposedCheckpointData`) and invalidation (`invalidateToPendingCheckpointNumber`) + * are mutually exclusive; passing both throws. */ -export async function buildPipelinedParentSimulationOverridesPlan( - input: PipelinedParentSimulationOverridesPlanInput, +export async function buildCheckpointSimulationOverridesPlan( + input: CheckpointSimulationOverridesPlanInput, ): Promise { - const builder = new SimulationOverridesBuilder(); - - if (input.pipeliningEnabled) { - const parentCheckpointNumber = CheckpointNumber(input.checkpointNumber - 1); - builder.withChainTips({ pending: parentCheckpointNumber }); - - if (input.proposedCheckpointData) { - const { header, archive, checkpointOutHash, feeAssetPriceModifier } = input.proposedCheckpointData; - builder.withPendingArchive(archive.root).withPendingTempCheckpointLogFields({ - headerHash: header.hash(), - outHash: checkpointOutHash, - slotNumber: header.slotNumber, - payloadDigest: computeCheckpointPayloadDigest({ - header, - archiveRoot: archive.root, - feeAssetPriceModifier, - signatureContext: input.signatureContext, - }), - }); - } - - const pendingFeeHeader = await computePipelinedParentFeeHeader(input); - if (pendingFeeHeader) { - builder.withPendingFeeHeader(pendingFeeHeader); - } + if (input.proposedCheckpointData && input.invalidateToPendingCheckpointNumber !== undefined) { + throw new Error( + 'Error in buildCheckpointSimulationOverridesPlan: proposedCheckpointData and invalidateToPendingCheckpointNumber are mutually exclusive', + ); } - if (input.prunePending) { - builder.withChainTips({ proven: input.prunePending.provenOverride }); + const builder = new SimulationOverridesBuilder(); + const pendingCheckpointNumber = derivePendingCheckpointNumber(input); + + // Override the latest checkpoint number when invalidating or pipelining, so our checkpoint + // follows from it. We also override the proven chain tip so we dont need to worry about + // prunes kicking in that would break out simulation if there's a prune pending. We always + // assume that a proof will land in time. If we don't have a pending checkpoint number to force, + // we still set both tips to the current checkpoint number to avoid the prune trigger. + const overridenChainTip = pendingCheckpointNumber ?? input.checkpointedCheckpointNumber; + builder.withChainTips({ pending: overridenChainTip, proven: overridenChainTip }); + + if (input.proposedCheckpointData) { + const { header, archive, checkpointOutHash, feeAssetPriceModifier } = input.proposedCheckpointData; + builder.withPendingArchive(archive.root); + // Override every locally-derivable `tempCheckpointLogs[parent]` field that L1 will eventually + // write. `slotNumber` is load-bearing for `STFLib.canPruneAtTime`: without it the cell reads + // slotNumber 0, the contract treats the pending tip as belonging to an expired epoch, and + // `getEffectivePendingCheckpointNumber` silently collapses pending back to proven — producing + // a spurious `Rollup__InvalidArchive` against the on-chain genesis archive. The other fields + // (headerHash, outHash, payloadDigest) are not strictly load-bearing for `canProposeAt` / + // `validateBlockHeader`, but mirroring the full cell keeps the simulation byte-faithful with + // what the actual `propose()` send will observe, which is a defense against future reads + // taking dependencies on them. + builder.withPendingTempCheckpointLogFields({ + headerHash: header.hash(), + outHash: checkpointOutHash, + slotNumber: header.slotNumber, + payloadDigest: computeCheckpointPayloadDigest({ + header, + archiveRoot: archive.root, + feeAssetPriceModifier, + signatureContext: input.signatureContext, + }), + }); + + const feeHeader = await computePipelinedParentFeeHeader({ + checkpointNumber: input.checkpointNumber, + proposedCheckpointData: input.proposedCheckpointData, + rollup: input.rollup, + log: input.log, + }); + if (feeHeader) { + builder.withPendingFeeHeader(feeHeader); + } } return builder.build(); } -/** Builds the simulated chain view used when validating and enqueueing checkpoint submission. */ -export function buildSubmissionSimulationOverridesPlan( - input: SubmissionSimulationOverridesPlanInput, -): SimulationOverridesPlan | undefined { - const pendingCheckpointNumber = - input.invalidateToPendingCheckpointNumber ?? input.pipelinedParentPlan?.chainTipsOverride?.pending; - - const builder = SimulationOverridesBuilder.from(input.pipelinedParentPlan); - if (pendingCheckpointNumber !== undefined) { - builder.withChainTips({ pending: pendingCheckpointNumber }); +function derivePendingCheckpointNumber(input: CheckpointSimulationOverridesPlanInput): CheckpointNumber | undefined { + if (input.invalidateToPendingCheckpointNumber !== undefined) { + return input.invalidateToPendingCheckpointNumber; } - - if (input.pipeliningEnabled && pendingCheckpointNumber !== undefined) { - builder.withPendingArchive(input.lastArchiveRoot); + if (!input.proposedCheckpointData) { + return undefined; } - - return builder.build(); + if (input.checkpointNumber < 1) { + throw new Error(`Cannot build simulation override for checkpoint ${input.checkpointNumber}: no parent exists`); + } + const expectedParent = CheckpointNumber(input.checkpointNumber - 1); + if (input.proposedCheckpointData.checkpointNumber !== expectedParent) { + throw new Error( + `Cannot build simulation override for checkpoint ${input.checkpointNumber}: proposedCheckpointData.checkpointNumber (${input.proposedCheckpointData.checkpointNumber}) does not match expected parent ${expectedParent}`, + ); + } + return expectedParent; } type PipelinedParentFeeHeaderInput = { checkpointNumber: CheckpointNumber; - proposedCheckpointData?: ProposedCheckpointData; + proposedCheckpointData: ProposedCheckpointData; rollup: RollupContract; log: Logger; }; -/** Derives the pending parent fee header used during pipelined proposal simulation. */ +/** + * Derives the pending parent fee header used during pipelined proposal simulation. Returns + * `undefined` only when no grandparent exists (i.e. the proposed parent is the genesis + * checkpoint); all other failure modes (missing grandparent state, missing fee header, RPC + * errors) throw so callers don't silently desync the fee-header override. + */ export async function computePipelinedParentFeeHeader(input: PipelinedParentFeeHeaderInput) { - if (!input.proposedCheckpointData || input.checkpointNumber < 2) { + if (input.checkpointNumber < 2) { return undefined; } const grandparentCheckpointNumber = CheckpointNumber(input.checkpointNumber - 2); - try { - const [grandparentCheckpoint, manaTarget] = await Promise.all([ - input.rollup.getCheckpoint(grandparentCheckpointNumber), - input.rollup.getManaTarget(), - ]); + const [grandparentCheckpoint, manaTarget] = await Promise.all([ + input.rollup.getCheckpoint(grandparentCheckpointNumber), + input.rollup.getManaTarget(), + ]); - if (!grandparentCheckpoint?.feeHeader) { - input.log.error( - `Grandparent checkpoint or feeHeader missing for checkpoint ${grandparentCheckpointNumber.toString()}`, - ); - return undefined; - } - - return RollupContract.computeChildFeeHeader( - grandparentCheckpoint.feeHeader, - input.proposedCheckpointData.totalManaUsed, - input.proposedCheckpointData.feeAssetPriceModifier, - manaTarget, - ); - } catch (err) { - input.log.error( - `Failed to derive pipelined parent fee header for checkpoint ${grandparentCheckpointNumber.toString()}: ${err}`, + if (!grandparentCheckpoint?.feeHeader) { + throw new Error( + `Grandparent checkpoint or feeHeader missing for checkpoint ${grandparentCheckpointNumber.toString()}`, ); - return undefined; } + + return RollupContract.computeChildFeeHeader( + grandparentCheckpoint.feeHeader, + input.proposedCheckpointData.totalManaUsed, + input.proposedCheckpointData.feeAssetPriceModifier, + manaTarget, + ); } diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts index 83345c8eef76..8661d7c0850b 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts @@ -69,10 +69,7 @@ import { mockTxIterator, setupTxsAndBlock, } from '../test/utils.js'; -import { - buildPipelinedParentSimulationOverridesPlan, - computePipelinedParentFeeHeader, -} from './chain_state_overrides.js'; +import { buildCheckpointSimulationOverridesPlan, computePipelinedParentFeeHeader } from './chain_state_overrides.js'; import { CheckpointProposalJob } from './checkpoint_proposal_job.js'; import type { CheckpointProposalJobMetricsRecorder } from './checkpoint_proposal_job_metrics.js'; import type { SequencerEvents } from './events.js'; @@ -188,8 +185,15 @@ describe('CheckpointProposalJob', () => { publisher.enqueueProposeCheckpoint.mockResolvedValue(undefined); publisher.enqueueGovernanceCastSignal.mockResolvedValue(true); publisher.enqueueSlashingActions.mockResolvedValue(true); + + // Default rollup contract reads used by pipelined fee-header derivation. Tests that exercise + // the failure modes override these via jest.spyOn. + jest.spyOn(publisher.rollupContract, 'getCheckpoint').mockResolvedValue({ + feeHeader: { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 1n, congestionCost: 0n, proverCost: 0n }, + } as any); + jest.spyOn(publisher.rollupContract, 'getManaTarget').mockResolvedValue(10_000n); publisher.sendRequestsAt.mockResolvedValue({ - result: { receipt: { status: 'success' } as TransactionReceipt, errorMsg: undefined }, + result: { receipt: { status: 'success' } as TransactionReceipt }, successfulActions: ['propose'], failedActions: [], sentActions: ['propose'], @@ -369,6 +373,8 @@ describe('CheckpointProposalJob', () => { checkpointBuilder.seedBlocks([block], [txs]); validatorClient.collectAttestations.mockResolvedValue(getAttestations(block)); epochCache.isProposerPipeliningEnabled.mockReturnValue(true); + // We build checkpoint 2 on top of proposed parent at checkpoint 1. + checkpointNumber = CheckpointNumber(2); const checkpoint = await createCheckpointProposalJob({ targetSlot: SlotNumber(newSlotNumber + 1), @@ -772,6 +778,7 @@ describe('CheckpointProposalJob', () => { overrides?.targetEpoch ?? epoch, checkpointNumber, lastBlockNumber, + CheckpointNumber(checkpointNumber - 1), proposer, publisher, attestorAddress, @@ -824,10 +831,10 @@ describe('CheckpointProposalJob', () => { proverCost: 10n, }; - it('returns undefined when proposedCheckpointData is not set', async () => { + it('returns undefined when checkpoint number is below 2 (genesis grandparent)', async () => { const result = await computePipelinedParentFeeHeader({ - checkpointNumber: pipelinedCheckpointNumber, - proposedCheckpointData: undefined, + checkpointNumber: CheckpointNumber(1), + proposedCheckpointData: pendingData, rollup: publisher.rollupContract, log: createLogger('test'), }); @@ -863,152 +870,155 @@ describe('CheckpointProposalJob', () => { expect(result).toEqual(expected); }); - it('returns undefined when grandparent checkpoint is not found', async () => { + it('throws when grandparent checkpoint is not found', async () => { mockRollup({ grandparentCheckpoint: undefined }); - const result = await computePipelinedParentFeeHeader({ - checkpointNumber: pipelinedCheckpointNumber, - proposedCheckpointData: pendingData, - rollup: publisher.rollupContract, - log: createLogger('test'), - }); - expect(result).toBeUndefined(); + await expect( + computePipelinedParentFeeHeader({ + checkpointNumber: pipelinedCheckpointNumber, + proposedCheckpointData: pendingData, + rollup: publisher.rollupContract, + log: createLogger('test'), + }), + ).rejects.toThrow(/Grandparent checkpoint or feeHeader missing/); }); - it('returns undefined when grandparent checkpoint has no feeHeader', async () => { + it('throws when grandparent checkpoint has no feeHeader', async () => { mockRollup({ grandparentCheckpoint: { feeHeader: undefined } }); - const result = await computePipelinedParentFeeHeader({ - checkpointNumber: pipelinedCheckpointNumber, - proposedCheckpointData: pendingData, - rollup: publisher.rollupContract, - log: createLogger('test'), - }); - expect(result).toBeUndefined(); + await expect( + computePipelinedParentFeeHeader({ + checkpointNumber: pipelinedCheckpointNumber, + proposedCheckpointData: pendingData, + rollup: publisher.rollupContract, + log: createLogger('test'), + }), + ).rejects.toThrow(/Grandparent checkpoint or feeHeader missing/); }); - it('returns undefined when rollup calls throw', async () => { + it('propagates errors from rollup calls', async () => { jest.spyOn(publisher.rollupContract, 'getCheckpoint').mockRejectedValue(new Error('rpc error')); - const result = await computePipelinedParentFeeHeader({ - checkpointNumber: pipelinedCheckpointNumber, - proposedCheckpointData: pendingData, - rollup: publisher.rollupContract, - log: createLogger('test'), - }); - expect(result).toBeUndefined(); + await expect( + computePipelinedParentFeeHeader({ + checkpointNumber: pipelinedCheckpointNumber, + proposedCheckpointData: pendingData, + rollup: publisher.rollupContract, + log: createLogger('test'), + }), + ).rejects.toThrow(/rpc error/); }); }); - describe('buildPipelinedParentSimulationOverridesPlan', () => { + describe('buildCheckpointSimulationOverridesPlan', () => { const checkpointNumberUnderTest = CheckpointNumber(2); - it('sets pending override for the parent checkpoint when pipelining is enabled', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ - checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, - rollup: publisher.rollupContract, - signatureContext, - log: createLogger('test'), - pipeliningEnabled: true, - }); - expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); - expect(plan?.chainTipsOverride?.proven).toBeUndefined(); - }); + const grandparentFeeHeader: FeeHeader = { + manaUsed: 3000n, + excessMana: 1000n, + ethPerFeeAsset: 500n, + congestionCost: 50n, + proverCost: 10n, + }; - it('returns undefined when pipelining off and no prunePending', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ - checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, - rollup: publisher.rollupContract, - signatureContext, - log: createLogger('test'), - pipeliningEnabled: false, - }); - expect(plan).toBeUndefined(); - }); + function mockGrandparentFeeHeader() { + jest + .spyOn(publisher.rollupContract, 'getCheckpoint') + .mockResolvedValue({ feeHeader: grandparentFeeHeader } as any); + jest.spyOn(publisher.rollupContract, 'getManaTarget').mockResolvedValue(10_000n); + } - it('returns plan with proven-only override when pipelining off and prunePending is set', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ - checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, - rollup: publisher.rollupContract, - signatureContext, - log: createLogger('test'), - pipeliningEnabled: false, - prunePending: { provenOverride: CheckpointNumber(0) }, - }); - expect(plan?.chainTipsOverride?.pending).toBeUndefined(); - expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(0)); - }); + function makeProposedParent(checkpointNumber: CheckpointNumber): ProposedCheckpointData { + return { + checkpointNumber, + header: CheckpointHeader.empty(), + archive: new AppendOnlyTreeSnapshot(Fr.random(), 1), + checkpointOutHash: Fr.random(), + startBlock: BlockNumber(1), + blockCount: 1, + totalManaUsed: 5000n, + feeAssetPriceModifier: 100n, + }; + } - it('attaches both parent and proven overrides when pipelining on and prunePending is set', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ + it('pins both pending and proven to the snapshot when no proposed/invalidate input is provided', async () => { + const plan = await buildCheckpointSimulationOverridesPlan({ checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, + checkpointedCheckpointNumber: CheckpointNumber(4), rollup: publisher.rollupContract, signatureContext, log: createLogger('test'), - pipeliningEnabled: true, - prunePending: { provenOverride: CheckpointNumber(0) }, }); - expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); - expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(0)); + expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(4)); + expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(4)); + expect(plan?.pendingCheckpointState).toBeUndefined(); }); - it('populates the per-checkpoint state from proposedCheckpointData when pipelining is enabled', async () => { - const proposedHeader = CheckpointHeader.empty({ slotNumber: SlotNumber(123) }); - const proposedArchive = new AppendOnlyTreeSnapshot(Fr.random(), 1); - const proposedOutHash = Fr.random(); - const proposedFeeHeader: FeeHeader = { - manaUsed: 3000n, - excessMana: 1000n, - ethPerFeeAsset: 500n, - congestionCost: 50n, - proverCost: 10n, - }; - jest.spyOn(publisher.rollupContract, 'getCheckpoint').mockResolvedValue({ feeHeader: proposedFeeHeader } as any); - jest.spyOn(publisher.rollupContract, 'getManaTarget').mockResolvedValue(10_000n); - - const proposedData: ProposedCheckpointData = { - checkpointNumber: CheckpointNumber(1), - header: proposedHeader, - archive: proposedArchive, - checkpointOutHash: proposedOutHash, - startBlock: BlockNumber(1), - blockCount: 1, - totalManaUsed: 5000n, - feeAssetPriceModifier: 100n, - }; + it('overrides the full pending checkpoint cell from a pipelined parent', async () => { + mockGrandparentFeeHeader(); + const proposedData = makeProposedParent(CheckpointNumber(1)); - const plan = await buildPipelinedParentSimulationOverridesPlan({ - checkpointNumber: CheckpointNumber(2), + const plan = await buildCheckpointSimulationOverridesPlan({ + checkpointNumber: checkpointNumberUnderTest, proposedCheckpointData: proposedData, + checkpointedCheckpointNumber: CheckpointNumber(0), rollup: publisher.rollupContract, signatureContext, log: createLogger('test'), - pipeliningEnabled: true, }); expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); - expect(plan?.pendingCheckpointState?.archive).toEqual(proposedArchive.root); - expect(plan?.pendingCheckpointState?.headerHash).toEqual(proposedHeader.hash()); - expect(plan?.pendingCheckpointState?.outHash).toEqual(proposedOutHash); - expect(plan?.pendingCheckpointState?.slotNumber).toEqual(SlotNumber(123)); + expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(1)); + expect(plan?.pendingCheckpointState?.archive).toEqual(proposedData.archive.root); + expect(plan?.pendingCheckpointState?.slotNumber).toEqual(proposedData.header.slotNumber); + expect(plan?.pendingCheckpointState?.headerHash).toEqual(proposedData.header.hash()); + expect(plan?.pendingCheckpointState?.outHash).toEqual(proposedData.checkpointOutHash); expect(plan?.pendingCheckpointState?.payloadDigest).toBeDefined(); expect(plan?.pendingCheckpointState?.feeHeader).toBeDefined(); }); - it('omits per-checkpoint state when proposedCheckpointData is undefined', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ + it('throws when the pipelined parent does not match the expected parent checkpoint', async () => { + const proposedData = makeProposedParent(CheckpointNumber(5)); + + await expect( + buildCheckpointSimulationOverridesPlan({ + checkpointNumber: checkpointNumberUnderTest, + proposedCheckpointData: proposedData, + checkpointedCheckpointNumber: CheckpointNumber(0), + rollup: publisher.rollupContract, + signatureContext, + log: createLogger('test'), + }), + ).rejects.toThrow(/does not match expected parent/); + }); + + it('throws when both proposedCheckpointData and invalidateToPendingCheckpointNumber are provided', async () => { + const proposedData = makeProposedParent(CheckpointNumber(1)); + + await expect( + buildCheckpointSimulationOverridesPlan({ + checkpointNumber: checkpointNumberUnderTest, + proposedCheckpointData: proposedData, + invalidateToPendingCheckpointNumber: CheckpointNumber(0), + checkpointedCheckpointNumber: CheckpointNumber(0), + rollup: publisher.rollupContract, + signatureContext, + log: createLogger('test'), + }), + ).rejects.toThrow(/mutually exclusive/); + }); + + it('sets pending and proven from an invalidation rollback without archive/fee overrides', async () => { + const plan = await buildCheckpointSimulationOverridesPlan({ checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, + invalidateToPendingCheckpointNumber: CheckpointNumber(0), + checkpointedCheckpointNumber: CheckpointNumber(2), rollup: publisher.rollupContract, signatureContext, log: createLogger('test'), - pipeliningEnabled: true, }); - expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); + expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(0)); + expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(0)); expect(plan?.pendingCheckpointState).toBeUndefined(); }); }); diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts index de0d8138b7c2..23ed57fb1e9a 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts @@ -301,6 +301,7 @@ describe('CheckpointProposalJob Timing Tests', () => { epoch, checkpointNumber, BlockNumber.ZERO, + CheckpointNumber(checkpointNumber - 1), proposer, publisher, attestorAddress, @@ -405,7 +406,7 @@ describe('CheckpointProposalJob Timing Tests', () => { publisher.enqueueGovernanceCastSignal.mockResolvedValue(true); publisher.enqueueSlashingActions.mockResolvedValue(true); publisher.sendRequestsAt.mockResolvedValue({ - result: { receipt: { status: 'success' } as any, errorMsg: undefined }, + result: { receipt: { status: 'success' } as any }, successfulActions: ['propose'], failedActions: [], sentActions: ['propose'], @@ -1047,6 +1048,7 @@ describe('CheckpointProposalJob Timing Tests', () => { epoch, checkpointNumber, BlockNumber.ZERO, + CheckpointNumber(checkpointNumber - 1), proposer, publisher, attestorAddress, diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts index 6c8af0a66a07..209e04b4856b 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts @@ -66,10 +66,7 @@ import { DutyAlreadySignedError, SlashingProtectionError } from '@aztec/validato import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js'; import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js'; -import { - buildPipelinedParentSimulationOverridesPlan, - buildSubmissionSimulationOverridesPlan, -} from './chain_state_overrides.js'; +import { buildCheckpointSimulationOverridesPlan } from './chain_state_overrides.js'; import type { CheckpointProposalJobMetricsRecorder } from './checkpoint_proposal_job_metrics.js'; import { CheckpointVoter } from './checkpoint_voter.js'; import { SequencerInterruptedError } from './errors.js'; @@ -110,11 +107,12 @@ export class CheckpointProposalJob implements Traceable { private pendingL1Submission: Promise | undefined; /** - * Build-time chain state overrides used both during build (globals + invariant checks) and - * later for enqueue-time submission validation. May carry the pipelined parent override, the - * pretend-proof-landed (`proven`) override at an epoch boundary, or both. + * Chain state overrides built once per slot in proposeCheckpoint after the checkpoint is + * complete. Carries the pending parent override (archive + slot + fee header) for pipelining, + * or the invalidation pending override when rolling back. Consumed by + * publisher.validateBlockHeader before broadcast. */ - private pipelinedParentSimulationOverridesPlan?: SimulationOverridesPlan; + private checkpointSimulationOverridesPlan?: SimulationOverridesPlan; private getSignatureContext(): CoordinationSignatureContext { return this.signatureContext; @@ -126,6 +124,7 @@ export class CheckpointProposalJob implements Traceable { private readonly targetEpoch: EpochNumber, private readonly checkpointNumber: CheckpointNumber, private readonly syncedToBlockNumber: BlockNumber, + private readonly checkpointedCheckpointNumber: CheckpointNumber, // TODO(palla/mbps): Can we remove the proposer in favor of attestorAddress? Need to check fisherman-node flows. private readonly proposer: EthAddress | undefined, private readonly publisher: SequencerPublisher, @@ -153,7 +152,6 @@ export class CheckpointProposalJob implements Traceable { public readonly tracer: Tracer, bindings?: LoggerBindings, private readonly proposedCheckpointData?: ProposedCheckpointData, - private readonly prunePending?: { provenOverride: CheckpointNumber }, ) { this.log = createLogger('sequencer:checkpoint-proposal', { ...bindings, @@ -215,11 +213,7 @@ export class CheckpointProposalJob implements Traceable { // signature verification to fail silently inside Multicall3. Delay submission to the // start of `targetSlot` so the tx mines in the slot the vote was signed for. if (!this.config.fishermanMode) { - const isPipelining = this.epochCache.isProposerPipeliningEnabled(); - const submitAfter = isPipelining - ? new Date(Number(getTimestampForSlot(this.targetSlot, this.l1Constants)) * 1000) - : this.dateProvider.nowAsDate(); - this.pendingL1Submission = this.publisher.sendRequestsAt(submitAfter).then(() => {}); + this.pendingL1Submission = this.publisher.sendRequestsAt(this.targetSlot).then(() => {}); } return undefined; } @@ -278,12 +272,7 @@ export class CheckpointProposalJob implements Traceable { } // Send whatever was enqueued: votes + (propose | invalidation | nothing). - // Compute the earliest time to submit: pipeline slot start when pipelining, now otherwise. - const submitAfter = isPipelining - ? new Date(Number(getTimestampForSlot(this.targetSlot, this.l1Constants)) * 1000) - : new Date(this.dateProvider.now()); - - const l1Response = await this.publisher.sendRequestsAt(submitAfter); + const l1Response = await this.publisher.sendRequestsAt(this.targetSlot); const proposedAction = l1Response?.successfulActions.find(a => a === 'propose'); if (proposedAction) { this.logCheckpointEvent('published', `Checkpoint published for slot ${this.targetSlot}`, { @@ -363,25 +352,8 @@ export class CheckpointProposalJob implements Traceable { } } - const isPipelining = this.epochCache.isProposerPipeliningEnabled(); - const enqueueSimulationOverridesPlan = buildSubmissionSimulationOverridesPlan({ - pipelinedParentPlan: this.pipelinedParentSimulationOverridesPlan, - invalidateToPendingCheckpointNumber: this.invalidateCheckpoint?.forcePendingCheckpointNumber, - lastArchiveRoot: checkpoint.header.lastArchiveRoot, - pipeliningEnabled: isPipelining, - }); - - const preCheckSimulationOverridesPlan = buildSubmissionSimulationOverridesPlan({ - pipelinedParentPlan: undefined, - invalidateToPendingCheckpointNumber: this.invalidateCheckpoint?.forcePendingCheckpointNumber, - lastArchiveRoot: checkpoint.header.lastArchiveRoot, - pipeliningEnabled: isPipelining, - }); - await this.publisher.enqueueProposeCheckpoint(checkpoint, attestations, attestationsSignature, { txTimeoutAt, - simulationOverridesPlan: enqueueSimulationOverridesPlan, - preCheckSimulationOverridesPlan, }); } @@ -563,25 +535,26 @@ export class CheckpointProposalJob implements Traceable { this.publisher.enqueueInvalidateCheckpoint(this.invalidateCheckpoint); } - // Create checkpoint builder for the slot. - // When pipelining, force the proposed checkpoint number and fee header to our parent so the - // fee computation sees the same chain tip that L1 will see once the previous pipelined checkpoint lands. + // Build the simulation plan for this slot. When pipelining, this overrides L1's view of + // pending/archive/fee-header to "as if the proposed parent had landed", so both the + // mana-min-fee simulation (in the globals builder) and the pre-broadcast + // validateBlockHeader see the chain tip the eventual L1 send will see. const isPipelining = this.epochCache.isProposerPipeliningEnabled(); - this.pipelinedParentSimulationOverridesPlan = await buildPipelinedParentSimulationOverridesPlan({ + this.checkpointSimulationOverridesPlan = await buildCheckpointSimulationOverridesPlan({ checkpointNumber: this.checkpointNumber, - proposedCheckpointData: this.proposedCheckpointData, + proposedCheckpointData: isPipelining ? this.proposedCheckpointData : undefined, + invalidateToPendingCheckpointNumber: this.invalidateCheckpoint?.forcePendingCheckpointNumber, + checkpointedCheckpointNumber: this.checkpointedCheckpointNumber, rollup: this.publisher.rollupContract, signatureContext: this.signatureContext, log: this.log, - pipeliningEnabled: isPipelining, - prunePending: this.prunePending, }); const checkpointGlobalVariables = await this.globalsBuilder.buildCheckpointGlobalVariables( coinbase, feeRecipient, this.targetSlot, - this.pipelinedParentSimulationOverridesPlan, + this.checkpointSimulationOverridesPlan, ); // Collect L1 to L2 messages for the checkpoint and compute their hash @@ -606,7 +579,7 @@ export class CheckpointProposalJob implements Traceable { // Anchor the modifier to the predicted parent fee header: L1 will apply it against // that, not against the latest published checkpoint (which lags by one under pipelining). const predictedParentEthPerFeeAssetE12 = - this.pipelinedParentSimulationOverridesPlan?.pendingCheckpointState?.feeHeader?.ethPerFeeAsset; + this.checkpointSimulationOverridesPlan?.pendingCheckpointState?.feeHeader?.ethPerFeeAsset; const feeAssetPriceModifier = await this.publisher.getFeeAssetPriceModifier(predictedParentEthPerFeeAssetE12); // Create a long-lived forked world state for the checkpoint builder @@ -631,7 +604,8 @@ export class CheckpointProposalJob implements Traceable { const checkpointProposalOptions: CheckpointProposalOptions = { publishFullTxs: !!this.config.publishTxsWithProposals, - broadcastInvalidCheckpointProposal: this.config.broadcastInvalidBlockProposal, + broadcastInvalidCheckpointProposal: + this.config.broadcastInvalidCheckpointProposalOnly || this.config.broadcastInvalidBlockProposal, }; let blocksInCheckpoint: L2Block[] = []; @@ -763,6 +737,25 @@ export class CheckpointProposalJob implements Traceable { return { checkpoint, proposal: undefined!, blockProposedAt: this.dateProvider.now() }; } + // Validate the header against L1 state before broadcasting. + // If this fails the slot is aborted before any gossip work; state drift between here + // and the eventual L1 send is caught by the bundle simulate at send time. + try { + await this.publisher.validateBlockHeader(checkpoint.header, this.checkpointSimulationOverridesPlan); + } catch (err) { + this.log.error(`Pre-broadcast header validation failed for slot ${this.targetSlot}; aborting`, err, { + slot: this.targetSlot, + checkpointNumber: this.checkpointNumber, + }); + this.metrics.recordCheckpointProposalFailed('header_validation_failed'); + this.eventEmitter.emit('header-validation-failed', { + slot: this.targetSlot, + checkpointNumber: this.checkpointNumber, + reason: err instanceof Error ? err.message : String(err), + }); + return undefined; + } + // Create the checkpoint proposal and broadcast it const proposal = await this.validatorClient.createCheckpointProposal( checkpoint.header, @@ -887,7 +880,12 @@ export class CheckpointProposalJob implements Traceable { usedTxs.forEach(tx => txHashesAlreadyIncluded.add(tx.txHash.toString())); // Sign the block proposal. This will throw if HA signing fails. - const proposal = await this.createBlockProposal(block, inHash, usedTxs, blockProposalOptions); + const proposal = await this.createBlockProposal(block, inHash, usedTxs, { + ...blockProposalOptions, + broadcastInvalidBlockProposal: + blockProposalOptions.broadcastInvalidBlockProposal || + block.indexWithinCheckpoint === this.config.invalidBlockProposalIndexWithinCheckpoint, + }); // Sync the proposed block to the archiver to make it available, only after we've managed to sign the proposal, // so we avoid polluting our archive with a block that would fail. @@ -1107,6 +1105,9 @@ export class CheckpointProposalJob implements Traceable { // `buildSlot` is the wall-clock slot during which the block was actually built. this.eventEmitter.emit('block-proposed', { blockNumber: block.number, + blockHash, + checkpointNumber: this.checkpointNumber, + indexWithinCheckpoint: block.indexWithinCheckpoint, slot: this.targetSlot, buildSlot: this.slotNow, }); diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_voter.ha.integration.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_voter.ha.integration.test.ts index 3a641f2bb8b3..d60279e32230 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_voter.ha.integration.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_voter.ha.integration.test.ts @@ -138,12 +138,16 @@ describe('CheckpointVoter HA Integration', () => { txUtils.client = { account: validatorAccount, getCode: () => Promise.resolve('0x1234' as `0x${string}`), + getGasPrice: () => Promise.resolve(1n), + getBlock: () => Promise.resolve({ timestamp: 0n } as any), } as any; txUtils.getSenderAddress.mockReturnValue(EthAddress.fromString(validatorAccount.address)); + txUtils.getSenderBalance.mockResolvedValue(10_000_000_000_000_000_000n); // 10 ETH txUtils.simulate.mockResolvedValue({ gasUsed: 100000n, result: '0x', }); + (txUtils as any).bumpGasLimit = (val: bigint) => val + (val * 20n) / 100n; // Mock getCode to return non-empty bytecode for governance/slashing payloads txUtils.getCode.mockResolvedValue('0x1234' as any); return txUtils; @@ -690,7 +694,8 @@ describe('CheckpointVoter HA Integration', () => { status: 'success', logs: [], } as any, - errorMsg: undefined, + stats: undefined, + multicallData: '0x', }); // Each node enqueues their respective votes diff --git a/yarn-project/sequencer-client/src/sequencer/events.ts b/yarn-project/sequencer-client/src/sequencer/events.ts index a0fa73c011e4..9d8aa54df437 100644 --- a/yarn-project/sequencer-client/src/sequencer/events.ts +++ b/yarn-project/sequencer-client/src/sequencer/events.ts @@ -1,4 +1,5 @@ -import type { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import type { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; +import type { BlockHash } from '@aztec/stdlib/block'; import type { Action } from '../publisher/sequencer-publisher.js'; import type { SequencerState } from './utils.js'; @@ -18,10 +19,14 @@ export type SequencerEvents = { * * - `hadProposedParent` indicates whether the build saw a proposed (pipelined) parent * checkpoint that hasn't landed on L1 yet. - * - `provenOverride` is the assumed proven checkpoint number when the proven-override - * for a pending prune was applied; `undefined` when no override was applied. - * - `simulatedPending` is the pending checkpoint passed to L1 simulation (when - * pipelining or invalidating; undefined otherwise). + * - `provenOverride` is the assumed proven checkpoint number pinned for the L1 + * simulation. The plan always pins both chain tips to short-circuit `canPruneAtTime`, + * so this is populated whenever a simulation plan was built — the value either + * matches the on-chain proven snapshot (defensive pin) or the assumed-proven + * checkpoint when building optimistically across a pruning boundary. + * - `simulatedPending` is the pending checkpoint passed to L1 simulation. The plan + * always pins both chain tips to short-circuit `canPruneAtTime`, so this reflects + * either the pipelined/invalidated tip or the on-chain pending snapshot. */ ['preparing-checkpoint']: (args: { targetSlot: SlotNumber; @@ -33,8 +38,26 @@ export type SequencerEvents = { ['proposer-rollup-check-failed']: (args: { reason: string; slot: SlotNumber }) => void; ['block-tx-count-check-failed']: (args: { minTxs: number; availableTxs: number; slot: SlotNumber }) => void; ['block-build-failed']: (args: { reason: string; slot: SlotNumber }) => void; - ['block-proposed']: (args: { blockNumber: BlockNumber; slot: SlotNumber; buildSlot: SlotNumber }) => void; + ['block-proposed']: (args: { + blockNumber: BlockNumber; + blockHash: BlockHash; + checkpointNumber: CheckpointNumber; + indexWithinCheckpoint: IndexWithinCheckpoint; + slot: SlotNumber; + buildSlot: SlotNumber; + }) => void; ['checkpoint-empty']: (args: { slot: SlotNumber }) => void; + /** + * Emitted when the proposer's pre-broadcast `validateBlockHeader` simulation fails. This is a + * last-chance check before we gossip a checkpoint proposal: a failure here means the header + * would not be accepted by L1 (e.g. archive mismatch, stale chain tip, or some other state + * drift between when we built the checkpoint and when we are about to broadcast it). + */ + ['header-validation-failed']: (args: { + slot: SlotNumber; + checkpointNumber: CheckpointNumber; + reason: string; + }) => void; ['checkpoint-publish-failed']: (args: { slot: SlotNumber; successfulActions?: Action[]; diff --git a/yarn-project/sequencer-client/src/sequencer/index.ts b/yarn-project/sequencer-client/src/sequencer/index.ts index 9f9721707764..4db5f7152b2a 100644 --- a/yarn-project/sequencer-client/src/sequencer/index.ts +++ b/yarn-project/sequencer-client/src/sequencer/index.ts @@ -1,3 +1,5 @@ +export * from './automine/automine_factory.js'; +export * from './automine/automine_sequencer.js'; export * from './checkpoint_proposal_job.js'; export * from './checkpoint_voter.js'; export * from './config.js'; diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index b2f0828f5341..d17475a5fee7 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -222,7 +222,7 @@ describe('sequencer', () => { publisher.enqueueGovernanceCastSignal.mockResolvedValue(true); publisher.enqueueSlashingActions.mockResolvedValue(true); publisher.sendRequestsAt.mockResolvedValue({ - result: { receipt: { status: 'success' } as any, errorMsg: undefined }, + result: { receipt: { status: 'success' } as any }, successfulActions: ['propose'], failedActions: [], sentActions: ['propose'], @@ -242,6 +242,11 @@ describe('sequencer', () => { rollupContract = mockDeep(); rollupContract.isEscapeHatchOpen.mockResolvedValue(false); + // Default rollup reads used by pipelined fee-header derivation. + rollupContract.getCheckpoint.mockResolvedValue({ + feeHeader: { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 1n, congestionCost: 0n, proverCost: 0n }, + } as any); + rollupContract.getManaTarget.mockResolvedValue(10_000n); globalVariableBuilder = mock(); globalVariableBuilder.buildGlobalVariables.mockResolvedValue(globalVariables); @@ -563,7 +568,7 @@ describe('sequencer', () => { pub.enqueueGovernanceCastSignal.mockResolvedValue(true); pub.enqueueSlashingActions.mockResolvedValue(true); pub.sendRequestsAt.mockResolvedValue({ - result: { receipt: { status: 'success' } as any, errorMsg: undefined }, + result: { receipt: { status: 'success' } as any }, successfulActions: ['propose'], failedActions: [], sentActions: ['propose'], @@ -671,7 +676,10 @@ describe('sequencer', () => { expect(slasherClient.getProposerActions).toHaveBeenCalledWith(SlotNumber(1)); expect(publisher.enqueueSlashingActions).toHaveBeenCalled(); expect(publisher.enqueueGovernanceCastSignal).toHaveBeenCalled(); - expect(publisher.sendRequests).toHaveBeenCalled(); + // Submission goes through sendRequestsAt so the bundle simulate's block.timestamp + // override matches the slot the EIP-712 signatures were generated for. + expect(publisher.sendRequestsAt).toHaveBeenCalled(); + expect(publisher.sendRequests).not.toHaveBeenCalled(); // But checkpoint proposal must not start expect(publisher.enqueueProposeCheckpoint).not.toHaveBeenCalled(); @@ -694,16 +702,16 @@ describe('sequencer', () => { await sequencer.work(); expect(publisher.enqueueSlashingActions).toHaveBeenCalledTimes(1); - expect(publisher.sendRequests).toHaveBeenCalledTimes(1); + expect(publisher.sendRequestsAt).toHaveBeenCalledTimes(1); publisher.enqueueSlashingActions.mockClear(); - publisher.sendRequests.mockClear(); + publisher.sendRequestsAt.mockClear(); slasherClient.getProposerActions.mockClear(); await sequencer.work(); expect(slasherClient.getProposerActions).not.toHaveBeenCalled(); expect(publisher.enqueueSlashingActions).not.toHaveBeenCalled(); - expect(publisher.sendRequests).not.toHaveBeenCalled(); + expect(publisher.sendRequestsAt).not.toHaveBeenCalled(); }); }); @@ -757,7 +765,8 @@ describe('sequencer', () => { expect.any(EthAddress), expect.any(Function), ); - expect(publisher.sendRequests).toHaveBeenCalled(); + // Votes are submitted via sendRequestsAt (fire-and-forget, scheduled at target slot start). + expect(publisher.sendRequestsAt).toHaveBeenCalled(); }); it('should not vote when sync fails and within time limit', async () => { @@ -817,18 +826,19 @@ describe('sequencer', () => { // First attempt should succeed await sequencer.work(); expect(publisher.enqueueSlashingActions).toHaveBeenCalledTimes(1); - expect(publisher.sendRequests).toHaveBeenCalledTimes(1); + // Votes are submitted via sendRequestsAt (fire-and-forget, scheduled at target slot start). + expect(publisher.sendRequestsAt).toHaveBeenCalledTimes(1); // Reset mocks publisher.enqueueSlashingActions.mockClear(); - publisher.sendRequests.mockClear(); + publisher.sendRequestsAt.mockClear(); slasherClient.getProposerActions.mockClear(); // Second attempt in the same slot should be skipped await sequencer.work(); expect(slasherClient.getProposerActions).not.toHaveBeenCalled(); expect(publisher.enqueueSlashingActions).not.toHaveBeenCalled(); - expect(publisher.sendRequests).not.toHaveBeenCalled(); + expect(publisher.sendRequestsAt).not.toHaveBeenCalled(); }); }); @@ -1114,7 +1124,7 @@ describe('sequencer', () => { const simulationOverridesPlan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; expect(simulationOverridesPlan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); - expect(simulationOverridesPlan?.pendingCheckpointState?.archive).toEqual(expect.anything()); + // The archive root is passed directly as the first arg to canProposeAt (not inside the plan). }); it('skips proposal when checkpoint exceeds pipeline depth', async () => { @@ -1177,15 +1187,19 @@ describe('sequencer', () => { expect(publisher.canProposeAt).not.toHaveBeenCalled(); }); - it('calls L1 check without archive override when no proposed checkpoint', async () => { + it('pins both chain tips to the on-chain pending snapshot when no proposed checkpoint applies', async () => { await setupSingleTxBlock(); await sequencer.work(); - expect(publisher.canProposeAt.mock.calls.at(-1)?.[2]).toBeUndefined(); + // The default `getL2Tips` mock has checkpointed.checkpoint.number == CheckpointNumber.ZERO. + const plan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; + expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber.ZERO); + expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber.ZERO); + expect(plan?.pendingCheckpointState).toBeUndefined(); }); - it('calls L1 check without overrides when not pipelining', async () => { + it('pins both chain tips to the on-chain pending snapshot when not pipelining', async () => { await setupSingleTxBlock(); // Override back to non-pipelining @@ -1204,23 +1218,13 @@ describe('sequencer', () => { await sequencer.work(); - expect(publisher.canProposeAt.mock.calls.at(-1)?.[2]).toBeUndefined(); - }); - - it('attaches proven override equal to real pending when isPruneDueAtSlot returns true', async () => { - await setupSingleTxBlock(); - - // No proposed checkpoint, so we exercise the standalone proven override path. - // The default `getL2Tips` mock has checkpointed.checkpoint.number == CheckpointNumber.ZERO. - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(true); - - await sequencer.work(); - const plan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; + expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber.ZERO); expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber.ZERO); + expect(plan?.pendingCheckpointState).toBeUndefined(); }); - it('uses the simulated pending as the proven override when the caller overrides pending', async () => { + it('mirrors pending onto proven when the caller overrides pending via pipelining', async () => { await setupSingleTxBlock(); // Set up a pipelined parent (pending override = parentCheckpointNumber = 1). @@ -1278,9 +1282,6 @@ describe('sequencer', () => { feeAssetPriceModifier: 0n, } satisfies ProposedCheckpointData); - // The sequencer sets proven == simulated pending so canPruneAtTime short-circuits to false. - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(true); - await sequencer.work(); const plan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; @@ -1288,52 +1289,25 @@ describe('sequencer', () => { expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(1)); }); - it('does not attach proven override when isPruneDueAtSlot returns false', async () => { - await setupSingleTxBlock(); - - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(false); - - await sequencer.work(); - - const plan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; - expect(plan?.chainTipsOverride?.proven).toBeUndefined(); - }); - - it('emits preparing-checkpoint with provenOverride when prune is due', async () => { + it('emits preparing-checkpoint with snapshot-pinned tips when no override applies', async () => { await setupSingleTxBlock(); - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(true); - const events: any[] = []; sequencer.on('preparing-checkpoint', args => events.push(args)); await sequencer.work(); expect(events).toHaveLength(1); + // With no pipelined or invalidation override, both `pending` and `proven` are pinned to the + // on-chain pending snapshot (checkpointedCheckpointNumber) so `canPruneAtTime` short-circuits + // and a live re-read inside `makeChainTipsOverride` can't reintroduce a phantom prune. + // `provenOverride` mirrors the pinned proven tip whenever a plan was built. expect(events[0]).toEqual({ targetSlot: SlotNumber(2), checkpointNumber: expect.anything(), hadProposedParent: false, provenOverride: CheckpointNumber.ZERO, - simulatedPending: undefined, - }); - }); - - it('emits preparing-checkpoint without provenOverride when no prune is due', async () => { - await setupSingleTxBlock(); - - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(false); - - const events: any[] = []; - sequencer.on('preparing-checkpoint', args => events.push(args)); - - await sequencer.work(); - - expect(events).toHaveLength(1); - expect(events[0]).toMatchObject({ - targetSlot: SlotNumber(2), - hadProposedParent: false, - provenOverride: undefined, + simulatedPending: CheckpointNumber.ZERO, }); }); }); diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index e49c922f378c..6dda210dad1a 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -1,6 +1,6 @@ import { getKzg } from '@aztec/blob-lib'; import type { EpochCache } from '@aztec/epoch-cache'; -import { NoCommitteeError, type RollupContract, SimulationOverridesBuilder } from '@aztec/ethereum/contracts'; +import { NoCommitteeError, type RollupContract } from '@aztec/ethereum/contracts'; import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { merge, omit, pick } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -14,7 +14,7 @@ import type { SlasherClientInterface } from '@aztec/slasher'; import type { BlockData, L2BlockSink, L2BlockSource, ValidateCheckpointResult } from '@aztec/stdlib/block'; import type { Checkpoint, ProposedCheckpointData } from '@aztec/stdlib/checkpoint'; import type { ChainConfig } from '@aztec/stdlib/config'; -import { getSlotStartBuildTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; +import { getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers'; import { type ResolvedSequencerConfig, type SequencerConfig, @@ -33,7 +33,7 @@ import { DefaultSequencerConfig } from '../config.js'; import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js'; import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js'; import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js'; -import { buildPipelinedParentSimulationOverridesPlan } from './chain_state_overrides.js'; +import { buildCheckpointSimulationOverridesPlan } from './chain_state_overrides.js'; import { CheckpointProposalJob } from './checkpoint_proposal_job.js'; import { CheckpointProposalJobMetrics } from './checkpoint_proposal_job_metrics.js'; import { CheckpointVoter } from './checkpoint_voter.js'; @@ -312,7 +312,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter TypedEventEmitter TypedEventEmitter TypedEventEmitter TypedEventEmitter TypedEventEmitter TypedEventEmitter { - this.log.error(`Failed to publish votes despite sync failure for slot ${slot}`, err, { slot }); - }); - } else { - await publisher.sendRequests(); - } + void publisher.sendRequestsAt(targetSlot).catch(err => { + this.log.error(`Failed to publish votes despite sync failure for slot ${slot}`, err, { slot }); + }); } /** @@ -892,9 +883,10 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter ({ [Attributes.SLOT_NUMBER]: slot })) protected async tryVoteWhenEscapeHatchOpen(args: { slot: SlotNumber; + targetSlot: SlotNumber; proposer: EthAddress | undefined; }): Promise { - const { slot, proposer } = args; + const { slot, targetSlot, proposer } = args; // Prevent duplicate attempts in the same slot if (this.lastSlotForFallbackVote === slot) { @@ -907,10 +899,19 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter TypedEventEmitter { + this.log.error(`Failed to publish escape-hatch votes for slot ${slot}`, err, { slot, targetSlot }); + }); } /** diff --git a/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md b/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md index f736c83c867d..6519f4aab32f 100644 --- a/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md +++ b/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md @@ -250,9 +250,9 @@ Click on an opcode name to view its detailed documentation. * **[🔗ECADD](opcodes/ecadd.md)**: Grumpkin elliptic curve addition * Opcode `0x42` ```javascript - M[dstOffset:dstOffset+3] = grumpkinAdd( - /*point1=*/{x: M[p1XOffset], y: M[p1YOffset], isInfinite: M[p1IsInfiniteOffset]}, - /*point2=*/{x: M[p2XOffset], y: M[p2YOffset], isInfinite: M[p2IsInfiniteOffset]} + M[dstOffset:dstOffset+1] = grumpkinAdd( + /*point1=*/{x: M[p1XOffset], y: M[p1YOffset]}, + /*point2=*/{x: M[p2XOffset], y: M[p2YOffset]} ) ``` * **[🔗TORADIXBE](opcodes/toradixbe.md)**: Convert to radix (big-endian) diff --git a/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md b/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md index 7e570e0eb2de..7cc324facb14 100644 --- a/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md +++ b/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md @@ -12,7 +12,7 @@ M[dstOffset] = contractInstance.exists ? 1 : 0; M[dstOffset+1] = contractInstanc ## Details -Looks up contract instance by address and retrieves the specified member. This opcode can get contract instance information for any contract address, not just the currently executing one. Returns existence flag (Uint1) and member value (FIELD). If the contract does not exist, the member value is set to 0. Supported enum values: `[DEPLOYER=0, CLASS_ID, INIT_HASH]`. +Looks up contract instance by address and retrieves the specified member. This opcode can get contract instance information for any contract address, not just the currently executing one. Returns existence flag (Uint1) and member value (FIELD). If the contract does not exist, the member value is set to 0. Supported enum values: `[DEPLOYER=0, CLASS_ID, INIT_HASH, IMMUTABLES_HASH]`. ## Contract Classes and Instances @@ -32,6 +32,7 @@ This separation allows for: | **Deployer Address** | The address of the account that deployed this contract instance. | | **Class ID** | The identifier of the contract class that this instance uses for its code. | | **Initialization Hash** | A hash of the constructor arguments used when the contract instance was deployed. | +| **Immutables Hash** | A hash of the immutable storage values declared by a contract instance when it was deployed. | **Example**: To check if a contract at a given `address` is an instance of a known `CLASS_ID`: 1. Use `GETCONTRACTINSTANCE` with the `address` and the `CLASS_ID` member enum. diff --git a/yarn-project/simulator/docs/avm/public-tx-simulation.md b/yarn-project/simulator/docs/avm/public-tx-simulation.md index 54a27fbeafd8..1896a7fff258 100644 --- a/yarn-project/simulator/docs/avm/public-tx-simulation.md +++ b/yarn-project/simulator/docs/avm/public-tx-simulation.md @@ -35,7 +35,7 @@ The app logic phase contains the main application functionality. This is where m - State changes from app logic are rolled back - Side effects from private's revertible portion are also discarded - Teardown still executes -- The transaction appears on-chain with `APP_LOGIC_REVERTED` status +- The transaction appears on-chain with `REVERTED` status ### TEARDOWN Phase (Revertible, Always Runs) diff --git a/yarn-project/simulator/src/public/avm/apps_tests/avm_test.test.ts b/yarn-project/simulator/src/public/avm/apps_tests/avm_test.test.ts index a2961338479e..d61fba0c8f46 100644 --- a/yarn-project/simulator/src/public/avm/apps_tests/avm_test.test.ts +++ b/yarn-project/simulator/src/public/avm/apps_tests/avm_test.test.ts @@ -47,6 +47,19 @@ describe('AVM simulator apps tests: AvmTestContract', () => { const expectContractInstance = instances[1]; const argsField = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + // Pinned grumpkin-Poseidon2 Schnorr signature (mirrors the C++ `pinned_test_vector_large` + // and noir-lang/schnorr v0.4.0's `pinned_vector_large`). Passing these in as calldata + // (rather than baking them into Noir as constants) keeps MSM + Poseidon2 from being folded + // by the Noir compiler. + const schnorrInputs = [ + Fr.fromHexString('0x065812e335a97c2108ea8cf4ccfe2f9dd6b117a0714f5e18461575be93f61da6'), // pubkey.x + Fr.fromHexString('0x1a915003e8ec534f9a15d926a7ded478e178468ccc4f28e236e67450a55ac622'), // pubkey.y + Fr.fromHexString('0xf3bc3b7147acb9c621fd9f72dbf15ffa'), // sig_s.lo + Fr.fromHexString('0x08599f379f0301dfefdbd0272554454d'), // sig_s.hi + Fr.fromHexString('0x97065383ebbbd76620398792bd259bc2'), // sig_e.lo + Fr.fromHexString('0x2ceaee87f45b7a417f0ffb05451a8c92'), // sig_e.hi + Fr.fromHexString('0x0123456789abcdef0fedcba9876543210123456789abcdef0fedcba987654321'), // message + ]; const args = [ argsField, argsU8, @@ -54,6 +67,8 @@ describe('AVM simulator apps tests: AvmTestContract', () => { /*expectedDeployer=*/ expectContractInstance.deployer, /*expectedClassId=*/ expectContractInstance.currentContractClassId, /*expectedInitializationHash=*/ expectContractInstance.initializationHash, + /*expectedImmutablesHash=*/ expectContractInstance.immutablesHash, + /*schnorrInputs=*/ schnorrInputs, /*skip_strictly_limited_side_effects=*/ false, ]; const results = await simTester.simulateCall(sender, /*address=*/ testContractAddress, 'bulk_testing', args); diff --git a/yarn-project/simulator/src/public/avm/avm_simulator.test.ts b/yarn-project/simulator/src/public/avm/avm_simulator.test.ts index a9354bfe30bf..baf7c9685884 100644 --- a/yarn-project/simulator/src/public/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/public/avm/avm_simulator.test.ts @@ -6,7 +6,6 @@ import { pedersenCommit, pedersenHash } from '@aztec/foundation/crypto/pedersen' import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon'; import { sha256 } from '@aztec/foundation/crypto/sha256'; import { Fq, Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import type { Fieldable } from '@aztec/foundation/serialize'; import { AvmGadgetsTestContract } from '@aztec/noir-test-contracts.js/AvmGadgetsTest'; import { AvmTestContract } from '@aztec/noir-test-contracts.js/AvmTest'; @@ -23,7 +22,7 @@ import { siloNoteHash, siloNullifier, } from '@aztec/stdlib/hash'; -import { PublicKeys } from '@aztec/stdlib/keys'; +import { PublicKey, PublicKeys } from '@aztec/stdlib/keys'; import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/stdlib/testing'; import { NativeWorldStateService } from '@aztec/world-state'; @@ -257,10 +256,8 @@ describe('AVM simulator: transpiled Noir contracts', () => { const calldata = new CallDataArray([ new Fr(1), // P1x new Fr(17631683881184975370165255887551781615748388533673675138860n), // P1y - new Fr(0), // P1inf new Fr(1), // P2x new Fr(17631683881184975370165255887551781615748388533673675138860n), // P2y - new Fr(0), // P2inf ]); const context = initContext({ env: initExecutionEnvironment({ calldata }) }); @@ -278,7 +275,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.reverted).toBe(false); const g3 = await Grumpkin.mul(Grumpkin.generator, new Fq(3)); - expect(results.output.readAll()).toEqual([g3.x, g3.y, Fr.ZERO]); + expect(results.output.readAll()).toEqual([g3.x, g3.y]); }); describe('msm', () => { @@ -298,7 +295,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const g3 = await Grumpkin.mul(Grumpkin.generator, new Fq(3)); const g20 = await Grumpkin.mul(Grumpkin.generator, new Fq(20)); const expectedResult = await Grumpkin.add(g3, g20); - expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y, Fr.ZERO]); + expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y]); }); it('with a zero', async () => { @@ -315,7 +312,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.reverted).toBe(false); const expectedResult = await Grumpkin.mul(Grumpkin.generator, new Fq(3)); - expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y, Fr.ZERO]); + expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y]); }); const fqToLimbs = (fq: Fq): [bigint, bigint] => { @@ -340,7 +337,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const g1 = await Grumpkin.mul(Grumpkin.generator, scalar); const g2 = await Grumpkin.mul(Grumpkin.generator, scalar2); const expectedResult = await Grumpkin.add(g1, g2); - expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y, Fr.ZERO]); + expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y]); }); }); @@ -352,11 +349,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(false); - // This doesnt include infinites const expectedResult = (await pedersenCommit([Buffer.from([100]), Buffer.from([1])], 20)).map(f => new Fr(f)); - // TODO: Come back to the handling of infinities when we confirm how they're handled in bb - const isInf = expectedResult[0] === new Fr(0) && expectedResult[1] === new Fr(0); - expectedResult.push(new Fr(isInf)); expect(results.output.readAll()).toEqual(expectedResult); }); @@ -452,7 +445,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { * Can run these as follows to measure sha256 instruction execution counts: * for i in 10 20 30 40 50 60 70 80 90 100 255 256 511 512 2048; do * echo sha-ing $i...; - * LOG_LEVEL=debug yarn test src/avm/avm_simulator.test.ts -t "sha256_hash_$i " &> sha$i.log; + * LOG_LEVEL="debug; info: json-rpc, simulator" yarn test src/avm/avm_simulator.test.ts -t "sha256_hash_$i " &> sha$i.log; * done * for i in 10 20 30 40 50 60 70 80 90 100 255 256 511 512 2048; do * echo sha256 of $i bytes $(grep -Eo 'Executed .* instructions.* Gas' sha$i.log); @@ -914,24 +907,27 @@ describe('AVM simulator: transpiled Noir contracts', () => { const context = createContext(calldata); // Contract instance must match noir const contractInstance = new SerializableContractInstance({ - version: 1 as const, + version: 2 as const, salt: new Fr(0x123), deployer: AztecAddress.fromBigInt(0x456n), currentContractClassId: new Fr(0x789), originalContractClassId: new Fr(0x789), initializationHash: new Fr(0x101112), + immutablesHash: new Fr(0x202221), publicKeys: new PublicKeys( - new Point(new Fr(0x131415), new Fr(0x161718), false), - new Point(new Fr(0x192021), new Fr(0x222324), false), - new Point(new Fr(0x252627), new Fr(0x282930), false), - new Point(new Fr(0x313233), new Fr(0x343536), false), + new Fr(0x131415), + new PublicKey(new Fr(0x192021), new Fr(0x222324)), + new Fr(0x252627), + new Fr(0x313233), ), }); const contractInstanceWithAddress = contractInstance.withAddress(address); - // mock once per enum value (deployer, classId, initializationHash) + // mock once per enum value (deployer, classId, initializationHash, immutablesHash) mockGetContractInstance(contractsDB, contractInstanceWithAddress); mockGetContractInstance(contractsDB, contractInstanceWithAddress); mockGetContractInstance(contractsDB, contractInstanceWithAddress); + mockGetContractInstance(contractsDB, contractInstanceWithAddress); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); diff --git a/yarn-project/simulator/src/public/avm/fixtures/utils.ts b/yarn-project/simulator/src/public/avm/fixtures/utils.ts index b9034b629890..382fdd2a9764 100644 --- a/yarn-project/simulator/src/public/avm/fixtures/utils.ts +++ b/yarn-project/simulator/src/public/avm/fixtures/utils.ts @@ -128,17 +128,20 @@ export async function createContractClassAndInstance( const constructorAbi = getContractFunctionAbi('constructor', contractArtifact); const { publicKeys } = await deriveKeys(new Fr(seed)); const initializationHash = await computeInitializationHash(constructorAbi, constructorArgs); + const immutablesHash = new Fr(seed + 1); const contractInstance = originalContractClassId === undefined ? await makeContractInstanceFromClassId(contractClass.id, seed, { deployer, initializationHash, + immutablesHash, publicKeys, }) : await makeContractInstanceFromClassId(originalContractClassId, seed, { deployer, initializationHash, currentClassId: contractClass.id, + immutablesHash, publicKeys, }); diff --git a/yarn-project/simulator/src/public/avm/opcodes/contract.test.ts b/yarn-project/simulator/src/public/avm/opcodes/contract.test.ts index c13063491558..cc459424acd6 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/contract.test.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/contract.test.ts @@ -16,6 +16,7 @@ describe('Contract opcodes', () => { let deployer: AztecAddress; let contractClassId: Fr; let initializationHash: Fr; + let immutablesHash: Fr; let persistableState: jest.Mocked; let context: AvmContext; @@ -26,6 +27,7 @@ describe('Contract opcodes', () => { deployer = contractInstance.deployer; contractClassId = contractInstance.currentContractClassId; initializationHash = contractInstance.initializationHash; + immutablesHash = contractInstance.immutablesHash; persistableState = mock(); context = initContext({ persistableState }); }); @@ -54,6 +56,7 @@ describe('Contract opcodes', () => { [ContractInstanceMember.DEPLOYER, () => deployer.toField()], [ContractInstanceMember.CLASS_ID, () => contractClassId.toField()], [ContractInstanceMember.INIT_HASH, () => initializationHash.toField()], + [ContractInstanceMember.IMMUTABLES_HASH, () => immutablesHash.toField()], ])('GETCONTRACTINSTANCE member instruction ', (memberEnum: ContractInstanceMember, valueGetter: () => Fr) => { it(`Should read '${ContractInstanceMember[memberEnum]}' correctly`, async () => { const value = valueGetter(); @@ -87,6 +90,7 @@ describe('Contract opcodes', () => { [ContractInstanceMember.DEPLOYER], [ContractInstanceMember.CLASS_ID], [ContractInstanceMember.INIT_HASH], + [ContractInstanceMember.IMMUTABLES_HASH], ])( 'GETCONTRACTINSTANCE member instruction works when contract does not exist', (memberEnum: ContractInstanceMember) => { @@ -124,7 +128,7 @@ describe('Contract opcodes', () => { /*memberEnum=*/ invalidEnum, ); await expect(instruction.execute(context)).rejects.toThrow( - `Invalid GETCONSTRACTINSTANCE member enum ${invalidEnum}`, + `Invalid GETCONTRACTINSTANCE member enum ${invalidEnum}`, ); }); }); diff --git a/yarn-project/simulator/src/public/avm/opcodes/contract.ts b/yarn-project/simulator/src/public/avm/opcodes/contract.ts index 801a894fbd0a..28f7ece9440d 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/contract.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/contract.ts @@ -9,6 +9,7 @@ export enum ContractInstanceMember { DEPLOYER, CLASS_ID, INIT_HASH, + IMMUTABLES_HASH, } export class GetContractInstance extends Instruction { @@ -41,7 +42,7 @@ export class GetContractInstance extends Instruction { ); if (!(this.memberEnum in ContractInstanceMember)) { - throw new InstructionExecutionError(`Invalid GETCONSTRACTINSTANCE member enum ${this.memberEnum}`); + throw new InstructionExecutionError(`Invalid GETCONTRACTINSTANCE member enum ${this.memberEnum}`); } const operands = [this.addressOffset, this.dstOffset]; @@ -64,6 +65,9 @@ export class GetContractInstance extends Instruction { case ContractInstanceMember.INIT_HASH: memberValue = new Field(instance.initializationHash); break; + case ContractInstanceMember.IMMUTABLES_HASH: + memberValue = new Field(instance.immutablesHash); + break; } } diff --git a/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts b/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts index 8e144efaed91..8c12fa4a9039 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts @@ -5,7 +5,7 @@ import { Point } from '@aztec/foundation/curves/grumpkin'; import { beforeEach } from '@jest/globals'; import type { AvmContext } from '../avm_context.js'; -import { Field, Uint1, Uint32 } from '../avm_memory_types.js'; +import { Field, Uint32 } from '../avm_memory_types.js'; import { EcAddPointNotOnCurveError } from '../errors.js'; import { initContext } from '../fixtures/initializers.js'; import { EcAdd } from './ec_add.js'; @@ -24,20 +24,16 @@ describe('EC Instructions', () => { ...Buffer.from('1234', 'hex'), // indirect ...Buffer.from('1235', 'hex'), // p1x ...Buffer.from('1236', 'hex'), // p1y - ...Buffer.from('0000', 'hex'), // p1IsInfinite ...Buffer.from('1237', 'hex'), // p2x ...Buffer.from('1238', 'hex'), // p2y - ...Buffer.from('0001', 'hex'), // p2IsInfinite ...Buffer.from('1239', 'hex'), // dstOffset ]); const inst = new EcAdd( /*addressing_mode=*/ 0x1234, /*p1X=*/ 0x1235, /*p1Y=*/ 0x1236, - /*p1IsInfinite=*/ 0, /*p2X=*/ 0x1237, /*p2Y=*/ 0x1238, - /*p2IsInfinite=*/ 1, /*dstOffset=*/ 0x1239, ); @@ -48,41 +44,24 @@ describe('EC Instructions', () => { it(`Should double correctly`, async () => { const x = new Field(Grumpkin.generator.x); const y = new Field(Grumpkin.generator.y); - const zero = new Uint1(0); context.machineState.memory.set(0, x); context.machineState.memory.set(1, y); - context.machineState.memory.set(2, zero); - context.machineState.memory.set(3, x); - context.machineState.memory.set(4, y); - context.machineState.memory.set(5, zero); - // context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - const pIsInfinite = context.machineState.memory.get(8).toNumber() === 1; - const actual = new Point( - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - pIsInfinite, + context.machineState.memory.set(2, x); + context.machineState.memory.set(3, y); + // context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, ); + + const actual = new Point(context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()); const expected = await Grumpkin.add(Grumpkin.generator, Grumpkin.generator); expect(actual).toEqual(expected); - expect(context.machineState.memory.get(8).toFr().equals(Fr.ZERO)).toBe(true); }); it('Should add correctly', async () => { const G2 = await Grumpkin.add(Grumpkin.generator, Grumpkin.generator); - const zero = new Uint1(0); const x1 = new Field(Grumpkin.generator.x); const y1 = new Field(Grumpkin.generator.y); @@ -91,36 +70,21 @@ describe('EC Instructions', () => { context.machineState.memory.set(0, x1); context.machineState.memory.set(1, y1); - context.machineState.memory.set(2, zero); - context.machineState.memory.set(3, x2); - context.machineState.memory.set(4, y2); - context.machineState.memory.set(5, zero); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - const actual = new Point( - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - false, + context.machineState.memory.set(2, x2); + context.machineState.memory.set(3, y2); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, ); + + const actual = new Point(context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()); const G3 = await Grumpkin.add(Grumpkin.generator, G2); expect(actual).toEqual(G3); - expect(context.machineState.memory.get(8).toFr().equals(Fr.ZERO)).toBe(true); }); it('Should add correctly with rhs being infinity', async () => { - const zero = new Uint1(0); - const one = new Uint1(1); + const zero = new Field(0); const x = new Field(Grumpkin.generator.x); const y = new Field(Grumpkin.generator.y); @@ -128,103 +92,67 @@ describe('EC Instructions', () => { // Point 1 is not infinity context.machineState.memory.set(0, x); context.machineState.memory.set(1, y); - context.machineState.memory.set(2, zero); // Point 2 is infinity - context.machineState.memory.set(3, x); - context.machineState.memory.set(4, y); - context.machineState.memory.set(5, one); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - expect([ - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - context.machineState.memory.get(8).toNumber(), - ]).toEqual([x.toFr(), y.toFr(), 0]); + context.machineState.memory.set(2, zero); + context.machineState.memory.set(3, zero); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, + ); + + expect([context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()]).toEqual([ + x.toFr(), + y.toFr(), + ]); }); it('Should add correctly with lhs being infinity', async () => { - const zero = new Uint1(0); - const one = new Uint1(1); + const zero = new Field(0); const x = new Field(Grumpkin.generator.x); const y = new Field(Grumpkin.generator.y); // Point 1 is infinity - context.machineState.memory.set(0, x); - context.machineState.memory.set(1, y); - context.machineState.memory.set(2, one); + context.machineState.memory.set(0, zero); + context.machineState.memory.set(1, zero); // Point 2 is not infinity - context.machineState.memory.set(3, x); - context.machineState.memory.set(4, y); - context.machineState.memory.set(5, zero); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - expect([ - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - context.machineState.memory.get(8).toNumber(), - ]).toEqual([x.toFr(), y.toFr(), 0]); + context.machineState.memory.set(2, x); + context.machineState.memory.set(3, y); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, + ); + + expect([context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()]).toEqual([ + x.toFr(), + y.toFr(), + ]); }); it('Should add correctly with both being infinity', async () => { - const one = new Uint1(1); - - const x = new Field(Grumpkin.generator.x); - const y = new Field(Grumpkin.generator.y); + const zero = new Field(0); // Point 1 is infinity - context.machineState.memory.set(0, x); - context.machineState.memory.set(1, y); - context.machineState.memory.set(2, one); + context.machineState.memory.set(0, zero); + context.machineState.memory.set(1, zero); // Point 2 is infinity - context.machineState.memory.set(3, x); - context.machineState.memory.set(4, y); - context.machineState.memory.set(5, one); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - expect([ - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - context.machineState.memory.get(8).toNumber(), - ]).toEqual([Fr.ZERO, Fr.ZERO, 1]); + context.machineState.memory.set(2, zero); + context.machineState.memory.set(3, zero); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, + ); + + expect([context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()]).toEqual([ + Fr.ZERO, + Fr.ZERO, + ]); }); it('Should add correctly with none infinity adding up to infinity', async () => { - const zero = new Uint1(0); - // Point 1 is a "random" point on the curve const x1 = new Field(2165030248772332382647339664685760681662697934905450801078761197378150920554n); const y1 = new Field(1518479793551399970960577643223827307749147426195887130444945641264602004320n); @@ -234,29 +162,19 @@ describe('EC Instructions', () => { context.machineState.memory.set(0, x1); context.machineState.memory.set(1, y1); - context.machineState.memory.set(2, zero); - context.machineState.memory.set(3, x2); - context.machineState.memory.set(4, y2); - context.machineState.memory.set(5, zero); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - expect([ - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - context.machineState.memory.get(8).toNumber(), - ]).toEqual([Fr.ZERO, Fr.ZERO, 1]); + context.machineState.memory.set(2, x2); + context.machineState.memory.set(3, y2); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, + ); + + expect([context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()]).toEqual([ + Fr.ZERO, + Fr.ZERO, + ]); }); }); @@ -265,29 +183,16 @@ describe('EC Instructions', () => { const validPoint = await Point.random(); const p1xOffset = 0; const p1yOffset = 1; - const p1IsInfiniteOffset = 2; - const p2xOffset = 3; - const p2yOffset = 4; - const p2IsInfiniteOffset = 5; - const dstOffset = 6; + const p2xOffset = 2; + const p2yOffset = 3; + const dstOffset = 4; context.machineState.memory.set(p1xOffset, new Field(new Fr(1))); // p1x (point is invalid) context.machineState.memory.set(p1yOffset, new Field(new Fr(1))); // p1y (point is invalid) - context.machineState.memory.set(p1IsInfiniteOffset, new Uint1(0)); // p1IsInfinite context.machineState.memory.set(p2xOffset, new Field(validPoint.x)); // p2x context.machineState.memory.set(p2yOffset, new Field(validPoint.y)); // p2y - context.machineState.memory.set(p2IsInfiniteOffset, new Uint1(validPoint.isInfinite ? 1 : 0)); // p2IsInfinite await expect( - new EcAdd( - /*addressing_mode=*/ 0, - p1xOffset, - p1yOffset, - p1IsInfiniteOffset, - p2xOffset, - p2yOffset, - p2IsInfiniteOffset, - dstOffset, - ).execute(context), + new EcAdd(/*addressing_mode=*/ 0, p1xOffset, p1yOffset, p2xOffset, p2yOffset, dstOffset).execute(context), ).rejects.toThrow(EcAddPointNotOnCurveError); }); @@ -295,29 +200,16 @@ describe('EC Instructions', () => { const validPoint = await Point.random(); const p1xOffset = 0; const p1yOffset = 1; - const p1IsInfiniteOffset = 2; - const p2xOffset = 3; - const p2yOffset = 4; - const p2IsInfiniteOffset = 5; - const dstOffset = 6; + const p2xOffset = 2; + const p2yOffset = 3; + const dstOffset = 4; context.machineState.memory.set(p1xOffset, new Field(validPoint.x)); // p1x context.machineState.memory.set(p1yOffset, new Field(validPoint.y)); // p1y - context.machineState.memory.set(p1IsInfiniteOffset, new Uint1(validPoint.isInfinite ? 1 : 0)); // p1IsInfinite context.machineState.memory.set(p2xOffset, new Field(new Fr(1))); // p2x (point is invalid) context.machineState.memory.set(p2yOffset, new Field(new Fr(1))); // p2y (point is invalid) - context.machineState.memory.set(p2IsInfiniteOffset, new Uint1(0)); // p2IsInfinite await expect( - new EcAdd( - /*addressing_mode=*/ 0, - p1xOffset, - p1yOffset, - p1IsInfiniteOffset, - p2xOffset, - p2yOffset, - p2IsInfiniteOffset, - dstOffset, - ).execute(context), + new EcAdd(/*addressing_mode=*/ 0, p1xOffset, p1yOffset, p2xOffset, p2yOffset, dstOffset).execute(context), ).rejects.toThrow(EcAddPointNotOnCurveError); }); }); diff --git a/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts b/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts index 19e3c1adc6ca..d21ca41561d3 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts @@ -2,7 +2,7 @@ import { Grumpkin } from '@aztec/foundation/crypto/grumpkin'; import { Point } from '@aztec/foundation/curves/grumpkin'; import type { AvmContext } from '../avm_context.js'; -import { Field, TypeTag, Uint1 } from '../avm_memory_types.js'; +import { Field, TypeTag } from '../avm_memory_types.js'; import { EcAddPointNotOnCurveError } from '../errors.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; import { Addressing } from './addressing_mode.js'; @@ -18,10 +18,8 @@ export class EcAdd extends Instruction { OperandType.UINT16, // indirect OperandType.UINT16, // p1X OperandType.UINT16, // p1Y - OperandType.UINT16, // p1IsInfinite OperandType.UINT16, // p2X OperandType.UINT16, // p2Y - OperandType.UINT16, // p2IsInfinite OperandType.UINT16, // dst ]; @@ -29,10 +27,8 @@ export class EcAdd extends Instruction { private addressingMode: number, private p1XOffset: number, private p1YOffset: number, - private p1IsInfiniteOffset: number, private p2XOffset: number, private p2YOffset: number, - private p2IsInfiniteOffset: number, private dstOffset: number, ) { super(); @@ -46,51 +42,38 @@ export class EcAdd extends Instruction { this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()), ); - const operands = [ - this.p1XOffset, - this.p1YOffset, - this.p1IsInfiniteOffset, - this.p2XOffset, - this.p2YOffset, - this.p2IsInfiniteOffset, - this.dstOffset, - ]; - const [p1XOffset, p1YOffset, p1IsInfiniteOffset, p2XOffset, p2YOffset, p2IsInfiniteOffset, dstOffset] = - addressing.resolve(operands, memory); + const operands = [this.p1XOffset, this.p1YOffset, this.p2XOffset, this.p2YOffset, this.dstOffset]; + const [p1XOffset, p1YOffset, p2XOffset, p2YOffset, dstOffset] = addressing.resolve(operands, memory); memory.checkTags(TypeTag.FIELD, p1XOffset, p1YOffset, p2XOffset, p2YOffset); - memory.checkTags(TypeTag.UINT1, p1IsInfiniteOffset, p2IsInfiniteOffset); const p1X = memory.get(p1XOffset); const p1Y = memory.get(p1YOffset); - const p1IsInfinite = memory.get(p1IsInfiniteOffset).toNumber() === 1; - const p1 = new Point(p1X.toFr(), p1Y.toFr(), p1IsInfinite); - if (!p1.isOnGrumpkin()) { + const p1 = new Point(p1X.toFr(), p1Y.toFr()); + if (!p1.isOnCurve()) { throw new EcAddPointNotOnCurveError(/*pointIndex=*/ 1, p1); } const p2X = memory.get(p2XOffset); const p2Y = memory.get(p2YOffset); - // unused. Point doesn't store this information - const p2IsInfinite = memory.get(p2IsInfiniteOffset).toNumber() === 1; - const p2 = new Point(p2X.toFr(), p2Y.toFr(), p2IsInfinite); - if (!p2.isOnGrumpkin()) { + const p2 = new Point(p2X.toFr(), p2Y.toFr()); + if (!p2.isOnCurve()) { throw new EcAddPointNotOnCurveError(/*pointIndex=*/ 2, p2); } let dest; - if (p1IsInfinite && p2IsInfinite) { - dest = Point.ZERO; - } else if (p1IsInfinite) { + if (p1.isInfinite && p2.isInfinite) { + dest = Point.INFINITY; + } else if (p1.isInfinite) { dest = p2; - } else if (p2IsInfinite) { + } else if (p2.isInfinite) { dest = p1; } else { // TS<>BB ecc add communication is broken for points that add up to infinity. // However, here we know that both points are on the curve, and that none is infinity // so we can check for the case where you add p + (-p) = infinity. if (p1.x.equals(p2.x) && !p1.y.equals(p2.y)) { - dest = Point.ZERO; + dest = Point.INFINITY; } else { dest = await Grumpkin.add(p1, p2); } @@ -99,7 +82,5 @@ export class EcAdd extends Instruction { // Important to use setSlice() and not set() in the two following statements as // this checks that the offsets lie within memory range. memory.setSlice(dstOffset, [new Field(dest.x), new Field(dest.y)]); - // Check representation of infinity for grumpkin - memory.setSlice(dstOffset + 2, [new Uint1(dest.equals(Point.ZERO) ? 1 : 0)]); } } diff --git a/yarn-project/simulator/src/public/fixtures/bulk_test.ts b/yarn-project/simulator/src/public/fixtures/bulk_test.ts index 0e600ad8be42..a551014e13fc 100644 --- a/yarn-project/simulator/src/public/fixtures/bulk_test.ts +++ b/yarn-project/simulator/src/public/fixtures/bulk_test.ts @@ -31,6 +31,19 @@ export async function bulkTest( const expectContractInstance = avmTestContract; const argsField = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + // Pinned grumpkin-Poseidon2 Schnorr signature (mirrors the C++ `pinned_test_vector_large` + // and noir-lang/schnorr v0.4.0's `pinned_vector_large`). Passing these in as calldata + // (rather than baking them into Noir as constants) keeps MSM + Poseidon2 from being folded + // by the Noir compiler. + const schnorrInputs = [ + Fr.fromHexString('0x065812e335a97c2108ea8cf4ccfe2f9dd6b117a0714f5e18461575be93f61da6'), // pubkey.x + Fr.fromHexString('0x1a915003e8ec534f9a15d926a7ded478e178468ccc4f28e236e67450a55ac622'), // pubkey.y + Fr.fromHexString('0xf3bc3b7147acb9c621fd9f72dbf15ffa'), // sig_s.lo + Fr.fromHexString('0x08599f379f0301dfefdbd0272554454d'), // sig_s.hi + Fr.fromHexString('0x97065383ebbbd76620398792bd259bc2'), // sig_e.lo + Fr.fromHexString('0x2ceaee87f45b7a417f0ffb05451a8c92'), // sig_e.hi + Fr.fromHexString('0x0123456789abcdef0fedcba9876543210123456789abcdef0fedcba987654321'), // message + ]; const args = [ argsField, argsU8, @@ -38,6 +51,8 @@ export async function bulkTest( /*expectedDeployer=*/ expectContractInstance.deployer, /*expectedClassId=*/ expectContractInstance.currentContractClassId, /*expectedInitializationHash=*/ expectContractInstance.initializationHash, + /*expectedImmutablesHash=*/ expectContractInstance.immutablesHash, + /*schnorrInputs=*/ schnorrInputs, /*skip_strictly_limited_side_effects=*/ false, ]; @@ -121,6 +136,15 @@ export async function megaBulkTest( //const argsField7 = [15, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); //const argsField8 = [17, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + const schnorrInputs = [ + Fr.fromHexString('0x065812e335a97c2108ea8cf4ccfe2f9dd6b117a0714f5e18461575be93f61da6'), // pubkey.x + Fr.fromHexString('0x1a915003e8ec534f9a15d926a7ded478e178468ccc4f28e236e67450a55ac622'), // pubkey.y + Fr.fromHexString('0xf3bc3b7147acb9c621fd9f72dbf15ffa'), // sig_s.lo + Fr.fromHexString('0x08599f379f0301dfefdbd0272554454d'), // sig_s.hi + Fr.fromHexString('0x97065383ebbbd76620398792bd259bc2'), // sig_e.lo + Fr.fromHexString('0x2ceaee87f45b7a417f0ffb05451a8c92'), // sig_e.hi + Fr.fromHexString('0x0123456789abcdef0fedcba9876543210123456789abcdef0fedcba987654321'), // message + ]; const genArgs = (argsField: Fr[]) => [ argsField, argsU8, @@ -128,6 +152,8 @@ export async function megaBulkTest( /*expectedDeployer=*/ expectContractInstance.deployer.toField(), /*expectedClassId=*/ expectContractInstance.currentContractClassId.toField(), /*expectedInitializationHash=*/ expectContractInstance.initializationHash.toField(), + /*expectedImmutablesHash=*/ expectContractInstance.immutablesHash.toField(), + /*schnorrInputs=*/ schnorrInputs, // Must skip strictly limited side effects (logs, messages) so we can spam the bulk test several times. /*skip_strictly_limited_side_effects=*/ true, ]; diff --git a/yarn-project/simulator/src/public/fixtures/opcode_spammer.ts b/yarn-project/simulator/src/public/fixtures/opcode_spammer.ts index 88e9a1663eb3..dd4322029d81 100644 --- a/yarn-project/simulator/src/public/fixtures/opcode_spammer.ts +++ b/yarn-project/simulator/src/public/fixtures/opcode_spammer.ts @@ -1339,20 +1339,16 @@ export const SPAM_CONFIGS: Partial> = { setup: [ { offset: 0, value: new Field(Grumpkin.generator.x) }, // p1X = G.x { offset: 1, value: new Field(Grumpkin.generator.y) }, // p1Y = G.y - { offset: 2, value: new Uint1(0n) }, // p1IsInfinite = false - { offset: 3, value: new Field(Grumpkin.generator.x) }, // p2X = G.x - { offset: 4, value: new Field(Grumpkin.generator.y) }, // p2Y = G.y - { offset: 5, value: new Uint1(0n) }, // p2IsInfinite = false + { offset: 2, value: new Field(Grumpkin.generator.x) }, // p2X = G.x + { offset: 3, value: new Field(Grumpkin.generator.y) }, // p2Y = G.y ], targetInstructions: () => [ new EcAdd( /*addressing_mode=*/ 0, /*p1XOffset=*/ 0, /*p1YOffset=*/ 1, - /*p1IsInfiniteOffset=*/ 2, - /*p2XOffset=*/ 3, - /*p2YOffset=*/ 4, - /*p2IsInfiniteOffset=*/ 5, + /*p2XOffset=*/ 2, + /*p2YOffset=*/ 3, /*dstOffset=*/ 0, ), ], diff --git a/yarn-project/simulator/src/public/fixtures/utils.ts b/yarn-project/simulator/src/public/fixtures/utils.ts index 2c0a5a275b79..d1e4c3532863 100644 --- a/yarn-project/simulator/src/public/fixtures/utils.ts +++ b/yarn-project/simulator/src/public/fixtures/utils.ts @@ -233,17 +233,13 @@ export async function addNewContractInstanceToTx( contractInstance: ContractInstanceWithAddress, skipNullifierInsertion = false, ) { - // can't use publicKeys.toFields() because it includes isInfinite which - // is not broadcast in such private logs + // Only ivpk_m is broadcast as a point (x, y); the other three keys are hashes. const publicKeysAsFields = [ - contractInstance.publicKeys.masterNullifierPublicKey.x, - contractInstance.publicKeys.masterNullifierPublicKey.y, - contractInstance.publicKeys.masterIncomingViewingPublicKey.x, - contractInstance.publicKeys.masterIncomingViewingPublicKey.y, - contractInstance.publicKeys.masterOutgoingViewingPublicKey.x, - contractInstance.publicKeys.masterOutgoingViewingPublicKey.y, - contractInstance.publicKeys.masterTaggingPublicKey.x, - contractInstance.publicKeys.masterTaggingPublicKey.y, + contractInstance.publicKeys.npkMHash, + contractInstance.publicKeys.ivpkM.x, + contractInstance.publicKeys.ivpkM.y, + contractInstance.publicKeys.ovpkMHash, + contractInstance.publicKeys.tpkMHash, ]; const logFields = [ CONTRACT_INSTANCE_PUBLISHED_EVENT_TAG, @@ -252,6 +248,7 @@ export async function addNewContractInstanceToTx( new Fr(contractInstance.salt), contractInstance.currentContractClassId, contractInstance.initializationHash, + contractInstance.immutablesHash, ...publicKeysAsFields, contractInstance.deployer.toField(), ]; diff --git a/yarn-project/simulator/src/public/hinting_db_sources.ts b/yarn-project/simulator/src/public/hinting_db_sources.ts index 85f8ab422ccf..71c7a99c9239 100644 --- a/yarn-project/simulator/src/public/hinting_db_sources.ts +++ b/yarn-project/simulator/src/public/hinting_db_sources.ts @@ -83,6 +83,7 @@ export class HintingPublicContractsDB implements PublicContractsDBInterface { instance.currentContractClassId, instance.originalContractClassId, instance.initializationHash, + instance.immutablesHash, instance.publicKeys, ), ); diff --git a/yarn-project/simulator/src/public/public_processor/apps_tests/deployments.test.ts b/yarn-project/simulator/src/public/public_processor/apps_tests/deployments.test.ts index 1183b99f0cfd..d8a6353581f3 100644 --- a/yarn-project/simulator/src/public/public_processor/apps_tests/deployments.test.ts +++ b/yarn-project/simulator/src/public/public_processor/apps_tests/deployments.test.ts @@ -249,7 +249,7 @@ describe.each([ expect(processedTxs[0].revertCode).toEqual(RevertCode.OK); // Second tx should revert in app logic (failed transfer) - expect(processedTxs[1].revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(processedTxs[1].revertCode).toEqual(RevertCode.REVERTED); // Third tx should succeed (mint), proving first contract is still accessible expect(processedTxs[2].revertCode).toEqual(RevertCode.OK); diff --git a/yarn-project/simulator/src/public/public_processor/public_processor.test.ts b/yarn-project/simulator/src/public/public_processor/public_processor.test.ts index abc3aedf918e..8cb98a15451b 100644 --- a/yarn-project/simulator/src/public/public_processor/public_processor.test.ts +++ b/yarn-project/simulator/src/public/public_processor/public_processor.test.ts @@ -21,14 +21,14 @@ import { strict as assert } from 'assert'; import { type MockProxy, mock } from 'jest-mock-extended'; import { PublicContractsDB } from '../public_db_sources.js'; -import type { PublicTxSimulator } from '../public_tx_simulator/public_tx_simulator.js'; +import type { PublicTxSimulatorInterface } from '../public_tx_simulator/index.js'; import { GuardedMerkleTreeOperations } from './guarded_merkle_tree.js'; import { PublicProcessor } from './public_processor.js'; describe('public_processor', () => { let merkleTree: MockProxy; let contractsDB: PublicContractsDB; - let publicTxSimulator: MockProxy; + let publicTxSimulator: MockProxy>; let mockedEnqueuedCallsResult: PublicTxResult; @@ -78,7 +78,7 @@ describe('public_processor', () => { beforeEach(() => { merkleTree = mock(); contractsDB = new PublicContractsDB(mock()); - publicTxSimulator = mock(); + publicTxSimulator = mock>(); const stateReference = StateReference.empty(); mockedEnqueuedCallsResult = PublicTxResult.empty(); @@ -136,7 +136,7 @@ describe('public_processor', () => { it('runs a tx with reverted enqueued public calls', async function () { const tx = await mockTxWithPublicCalls(); - mockedEnqueuedCallsResult.revertCode = RevertCode.APP_LOGIC_REVERTED; + mockedEnqueuedCallsResult.revertCode = RevertCode.REVERTED; const [processed, failed] = await processor.process([tx]); @@ -239,6 +239,32 @@ describe('public_processor', () => { expect(failed.length).toBe(1); }); + it('aborts in-flight tx processing and cancels the simulator', async function () { + const tx = await mockTxWithPublicCalls(); + const controller = new AbortController(); + + let finishSimulation!: () => void; + const simulationFinished = new Promise(resolve => { + finishSimulation = resolve; + }); + + publicTxSimulator.simulate.mockImplementation(async () => { + controller.abort(); + await simulationFinished; + return mockedEnqueuedCallsResult; + }); + publicTxSimulator.cancel.mockImplementation(() => { + finishSimulation(); + return Promise.resolve(); + }); + + const [processed, failed] = await processor.process([tx], { signal: controller.signal }); + + expect(processed).toEqual([]); + expect(failed).toEqual([]); + expect(publicTxSimulator.cancel).toHaveBeenCalled(); + }); + // Flakey timing test that's totally dependent on system load/architecture etc. it.skip('does not go past the deadline', async function () { const txs = await timesParallel(3, seed => mockTxWithPublicCalls({ seed })); diff --git a/yarn-project/simulator/src/public/public_processor/public_processor.ts b/yarn-project/simulator/src/public/public_processor/public_processor.ts index 6f8523d6096b..8a4e9c16c463 100644 --- a/yarn-project/simulator/src/public/public_processor/public_processor.ts +++ b/yarn-project/simulator/src/public/public_processor/public_processor.ts @@ -3,7 +3,7 @@ import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider, Timer, elapsed, executeTimeout } from '@aztec/foundation/timer'; +import { DateProvider, Timer, elapsed, execWithSignal } from '@aztec/foundation/timer'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry'; import { computeFeePayerBalanceLeafSlot, computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice'; @@ -123,6 +123,17 @@ class PublicProcessorTimeoutError extends Error { } } +class PublicProcessorAbortError extends Error { + constructor(message: string = 'Aborted while processing tx') { + super(message); + this.name = 'PublicProcessorAbortError'; + } +} + +function isPublicProcessorInterruptError(err: any) { + return err?.name === 'PublicProcessorTimeoutError' || err?.name === 'PublicProcessorAbortError'; +} + /** * Converts Txs lifted from the P2P module into ProcessedTx objects by executing * any public function calls in them. Txs with private calls only are unaffected. @@ -159,7 +170,7 @@ export class PublicProcessor implements Traceable { limits: PublicProcessorLimits = {}, validator: PublicProcessorValidator = {}, ): Promise<[ProcessedTx[], FailedTx[], Tx[], NestedProcessReturnValues[], DebugLog[]]> { - const { maxTransactions, deadline, maxBlockGas, maxBlobFields, isBuildingProposal } = limits; + const { maxTransactions, deadline, maxBlockGas, maxBlobFields, isBuildingProposal, signal } = limits; const { preprocessValidator, nullifierCache } = validator; const result: ProcessedTx[] = []; const usedTxs: Tx[] = []; @@ -182,11 +193,15 @@ export class PublicProcessor implements Traceable { break; } - // Bail if we've hit the deadline + // Bail if we've hit the deadline or have been interrupted. if (deadline && this.dateProvider.now() > +deadline) { this.log.warn(`Stopping tx processing due to timeout.`); break; } + if (signal?.aborted) { + this.log.warn(`Stopping tx processing due to abort signal.`); + break; + } const txHash = tx.getTxHash().toString(); @@ -240,7 +255,7 @@ export class PublicProcessor implements Traceable { try { const [txProcessingTimeMs, [processedTx, returnValues, txDebugLogs]] = await elapsed(() => - this.processTx(tx, deadline), + this.processTx(tx, deadline, signal), ); // Inject a fake processing failure after N txs if requested @@ -311,15 +326,11 @@ export class PublicProcessor implements Traceable { // Commit the tx-level contracts checkpoint on success this.contractsDB.commitCheckpoint(); } catch (err: any) { - if (err?.name === 'PublicProcessorTimeoutError') { - this.log.warn(`Stopping tx processing due to timeout.`); - // We hit the transaction execution deadline. - // There may still be a transaction executing on a worker thread (C++ via NAPI). - // Signal cancellation AND WAIT for the simulation to actually stop. - // This is critical because C++ might be in the middle of a slow operation (e.g., pad_trees) - // and won't check the cancellation flag until that operation completes. - // Without waiting, we'd proceed to revert checkpoints while C++ is still writing to state. - // Wait for C++ to stop gracefully. + if (isPublicProcessorInterruptError(err)) { + const interruptReason = err.name === 'PublicProcessorTimeoutError' ? 'timeout' : 'abort signal'; + this.log.warn(`Stopping tx processing due to ${interruptReason}.`); + // The tx may still be executing on a worker thread (C++ via NAPI). + // Signal cancellation AND WAIT for the simulation to actually stop before touching fork checkpoints. await this.publicTxSimulator.cancel?.(); // Now stop the guarded fork to prevent any further TS-side access to the world state. @@ -407,9 +418,10 @@ export class PublicProcessor implements Traceable { private async processTx( tx: Tx, deadline: Date | undefined, + signal: AbortSignal | undefined, ): Promise<[ProcessedTx, NestedProcessReturnValues[], DebugLog[]]> { const [time, [processedTx, returnValues, debugLogs]] = await elapsed(() => - this.processTxWithinDeadline(tx, deadline), + this.processTxWithinDeadline(tx, deadline, signal), ); this.log.verbose( @@ -463,10 +475,11 @@ export class PublicProcessor implements Traceable { this.metrics.recordTreeInsertions(Number(treeInsertionEnd - treeInsertionStart) / 1_000); } - /** Processes the given tx within deadline. Returns timeout if deadline is hit. */ + /** Processes the given tx within deadline or until the signal is aborted. */ private async processTxWithinDeadline( tx: Tx, deadline: Date | undefined, + signal: AbortSignal | undefined, ): Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined, DebugLog[]]> { const innerProcessFn: () => Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined, DebugLog[]]> = tx.hasPublicCalls() ? () => this.processTxWithPublicCalls(tx) : () => this.processPrivateOnlyTx(tx); @@ -483,27 +496,38 @@ export class PublicProcessor implements Traceable { } : innerProcessFn; - if (!deadline) { + const processingSignal = this.getProcessingSignal(tx, deadline, signal); + if (!processingSignal) { return await processFn(); } - const txHash = tx.getTxHash(); + return await execWithSignal( + () => processFn(), + processingSignal, + signal => + signal.reason?.name === 'TimeoutError' ? new PublicProcessorTimeoutError() : new PublicProcessorAbortError(), + ); + } + + private getProcessingSignal(tx: Tx, deadline: Date | undefined, signal: AbortSignal | undefined) { + if (!deadline) { + return signal; + } + const timeout = +deadline - this.dateProvider.now(); if (timeout <= 0) { throw new PublicProcessorTimeoutError(); } + const txHash = tx.getTxHash(); this.log.debug(`Processing tx ${txHash.toString()} within ${timeout}ms`, { deadline: deadline.toISOString(), now: new Date(this.dateProvider.now()).toISOString(), txHash, }); - return await executeTimeout( - () => processFn(), - timeout, - () => new PublicProcessorTimeoutError(), - ); + const timeoutSignal = AbortSignal.timeout(timeout); + return signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal; } /** diff --git a/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.test.ts b/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.test.ts index 337bd982431d..64a6cf8b585b 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.test.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.test.ts @@ -691,7 +691,7 @@ describe('public_tx_simulator', () => { const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); // tx reports app logic failure expect(txResult.findRevertReason()).toEqual(appLogicFailure); @@ -812,7 +812,7 @@ describe('public_tx_simulator', () => { const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.TEARDOWN_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); expect(txResult.findRevertReason()).toEqual(teardownFailure); const expectedSetupGas = enqueuedCallGasUsed; @@ -921,7 +921,7 @@ describe('public_tx_simulator', () => { const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.BOTH_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); // tx reports app logic failure expect(txResult.findRevertReason()).toEqual(appLogicFailure); @@ -1246,7 +1246,7 @@ describe('public_tx_simulator', () => { }); const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); const revertReason = txResult.findRevertReason(); expect(revertReason).toBeDefined(); expect(revertReason?.getOriginalMessage()).toContain(new NullifierLimitReachedError().message); @@ -1269,7 +1269,7 @@ describe('public_tx_simulator', () => { throw new NoteHashLimitReachedError(); }); const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); const revertReason = txResult.findRevertReason(); expect(revertReason).toBeDefined(); expect(revertReason?.getOriginalMessage()).toContain(new NoteHashLimitReachedError().message); @@ -1296,7 +1296,7 @@ describe('public_tx_simulator', () => { }); const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); const revertReason = txResult.findRevertReason(); expect(revertReason).toBeDefined(); expect(revertReason?.getOriginalMessage()).toContain(new L2ToL1MessageLimitReachedError().message); diff --git a/yarn-project/slasher/README.md b/yarn-project/slasher/README.md index fd8aa439b041..fca7713ef588 100644 --- a/yarn-project/slasher/README.md +++ b/yarn-project/slasher/README.md @@ -81,16 +81,10 @@ Key features: List of all slashable offenses in the system: ### DATA_WITHHOLDING -**Description**: The data required for proving an epoch was not made publicly available. -**Detection**: EpochPruneWatcher detects when an epoch cannot be proven due to missing data. -**Target**: Committee members of the affected epoch. -**Time Unit**: Epoch-based offense. - -### VALID_EPOCH_PRUNED -**Description**: An epoch was not successfully proven within the proof submission window. -**Detection**: EpochPruneWatcher monitors epochs that expire without valid proofs. -**Target**: Committee members of the unpruned epoch. -**Time Unit**: Epoch-based offense. +**Description**: The transaction data for a published checkpoint was not made available within the tolerance window. +**Detection**: DataWithholdingWatcher checks each published checkpoint's txs against the local mempool once `slashDataWithholdingToleranceSlots` full slots have elapsed past the checkpoint's slot (i.e. at `slotStart(checkpoint.slot + slashDataWithholdingToleranceSlots + 1)`). +**Target**: Validators who attested to the checkpoint. +**Time Unit**: Slot-based offense (the checkpoint's slot). ### INACTIVITY **Description**: A proposer failed to attest or propose blocks during their assigned slots. @@ -116,15 +110,15 @@ List of all slashable offenses in the system: **Target**: Block proposer. **Time Unit**: Slot-based offense. -### ATTESTED_DESCENDANT_OF_INVALID -**Description**: A committee member attested to a block built on top of an invalid ancestor. -**Detection**: AttestationsBlockWatcher tracks invalid blocks and their descendants. -**Target**: Committee members who attested to the descendant block. +### PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS +**Description**: A proposer published a checkpoint to L1 that builds on an invalid checkpoint (one with invalid or insufficient attestations). +**Detection**: AttestationsBlockWatcher tracks invalid checkpoints and their descendants. +**Target**: Proposer of the descendant checkpoint. **Time Unit**: Slot-based offense. ### DUPLICATE_PROPOSAL -**Description**: A proposer sent multiple block or checkpoint proposals for the same position (slot and indexWithinCheckpoint for blocks, or slot for checkpoints) with different content. Since each slot has exactly one designated proposer, sending conflicting proposals is equivocation. -**Detection**: Detected in the P2P layer when proposals are received. The AttestationPool tracks proposals by position; when a second proposal arrives for the same position with a different archive, it flags the duplicate. The first duplicate is propagated (Accept) so other validators can witness the offense. +**Description**: A proposer sent multiple block or checkpoint proposals for the same position (slot and indexWithinCheckpoint for blocks, or slot for checkpoints) with different content. Since each slot has exactly one designated proposer, sending conflicting proposals is equivocation. This also covers the case where a proposer broadcasts one checkpoint proposal via P2P but submits a different checkpoint to L1 for the same slot. +**Detection**: Detected in two places. (1) The P2P layer flags duplicates when a second proposal arrives for the same position with a different archive; the AttestationPool tracks proposals by position and the first duplicate is propagated (Accept) so other validators can witness the offense. (2) CheckpointEquivocationWatcher compares the archive root of each L1-confirmed checkpoint against retained signed P2P checkpoint proposals from the same slot's proposer and flags any mismatch. **Target**: Proposer who broadcast the duplicate proposal. **Time Unit**: Slot-based offense. @@ -134,6 +128,12 @@ List of all slashable offenses in the system: **Target**: Committee members who attested in the invalid proposal slot. **Time Unit**: Slot-based offense. +### BROADCASTED_INVALID_CHECKPOINT_PROPOSAL +**Description**: A proposer broadcast an invalid checkpoint proposal, either one that terminates before a higher-index block proposal signed by the same proposer in the same slot, one whose signed header does not match deterministic validator recomputation, or one with a malformed fee asset price modifier. +**Detection**: BroadcastedInvalidCheckpointProposalWatcher scans retained P2P proposal evidence and compares checkpoint archive roots to signed block proposals from the same slot and signer. ValidatorClient also validates checkpoint proposals during the all-nodes callback and emits this offense when checkpoint header recomputation fails or the signed fee asset price modifier is malformed. +**Target**: Proposer who broadcast the invalid checkpoint proposal. +**Time Unit**: Slot-based offense. + ## Configuration ### L1 System Settings (L1ContractsConfig) @@ -150,26 +150,31 @@ Considerations: - The `slashingQuorumSize` should be more than half and less than the total number of validators in a round, so that we require a majority to slash. The number of validators in a round is the committee size times the number of epochs in a round. - The bigger a `slashingRoundSizeInEpochs`, the bigger the upper bound on the quorum size. This increases security, as we need more validators to agree before slashing. However, it also makes slashing slower, and more expensive to execute in terms of gas. -- The `slashingOffsetInRounds` is required because the validators in a given slashing round must vote for _past_ offenses. Otherwise, if someone commits an offense near the end of a round, they can get away with their offense without the validators being able to collect enough votes to slash them. The offset needs to be big enough so that all offenses are discoverable, so this value should be strictly greater than the proof submission window in order to be able to slash for epoch prunes or data withholding. +- The `slashingOffsetInRounds` is required because the validators in a given slashing round must vote for _past_ offenses. Otherwise, if someone commits an offense near the end of a round, they can get away with their offense without the validators being able to collect enough votes to slash them. The offset needs to be big enough so that all offenses are discoverable, so this value should be strictly greater than the data-withholding tolerance window so that there is time to detect missing data and vote. - The `slashingExecutionDelayInRounds` allows vetoers to stop an invalid slash. This should be large enough to give vetoers time to act, but strictly smaller than the validator exit window, so an offender cannot escape before they are slashed. It should also be small enough so that an offender that would be kicked out does not get picked up to be a committee member again before their slash is executed. In other words, if a validator commits a serious enough offense that we want them out of the validator set as soon as possible, the execution delay should not allow them to be chosen to participate in another committee. ### Local Node Configuration (SlasherConfig) These settings are configured locally on each validator node: +Block and checkpoint validation settings are expected to be the same across all validators. Slashing relies on +validators making the same deterministic validity decisions for block and checkpoint proposals; operators should not run +with divergent validation limits. + - `slashGracePeriodL2Slots`: Number of initial L2 slots where slashing is disabled - `slashOffenseExpirationRounds`: Number of rounds after which pending offenses expire - `slashValidatorsAlways`: Array of validator addresses that should always be slashed - `slashValidatorsNever`: Array of validator addresses that should never be slashed (own validator addresses are automatically added to this list) - `slashInactivityTargetPercentage`: Percentage of misses during an epoch to be slashed for INACTIVITY - `slashInactivityConsecutiveEpochThreshold`: How many consecutive inactive epochs are needed to trigger an INACTIVITY slash on a validator -- `slashPrunePenalty`: Penalty for VALID_EPOCH_PRUNED - `slashDataWithholdingPenalty`: Penalty for DATA_WITHHOLDING +- `slashDataWithholdingToleranceSlots`: Number of full L2 slots to wait after a checkpoint's slot before declaring its txs missing - `slashInactivityPenalty`: Penalty for INACTIVITY - `slashBroadcastedInvalidBlockPenalty`: Penalty for BROADCASTED_INVALID_BLOCK_PROPOSAL +- `slashBroadcastedInvalidCheckpointProposalPenalty`: Penalty for BROADCASTED_INVALID_CHECKPOINT_PROPOSAL - `slashDuplicateProposalPenalty`: Penalty for DUPLICATE_PROPOSAL - `slashProposeInvalidAttestationsPenalty`: Penalty for PROPOSED_INSUFFICIENT_ATTESTATIONS and PROPOSED_INCORRECT_ATTESTATIONS -- `slashAttestDescendantOfInvalidPenalty`: Penalty for ATTESTED_DESCENDANT_OF_INVALID +- `slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty`: Penalty for PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS - `slashAttestInvalidCheckpointProposalPenalty`: Penalty for ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL - `slashUnknownPenalty`: Default penalty for unknown offense types - `slashMaxPayloadSize`: Limits the number of **unique validators** (across all committees and epochs in a round) that receive non-zero votes. When this cap is hit, the lowest-severity validator-epoch pairs are zeroed out first, so the most severe slashes are always preserved. Note that multiple offenses for the same validator in the same epoch are summed and counted as a single validator entry against this limit. @@ -187,25 +192,34 @@ Details about specific offenses in the system: Inactivity slashing is one of the most critical, since it allows purging validators that are not fulfilling their duties, which could potentially bring the chain to a halt. This slashing must be aggressive enough to balance out the rate of the entry queue, in case the queue is filled with inactive validators. Furthermore, if enough inactive validators join the system, it may become impossible to gather enough quorum to pass any governance proposal. -Inactivity slashing is handled by the `Sentinel` which monitors performance of all validators slot-by-slot. With the multiple-blocks-per-slot model, block proposals and checkpoints are distinct concepts: proposers build multiple blocks per slot, but attestations are only for checkpoints. After each slot, the sentinel assigns one of the following to the proposer for the slot: -- `checkpoint-mined` if the checkpoint was added to L1 -- `checkpoint-proposed` if the checkpoint received at least one attestation, but didn't make it to L1 -- `checkpoint-missed` if blocks were proposed but the checkpoint received no attestations -- `blocks-missed` if no block proposals were sent for this slot at all +Inactivity slashing is handled by the `Sentinel` (in `aztec-node/src/sentinel/`), which monitors performance of all validators slot-by-slot. With the multiple-blocks-per-slot model, block proposals and checkpoints are distinct concepts: proposers build multiple blocks per slot, but attestations are only for checkpoints. After each slot, the sentinel assigns one of the following to the proposer for the slot, in highest-confidence order: + +- `checkpoint-mined` — a checkpoint covering this slot has landed on L1 +- `checkpoint-valid` — the local node re-executed a checkpoint proposal for this slot successfully +- `checkpoint-invalid` — the local node re-executed a checkpoint proposal for this slot and rejected it (header / archive / out-hash mismatch, limit breach, etc.). Proposer-fault +- `checkpoint-unvalidated` — a checkpoint proposal arrived but the local node could not validate it (missing blocks/txs, timeout). Treated as proposer-fault +- `checkpoint-missed` — block proposals seen on P2P but no checkpoint proposal at all +- `blocks-missed` — no block proposals seen for this slot at all + +Re-execution outcomes are read from the `CheckpointReexecutionTracker`, which the validator client populates at every early-return in `validateCheckpointProposal`. The same tracker is consumed by the data-withholding watcher via `hasReexecuted(checkpointNumber, archiveRoot)`. + +Each non-proposer committee member is assigned one of: +- `attestation-sent` if their checkpoint attestation was seen on L1 or on the P2P network +- `attestation-missed` if the proposer status was `checkpoint-mined` or `checkpoint-valid` but no checkpoint attestation was seen +- none in any other case -And assigns one of the following to each validator (these refer to checkpoint attestations): -- `attestation-sent` if there was a `checkpoint-proposed` or `checkpoint-mined` and a checkpoint attestation from this validator was seen on either on L1 or on the P2P network -- `attestation-missed` if there was a `checkpoint-proposed` or `checkpoint-mined` but no checkpoint attestation was seen -- none if the slot was a `blocks-missed` +`blocks-missed`, `checkpoint-missed`, `checkpoint-invalid`, and `checkpoint-unvalidated` all count as proposer inactivity for the slot. -Both `blocks-missed` and `checkpoint-missed` count as proposer inactivity. +The sentinel evaluates an epoch once `sentinelEpochEndBufferSlots` (default 2) L2 slots have elapsed past the epoch's last slot AND the per-slot recorder has covered that last slot. Epoch evaluation does not wait for an L1 proof — it relies on local-state evidence (the re-execution tracker plus L1 checkpoint landings) — so inactive validators are slashed promptly regardless of prover availability. -Once an epoch is proven, the sentinel computes the _proven performance_ for the epoch for each validator. Note that we wait until the epoch is proven so we know that the data for all blocks in the epoch was available, and validators who did not attest were effectively inactive. Then, for each validator such that: +At end-of-epoch evaluation, for each validator such that: ``` -total_failures = count(blocks-missed) + count(checkpoint-missed) + count(attestation-missed) +total_failures = count(blocks-missed) + count(checkpoint-missed) + + count(checkpoint-invalid) + count(checkpoint-unvalidated) + + count(attestation-missed) total = count(checkpoint-*) + count(blocks-*) + count(attestation-*) -total_failures / total >= slash_inactivity_target_percentage +total_failures / total >= slashInactivityTargetPercentage ``` -They are voted to be slashed for inactivity. Note that, if `slashInactivityConsecutiveEpochThreshold` is greater than one, we first check if the above is true for the last `threshold` times the given validator was part of a committee, and only then trigger the offense. +they are voted to be slashed for inactivity. If `slashInactivityConsecutiveEpochThreshold` is greater than one, the above must also hold for the last `threshold` times the validator was part of a committee. diff --git a/yarn-project/slasher/src/config.ts b/yarn-project/slasher/src/config.ts index 26102d3bb805..ddc934f02b62 100644 --- a/yarn-project/slasher/src/config.ts +++ b/yarn-project/slasher/src/config.ts @@ -16,16 +16,19 @@ export const DefaultSlasherConfig: SlasherConfig = { slashOverridePayload: undefined, slashValidatorsAlways: [], // Empty by default slashValidatorsNever: [], // Empty by default - slashPrunePenalty: BigInt(slasherDefaultEnv.SLASH_PRUNE_PENALTY), slashDataWithholdingPenalty: BigInt(slasherDefaultEnv.SLASH_DATA_WITHHOLDING_PENALTY), + slashDataWithholdingToleranceSlots: slasherDefaultEnv.SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS, slashInactivityTargetPercentage: slasherDefaultEnv.SLASH_INACTIVITY_TARGET_PERCENTAGE, slashInactivityConsecutiveEpochThreshold: slasherDefaultEnv.SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD, slashBroadcastedInvalidBlockPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_BLOCK_PENALTY), + slashBroadcastedInvalidCheckpointProposalPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY), slashDuplicateProposalPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_PROPOSAL_PENALTY), slashDuplicateAttestationPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_ATTESTATION_PENALTY), slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY), slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY), - slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY), + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: BigInt( + slasherDefaultEnv.SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY, + ), slashAttestInvalidCheckpointProposalPenalty: BigInt( slasherDefaultEnv.SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY, ), @@ -66,21 +69,27 @@ export const slasherConfigMappings: ConfigMappingsType = { .map(addr => EthAddress.fromString(addr)), defaultValue: DefaultSlasherConfig.slashValidatorsNever, }, - slashPrunePenalty: { - env: 'SLASH_PRUNE_PENALTY', - description: 'Penalty amount for slashing validators of a valid pruned epoch (set to 0 to disable).', - ...bigintConfigHelper(DefaultSlasherConfig.slashPrunePenalty), - }, slashDataWithholdingPenalty: { env: 'SLASH_DATA_WITHHOLDING_PENALTY', description: 'Penalty amount for slashing validators for data withholding (set to 0 to disable).', ...bigintConfigHelper(DefaultSlasherConfig.slashDataWithholdingPenalty), }, + slashDataWithholdingToleranceSlots: { + env: 'SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS', + description: + 'Number of full L2 slots that must elapse after a checkpoint slot before declaring its txs missing and slashing its attesters for data withholding.', + ...numberConfigHelper(DefaultSlasherConfig.slashDataWithholdingToleranceSlots), + }, slashBroadcastedInvalidBlockPenalty: { env: 'SLASH_INVALID_BLOCK_PENALTY', description: 'Penalty amount for slashing a validator for an invalid block proposed via p2p.', ...bigintConfigHelper(DefaultSlasherConfig.slashBroadcastedInvalidBlockPenalty), }, + slashBroadcastedInvalidCheckpointProposalPenalty: { + env: 'SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY', + description: 'Penalty amount for slashing a validator for an invalid checkpoint proposal proposed via p2p.', + ...bigintConfigHelper(DefaultSlasherConfig.slashBroadcastedInvalidCheckpointProposalPenalty), + }, slashDuplicateProposalPenalty: { env: 'SLASH_DUPLICATE_PROPOSAL_PENALTY', description: 'Penalty amount for slashing a validator for sending duplicate proposals.', @@ -124,11 +133,11 @@ export const slasherConfigMappings: ConfigMappingsType = { description: 'Penalty amount for slashing a proposer that proposed invalid attestations (set to 0 to disable).', ...bigintConfigHelper(DefaultSlasherConfig.slashProposeInvalidAttestationsPenalty), }, - slashAttestDescendantOfInvalidPenalty: { - env: 'SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY', + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: { + env: 'SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY', description: - 'Penalty amount for slashing a validator that attested to a descendant of an invalid block (set to 0 to disable).', - ...bigintConfigHelper(DefaultSlasherConfig.slashAttestDescendantOfInvalidPenalty), + 'Penalty amount for slashing a proposer that published a checkpoint building on an invalid checkpoint (set to 0 to disable).', + ...bigintConfigHelper(DefaultSlasherConfig.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty), }, slashAttestInvalidCheckpointProposalPenalty: { env: 'SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY', diff --git a/yarn-project/slasher/src/index.ts b/yarn-project/slasher/src/index.ts index 797815fceec6..d947aad82568 100644 --- a/yarn-project/slasher/src/index.ts +++ b/yarn-project/slasher/src/index.ts @@ -1,6 +1,8 @@ export * from './config.js'; -export * from './watchers/epoch_prune_watcher.js'; +export * from './watchers/data_withholding_watcher.js'; export * from './watchers/attestations_block_watcher.js'; +export * from './watchers/broadcasted_invalid_checkpoint_proposal_watcher.js'; +export * from './watchers/checkpoint_equivocation_watcher.js'; export * from './slasher_client.js'; export * from './slash_offenses_collector.js'; export * from './slasher_client_interface.js'; diff --git a/yarn-project/slasher/src/slash_offenses_collector.test.ts b/yarn-project/slasher/src/slash_offenses_collector.test.ts index c599ac0866a8..01b7957d2fdd 100644 --- a/yarn-project/slasher/src/slash_offenses_collector.test.ts +++ b/yarn-project/slasher/src/slash_offenses_collector.test.ts @@ -164,7 +164,7 @@ describe('SlashOffensesCollector', () => { { validator: validator3, amount: 1500000000000000000n, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 175n, // slot 175 >= 110 }, ]; @@ -201,7 +201,7 @@ describe('SlashOffensesCollector', () => { expect(offensesByValidator[validator3.toString()]).toMatchObject({ validator: validator3, amount: 1500000000000000000n, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 175n, }); }); diff --git a/yarn-project/slasher/src/stores/offenses_store.test.ts b/yarn-project/slasher/src/stores/offenses_store.test.ts index 6215e541cbca..2aeba6e6aea7 100644 --- a/yarn-project/slasher/src/stores/offenses_store.test.ts +++ b/yarn-project/slasher/src/stores/offenses_store.test.ts @@ -107,7 +107,7 @@ describe('SlasherOffensesStore', () => { it('should handle large amounts and epoch/slot values', async () => { const largeAmount = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'); // Max uint128 const largeEpochOrSlot = BigInt(1_000_000_000); - const offense = createOffense(EthAddress.random(), largeAmount, OffenseType.VALID_EPOCH_PRUNED, largeEpochOrSlot); + const offense = createOffense(EthAddress.random(), largeAmount, OffenseType.INACTIVITY, largeEpochOrSlot); await store.addOffense(offense); @@ -119,7 +119,12 @@ describe('SlasherOffensesStore', () => { it('should preserve offense data across store operations', async () => { const validator = EthAddress.fromString('0x1234567890abcdef1234567890abcdef12345678'); - const offense = createOffense(validator, 12345n, OffenseType.ATTESTED_DESCENDANT_OF_INVALID, 54321n); + const offense = createOffense( + validator, + 12345n, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, + 54321n, + ); await store.addOffense(offense); @@ -127,7 +132,9 @@ describe('SlasherOffensesStore', () => { expect(pendingOffenses).toHaveLength(1); expect(pendingOffenses[0].validator.toString()).toBe(validator.toString()); expect(pendingOffenses[0].amount).toBe(12345n); - expect(pendingOffenses[0].offenseType).toBe(OffenseType.ATTESTED_DESCENDANT_OF_INVALID); + expect(pendingOffenses[0].offenseType).toBe( + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, + ); expect(pendingOffenses[0].epochOrSlot).toBe(54321n); }); diff --git a/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts b/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts index 5d418ebbd49c..933362d00cde 100644 --- a/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts +++ b/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts @@ -176,14 +176,14 @@ describe('AttestationsBlockWatcher', () => { expect(handler).toHaveBeenCalledWith([ { validator: attestor1, - amount: config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 2n, }, { validator: attestor2, - amount: config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 2n, }, ] satisfies WantToSlashArgs[]); diff --git a/yarn-project/slasher/src/watchers/attestations_block_watcher.ts b/yarn-project/slasher/src/watchers/attestations_block_watcher.ts index b9d1dcdfd068..cd02e7312c5b 100644 --- a/yarn-project/slasher/src/watchers/attestations_block_watcher.ts +++ b/yarn-project/slasher/src/watchers/attestations_block_watcher.ts @@ -1,6 +1,7 @@ import { EpochCache } from '@aztec/epoch-cache'; import { SlotNumber } from '@aztec/foundation/branded-types'; import { merge, pick } from '@aztec/foundation/collection'; +import { FifoSet } from '@aztec/foundation/fifo-set'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { type InvalidCheckpointDetectedEvent, @@ -8,7 +9,6 @@ import { L2BlockSourceEvents, type ValidateCheckpointNegativeResult, } from '@aztec/stdlib/block'; -import type { CheckpointInfo } from '@aztec/stdlib/checkpoint'; import { OffenseType } from '@aztec/stdlib/slashing'; import EventEmitter from 'node:events'; @@ -17,9 +17,10 @@ import type { SlasherConfig } from '../config.js'; import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; const AttestationsBlockWatcherConfigKeys = [ - 'slashAttestDescendantOfInvalidPenalty', + 'slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty', 'slashProposeInvalidAttestationsPenalty', ] as const; +const MAX_INVALID_CHECKPOINTS = 100; type AttestationsBlockWatcherConfig = Pick; @@ -32,11 +33,8 @@ type AttestationsBlockWatcherConfig = Pick WatcherEmitter) implements Watcher { private log: Logger = createLogger('attestations-block-watcher'); - // Only keep track of the last N invalid checkpoints - private maxInvalidCheckpoints = 100; - - // All invalid archive roots seen - private invalidArchiveRoots: Set = new Set(); + // Recently seen invalid archive roots. + private invalidArchiveRoots = FifoSet.withLimit(MAX_INVALID_CHECKPOINTS); private config: AttestationsBlockWatcherConfig; @@ -98,8 +96,7 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher reason: validationResult.valid === false ? validationResult.reason : 'unknown', }); - // Store the invalid checkpoint - this.addInvalidCheckpoint(event.validationResult.checkpoint); + this.invalidArchiveRoots.add(checkpoint.archive.toString()); // Slash the proposer of the invalid checkpoint this.slashProposer(event.validationResult); @@ -127,8 +124,8 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher WANT_TO_SLASH_EVENT, attestors.map(attestor => ({ validator: attestor, - amount: this.config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: this.config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: BigInt(SlotNumber(checkpoint.slotNumber)), })), ); @@ -181,14 +178,4 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher } } } - - private addInvalidCheckpoint(checkpoint: CheckpointInfo) { - this.invalidArchiveRoots.add(checkpoint.archive.toString()); - - // Prune old entries if we exceed the maximum - if (this.invalidArchiveRoots.size > this.maxInvalidCheckpoints) { - const oldestKey = this.invalidArchiveRoots.keys().next().value!; - this.invalidArchiveRoots.delete(oldestKey); - } - } } diff --git a/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.test.ts b/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.test.ts new file mode 100644 index 000000000000..5d8432b9d3d2 --- /dev/null +++ b/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.test.ts @@ -0,0 +1,290 @@ +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; +import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import { EmptyL1RollupConstants } from '@aztec/stdlib/epoch-helpers'; +import type { P2PClient } from '@aztec/stdlib/interfaces/server'; +import type { BlockProposal, CheckpointProposalCore } from '@aztec/stdlib/p2p'; +import { OffenseType } from '@aztec/stdlib/slashing'; +import { + makeBlockHeader, + makeBlockProposal, + makeCheckpointHeader, + makeCheckpointProposal, +} from '@aztec/stdlib/testing'; + +import { jest } from '@jest/globals'; +import { type MockProxy, mock } from 'jest-mock-extended'; + +import { DefaultSlasherConfig, type SlasherConfig } from '../config.js'; +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs } from '../watcher.js'; +import { BroadcastedInvalidCheckpointProposalWatcher } from './broadcasted_invalid_checkpoint_proposal_watcher.js'; + +describe('BroadcastedInvalidCheckpointProposalWatcher', () => { + let p2pClient: MockProxy>; + let l2BlockSource: MockProxy>; + let epochCache: MockProxy>; + let config: SlasherConfig; + let watcher: BroadcastedInvalidCheckpointProposalWatcher; + let handler: jest.MockedFunction<(args: WantToSlashArgs[]) => void>; + + beforeEach(() => { + p2pClient = mock>(); + l2BlockSource = mock>(); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(12)); + epochCache = mock>(); + epochCache.getSlotNow.mockReturnValue(SlotNumber(12)); + epochCache.getL1Constants.mockReturnValue({ + ...EmptyL1RollupConstants, + epochDuration: 8, + ethereumSlotDuration: 12, + }); + config = { + ...DefaultSlasherConfig, + slashBroadcastedInvalidCheckpointProposalPenalty: 11n, + }; + watcher = new BroadcastedInvalidCheckpointProposalWatcher(p2pClient, l2BlockSource, epochCache, config, 4); + handler = jest.fn(); + watcher.on(WANT_TO_SLASH_EVENT, handler); + }); + + const makeBlocks = async (signer: Secp256k1Signer, slot: SlotNumber, count: number): Promise => + await Promise.all( + Array.from({ length: count }, (_, index) => + makeBlockProposal({ + signer, + blockHeader: makeBlockHeader(index + 1, { slotNumber: slot }), + archiveRoot: Fr.random(), + indexWithinCheckpoint: IndexWithinCheckpoint(index), + }), + ), + ); + + const makeCheckpointCore = async ( + signer: Secp256k1Signer, + slot: SlotNumber, + terminalBlock: BlockProposal, + includeLastBlock = false, + ): Promise => { + const checkpoint = await makeCheckpointProposal({ + signer, + checkpointHeader: makeCheckpointHeader(1, { slotNumber: slot }), + archiveRoot: terminalBlock.archive, + lastBlock: includeLastBlock + ? { + blockHeader: terminalBlock.blockHeader, + indexWithinCheckpoint: terminalBlock.indexWithinCheckpoint, + txHashes: terminalBlock.txHashes, + } + : undefined, + }); + return checkpoint.toCore(); + }; + + const mockProposals = ( + slot: SlotNumber, + blockProposals: BlockProposal[], + checkpointProposals: CheckpointProposalCore[], + ) => + p2pClient.getProposalsForSlot.mockImplementation(querySlot => + Promise.resolve( + querySlot === slot ? { blockProposals, checkpointProposals } : { blockProposals: [], checkpointProposals: [] }, + ), + ); + + it('slashes when higher-index block proposals arrive before a truncated checkpoint proposal', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scanSlot(slot); + + expect(handler).toHaveBeenCalledWith([ + { + validator: signer.address, + amount: 11n, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: 10n, + }, + ]); + }); + + it('slashes when a higher-index proposal arrives after an earlier non-slashing scan', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, blocks.slice(0, 2), [checkpoint]); + + await watcher.scanSlot(slot); + expect(handler).not.toHaveBeenCalled(); + + mockProposals(slot, blocks, [checkpoint]); + await watcher.scanSlot(slot); + + expect(handler).toHaveBeenCalledTimes(1); + expect(handler.mock.calls[0][0][0].validator).toEqual(signer.address); + }); + + it('infers the terminal proposal from a retained block reconstructed out of embedded lastBlock', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpointWithLastBlock = await makeCheckpointProposal({ + signer, + checkpointHeader: makeCheckpointHeader(1, { slotNumber: slot }), + archiveRoot: blocks[1].archive, + lastBlock: { + blockHeader: blocks[1].blockHeader, + indexWithinCheckpoint: blocks[1].indexWithinCheckpoint, + txHashes: blocks[1].txHashes, + }, + }); + mockProposals(slot, [checkpointWithLastBlock.getBlockProposal()!, blocks[2]], [checkpointWithLastBlock.toCore()]); + + await watcher.scanSlot(slot); + + expect(handler).toHaveBeenCalledTimes(1); + expect(handler.mock.calls[0][0][0].validator).toEqual(signer.address); + }); + + it('does not slash when the checkpoint terminates at the highest known block', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[3]); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scanSlot(slot); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('does not slash without a matching signed terminal block proposal', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const missingTerminal = await makeBlockProposal({ + signer, + blockHeader: makeBlockHeader(99, { slotNumber: slot }), + archiveRoot: Fr.random(), + indexWithinCheckpoint: IndexWithinCheckpoint(1), + }); + const checkpoint = await makeCheckpointCore(signer, slot, missingTerminal); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scanSlot(slot); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('does not slash when the higher-index block is signed by a different validator', async () => { + const signer = Secp256k1Signer.random(); + const otherSigner = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 2); + const higherBlock = (await makeBlocks(otherSigner, slot, 3))[2]; + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, [...blocks, higherBlock], [checkpoint]); + + await watcher.scanSlot(slot); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('does not emit duplicate offenses on repeated scans', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scanSlot(slot); + await watcher.scanSlot(slot); + + expect(handler).toHaveBeenCalledTimes(1); + }); + + it('scans a lookback of closed slots', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot).toHaveBeenCalledWith(SlotNumber(7)); + expect(p2pClient.getProposalsForSlot).toHaveBeenCalledWith(SlotNumber(10)); + expect(handler).toHaveBeenCalledTimes(1); + }); + + it('anchors the scan at the archiver synced L2 slot, not the wallclock', async () => { + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(9)); + epochCache.getSlotNow.mockReturnValue(SlotNumber(20)); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot.mock.calls.map(([slot]) => slot)).toEqual([ + SlotNumber(4), + SlotNumber(5), + SlotNumber(6), + SlotNumber(7), + ]); + }); + + it('falls back to the wallclock when the archiver has not yet synced', async () => { + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(undefined); + epochCache.getSlotNow.mockReturnValue(SlotNumber(12)); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot.mock.calls.map(([slot]) => slot)).toEqual([ + SlotNumber(7), + SlotNumber(8), + SlotNumber(9), + SlotNumber(10), + ]); + }); + + it('does not expand the scan window when L1 stalls but wallclock keeps moving', async () => { + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(12)); + epochCache.getSlotNow.mockReturnValue(SlotNumber(12)); + + await watcher.scan(); + p2pClient.getProposalsForSlot.mockClear(); + epochCache.getSlotNow.mockReturnValue(SlotNumber(50)); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot.mock.calls.map(([slot]) => slot)).toEqual([ + SlotNumber(7), + SlotNumber(8), + SlotNumber(9), + SlotNumber(10), + ]); + }); + + it('only expands beyond the lookback for newly closed slots', async () => { + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); + + await watcher.scan(); + p2pClient.getProposalsForSlot.mockClear(); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(13)); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot.mock.calls.map(([slot]) => slot)).toEqual([ + SlotNumber(8), + SlotNumber(9), + SlotNumber(10), + SlotNumber(11), + ]); + }); +}); diff --git a/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts b/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts new file mode 100644 index 000000000000..1e9249b2cdf4 --- /dev/null +++ b/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts @@ -0,0 +1,199 @@ +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { SlotNumber } from '@aztec/foundation/branded-types'; +import { merge, pick } from '@aztec/foundation/collection'; +import type { EthAddress } from '@aztec/foundation/eth-address'; +import { FifoSet } from '@aztec/foundation/fifo-set'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { RunningPromise } from '@aztec/foundation/running-promise'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import type { P2PClient, SlasherConfig } from '@aztec/stdlib/interfaces/server'; +import type { BlockProposal, CheckpointProposalCore } from '@aztec/stdlib/p2p'; +import { OffenseType } from '@aztec/stdlib/slashing'; + +import EventEmitter from 'node:events'; + +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; + +const BroadcastedInvalidCheckpointProposalWatcherConfigKeys = [ + 'slashBroadcastedInvalidCheckpointProposalPenalty', +] as const; + +const SCAN_SLOT_LAG = 1; +const DEFAULT_SCAN_SLOT_LOOKBACK = 4; + +type BroadcastedInvalidCheckpointProposalWatcherConfig = Pick< + SlasherConfig, + (typeof BroadcastedInvalidCheckpointProposalWatcherConfigKeys)[number] +>; + +type ProposalsForSlot = Awaited>; +type P2PProposalsForSlotSource = Pick; + +type SignedBlockProposal = { + proposal: BlockProposal; + signer: EthAddress; +}; + +/** Detects truncated-checkpoint proposal offenses from retained signed P2P proposals. */ +export class BroadcastedInvalidCheckpointProposalWatcher + extends (EventEmitter as new () => WatcherEmitter) + implements Watcher +{ + private readonly log: Logger = createLogger('broadcasted-invalid-checkpoint-proposal-watcher'); + private readonly runningPromise: RunningPromise; + private readonly emittedOffenses: FifoSet; + private readonly scanSlotLookback: number; + private config: BroadcastedInvalidCheckpointProposalWatcherConfig; + private lastScannedSlot: SlotNumber | undefined; + + constructor( + private readonly p2pClient: P2PProposalsForSlotSource, + private readonly l2BlockSource: Pick, + private readonly epochCache: Pick, + config: BroadcastedInvalidCheckpointProposalWatcherConfig, + scanSlotLookback = DEFAULT_SCAN_SLOT_LOOKBACK, + ) { + super(); + const constants = epochCache.getL1Constants(); + this.config = pick(config, ...BroadcastedInvalidCheckpointProposalWatcherConfigKeys); + this.scanSlotLookback = Math.max(1, scanSlotLookback); + + // Bound emitted offenses to the number of slots we rescan. This watcher currently tracks one offense type, + // and at most one offense of that type can be emitted per slot. + const offenseTypes = 1; + this.emittedOffenses = FifoSet.withLimit(offenseTypes * this.scanSlotLookback); + + const intervalMs = Math.max(1000, (constants.ethereumSlotDuration * 1000) / 4); + this.runningPromise = new RunningPromise(() => this.scan(), this.log, intervalMs); + this.log.info('BroadcastedInvalidCheckpointProposalWatcher initialized', { + scanSlotLookback: this.scanSlotLookback, + }); + } + + public updateConfig(config: Partial): void { + this.config = merge(this.config, pick(config, ...BroadcastedInvalidCheckpointProposalWatcherConfigKeys)); + this.log.verbose('BroadcastedInvalidCheckpointProposalWatcher config updated', this.config); + } + + public start(): Promise { + this.runningPromise.start(); + return Promise.resolve(); + } + + public stop(): Promise { + return this.runningPromise.stop(); + } + + /** + * Scans newly closed slots, plus a small lookback for late-arriving proposals. Anchors + * `currentSlot` at the archiver's last synced L2 slot. + */ + public async scan(): Promise { + if (this.config.slashBroadcastedInvalidCheckpointProposalPenalty <= 0n) { + return; + } + + const currentSlot = (await this.l2BlockSource.getSyncedL2SlotNumber()) ?? this.epochCache.getSlotNow(); + if (currentSlot <= SlotNumber(SCAN_SLOT_LAG)) { + return; + } + + const newestSlotToConsider = SlotNumber(currentSlot - 1 - SCAN_SLOT_LAG); + const oldestLookbackSlot = SlotNumber(Math.max(0, newestSlotToConsider - this.scanSlotLookback + 1)); + const oldestUnscannedSlot = + this.lastScannedSlot === undefined ? oldestLookbackSlot : SlotNumber(this.lastScannedSlot + 1); + const oldestSlot = SlotNumber(Math.min(oldestLookbackSlot, oldestUnscannedSlot)); + for (let slot = oldestSlot; slot <= newestSlotToConsider; slot++) { + await this.scanSlot(SlotNumber(slot)); + } + this.lastScannedSlot = newestSlotToConsider; + } + + /** Scans a single slot. Public for tests. */ + public async scanSlot(slot: SlotNumber): Promise { + if (this.config.slashBroadcastedInvalidCheckpointProposalPenalty <= 0n) { + return; + } + + const proposals = await this.p2pClient.getProposalsForSlot(slot); + const slashArgs = this.getSlashArgsForProposals(slot, proposals).filter(args => this.markAsNewOffense(args)); + if (slashArgs.length === 0) { + return; + } + + this.log.info(`Detected broadcasted invalid checkpoint proposal offense`, { + slot, + offenses: slashArgs.map(args => ({ + validator: args.validator.toString(), + offenseType: args.offenseType, + epochOrSlot: args.epochOrSlot, + })), + }); + this.emit(WANT_TO_SLASH_EVENT, slashArgs); + } + + private getSlashArgsForProposals(slot: SlotNumber, proposals: ProposalsForSlot): WantToSlashArgs[] { + const offenders = this.findOffenders(proposals.blockProposals, proposals.checkpointProposals); + // we expect one proposer per slot today. + return [...offenders.values()].map(validator => ({ + validator, + amount: this.config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: BigInt(slot), + })); + } + + private findOffenders(blockProposals: BlockProposal[], checkpointProposals: CheckpointProposalCore[]) { + const blocksBySigner = this.getSignedBlocksBySigner(blockProposals); + const offenders = new Map(); + + for (const checkpoint of checkpointProposals) { + const checkpointSigner = checkpoint.getSender(); + if (!checkpointSigner) { + continue; + } + + const signerKey = checkpointSigner.toString(); + const signerBlocks = blocksBySigner.get(signerKey) ?? []; + const terminalBlocks = signerBlocks.filter( + ({ proposal }) => proposal.slotNumber === checkpoint.slotNumber && proposal.archive.equals(checkpoint.archive), + ); + if (terminalBlocks.length === 0) { + continue; + } + + const hasTruncatedHigherBlock = terminalBlocks.some(terminalBlock => + signerBlocks.some( + ({ proposal }) => + proposal.slotNumber === checkpoint.slotNumber && + proposal.indexWithinCheckpoint > terminalBlock.proposal.indexWithinCheckpoint, + ), + ); + if (hasTruncatedHigherBlock) { + offenders.set(signerKey, checkpointSigner); + } + } + + return offenders; + } + + private getSignedBlocksBySigner(blockProposals: BlockProposal[]): Map { + const blocksBySigner = new Map(); + for (const proposal of blockProposals) { + const signer = proposal.getSender(); + if (!signer) { + continue; + } + const signerKey = signer.toString(); + const signerBlocks = blocksBySigner.get(signerKey) ?? []; + signerBlocks.push({ proposal, signer }); + blocksBySigner.set(signerKey, signerBlocks); + } + return blocksBySigner; + } + + private markAsNewOffense(args: WantToSlashArgs): boolean { + const key = `${args.validator.toString()}-${args.offenseType}-${args.epochOrSlot}`; + return this.emittedOffenses.addIfAbsent(key); + } +} diff --git a/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.test.ts b/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.test.ts new file mode 100644 index 000000000000..8b6fe48f2fde --- /dev/null +++ b/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.test.ts @@ -0,0 +1,120 @@ +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { EthAddress } from '@aztec/foundation/eth-address'; +import { + type ArchiverEmitter, + type CheckpointEquivocationDetectedEvent, + type L2BlockSourceEventEmitter, + L2BlockSourceEvents, +} from '@aztec/stdlib/block'; +import { OffenseType } from '@aztec/stdlib/slashing'; + +import { jest } from '@jest/globals'; +import { type MockProxy, mock } from 'jest-mock-extended'; +import EventEmitter from 'node:events'; + +import { DefaultSlasherConfig, type SlasherConfig } from '../config.js'; +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs } from '../watcher.js'; +import { CheckpointEquivocationWatcher } from './checkpoint_equivocation_watcher.js'; + +describe('CheckpointEquivocationWatcher', () => { + let archiverEmitter: ArchiverEmitter; + let l2BlockSource: Pick; + let epochCache: MockProxy>; + let config: SlasherConfig; + let watcher: CheckpointEquivocationWatcher; + let handler: jest.MockedFunction<(args: WantToSlashArgs[]) => void>; + + const makeEvent = ( + overrides: Partial = {}, + ): CheckpointEquivocationDetectedEvent => ({ + type: L2BlockSourceEvents.CheckpointEquivocationDetected, + slotNumber: SlotNumber(10), + checkpointNumber: CheckpointNumber(2), + l1ArchiveRoot: Fr.random(), + proposedArchiveRoot: Fr.random(), + ...overrides, + }); + + beforeEach(async () => { + archiverEmitter = new EventEmitter() as unknown as ArchiverEmitter; + l2BlockSource = { events: archiverEmitter }; + epochCache = mock>(); + epochCache.getProposerAttesterAddressInSlot.mockResolvedValue(EthAddress.random()); + config = { + ...DefaultSlasherConfig, + slashDuplicateProposalPenalty: 23n, + }; + watcher = new CheckpointEquivocationWatcher(l2BlockSource, epochCache, config); + handler = jest.fn(); + watcher.on(WANT_TO_SLASH_EVENT, handler); + await watcher.start(); + }); + + afterEach(async () => { + await watcher.stop(); + }); + + const emitAndFlush = async (event: CheckpointEquivocationDetectedEvent) => { + archiverEmitter.emit(L2BlockSourceEvents.CheckpointEquivocationDetected, event); + // Allow the async handler to settle. + await new Promise(resolve => setImmediate(resolve)); + }; + + it('emits a DUPLICATE_PROPOSAL slash for the slot proposer when divergence is detected', async () => { + const proposer = EthAddress.random(); + epochCache.getProposerAttesterAddressInSlot.mockResolvedValueOnce(proposer); + + await emitAndFlush(makeEvent()); + + expect(handler).toHaveBeenCalledWith([ + { + validator: proposer, + amount: 23n, + offenseType: OffenseType.DUPLICATE_PROPOSAL, + epochOrSlot: 10n, + }, + ]); + }); + + it('does not emit when there is no proposer for the slot', async () => { + epochCache.getProposerAttesterAddressInSlot.mockResolvedValueOnce(undefined); + + await emitAndFlush(makeEvent()); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('does not emit when the penalty is zero', async () => { + await watcher.stop(); + config = { ...config, slashDuplicateProposalPenalty: 0n }; + watcher = new CheckpointEquivocationWatcher(l2BlockSource, epochCache, config); + handler = jest.fn(); + watcher.on(WANT_TO_SLASH_EVENT, handler); + await watcher.start(); + + await emitAndFlush(makeEvent()); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('emits separately for distinct slots', async () => { + const proposer = EthAddress.random(); + epochCache.getProposerAttesterAddressInSlot.mockResolvedValue(proposer); + + await emitAndFlush(makeEvent({ slotNumber: SlotNumber(10) })); + await emitAndFlush(makeEvent({ slotNumber: SlotNumber(11) })); + + expect(handler).toHaveBeenCalledTimes(2); + expect(handler.mock.calls[0][0][0].epochOrSlot).toBe(10n); + expect(handler.mock.calls[1][0][0].epochOrSlot).toBe(11n); + }); + + it('does not slash after stop()', async () => { + await watcher.stop(); + await emitAndFlush(makeEvent()); + + expect(handler).not.toHaveBeenCalled(); + }); +}); diff --git a/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.ts b/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.ts new file mode 100644 index 000000000000..887986a8ba7e --- /dev/null +++ b/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.ts @@ -0,0 +1,98 @@ +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { merge, pick } from '@aztec/foundation/collection'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { + type CheckpointEquivocationDetectedEvent, + type L2BlockSourceEventEmitter, + L2BlockSourceEvents, +} from '@aztec/stdlib/block'; +import type { SlasherConfig } from '@aztec/stdlib/interfaces/server'; +import { OffenseType } from '@aztec/stdlib/slashing'; + +import EventEmitter from 'node:events'; + +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; + +const CheckpointEquivocationWatcherConfigKeys = ['slashDuplicateProposalPenalty'] as const; + +type CheckpointEquivocationWatcherConfig = Pick< + SlasherConfig, + (typeof CheckpointEquivocationWatcherConfigKeys)[number] +>; + +type EquivocationEventSource = Pick; +type ProposerLookup = Pick; + +/** + * Slashes the slot proposer for DUPLICATE_PROPOSAL when the archiver detects that a + * locally-stored proposed checkpoint disagrees with the L1-confirmed checkpoint at the + * same slot. Both are signed by the slot proposer (the proposed one by accepting it via + * P2P or building it locally; the L1 one by submission), so the proposer equivocated. + */ +export class CheckpointEquivocationWatcher extends (EventEmitter as new () => WatcherEmitter) implements Watcher { + private readonly log: Logger = createLogger('checkpoint-equivocation-watcher'); + private readonly handler: (args: CheckpointEquivocationDetectedEvent) => void; + private config: CheckpointEquivocationWatcherConfig; + + constructor( + private readonly l2BlockSource: EquivocationEventSource, + private readonly epochCache: ProposerLookup, + config: CheckpointEquivocationWatcherConfig, + ) { + super(); + this.config = pick(config, ...CheckpointEquivocationWatcherConfigKeys); + this.handler = event => { + this.onEquivocationDetected(event).catch(err => + this.log.error('Failed to handle checkpoint equivocation event', err), + ); + }; + this.log.info('CheckpointEquivocationWatcher initialized'); + } + + public updateConfig(config: Partial): void { + this.config = merge(this.config, pick(config, ...CheckpointEquivocationWatcherConfigKeys)); + this.log.verbose('CheckpointEquivocationWatcher config updated', this.config); + } + + public start(): Promise { + this.l2BlockSource.events.on(L2BlockSourceEvents.CheckpointEquivocationDetected, this.handler); + return Promise.resolve(); + } + + public stop(): Promise { + this.l2BlockSource.events.off(L2BlockSourceEvents.CheckpointEquivocationDetected, this.handler); + return Promise.resolve(); + } + + /** Public for tests. */ + public async onEquivocationDetected(event: CheckpointEquivocationDetectedEvent): Promise { + if (this.config.slashDuplicateProposalPenalty <= 0n) { + return; + } + + const proposer = await this.epochCache.getProposerAttesterAddressInSlot(event.slotNumber); + if (!proposer) { + this.log.warn(`Cannot attribute checkpoint equivocation: no proposer for slot ${event.slotNumber}`, { + slotNumber: event.slotNumber, + checkpointNumber: event.checkpointNumber, + }); + return; + } + + const slashArgs: WantToSlashArgs = { + validator: proposer, + amount: this.config.slashDuplicateProposalPenalty, + offenseType: OffenseType.DUPLICATE_PROPOSAL, + epochOrSlot: BigInt(event.slotNumber), + }; + + this.log.info(`Detected checkpoint equivocation offense`, { + slotNumber: event.slotNumber, + checkpointNumber: event.checkpointNumber, + l1ArchiveRoot: event.l1ArchiveRoot.toString(), + proposedArchiveRoot: event.proposedArchiveRoot.toString(), + validator: proposer.toString(), + }); + this.emit(WANT_TO_SLASH_EVENT, [slashArgs]); + } +} diff --git a/yarn-project/slasher/src/watchers/data_withholding_watcher.test.ts b/yarn-project/slasher/src/watchers/data_withholding_watcher.test.ts new file mode 100644 index 000000000000..310eaf3c3b62 --- /dev/null +++ b/yarn-project/slasher/src/watchers/data_withholding_watcher.test.ts @@ -0,0 +1,340 @@ +import type { EpochCache } from '@aztec/epoch-cache'; +import { SlotNumber } from '@aztec/foundation/branded-types'; +import { EthAddress } from '@aztec/foundation/eth-address'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; +import type { ITxProvider, P2PApi } from '@aztec/stdlib/interfaces/server'; +import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { OffenseType } from '@aztec/stdlib/slashing'; +import { TxHash } from '@aztec/stdlib/tx'; + +import { type MockProxy, mock } from 'jest-mock-extended'; + +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs } from '../watcher.js'; +import { DataWithholdingWatcher } from './data_withholding_watcher.js'; + +class TestDataWithholdingWatcher extends DataWithholdingWatcher { + public attestersBySlot = new Map(); + + protected override extractAttesters(published: PublishedCheckpoint): Promise { + return Promise.resolve(this.attestersBySlot.get(published.checkpoint.header.slotNumber) ?? []); + } +} + +describe('DataWithholdingWatcher', () => { + const TOLERANCE = 3; + const PENALTY = 1_000_000_000_000_000_000n; + const signatureContext: CoordinationSignatureContext = { + chainId: 31337, + rollupAddress: EthAddress.fromNumber(1), + }; + + let epochCache: MockProxy; + let l2BlockSource: MockProxy>; + let txProvider: MockProxy>; + let p2p: MockProxy>; + let reexecutionTracker: MockProxy>; + let watcher: TestDataWithholdingWatcher; + let l1Constants: L1RollupConstants; + + beforeEach(() => { + epochCache = mock(); + l2BlockSource = mock>(); + txProvider = mock>(); + p2p = mock>(); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); + reexecutionTracker = mock>(); + reexecutionTracker.getTxsCollectedRecord.mockReturnValue(undefined); + + l1Constants = { + l1StartBlock: 1n, + l1GenesisTime: 1_700_000_000n, + slotDuration: 24, + epochDuration: 8, + ethereumSlotDuration: 12, + proofSubmissionEpochs: 1, + targetCommitteeSize: 48, + rollupManaLimit: Number.MAX_SAFE_INTEGER, + }; + epochCache.getL1Constants.mockReturnValue(l1Constants); + + watcher = new TestDataWithholdingWatcher( + epochCache as EpochCache, + l2BlockSource, + txProvider, + p2p, + reexecutionTracker, + signatureContext, + { + slashDataWithholdingPenalty: PENALTY, + slashDataWithholdingToleranceSlots: TOLERANCE, + }, + ); + }); + + afterEach(async () => { + await watcher.stop(); + }); + + /** + * Builds a minimal published-checkpoint shape carrying just the fields the watcher reads: + * `checkpoint.{header.slotNumber, number, archive.root, blocks[*].{header.getSlot, body.txEffects[*].txHash}}`. + * Each block's header.getSlot() returns the checkpoint's slot (single-block-per-checkpoint test default). + */ + const makePublished = (slot: number, txCount: number, blockCount = 1): PublishedCheckpoint => { + const blocks = Array.from({ length: blockCount }, () => ({ + header: { getSlot: () => SlotNumber(slot) }, + body: { txEffects: Array.from({ length: txCount }, () => ({ txHash: TxHash.random() })) }, + })); + return { + checkpoint: { + header: { slotNumber: SlotNumber(slot) }, + number: slot, + archive: { root: { toString: () => `archive-${slot}` } }, + blocks, + }, + } as unknown as PublishedCheckpoint; + }; + + /** Configures the synced-slot fallback used by start() and seeds initial slot. */ + const startAtSlot = async (initialSlot: number) => { + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(initialSlot)); + await watcher.start(); + }; + + /** Sets the watcher's "current slot" as seen by `work()` (via the archiver's synced slot). */ + const setSyncedSlot = (slot: number) => l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(slot)); + + /** Captures emitted slash args. */ + const captureEmits = (): WantToSlashArgs[][] => { + const captured: WantToSlashArgs[][] = []; + watcher.on(WANT_TO_SLASH_EVENT, args => captured.push(args)); + return captured; + }; + + /** Mocks `hasTxs` so the given hashes report as missing and all others as present. */ + const mockMissing = (missingHashes: TxHash[]) => { + const missingSet = new Set(missingHashes.map(h => h.toString())); + txProvider.hasTxs.mockImplementation((hashes: TxHash[]) => + Promise.resolve(hashes.map(h => !missingSet.has(h.toString()))), + ); + }; + + it('does nothing on a tick before tolerance has elapsed', async () => { + await startAtSlot(0); + setSyncedSlot(TOLERANCE - 1); + const captured = captureEmits(); + + await watcher.work(); + + expect(l2BlockSource.getCheckpoint).not.toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('does not look back before its initial slot', async () => { + await startAtSlot(100); + setSyncedSlot(100 + TOLERANCE); + const captured = captureEmits(); + + await watcher.work(); + + expect(l2BlockSource.getCheckpoint).not.toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('skips slots with no published checkpoint', async () => { + await startAtSlot(10); + setSyncedSlot(17); + l2BlockSource.getCheckpoint.mockResolvedValue(undefined); + const captured = captureEmits(); + + await watcher.work(); + + expect(l2BlockSource.getCheckpoint).toHaveBeenCalledWith({ slot: SlotNumber(11) }); + expect(l2BlockSource.getCheckpoint).toHaveBeenCalledWith({ slot: SlotNumber(12) }); + expect(l2BlockSource.getCheckpoint).toHaveBeenCalledWith({ slot: SlotNumber(13) }); + expect(captured).toHaveLength(0); + }); + + it('does not slash when all block proposals report collected=true (skips mempool probe)', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 2); + l2BlockSource.getCheckpoint.mockResolvedValue(published); + reexecutionTracker.getTxsCollectedRecord.mockReturnValue(true); + watcher.attestersBySlot.set(slot, [EthAddress.random(), EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + + expect(txProvider.hasTxs).not.toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('falls back to mempool probe when some blocks have collected=false (DW tolerance may permit late arrivals)', async () => { + // A `false` record means we missed the re-execution deadline, but the DW tolerance window + // gives more time for txs to propagate. The watcher must consult the mempool to decide. + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 2, 2); + l2BlockSource.getCheckpoint.mockResolvedValue(published); + reexecutionTracker.getTxsCollectedRecord.mockImplementation((_s, idx) => (idx === 0 ? true : false)); + + // Mempool now reports both txs as available — late arrival saves the proposer. + mockMissing([]); + watcher.attestersBySlot.set(slot, [EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + + expect(txProvider.hasTxs).toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('falls back to mempool probe when records are partial (some undefined, no false)', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 1, 2); + l2BlockSource.getCheckpoint.mockResolvedValue(published); + reexecutionTracker.getTxsCollectedRecord.mockImplementation((_s, idx) => (idx === 0 ? true : undefined)); + + const missing = published.checkpoint.blocks[1].body.txEffects[0].txHash; + mockMissing([missing]); + const attester = EthAddress.random(); + watcher.attestersBySlot.set(slot, [attester]); + const captured = captureEmits(); + + await watcher.work(); + + expect(txProvider.hasTxs).toHaveBeenCalled(); + expect(captured).toHaveLength(1); + expect(captured[0][0].offenseType).toBe(OffenseType.DATA_WITHHOLDING); + }); + + it('does not slash on partial records when mempool probe finds all txs available', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 2); + l2BlockSource.getCheckpoint.mockResolvedValue(published); + reexecutionTracker.getTxsCollectedRecord.mockReturnValue(undefined); + mockMissing([]); + watcher.attestersBySlot.set(slot, [EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + + expect(txProvider.hasTxs).toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('emits a slash for the per-checkpoint attesters when mempool probe reports missing', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 3); + const missingHash = published.checkpoint.blocks[0].body.txEffects[0].txHash; + l2BlockSource.getCheckpoint.mockResolvedValue(published); + mockMissing([missingHash]); + + const attesterA = EthAddress.random(); + const attesterB = EthAddress.random(); + watcher.attestersBySlot.set(slot, [attesterA, attesterB]); + + const captured = captureEmits(); + + await watcher.work(); + + expect(captured).toHaveLength(1); + expect(captured[0]).toEqual([ + { + validator: attesterA, + amount: PENALTY, + offenseType: OffenseType.DATA_WITHHOLDING, + epochOrSlot: BigInt(slot), + }, + { + validator: attesterB, + amount: PENALTY, + offenseType: OffenseType.DATA_WITHHOLDING, + epochOrSlot: BigInt(slot), + }, + ]); + }); + + it('does not re-emit for the same slot on subsequent ticks', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 1); + const missing = published.checkpoint.blocks[0].body.txEffects[0].txHash; + l2BlockSource.getCheckpoint.mockResolvedValue(published); + mockMissing([missing]); + watcher.attestersBySlot.set(slot, [EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + expect(captured).toHaveLength(1); + + await watcher.work(); + expect(captured).toHaveLength(1); + expect(l2BlockSource.getCheckpoint).toHaveBeenCalledTimes(1); + }); + + it('respects penalty=0 as a disable switch', async () => { + watcher.updateConfig({ slashDataWithholdingPenalty: 0n }); + await startAtSlot(10); + setSyncedSlot(10 + TOLERANCE + 5); + + const captured = captureEmits(); + await watcher.work(); + + expect(l2BlockSource.getCheckpoint).not.toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('does not slash a checkpoint with no recoverable attesters even if txs are missing', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 1); + const missing = published.checkpoint.blocks[0].body.txEffects[0].txHash; + l2BlockSource.getCheckpoint.mockResolvedValue(published); + mockMissing([missing]); + watcher.attestersBySlot.set(slot, []); + const captured = captureEmits(); + + await watcher.work(); + + expect(captured).toHaveLength(0); + }); + + it('sets epochOrSlot to the checkpoint slot, not its epoch (slot-keyed offense)', async () => { + await startAtSlot(0); + setSyncedSlot(1 + TOLERANCE + 1); + + const slot = 1; + const published = makePublished(slot, 1); + const missing = published.checkpoint.blocks[0].body.txEffects[0].txHash satisfies TxHash; + l2BlockSource.getCheckpoint.mockResolvedValue(published); + mockMissing([missing]); + watcher.attestersBySlot.set(slot, [EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + + expect(captured).toHaveLength(1); + expect(captured[0][0].epochOrSlot).toEqual(BigInt(slot)); + }); +}); diff --git a/yarn-project/slasher/src/watchers/data_withholding_watcher.ts b/yarn-project/slasher/src/watchers/data_withholding_watcher.ts new file mode 100644 index 000000000000..091c2be823f6 --- /dev/null +++ b/yarn-project/slasher/src/watchers/data_withholding_watcher.ts @@ -0,0 +1,227 @@ +import type { EpochCache } from '@aztec/epoch-cache'; +import { CheckpointProposalHash, SlotNumber } from '@aztec/foundation/branded-types'; +import { compactArray, merge, pick } from '@aztec/foundation/collection'; +import type { EthAddress } from '@aztec/foundation/eth-address'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { RunningPromise } from '@aztec/foundation/promise'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import { getAttestationInfoFromPublishedCheckpoint } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import type { ITxProvider, P2PApi, SlasherConfig } from '@aztec/stdlib/interfaces/server'; +import { ConsensusPayload, type CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { OffenseType } from '@aztec/stdlib/slashing'; +import type { TxHash } from '@aztec/stdlib/tx'; + +import EventEmitter from 'node:events'; + +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; + +const DataWithholdingWatcherConfigKeys = ['slashDataWithholdingPenalty', 'slashDataWithholdingToleranceSlots'] as const; + +type DataWithholdingWatcherConfig = Pick; + +/** + * Detects data-withholding offenses by probing the local mempool for the txs in published + * checkpoints once they are old enough that an honest node should have collected them. + * + * Per AZIP-7: once `slashDataWithholdingToleranceSlots` full slots have elapsed after the + * checkpoint's slot — i.e. at `slotStart(checkpoint.slot + slashDataWithholdingToleranceSlots + * + 1)` — if any tx from the checkpoint's blocks is still missing locally, the checkpoint's + * attesters are considered at fault for not making the data available, and we emit a slash + * for them. + * + * The watcher ticks at quarter-eth-slot cadence (matching the Sentinel template). On boot it + * floors processing at the current slot — restart-time gaps are accepted and not back-filled, + * matching the Sentinel approach. + */ +export class DataWithholdingWatcher extends (EventEmitter as new () => WatcherEmitter) implements Watcher { + private runningPromise: RunningPromise; + private initialSlot: SlotNumber | undefined; + private lastCheckedSlot: SlotNumber | undefined; + private config: DataWithholdingWatcherConfig; + + constructor( + private readonly epochCache: EpochCache, + private readonly l2BlockSource: Pick, + private readonly txProvider: Pick, + private readonly p2p: Pick, + private readonly reexecutionTracker: Pick, + private readonly signatureContext: CoordinationSignatureContext, + config: DataWithholdingWatcherConfig, + private readonly log: Logger = createLogger('data-withholding-watcher'), + ) { + super(); + this.config = pick(config, ...DataWithholdingWatcherConfigKeys); + const interval = (epochCache.getL1Constants().ethereumSlotDuration * 1000) / 4; + this.runningPromise = new RunningPromise(this.work.bind(this), log, interval); + this.log.verbose(`DataWithholdingWatcher initialized`, this.config); + } + + public async start(): Promise { + // Floor processing at the archiver's synced slot rather than the wallclock — restart-time + // gaps before the archiver catches up are accepted and not back-filled. Falls back to the + // wallclock if the archiver isn't ready yet (cold start). + const syncedSlot = await this.l2BlockSource.getSyncedL2SlotNumber(); + this.initialSlot = syncedSlot ?? this.epochCache.getSlotNow(); + this.log.info(`Starting data-withholding watcher with initial slot ${this.initialSlot}`); + this.runningPromise.start(); + } + + public stop(): Promise { + return this.runningPromise.stop(); + } + + public updateConfig(config: Partial): void { + this.config = merge(this.config, pick(config, ...DataWithholdingWatcherConfigKeys)); + this.log.verbose('DataWithholdingWatcher config updated', this.config); + } + + /** + * Runs every tick. Walks newly-eligible slots and probes their checkpoints for data + * availability; emits a DATA_WITHHOLDING slash for any checkpoint whose txs are missing. + */ + public async work(): Promise { + if (this.initialSlot === undefined) { + return; + } + + if (this.config.slashDataWithholdingPenalty === 0n) { + return; // disabled + } + + // tolerance is the number of full slots that must elapse after the checkpoint's slot + // before we declare its data missing. For checkpoint slot S, we therefore process S + // only once we are in slot `S + tolerance + 1` or later. Drive this off the archiver's + // synced slot rather than the wallclock so we don't make claims about slots we haven't + // fully ingested yet (archiver may lag behind L1). + const tolerance = this.config.slashDataWithholdingToleranceSlots; + const currentSlot = (await this.l2BlockSource.getSyncedL2SlotNumber()) ?? this.epochCache.getSlotNow(); + if (currentSlot <= tolerance) { + return; + } + + const targetSlot = SlotNumber(currentSlot - tolerance - 1); + if (targetSlot <= this.initialSlot) { + return; + } + + const startSlot = this.lastCheckedSlot === undefined ? this.initialSlot : this.lastCheckedSlot; + for (let slot = SlotNumber(startSlot + 1); slot <= targetSlot; slot = SlotNumber(slot + 1)) { + try { + await this.processSlot(slot); + } catch (err) { + this.log.error(`Error processing slot ${slot} for data-withholding check`, err, { slot }); + } + this.lastCheckedSlot = slot; + } + } + + /** Probes the checkpoint at the given slot, if any, and emits a slash on missing txs. */ + private async processSlot(slot: SlotNumber): Promise { + const published = await this.l2BlockSource.getCheckpoint({ slot }); + if (!published) { + this.log.trace(`No published checkpoint at slot ${slot}`, { slot }); + return; + } + + const checkpointNumber = published.checkpoint.number; + + // Per-block tx-collection records (true | false | undefined) for every block in this + // published checkpoint. Captured by the validator's proposal handler at the moment of + // tx collection (i.e. by the *re-execution* deadline). Used as a positive short-circuit + // only: a `true` for every block means we know the data was available locally, so this + // checkpoint cannot be a data-withholding offense. A `false` does *not* trigger a slash + // on its own — the re-execution deadline is much earlier than the data-withholding + // tolerance window, so missing txs at that earlier deadline may still arrive in time. + // Anything other than all-true falls through to the mempool probe, which respects the + // tolerance window. + const collectionRecords = published.checkpoint.blocks.map((block, idx) => + this.reexecutionTracker.getTxsCollectedRecord(block.header.getSlot(), idx), + ); + + if (collectionRecords.every(r => r === true)) { + this.log.trace(`All blocks for checkpoint at slot ${slot} were collected locally; skipping`, { + slot, + checkpointNumber, + }); + return; + } + + const txHashes: TxHash[] = published.checkpoint.blocks.flatMap(block => + block.body.txEffects.map(txEffect => txEffect.txHash), + ); + + if (txHashes.length === 0) { + this.log.trace(`Checkpoint at slot ${slot} has no txs`, { slot }); + return; + } + + const availability = await this.txProvider.hasTxs(txHashes); + const missingTxs = txHashes.filter((_, i) => !availability[i]); + if (missingTxs.length === 0) { + this.log.trace(`All ${txHashes.length} txs available for checkpoint at slot ${slot}`, { slot }); + return; + } + + const attesters = await this.extractAttesters(published); + + if (attesters.length === 0) { + this.log.warn(`Detected data withholding at slot ${slot} but no recoverable attesters`, { + slot, + checkpointNumber, + missingTxs: missingTxs.map(h => h.toString()), + records: collectionRecords, + }); + return; + } + + this.log.warn(`Detected data withholding at slot ${slot}. Slashing ${attesters.length} attesters.`, { + slot, + checkpointNumber, + missingTxs: missingTxs.map(h => h.toString()), + records: collectionRecords, + attesters: attesters.map(a => a.toString()), + }); + + const args: WantToSlashArgs[] = attesters.map(validator => ({ + validator, + amount: this.config.slashDataWithholdingPenalty, + offenseType: OffenseType.DATA_WITHHOLDING, + epochOrSlot: BigInt(slot), + })); + this.emit(WANT_TO_SLASH_EVENT, args); + } + + /** + * Returns the union of: + * 1. attesters whose signatures landed in the published checkpoint on L1, and + * 2. attesters we observed signing the same proposal on p2p (the proposer publishes as + * soon as it has hit committee quorum, so honest peer attestations that arrive after + * that point are dropped — but they still vouched for the data and + * should be slashed for withholding it). + * + * + * Exposed as protected so tests can substitute a deterministic recovery without having + * to construct real secp256k1 signatures. + */ + protected async extractAttesters(published: PublishedCheckpoint): Promise { + const fromL1 = getAttestationInfoFromPublishedCheckpoint(published, this.signatureContext) + .filter(info => info.status === 'recovered-from-signature') + .map(info => info.address); + + const slot = published.checkpoint.header.slotNumber; + const proposalPayloadHash = CheckpointProposalHash.fromBuffer( + ConsensusPayload.fromCheckpoint(published.checkpoint, this.signatureContext).getPayloadHash(), + ); + const fromP2p = await this.p2p + .getCheckpointAttestationsForSlot(slot, proposalPayloadHash) + .then(attestations => attestations.map(a => a.getSender())); + + // Dedupe + const all = new Map(); + for (const addr of compactArray([...fromL1, ...fromP2p])) { + all.set(addr.toString(), addr); + } + return [...all.values()]; + } +} diff --git a/yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts b/yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts deleted file mode 100644 index cca7caf88caa..000000000000 --- a/yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts +++ /dev/null @@ -1,260 +0,0 @@ -import type { EpochCache } from '@aztec/epoch-cache'; -import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; -import { EthAddress } from '@aztec/foundation/eth-address'; -import { sleep } from '@aztec/foundation/sleep'; -import { L2Block, type L2BlockSourceEventEmitter, L2BlockSourceEvents } from '@aztec/stdlib/block'; -import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; -import type { - ICheckpointBlockBuilder, - ICheckpointsBuilder, - ITxProvider, - MerkleTreeWriteOperations, -} from '@aztec/stdlib/interfaces/server'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; -import { OffenseType } from '@aztec/stdlib/slashing'; -import { Tx } from '@aztec/stdlib/tx'; - -import { jest } from '@jest/globals'; -import { type MockProxy, mock } from 'jest-mock-extended'; -import EventEmitter from 'node:events'; -import type { Hex } from 'viem'; - -import { WANT_TO_SLASH_EVENT, type WantToSlashArgs } from '../watcher.js'; -import { EpochPruneWatcher } from './epoch_prune_watcher.js'; - -describe('EpochPruneWatcher', () => { - let watcher: EpochPruneWatcher; - let l2BlockSource: L2BlockSourceEventEmitter; - let l1ToL2MessageSource: MockProxy; - let epochCache: MockProxy; - let txProvider: MockProxy>; - let checkpointsBuilder: MockProxy; - let checkpointBuilder: MockProxy; - let fork: MockProxy; - - let ts: bigint; - let l1Constants: L1RollupConstants; - - const validEpochPrunedPenalty = BigInt(1000000000000000000n); - const dataWithholdingPenalty = BigInt(2000000000000000000n); - - beforeEach(async () => { - l2BlockSource = new MockL2BlockSource() as unknown as L2BlockSourceEventEmitter; - l1ToL2MessageSource = mock(); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue([]); - epochCache = mock(); - txProvider = mock>(); - checkpointsBuilder = mock(); - checkpointBuilder = mock(); - fork = mock(); - checkpointsBuilder.getFork.mockResolvedValue(fork); - checkpointsBuilder.startCheckpoint.mockResolvedValue(checkpointBuilder); - - ts = BigInt(Math.ceil(Date.now() / 1000)); - l1Constants = { - l1StartBlock: 1n, - l1GenesisTime: ts, - slotDuration: 24, - epochDuration: 8, - ethereumSlotDuration: 12, - proofSubmissionEpochs: 1, - targetCommitteeSize: 48, - rollupManaLimit: Number.MAX_SAFE_INTEGER, - }; - - epochCache.getL1Constants.mockReturnValue(l1Constants); - - watcher = new EpochPruneWatcher(l2BlockSource, l1ToL2MessageSource, epochCache, txProvider, checkpointsBuilder, { - slashPrunePenalty: validEpochPrunedPenalty, - slashDataWithholdingPenalty: dataWithholdingPenalty, - }); - await watcher.start(); - }); - - afterEach(async () => { - await watcher.stop(); - }); - - it('should emit WANT_TO_SLASH_EVENT when a validator is in a pruned epoch when data is unavailable', async () => { - const emitSpy = jest.spyOn(watcher, 'emit'); - const epochNumber = EpochNumber(1); - const checkpointNumber = CheckpointNumber(1); - - const block = await L2Block.random( - BlockNumber(12), // block number - { - txsPerBlock: 4, - slotNumber: SlotNumber(10), - checkpointNumber, - }, - ); - txProvider.getAvailableTxs.mockResolvedValue({ txs: [], missingTxs: [block.body.txEffects[0].txHash] }); - - const committee: Hex[] = [ - '0x0000000000000000000000000000000000000abc', - '0x0000000000000000000000000000000000000def', - ]; - epochCache.getCommitteeForEpoch.mockResolvedValue({ - committee: committee.map(EthAddress.fromString), - seed: 0n, - epoch: epochNumber, - isEscapeHatchOpen: false, - }); - - l2BlockSource.events.emit(L2BlockSourceEvents.L2PruneUnproven, { - epochNumber: EpochNumber(1), - blocks: [block], - type: L2BlockSourceEvents.L2PruneUnproven, - }); - - // Just need to yield to the event loop to clear our synchronous promises - await sleep(0); - - expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ - { - validator: EthAddress.fromString(committee[0]), - amount: dataWithholdingPenalty, - offenseType: OffenseType.DATA_WITHHOLDING, - epochOrSlot: BigInt(epochNumber), - }, - { - validator: EthAddress.fromString(committee[1]), - amount: dataWithholdingPenalty, - offenseType: OffenseType.DATA_WITHHOLDING, - epochOrSlot: BigInt(epochNumber), - }, - ] satisfies WantToSlashArgs[]); - }); - - it('should slash if the data is available and the epoch could have been proven', async () => { - const emitSpy = jest.spyOn(watcher, 'emit'); - const checkpointNumber = CheckpointNumber(1); - - const block = await L2Block.random( - BlockNumber(12), // block number - { - txsPerBlock: 4, - slotNumber: SlotNumber(10), - checkpointNumber, - }, - ); - const tx = Tx.random(); - txProvider.getAvailableTxs.mockResolvedValue({ txs: [tx], missingTxs: [] }); - checkpointBuilder.buildBlock.mockResolvedValue({ - block: block, - failedTxs: [], - numTxs: 1, - } as any); - - const committee: Hex[] = [ - '0x0000000000000000000000000000000000000abc', - '0x0000000000000000000000000000000000000def', - ]; - epochCache.getCommitteeForEpoch.mockResolvedValue({ - committee: committee.map(EthAddress.fromString), - seed: 0n, - epoch: EpochNumber(1), - isEscapeHatchOpen: false, - }); - - l2BlockSource.events.emit(L2BlockSourceEvents.L2PruneUnproven, { - epochNumber: EpochNumber(1), - blocks: [block], - type: L2BlockSourceEvents.L2PruneUnproven, - }); - - // Just need to yield to the event loop to clear our synchronous promises - await sleep(0); - - expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ - { - validator: EthAddress.fromString(committee[0]), - amount: validEpochPrunedPenalty, - offenseType: OffenseType.VALID_EPOCH_PRUNED, - epochOrSlot: 1n, - }, - { - validator: EthAddress.fromString(committee[1]), - amount: validEpochPrunedPenalty, - offenseType: OffenseType.VALID_EPOCH_PRUNED, - epochOrSlot: 1n, - }, - ] satisfies WantToSlashArgs[]); - - expect(checkpointsBuilder.startCheckpoint).toHaveBeenCalled(); - expect(checkpointBuilder.buildBlock).toHaveBeenCalledWith( - [tx], - block.header.globalVariables.blockNumber, - block.header.globalVariables.timestamp, - { isBuildingProposal: false, minValidTxs: 0 }, - ); - }); - - it('should not slash if the data is available but the epoch could not have been proven', async () => { - const emitSpy = jest.spyOn(watcher, 'emit'); - const checkpointNumber = CheckpointNumber(1); - - const blockFromL1 = await L2Block.random( - BlockNumber(12), // block number - { - txsPerBlock: 1, - slotNumber: SlotNumber(10), - checkpointNumber, - }, - ); - - const blockFromBuilder = await L2Block.random( - BlockNumber(13), // block number - { - txsPerBlock: 1, - slotNumber: SlotNumber(10), - checkpointNumber, - }, - ); - const tx = Tx.random(); - txProvider.getAvailableTxs.mockResolvedValue({ txs: [tx], missingTxs: [] }); - checkpointBuilder.buildBlock.mockResolvedValue({ - block: blockFromBuilder, - failedTxs: [], - numTxs: 1, - } as any); - - const committee: Hex[] = [ - '0x0000000000000000000000000000000000000abc', - '0x0000000000000000000000000000000000000def', - ]; - epochCache.getCommitteeForEpoch.mockResolvedValue({ - committee: committee.map(EthAddress.fromString), - seed: 0n, - epoch: EpochNumber(1), - isEscapeHatchOpen: false, - }); - - l2BlockSource.events.emit(L2BlockSourceEvents.L2PruneUnproven, { - epochNumber: EpochNumber(1), - blocks: [blockFromL1], - type: L2BlockSourceEvents.L2PruneUnproven, - }); - - // Just need to yield to the event loop to clear our synchronous promises - await sleep(0); - - expect(emitSpy).not.toHaveBeenCalled(); - - expect(checkpointsBuilder.startCheckpoint).toHaveBeenCalled(); - expect(checkpointBuilder.buildBlock).toHaveBeenCalledWith( - [tx], - blockFromL1.header.globalVariables.blockNumber, - blockFromL1.header.globalVariables.timestamp, - { isBuildingProposal: false, minValidTxs: 0 }, - ); - }); -}); - -class MockL2BlockSource { - public readonly events = new EventEmitter(); - public getCheckpoints = () => []; - public getCheckpointsData = () => []; - - constructor() {} -} diff --git a/yarn-project/slasher/src/watchers/epoch_prune_watcher.ts b/yarn-project/slasher/src/watchers/epoch_prune_watcher.ts deleted file mode 100644 index bfbed6d1f552..000000000000 --- a/yarn-project/slasher/src/watchers/epoch_prune_watcher.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { EpochCache } from '@aztec/epoch-cache'; -import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types'; -import { chunkBy, merge, pick } from '@aztec/foundation/collection'; -import type { Fr } from '@aztec/foundation/curves/bn254'; -import { type Logger, createLogger } from '@aztec/foundation/log'; -import { - EthAddress, - L2Block, - type L2BlockSourceEventEmitter, - L2BlockSourceEvents, - type L2PruneUnprovenEvent, -} from '@aztec/stdlib/block'; -import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers'; -import type { - ICheckpointBlockBuilder, - ICheckpointsBuilder, - ITxProvider, - MerkleTreeWriteOperations, - SlasherConfig, -} from '@aztec/stdlib/interfaces/server'; -import { type L1ToL2MessageSource, computeCheckpointOutHash } from '@aztec/stdlib/messaging'; -import { OffenseType, getOffenseTypeName } from '@aztec/stdlib/slashing'; -import type { CheckpointGlobalVariables } from '@aztec/stdlib/tx'; -import { - ReExFailedTxsError, - ReExStateMismatchError, - TransactionsNotAvailableError, - ValidatorError, -} from '@aztec/stdlib/validators'; - -import EventEmitter from 'node:events'; - -import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; - -const EpochPruneWatcherPenaltiesConfigKeys = ['slashPrunePenalty', 'slashDataWithholdingPenalty'] as const; - -type EpochPruneWatcherPenalties = Pick; - -/** - * This watcher is responsible for detecting chain prunes and creating slashing arguments for the committee. - * It only wants to slash if: - * - the transactions are not available - * - OR the archive roots match when re-building all the blocks in the epoch (i.e. the epoch *could* have been proven) - */ -export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter) implements Watcher { - private log: Logger = createLogger('epoch-prune-watcher'); - - // Store bound function reference for proper listener removal - private boundHandlePruneL2Blocks = this.handlePruneL2Blocks.bind(this); - - private penalties: EpochPruneWatcherPenalties; - - constructor( - private l2BlockSource: L2BlockSourceEventEmitter, - private l1ToL2MessageSource: L1ToL2MessageSource, - private epochCache: EpochCache, - private txProvider: Pick, - private checkpointsBuilder: ICheckpointsBuilder, - penalties: EpochPruneWatcherPenalties, - ) { - super(); - this.penalties = pick(penalties, ...EpochPruneWatcherPenaltiesConfigKeys); - this.log.verbose( - `EpochPruneWatcher initialized with penalties: valid epoch pruned=${penalties.slashPrunePenalty} data withholding=${penalties.slashDataWithholdingPenalty}`, - ); - } - - public start() { - this.l2BlockSource.events.on(L2BlockSourceEvents.L2PruneUnproven, this.boundHandlePruneL2Blocks); - return Promise.resolve(); - } - - public stop() { - this.l2BlockSource.events.removeListener(L2BlockSourceEvents.L2PruneUnproven, this.boundHandlePruneL2Blocks); - return Promise.resolve(); - } - - public updateConfig(config: Partial): void { - this.penalties = merge(this.penalties, pick(config, ...EpochPruneWatcherPenaltiesConfigKeys)); - this.log.verbose('EpochPruneWatcher config updated', this.penalties); - } - - private handlePruneL2Blocks(event: L2PruneUnprovenEvent): void { - const { blocks, epochNumber } = event; - void this.processPruneL2Blocks(blocks, epochNumber).catch(err => - this.log.error('Error processing pruned L2 blocks', err, { epochNumber }), - ); - } - - private async emitSlashForEpoch(offense: OffenseType, epochNumber: EpochNumber): Promise { - const validators = await this.getValidatorsForEpoch(epochNumber); - if (validators.length === 0) { - this.log.warn(`No validators found for epoch ${epochNumber} (cannot slash for ${getOffenseTypeName(offense)})`); - return; - } - const args = this.validatorsToSlashingArgs(validators, offense, epochNumber); - this.log.verbose(`Created slash for ${getOffenseTypeName(offense)} at epoch ${epochNumber}`, args); - this.emit(WANT_TO_SLASH_EVENT, args); - } - - private async processPruneL2Blocks(blocks: L2Block[], epochNumber: EpochNumber): Promise { - try { - const l1Constants = this.epochCache.getL1Constants(); - const epochBlocks = blocks.filter(b => getEpochAtSlot(b.header.getSlot(), l1Constants) === epochNumber); - this.log.info( - `Detected chain prune. Validating epoch ${epochNumber} with blocks ${epochBlocks[0]?.number} to ${epochBlocks[epochBlocks.length - 1]?.number}.`, - { blocks: epochBlocks.map(b => b.toBlockInfo()) }, - ); - - await this.validateBlocks(epochBlocks, epochNumber); - this.log.info(`Pruned epoch ${epochNumber} was valid. Want to slash committee for not having it proven.`); - await this.emitSlashForEpoch(OffenseType.VALID_EPOCH_PRUNED, epochNumber); - } catch (error) { - if (error instanceof TransactionsNotAvailableError) { - this.log.info(`Data for pruned epoch ${epochNumber} was not available. Will want to slash.`, { - message: error.message, - }); - await this.emitSlashForEpoch(OffenseType.DATA_WITHHOLDING, epochNumber); - } else { - this.log.error(`Error while validating pruned epoch ${epochNumber}. Will not want to slash.`, error); - } - } - } - - public async validateBlocks(blocks: L2Block[], epochNumber: EpochNumber): Promise { - if (blocks.length === 0) { - return; - } - - // Sort blocks by block number and group by checkpoint - const sortedBlocks = [...blocks].sort((a, b) => a.number - b.number); - const blocksByCheckpoint = chunkBy(sortedBlocks, b => b.checkpointNumber); - - // Get prior checkpoints in the epoch (in case this was a partial prune) to extract the out hashes - const priorCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsData({ epoch: epochNumber })) - .filter(c => c.checkpointNumber < sortedBlocks[0].checkpointNumber) - .map(c => c.checkpointOutHash); - let previousCheckpointOutHashes: Fr[] = [...priorCheckpointOutHashes]; - - const fork = await this.checkpointsBuilder.getFork( - BlockNumber(sortedBlocks[0].header.globalVariables.blockNumber - 1), - ); - try { - for (const checkpointBlocks of blocksByCheckpoint) { - await this.validateCheckpoint(checkpointBlocks, previousCheckpointOutHashes, fork); - - // Compute checkpoint out hash from all blocks in this checkpoint - const checkpointOutHash = computeCheckpointOutHash( - checkpointBlocks.map(b => b.body.txEffects.map(tx => tx.l2ToL1Msgs)), - ); - previousCheckpointOutHashes = [...previousCheckpointOutHashes, checkpointOutHash]; - } - } finally { - await fork.close(); - } - } - - private async validateCheckpoint( - checkpointBlocks: L2Block[], - previousCheckpointOutHashes: Fr[], - fork: MerkleTreeWriteOperations, - ): Promise { - const checkpointNumber = checkpointBlocks[0].checkpointNumber; - this.log.debug(`Validating pruned checkpoint ${checkpointNumber} with ${checkpointBlocks.length} blocks`); - - // Get L1ToL2Messages once for the entire checkpoint - const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber); - - // Build checkpoint constants from first block's global variables - const gv = checkpointBlocks[0].header.globalVariables; - const constants: CheckpointGlobalVariables = { - chainId: gv.chainId, - version: gv.version, - slotNumber: gv.slotNumber, - timestamp: gv.timestamp, - coinbase: gv.coinbase, - feeRecipient: gv.feeRecipient, - gasFees: gv.gasFees, - }; - - // Start checkpoint builder once for all blocks in this checkpoint - const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint( - checkpointNumber, - constants, - 0n, // feeAssetPriceModifier is not used for validation of the checkpoint content - l1ToL2Messages, - previousCheckpointOutHashes, - fork, - this.log.getBindings(), - ); - - // Validate all blocks in the checkpoint sequentially - for (const block of checkpointBlocks) { - await this.validateBlockInCheckpoint(block, checkpointBuilder); - } - } - - private async validateBlockInCheckpoint( - blockFromL1: L2Block, - checkpointBuilder: ICheckpointBlockBuilder, - ): Promise { - this.log.debug(`Validating pruned block ${blockFromL1.header.globalVariables.blockNumber}`); - const txHashes = blockFromL1.body.txEffects.map(txEffect => txEffect.txHash); - // We load txs from the mempool directly, since the TxCollector running in the background has already been - // trying to fetch them from nodes or via reqresp. If we haven't managed to collect them by now, - // it's likely that they are not available in the network at all. - const { txs, missingTxs } = await this.txProvider.getAvailableTxs(txHashes); - - if (missingTxs && missingTxs.length > 0) { - throw new TransactionsNotAvailableError(missingTxs); - } - - const gv = blockFromL1.header.globalVariables; - const { block, failedTxs, numTxs } = await checkpointBuilder.buildBlock(txs, gv.blockNumber, gv.timestamp, { - isBuildingProposal: false, - minValidTxs: 0, - }); - - if (numTxs !== txs.length) { - // This should be detected by state mismatch, but this makes it easier to debug. - throw new ValidatorError(`Built block with ${numTxs} txs, expected ${txs.length}`); - } - if (failedTxs.length > 0) { - throw new ReExFailedTxsError(failedTxs.length); - } - if (!block.archive.root.equals(blockFromL1.archive.root)) { - throw new ReExStateMismatchError(blockFromL1.archive.root, block.archive.root); - } - } - - private async getValidatorsForEpoch(epochNumber: EpochNumber): Promise { - const { committee } = await this.epochCache.getCommitteeForEpoch(epochNumber); - if (!committee) { - this.log.trace(`No committee found for epoch ${epochNumber}`); - return []; - } - return committee; - } - - private validatorsToSlashingArgs( - validators: EthAddress[], - offenseType: OffenseType, - epochOrSlot: EpochNumber, - ): WantToSlashArgs[] { - const penalty = - offenseType === OffenseType.DATA_WITHHOLDING - ? this.penalties.slashDataWithholdingPenalty - : this.penalties.slashPrunePenalty; - return validators.map(v => ({ - validator: v, - amount: penalty, - offenseType, - epochOrSlot: BigInt(epochOrSlot), - })); - } -} diff --git a/yarn-project/sqlite3mc-wasm/scripts/vendor.sh b/yarn-project/sqlite3mc-wasm/scripts/vendor.sh index c4abb0a2ae28..0ea4d3bad4c2 100755 --- a/yarn-project/sqlite3mc-wasm/scripts/vendor.sh +++ b/yarn-project/sqlite3mc-wasm/scripts/vendor.sh @@ -75,7 +75,11 @@ WORK_DIR=$(mktemp -d) trap 'rm -rf "$WORK_DIR"' EXIT echo "==> Downloading ${ASSET}" -curl -fsSL -o "$WORK_DIR/$ASSET" "$URL" +# Retries cover transient DNS / TLS failures on CI runners — a one-off +# `Could not resolve host: release-assets.githubusercontent.com` here has +# dequeued the merge train. +curl -fsSL --retry 5 --retry-delay 2 --retry-all-errors --retry-connrefused \ + -o "$WORK_DIR/$ASSET" "$URL" echo "==> Verifying zip SHA256" ACTUAL_SHA=$(sha256sum "$WORK_DIR/$ASSET" | awk '{print $1}') diff --git a/yarn-project/stdlib/src/abi/decoder.test.ts b/yarn-project/stdlib/src/abi/decoder.test.ts index 6a19c8483296..2992dd4aeb30 100644 --- a/yarn-project/stdlib/src/abi/decoder.test.ts +++ b/yarn-project/stdlib/src/abi/decoder.test.ts @@ -236,12 +236,6 @@ describe('decoder', () => { kind: 'field', }, }, - { - name: 'is_infinite', - type: { - kind: 'boolean', - }, - }, ], }, ], @@ -257,19 +251,10 @@ describe('decoder', () => { Fr.fromBuffer(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')), // address Fr.fromBuffer(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')), // point.x Fr.fromBuffer(Buffer.from('0000000000000000000000000000000000000000000000000000000000000002', 'hex')), // point.y - Fr.fromBuffer(Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')), // point.is_infinite ], ); - expect(decoded).toEqual([ - 1n, - 2n, - false, - 'xyz', - AztecAddress.fromBigInt(1n), - // eslint-disable-next-line camelcase - { x: 1n, y: 2n, is_infinite: false }, - ]); + expect(decoded).toEqual([1n, 2n, false, 'xyz', AztecAddress.fromBigInt(1n), { x: 1n, y: 2n }]); }); it('decodes Option::Some as the wrapped value', () => { diff --git a/yarn-project/stdlib/src/abi/utils.ts b/yarn-project/stdlib/src/abi/utils.ts index a1dea3316468..cd18b8394a0f 100644 --- a/yarn-project/stdlib/src/abi/utils.ts +++ b/yarn-project/stdlib/src/abi/utils.ts @@ -59,10 +59,10 @@ export function isPublicKeysStruct(abiType: AbiType) { abiType.kind === 'struct' && abiType.path === 'aztec::protocol_types::public_keys::PublicKeys' && abiType.fields.length === 4 && - abiType.fields[0].name === 'npk_m' && + abiType.fields[0].name === 'npk_m_hash' && abiType.fields[1].name === 'ivpk_m' && - abiType.fields[2].name === 'ovpk_m' && - abiType.fields[3].name === 'tpk_m' + abiType.fields[2].name === 'ovpk_m_hash' && + abiType.fields[3].name === 'tpk_m_hash' ); } diff --git a/yarn-project/stdlib/src/avm/avm.ts b/yarn-project/stdlib/src/avm/avm.ts index 339fe4271467..a5f2a4963bf3 100644 --- a/yarn-project/stdlib/src/avm/avm.ts +++ b/yarn-project/stdlib/src/avm/avm.ts @@ -130,6 +130,7 @@ export class AvmContractInstanceHint { public readonly currentContractClassId: Fr, public readonly originalContractClassId: Fr, public readonly initializationHash: Fr, + public readonly immutablesHash: Fr, public readonly publicKeys: PublicKeys, ) {} @@ -143,6 +144,7 @@ export class AvmContractInstanceHint { currentContractClassId: schemas.Fr, originalContractClassId: schemas.Fr, initializationHash: schemas.Fr, + immutablesHash: schemas.Fr, publicKeys: PublicKeys.schema, }) .transform( @@ -154,6 +156,7 @@ export class AvmContractInstanceHint { currentContractClassId, originalContractClassId, initializationHash, + immutablesHash, publicKeys, }) => new AvmContractInstanceHint( @@ -164,6 +167,7 @@ export class AvmContractInstanceHint { currentContractClassId, originalContractClassId, initializationHash, + immutablesHash, publicKeys, ), ); @@ -188,6 +192,7 @@ export class AvmContractInstanceHint { Fr.fromPlainObject(obj.currentContractClassId), Fr.fromPlainObject(obj.originalContractClassId), Fr.fromPlainObject(obj.initializationHash), + Fr.fromPlainObject(obj.immutablesHash), PublicKeys.fromPlainObject(obj.publicKeys), ); } diff --git a/yarn-project/stdlib/src/avm/message_pack.ts b/yarn-project/stdlib/src/avm/message_pack.ts index f07953876e2c..d1d75790f8e9 100644 --- a/yarn-project/stdlib/src/avm/message_pack.ts +++ b/yarn-project/stdlib/src/avm/message_pack.ts @@ -64,13 +64,22 @@ function setUpMessagePackExtensions() { addExtension({ Class: Point, write: (p: Point) => { - assert(!p.inf, 'Cannot serialize infinity'); - // TODO: should these be Frs? + // TODO: Now that we use a 2 elt point representation, we should be able to handle infs here. + // However this opens possible bad paths with public keys and requires sanitised conversion between + // BB's inf representation (see below), and ours/Noir's (0, 0), and empty points from BB, when inf + // does not actually pass through. + assert(!p.isInfinite, 'Cannot serialize infinity'); return { x: new Fq(p.x.toBigInt()), y: new Fq(p.y.toBigInt()) }; }, read: (data: { x: Fq; y: Fq }) => { + // Note: BB encodes infinity as x == y == Buffer of all ones. + // Infinity should never pass through here, but for correctness: + const ALL_ONES = (1n << 256n) - 1n; + if (data.x.toBigInt() === ALL_ONES && data.y.toBigInt() === ALL_ONES) { + return Point.INFINITY; + } // Convert Fq back to Fr for Point constructor - return new Point(new Fr(data.x.toBigInt()), new Fr(data.y.toBigInt()), false); + return new Point(new Fr(data.x.toBigInt()), new Fr(data.y.toBigInt())); }, }); // EthAddress is a class that has a buffer in TS, but is itself just a field in C++. diff --git a/yarn-project/stdlib/src/avm/revert_code.ts b/yarn-project/stdlib/src/avm/revert_code.ts index 810c779d563b..23d054af08e7 100644 --- a/yarn-project/stdlib/src/avm/revert_code.ts +++ b/yarn-project/stdlib/src/avm/revert_code.ts @@ -28,12 +28,6 @@ export class RevertCode { } static readonly OK: RevertCode = new RevertCode(RevertCodeEnum.OK); static readonly REVERTED: RevertCode = new RevertCode(RevertCodeEnum.REVERTED); - /** @deprecated Use REVERTED instead. */ - static readonly APP_LOGIC_REVERTED: RevertCode = RevertCode.REVERTED; - /** @deprecated Use REVERTED instead. */ - static readonly TEARDOWN_REVERTED: RevertCode = RevertCode.REVERTED; - /** @deprecated Use REVERTED instead. */ - static readonly BOTH_REVERTED: RevertCode = RevertCode.REVERTED; public getCode(): RevertCodeEnum { return this.code; diff --git a/yarn-project/stdlib/src/aztec-address/aztec-address.test.ts b/yarn-project/stdlib/src/aztec-address/aztec-address.test.ts index 2efab96544e7..d00329824a02 100644 --- a/yarn-project/stdlib/src/aztec-address/aztec-address.test.ts +++ b/yarn-project/stdlib/src/aztec-address/aztec-address.test.ts @@ -40,7 +40,7 @@ describe('aztec-address', () => { it("reconstructs an address's point", async () => { const address = await AztecAddress.random(); const point = await address.toAddressPoint(); - expect(point.isOnGrumpkin()).toEqual(true); + expect(point.isOnCurve()).toEqual(true); }); it('throws for an invalid address', async () => { diff --git a/yarn-project/stdlib/src/block/l2_block_source.ts b/yarn-project/stdlib/src/block/l2_block_source.ts index c8ac9b303b33..429e36da59d7 100644 --- a/yarn-project/stdlib/src/block/l2_block_source.ts +++ b/yarn-project/stdlib/src/block/l2_block_source.ts @@ -293,6 +293,7 @@ export type ArchiverEmitter = TypedEventEmitter<{ [L2BlockSourceEvents.L2BlockProven]: (args: L2BlockProvenEvent) => void; [L2BlockSourceEvents.InvalidAttestationsCheckpointDetected]: (args: InvalidCheckpointDetectedEvent) => void; [L2BlockSourceEvents.L2BlocksCheckpointed]: (args: L2CheckpointEvent) => void; + [L2BlockSourceEvents.CheckpointEquivocationDetected]: (args: CheckpointEquivocationDetectedEvent) => void; }>; export interface L2BlockSourceEventEmitter extends L2BlockSource { events: ArchiverEmitter; @@ -374,6 +375,7 @@ export enum L2BlockSourceEvents { L2BlockProven = 'l2BlockProven', L2BlocksCheckpointed = 'l2BlocksCheckpointed', InvalidAttestationsCheckpointDetected = 'invalidCheckpointDetected', + CheckpointEquivocationDetected = 'checkpointEquivocationDetected', } export type L2BlockProvenEvent = { @@ -404,3 +406,15 @@ export type InvalidCheckpointDetectedEvent = { type: 'invalidCheckpointDetected'; validationResult: ValidateCheckpointNegativeResult; }; + +/** + * Emitted when a local proposed checkpoint is found to disagree with the L1-confirmed + * checkpoint at the same slot. The slot proposer signed both — equivocation. + */ +export type CheckpointEquivocationDetectedEvent = { + type: 'checkpointEquivocationDetected'; + slotNumber: SlotNumber; + checkpointNumber: CheckpointNumber; + l1ArchiveRoot: Fr; + proposedArchiveRoot: Fr; +}; diff --git a/yarn-project/stdlib/src/block/l2_block_stream/l2_tips_store_base.ts b/yarn-project/stdlib/src/block/l2_block_stream/l2_tips_store_base.ts index 676e732b665b..9637ff5fd17d 100644 --- a/yarn-project/stdlib/src/block/l2_block_stream/l2_tips_store_base.ts +++ b/yarn-project/stdlib/src/block/l2_block_stream/l2_tips_store_base.ts @@ -213,11 +213,30 @@ export abstract class L2TipsStoreBase implements L2BlockStreamEventHandler, L2Bl await this.saveTag('finalized', event.block); const finalizedCheckpointNumber = await this.getCheckpointNumberForBlock(event.block.number); - await this.deleteBlockHashesBefore(event.block.number); - await this.deleteBlockToCheckpointBefore(event.block.number); + // Cap the deletion bound at the lowest live tip. This should always be the finalized tip, but + // we have hit bugs where this is not the case. Deleting the block hash, block-to-checkpoint mapping, + // or enclosing checkpoint object for a live tip would dangle subsequent `getBlockId`/`getCheckpointId` + // lookups and lock the block stream into an error loop. + const tips = await Promise.all([ + this.getTip('proposed'), + this.getTip('proposedCheckpoint'), + this.getTip('checkpointed'), + this.getTip('proven'), + ]); + const liveTipBlocks = tips.filter((t): t is BlockNumber => t !== undefined && t > 0); + const safeBlockBound = BlockNumber(Math.min(event.block.number, ...liveTipBlocks)); + await this.deleteBlockHashesBefore(safeBlockBound); + await this.deleteBlockToCheckpointBefore(safeBlockBound); if (finalizedCheckpointNumber !== undefined) { - await this.deleteCheckpointsBefore(finalizedCheckpointNumber); + const tipCheckpoints = await Promise.all(liveTipBlocks.map(b => this.getCheckpointNumberForBlock(b))); + const safeCheckpointBound = CheckpointNumber( + Math.min( + finalizedCheckpointNumber, + ...tipCheckpoints.filter((c): c is CheckpointNumber => c !== undefined && c > 0), + ), + ); + await this.deleteCheckpointsBefore(safeCheckpointBound); } }); } diff --git a/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.test.ts b/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.test.ts new file mode 100644 index 000000000000..7aec09513992 --- /dev/null +++ b/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.test.ts @@ -0,0 +1,168 @@ +import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { Fr } from '@aztec/foundation/curves/bn254'; + +import { CheckpointReexecutionTracker } from './checkpoint_reexecution_tracker.js'; + +describe('CheckpointReexecutionTracker', () => { + let tracker: CheckpointReexecutionTracker; + + beforeEach(() => { + tracker = new CheckpointReexecutionTracker(); + }); + + it('records and queries `valid` outcomes by (checkpoint number, archive root)', () => { + const cp = CheckpointNumber(7); + const archive = Fr.random(); + tracker.recordOutcome(SlotNumber(42), archive, 'valid', cp); + + expect(tracker.hasReexecuted(cp, archive)).toBe(true); + expect(tracker.hasReexecuted(cp, Fr.random())).toBe(false); + expect(tracker.hasReexecuted(CheckpointNumber(8), archive)).toBe(false); + }); + + it('hasReexecuted is true only for `valid` outcomes', () => { + const cp = CheckpointNumber(1); + const archive = Fr.random(); + + tracker.recordOutcome(SlotNumber(1), archive, 'invalid', cp); + expect(tracker.hasReexecuted(cp, archive)).toBe(false); + + tracker.recordOutcome(SlotNumber(1), archive, 'unvalidated', cp); + expect(tracker.hasReexecuted(cp, archive)).toBe(false); + + tracker.recordOutcome(SlotNumber(1), archive, 'valid', cp); + expect(tracker.hasReexecuted(cp, archive)).toBe(true); + }); + + it('exposes outcomes by slot', () => { + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'invalid', CheckpointNumber(2)); + tracker.recordOutcome(SlotNumber(30), Fr.random(), 'unvalidated', CheckpointNumber(3)); + + expect(tracker.getOutcomeForSlot(SlotNumber(10))).toBe('valid'); + expect(tracker.getOutcomeForSlot(SlotNumber(20))).toBe('invalid'); + expect(tracker.getOutcomeForSlot(SlotNumber(30))).toBe('unvalidated'); + expect(tracker.getOutcomeForSlot(SlotNumber(99))).toBeUndefined(); + }); + + it('records slot-only outcomes when checkpoint number is unknown', () => { + const archive = Fr.random(); + tracker.recordOutcome(SlotNumber(5), archive, 'invalid'); + + expect(tracker.getOutcomeForSlot(SlotNumber(5))).toBe('invalid'); + expect(tracker.hasReexecuted(CheckpointNumber(0), archive)).toBe(false); + }); + + it('tracks competing archive roots at the same checkpoint independently', () => { + const cp = CheckpointNumber(5); + const archiveA = Fr.random(); + const archiveB = Fr.random(); + + tracker.recordOutcome(SlotNumber(50), archiveB, 'invalid', cp); + tracker.recordOutcome(SlotNumber(51), archiveA, 'valid', cp); + + expect(tracker.hasReexecuted(cp, archiveA)).toBe(true); + expect(tracker.hasReexecuted(cp, archiveB)).toBe(false); + }); + + it('removeBefore drops entries below the cutoff and clears their slot index', () => { + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'valid', CheckpointNumber(2)); + tracker.recordOutcome(SlotNumber(30), Fr.random(), 'valid', CheckpointNumber(3)); + + tracker.removeBefore(CheckpointNumber(3)); + + expect(tracker.getOutcomeForSlot(SlotNumber(10))).toBeUndefined(); + expect(tracker.getOutcomeForSlot(SlotNumber(20))).toBeUndefined(); + expect(tracker.getOutcomeForSlot(SlotNumber(30))).toBe('valid'); + }); + + it('overwrites a prior outcome for the same (checkpoint, archive)', () => { + const cp = CheckpointNumber(1); + const archive = Fr.random(); + tracker.recordOutcome(SlotNumber(1), archive, 'unvalidated', cp); + tracker.recordOutcome(SlotNumber(1), archive, 'valid', cp); + + expect(tracker.hasReexecuted(cp, archive)).toBe(true); + expect(tracker.getOutcomeForSlot(SlotNumber(1))).toBe('valid'); + }); + + it('removeBefore drops slot-only entries older than the highest removed slot', () => { + // Slot-only entries (no checkpoint number) cannot be reached via byCheckpoint pruning. + // Without slot-watermark pruning they would accumulate forever. + tracker.recordOutcome(SlotNumber(5), Fr.random(), 'unvalidated'); + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordOutcome(SlotNumber(12), Fr.random(), 'unvalidated'); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'valid', CheckpointNumber(2)); + tracker.recordOutcome(SlotNumber(25), Fr.random(), 'unvalidated'); + + tracker.removeBefore(CheckpointNumber(2)); + + expect(tracker.getOutcomeForSlot(SlotNumber(5))).toBeUndefined(); + expect(tracker.getOutcomeForSlot(SlotNumber(10))).toBeUndefined(); + // Slot 12 is above the highest removed slot (10) + expect(tracker.getOutcomeForSlot(SlotNumber(12))).toBe('unvalidated'); + expect(tracker.getOutcomeForSlot(SlotNumber(20))).toBe('valid'); + expect(tracker.getOutcomeForSlot(SlotNumber(25))).toBe('unvalidated'); + }); + + describe('recordTxsCollected', () => { + it('records and queries by (slot, indexWithinCheckpoint) with three-valued result', () => { + tracker.recordTxsCollected(SlotNumber(11), 0, true); + tracker.recordTxsCollected(SlotNumber(11), 1, false); + + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 0)).toBe(true); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 1)).toBe(false); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 2)).toBeUndefined(); + expect(tracker.getTxsCollectedRecord(SlotNumber(99), 0)).toBeUndefined(); + }); + + it('preserves prior txsCollected entries when recordOutcome fires for the same slot', () => { + tracker.recordTxsCollected(SlotNumber(11), 0, true); + tracker.recordTxsCollected(SlotNumber(11), 1, false); + + tracker.recordOutcome(SlotNumber(11), Fr.random(), 'valid', CheckpointNumber(7)); + + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 0)).toBe(true); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 1)).toBe(false); + expect(tracker.getOutcomeForSlot(SlotNumber(11))).toBe('valid'); + }); + + it('overwrites a prior collected value at the same (slot, index)', () => { + tracker.recordTxsCollected(SlotNumber(11), 0, false); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 0)).toBe(false); + + tracker.recordTxsCollected(SlotNumber(11), 0, true); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 0)).toBe(true); + }); + + it('removeBefore drops txsCollected entries together with their slot', () => { + tracker.recordTxsCollected(SlotNumber(10), 0, true); + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordTxsCollected(SlotNumber(20), 0, false); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'valid', CheckpointNumber(2)); + + tracker.removeBefore(CheckpointNumber(2)); + + expect(tracker.getTxsCollectedRecord(SlotNumber(10), 0)).toBeUndefined(); + expect(tracker.getTxsCollectedRecord(SlotNumber(20), 0)).toBe(false); + }); + + it('removeBefore drops standalone txsCollected entries via the slot watermark', () => { + // recordTxsCollected without a subsequent recordOutcome creates a slot-only entry with + // no checkpoint number; it must still be reachable by the slot-watermark cleanup. + tracker.recordTxsCollected(SlotNumber(5), 0, true); + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordTxsCollected(SlotNumber(12), 0, true); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'valid', CheckpointNumber(2)); + + tracker.removeBefore(CheckpointNumber(2)); + + expect(tracker.getTxsCollectedRecord(SlotNumber(5), 0)).toBeUndefined(); + expect(tracker.getTxsCollectedRecord(SlotNumber(10), 0)).toBeUndefined(); + // Slot 12 is above the highest removed slot (10), so it survives. + expect(tracker.getTxsCollectedRecord(SlotNumber(12), 0)).toBe(true); + expect(tracker.getOutcomeForSlot(SlotNumber(20))).toBe('valid'); + }); + }); +}); diff --git a/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.ts b/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.ts new file mode 100644 index 000000000000..c4b85c73e2ea --- /dev/null +++ b/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.ts @@ -0,0 +1,167 @@ +import type { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import type { Fr } from '@aztec/foundation/curves/bn254'; + +/** + * Outcome of attempting to re-execute a checkpoint proposal locally. + * + * - `valid` — re-execution succeeded and the computed checkpoint matched the proposal. + * - `invalid` — the proposal disagreed with the computed checkpoint, or violated a deterministic + * constraint (limits, signatures, etc). + * - `unvalidated` — the local node could not complete validation for non-deterministic reasons + * (missing blocks/txs, timeouts, infra errors). Treated as proposer-fault for + * slashing but surfaced separately for telemetry. + */ +export type ReexecutionOutcome = 'valid' | 'invalid' | 'unvalidated'; + +/** + * Tracks two pieces of per-slot state collected during proposal handling: + * + * 1. Whether each block proposal's transactions were successfully collected locally + * (keyed by `slot` + `indexWithinCheckpoint`). Consumed by the data-withholding watcher. + * 2. The outcome of locally re-executing each checkpoint proposal (keyed by + * `(checkpointNumber, archiveRoot)` and by `slot`). Consumed by the data-withholding + * watcher (via `hasReexecuted`) and the sentinel (via `getOutcomeForSlot`). + * + * Both pieces of state live on the same per-slot `Entry`, so cleanup via `removeBefore` + * naturally drops everything for a pruned slot in one step. + */ +interface Entry { + // Set by recordOutcome — these may be undefined until the checkpoint proposal has been + // evaluated. recordTxsCollected may create an Entry before any of them are known. + checkpointNumber: CheckpointNumber | undefined; + archiveRoot: string | undefined; + outcome: ReexecutionOutcome | undefined; + + slot: SlotNumber; + + // Per block-proposal at this slot: indexWithinCheckpoint → true (collected) | false (failed to collect). + txsCollected: Map; +} + +export class CheckpointReexecutionTracker { + private readonly byCheckpoint = new Map>(); + private readonly bySlot = new Map(); + + /** + * Record the outcome of evaluating a checkpoint proposal. + * @param slot - Slot the proposal was for. Always required. + * @param archiveRoot - Archive root in the proposal. + * @param outcome - Outcome of evaluation. + * @param checkpointNumber - Checkpoint number, if known. Required for `valid` outcomes; optional + * for `invalid`/`unvalidated` because some early rejections fire before blocks are loaded. + */ + public recordOutcome( + slot: SlotNumber, + archiveRoot: Fr, + outcome: ReexecutionOutcome, + checkpointNumber?: CheckpointNumber, + ): void { + const archiveRootStr = archiveRoot.toString(); + + // Preserve any per-block txsCollected already accumulated for this slot. + const existing = this.bySlot.get(slot); + const entry: Entry = { + checkpointNumber, + archiveRoot: archiveRootStr, + slot, + outcome, + txsCollected: existing?.txsCollected ?? new Map(), + }; + + if (checkpointNumber !== undefined) { + let archives = this.byCheckpoint.get(checkpointNumber); + if (!archives) { + archives = new Map(); + this.byCheckpoint.set(checkpointNumber, archives); + } + archives.set(archiveRootStr, entry); + } + + this.bySlot.set(slot, entry); + } + + /** + * Record whether the local node successfully collected the transactions for a block proposal. + * Called from the validator's proposal handler immediately after tx collection completes + * (regardless of whether re-execution will subsequently succeed). The data-withholding + * watcher consults these records as an authoritative signal: tx availability now is too + * weak (txs may have been evicted from the mempool by the time the watcher runs), but a + * record that the txs *were* available at proposal time still vouches for the proposer. + * + * @param slot - Slot the block proposal was for. + * @param indexWithinCheckpoint - Index of the block within its enclosing checkpoint. + * @param collected - True if every tx in the proposal was collected locally before deadline. + */ + public recordTxsCollected(slot: SlotNumber, indexWithinCheckpoint: number, collected: boolean): void { + let entry = this.bySlot.get(slot); + if (!entry) { + entry = { + checkpointNumber: undefined, + archiveRoot: undefined, + slot, + outcome: undefined, + txsCollected: new Map(), + }; + this.bySlot.set(slot, entry); + } + entry.txsCollected.set(indexWithinCheckpoint, collected); + } + + /** + * Returns true if the given (checkpoint number, archive root) has been successfully + * re-executed locally (outcome `valid`). + */ + public hasReexecuted(checkpointNumber: CheckpointNumber, archiveRoot: Fr): boolean { + return this.byCheckpoint.get(checkpointNumber)?.get(archiveRoot.toString())?.outcome === 'valid'; + } + + /** Returns the recorded outcome for a given slot, or undefined if no proposal was evaluated. */ + public getOutcomeForSlot(slot: SlotNumber): ReexecutionOutcome | undefined { + return this.bySlot.get(slot)?.outcome; + } + + /** + * Returns the recorded tx-collection result for a block proposal at the given slot and + * `indexWithinCheckpoint`, or `undefined` if no record exists. + * + * Three-valued by design: + * - `true` — we collected every tx for this block proposal before the deadline. + * - `false` — we tried and failed (missing txs at the deadline). + * - `undefined` — no record (e.g. we never saw the block proposal). Callers should fall + * back to a current-state check (e.g. mempool probe) for this case. + */ + public getTxsCollectedRecord(slot: SlotNumber, indexWithinCheckpoint: number): boolean | undefined { + return this.bySlot.get(slot)?.txsCollected.get(indexWithinCheckpoint); + } + + /** Drops entries for checkpoints with `number < checkpointNumber`. */ + public removeBefore(checkpointNumber: CheckpointNumber): void { + // Track the highest slot among checkpoints we're pruning. Once we know it, any slot + // strictly below that watermark is older than the most recently pruned checkpoint and + // can be dropped from `bySlot` too — including slot-only entries (no checkpoint number) + // which would otherwise leak, because removing by checkpoint number can't reach them. + let maxRemovedSlot: SlotNumber | undefined; + for (const [n, archives] of this.byCheckpoint) { + if (n < checkpointNumber) { + for (const entry of archives.values()) { + // Only drop the slot index if it still points at the entry we're removing. + if (this.bySlot.get(entry.slot) === entry) { + this.bySlot.delete(entry.slot); + } + if (maxRemovedSlot === undefined || entry.slot > maxRemovedSlot) { + maxRemovedSlot = entry.slot; + } + } + this.byCheckpoint.delete(n); + } + } + + if (maxRemovedSlot !== undefined) { + for (const slot of [...this.bySlot.keys()]) { + if (slot < maxRemovedSlot) { + this.bySlot.delete(slot); + } + } + } + } +} diff --git a/yarn-project/stdlib/src/checkpoint/index.ts b/yarn-project/stdlib/src/checkpoint/index.ts index 33dec7639e8c..cff0a7d04b2d 100644 --- a/yarn-project/stdlib/src/checkpoint/index.ts +++ b/yarn-project/stdlib/src/checkpoint/index.ts @@ -1,6 +1,7 @@ export * from './checkpoint.js'; export * from './checkpoint_data.js'; export * from './checkpoint_info.js'; +export * from './checkpoint_reexecution_tracker.js'; export * from './digest.js'; export * from './previous_checkpoint_out_hashes.js'; export * from './published_checkpoint.js'; diff --git a/yarn-project/stdlib/src/contract/complete_address.test.ts b/yarn-project/stdlib/src/contract/complete_address.test.ts index 0d68a3366609..c9f610801965 100644 --- a/yarn-project/stdlib/src/contract/complete_address.test.ts +++ b/yarn-project/stdlib/src/contract/complete_address.test.ts @@ -3,6 +3,7 @@ import { Point } from '@aztec/foundation/curves/grumpkin'; import { AztecAddress } from '../aztec-address/index.js'; import { computeAddress } from '../keys/derivation.js'; +import { hashPublicKey } from '../keys/public_key.js'; import { PublicKeys } from '../keys/public_keys.js'; import { CompleteAddress } from './complete_address.js'; @@ -47,7 +48,12 @@ describe('CompleteAddress', () => { const partialAddress = Fr.fromHexString('0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de'); - const publicKeys = new PublicKeys(npkM, ivpkM, ovpkM, tpkM); + const publicKeys = new PublicKeys( + await hashPublicKey(npkM), + ivpkM, + await hashPublicKey(ovpkM), + await hashPublicKey(tpkM), + ); // Compute the expected address from the public keys and partial address const expectedAddress = await computeAddress(publicKeys, partialAddress); diff --git a/yarn-project/stdlib/src/contract/complete_address.ts b/yarn-project/stdlib/src/contract/complete_address.ts index 4b0442ebbb40..cea9fc138c2e 100644 --- a/yarn-project/stdlib/src/contract/complete_address.ts +++ b/yarn-project/stdlib/src/contract/complete_address.ts @@ -38,7 +38,8 @@ export class CompleteAddress { } /** Size in bytes of an instance */ - static readonly SIZE_IN_BYTES = 32 * 10; + // address (1 Fr) + publicKeys (1 Fr hash + 1 Point + 2 Fr hashes = 5 Fr) + partialAddress (1 Fr) = 7 Fr + static readonly SIZE_IN_BYTES = 32 * 7; static get schema() { return hexSchemaFor(CompleteAddress); @@ -54,8 +55,11 @@ export class CompleteAddress { static async fromSecretKeyAndPartialAddress(secretKey: Fr, partialAddress: Fr): Promise { const { publicKeys } = await deriveKeys(secretKey); - const address = await computeAddress(publicKeys, partialAddress); + return await this.fromPublicKeysAndPartialAddress(publicKeys, partialAddress); + } + static async fromPublicKeysAndPartialAddress(publicKeys: PublicKeys, partialAddress: Fr): Promise { + const address = await computeAddress(publicKeys, partialAddress); return new CompleteAddress(address, publicKeys, partialAddress); } @@ -87,7 +91,7 @@ export class CompleteAddress { * @returns A readable string representation of the complete address. */ public toReadableString(): string { - return `Address: ${this.address.toString()}\nMaster Nullifier Public Key: ${this.publicKeys.masterNullifierPublicKey.toString()}\nMaster Incoming Viewing Public Key: ${this.publicKeys.masterIncomingViewingPublicKey.toString()}\nMaster Outgoing Viewing Public Key: ${this.publicKeys.masterOutgoingViewingPublicKey.toString()}\nMaster Tagging Public Key: ${this.publicKeys.masterTaggingPublicKey.toString()}\nPartial Address: ${this.partialAddress.toString()}\n`; + return `Address: ${this.address.toString()}\nNpkM hash: ${this.publicKeys.npkMHash.toString()}\nIvpkM: ${this.publicKeys.ivpkM.toString()}\nOvpkM hash: ${this.publicKeys.ovpkMHash.toString()}\nTpkM hash: ${this.publicKeys.tpkMHash.toString()}\nPartial Address: ${this.partialAddress.toString()}\n`; } /** diff --git a/yarn-project/stdlib/src/contract/contract_address.test.ts b/yarn-project/stdlib/src/contract/contract_address.test.ts index def2ccb6bac6..5470ca43e78e 100644 --- a/yarn-project/stdlib/src/contract/contract_address.test.ts +++ b/yarn-project/stdlib/src/contract/contract_address.test.ts @@ -23,19 +23,18 @@ describe('ContractAddress', () => { `"0x2f43fe475e50f6066260038fd16fa97029a76395b2d38388808e60bc24651a0c"`, ); }); - it('computeSaltedInitializationHash', async () => { const mockInstance = { initializationHash: new Fr(1), salt: new Fr(2), deployer: AztecAddress.fromField(new Fr(4)), + immutablesHash: new Fr(3), }; const result = await computeSaltedInitializationHash(mockInstance); expect(result.toString()).toMatchInlineSnapshot( - `"0x2175c2437c52b1bfae8eed40f2e9968546a7053272f94f3937c52ed7e0018349"`, + `"0x093c5f7e0d5a56a1fce27bb347233fd1884db1ff78573c5b9b2de9d3fe8babe1"`, ); }); - it('computeInitializationHash', async () => { const mockInitFn: FunctionAbi = { functionType: FunctionType.PRIVATE, @@ -53,17 +52,16 @@ describe('ContractAddress', () => { `"0x08b683284b4344302193cb36c05f043d4225e2d88d9e0f6ffde12547098cab98"`, ); }); - it('computeInitializationHash empty', async () => { const result = await computeInitializationHash(undefined, []); expect(result).toEqual(Fr.ZERO); }); - it('computeContractAddressFromInstance', async () => { const secretKey = new Fr(2n); const salt = new Fr(3n); const contractClassId = new Fr(4n); const initializationHash = new Fr(5n); + const immutablesHash = new Fr(6n); const deployer = AztecAddress.fromField(new Fr(7)); const publicKeys = (await deriveKeys(secretKey)).publicKeys; const instance = { @@ -73,14 +71,14 @@ describe('ContractAddress', () => { currentContractClassId: contractClassId, initializationHash, deployer, - version: 1 as const, + immutablesHash, + version: 2 as const, }; - const [ms, address] = await elapsed(computeContractAddressFromInstance(instance)); const logger = createLogger('stdlib:contract_address:test'); logger.info(`Computed contract address from instance in ${ms}ms`); expect(address.toString()).toMatchInlineSnapshot( - `"0x260f462e7ae7b7031cdb5e41a691a265d7debe6863d8a12887b97f5f8e5d7727"`, + `"0x2527876b96f9da428aaec968da7a89018db43c78dcdb2e7246060dc37e49e0ac"`, ); }); }); diff --git a/yarn-project/stdlib/src/contract/contract_address.ts b/yarn-project/stdlib/src/contract/contract_address.ts index 6376a263a9d4..a5c36107b344 100644 --- a/yarn-project/stdlib/src/contract/contract_address.ts +++ b/yarn-project/stdlib/src/contract/contract_address.ts @@ -13,9 +13,9 @@ import type { ContractInstance } from './interfaces/contract_instance.js'; /** * Returns the deployment address for a given contract instance. * ``` - * salted_initialization_hash = poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, [salt, initialization_hash, deployer]) + * salted_initialization_hash = poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, [salt, initialization_hash, deployer, immutables_hash]) * partial_address = poseidon2(DOM_SEP__PARTIAL_ADDRESS, [contract_class_id, salted_initialization_hash]) - * address = ((poseidon2(DOM_SEP__CONTRACT_ADDRESS_V1, [public_keys_hash, partial_address]) * G) + ivpk_m).x <- the x-coordinate of the address point + * address = ((poseidon2(DOM_SEP__CONTRACT_ADDRESS_V2, [public_keys_hash, partial_address]) * G) + ivpk_m).x <- the x-coordinate of the address point * ``` * @param instance - A contract instance for which to calculate the deployment address. */ @@ -34,7 +34,7 @@ export async function computeContractAddressFromInstance( */ export async function computePartialAddress( instance: - | Pick + | Pick | { originalContractClassId: Fr; saltedInitializationHash: Fr }, ): Promise { const saltedInitializationHash = @@ -53,10 +53,10 @@ export async function computePartialAddress( * @param instance - Contract instance for which to compute the salted initialization hash. */ export function computeSaltedInitializationHash( - instance: Pick, + instance: Pick, ): Promise { return poseidon2HashWithSeparator( - [instance.salt, instance.initializationHash, instance.deployer], + [instance.salt, instance.initializationHash, instance.deployer, instance.immutablesHash], DomainSeparator.SALTED_INITIALIZATION_HASH, ); } diff --git a/yarn-project/stdlib/src/contract/contract_instance.ts b/yarn-project/stdlib/src/contract/contract_instance.ts index d3dcb4b79f8c..7be8330eeea5 100644 --- a/yarn-project/stdlib/src/contract/contract_instance.ts +++ b/yarn-project/stdlib/src/contract/contract_instance.ts @@ -20,7 +20,7 @@ import { } from './contract_address.js'; import type { ContractInstance, ContractInstanceWithAddress } from './interfaces/contract_instance.js'; -const VERSION = 1 as const; +const VERSION = 2 as const; export type ContractInstantiationData = { constructorArtifact?: FunctionAbi | string; @@ -29,6 +29,7 @@ export type ContractInstantiationData = { salt: Fr; publicKeys?: PublicKeys; deployer?: AztecAddress; + immutablesHash?: Fr; }; export class SerializableContractInstance { @@ -38,6 +39,7 @@ export class SerializableContractInstance { public readonly currentContractClassId: Fr; public readonly originalContractClassId: Fr; public readonly initializationHash: Fr; + public readonly immutablesHash: Fr; public readonly publicKeys: PublicKeys; constructor(instance: ContractInstance) { @@ -49,6 +51,7 @@ export class SerializableContractInstance { this.currentContractClassId = instance.currentContractClassId; this.originalContractClassId = instance.originalContractClassId; this.initializationHash = instance.initializationHash; + this.immutablesHash = instance.immutablesHash; this.publicKeys = instance.publicKeys; } @@ -60,6 +63,7 @@ export class SerializableContractInstance { this.currentContractClassId, this.originalContractClassId, this.initializationHash, + this.immutablesHash, this.publicKeys, ); } @@ -78,6 +82,7 @@ export class SerializableContractInstance { currentContractClassId: reader.readObject(Fr), originalContractClassId: reader.readObject(Fr), initializationHash: reader.readObject(Fr), + immutablesHash: reader.readObject(Fr), publicKeys: reader.readObject(PublicKeys), }); } @@ -90,6 +95,7 @@ export class SerializableContractInstance { currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), ...opts, }); @@ -103,6 +109,7 @@ export class SerializableContractInstance { currentContractClassId: Fr.zero(), originalContractClassId: Fr.zero(), initializationHash: Fr.zero(), + immutablesHash: Fr.zero(), publicKeys: PublicKeys.default(), }); } @@ -130,15 +137,17 @@ export async function getContractInstanceFromInstantiationParams( ) : await computeInitializationHash(constructorArtifact, args); const publicKeys = opts.publicKeys ?? PublicKeys.default(); + const immutablesHash = opts.immutablesHash ?? Fr.ZERO; const instance: ContractInstance = { currentContractClassId: contractClass.id, originalContractClassId: contractClass.id, initializationHash, + immutablesHash, publicKeys, salt: opts.salt, deployer, - version: 1, + version: 2, }; return { ...instance, address: await computeContractAddressFromInstance(instance) }; diff --git a/yarn-project/stdlib/src/contract/interfaces/contract_instance.ts b/yarn-project/stdlib/src/contract/interfaces/contract_instance.ts index 6e7f986b1ce1..2d992dbac99c 100644 --- a/yarn-project/stdlib/src/contract/interfaces/contract_instance.ts +++ b/yarn-project/stdlib/src/contract/interfaces/contract_instance.ts @@ -6,7 +6,7 @@ import { AztecAddress } from '../../aztec-address/index.js'; import { PublicKeys } from '../../keys/public_keys.js'; import { schemas, zodFor } from '../../schemas/index.js'; -const VERSION = 1 as const; +const VERSION = 2 as const; /** * A contract instance is a concrete deployment of a contract class. It always references a contract class, @@ -26,6 +26,8 @@ export interface ContractInstance { originalContractClassId: Fr; /** Hash of the selector and arguments to the constructor. */ initializationHash: Fr; + /** Hash of Immutables Values the contract is deployed with. */ + immutablesHash: Fr; /** Public keys associated with this instance. */ publicKeys: PublicKeys; } @@ -40,6 +42,7 @@ export const ContractInstanceSchema = zodFor()( currentContractClassId: schemas.Fr, originalContractClassId: schemas.Fr, initializationHash: schemas.Fr, + immutablesHash: schemas.Fr, publicKeys: PublicKeys.schema, }), ); @@ -54,12 +57,13 @@ export const ContractInstanceWithAddressSchema = zodFor { originalContractClassId: expect.any(Fr), deployer: expect.any(AztecAddress), initializationHash: expect.any(Fr), + immutablesHash: expect.any(Fr), publicKeys: expect.any(PublicKeys), salt: expect.any(Fr), - version: 1, + version: 2, }); }); @@ -578,9 +579,10 @@ class MockArchiver implements ArchiverApi { originalContractClassId: Fr.random(), deployer: await AztecAddress.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), salt: Fr.random(), - version: 1, + version: 2, }; } getContractClassIds(): Promise { diff --git a/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts b/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts index 127d58eb453e..89b3d50fa901 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts @@ -57,6 +57,14 @@ describe('AztecNodeAdminApiSchema', () => { await context.client.resumeSync(); }); + it('pauseSequencer', async () => { + await context.client.pauseSequencer(); + }); + + it('resumeSequencer', async () => { + await context.client.resumeSequencer(); + }); + it('getSlashOffenses', async () => { const offenses = await context.client.getSlashOffenses('all'); expect(offenses).toHaveLength(1); @@ -107,19 +115,20 @@ class MockAztecNodeAdmin implements AztecNodeAdmin { slashAmountLarge: 2000n, slashValidatorsAlways: [], slashValidatorsNever: [], - slashPrunePenalty: 1000n, slashDataWithholdingPenalty: 1000n, + slashDataWithholdingToleranceSlots: 3, slashInactivityTargetPercentage: 0.5, slashInactivityConsecutiveEpochThreshold: 1, slashInactivityPenalty: 1000n, slashBroadcastedInvalidBlockPenalty: 1n, + slashBroadcastedInvalidCheckpointProposalPenalty: 1n, slashDuplicateProposalPenalty: 1n, slashDuplicateAttestationPenalty: 1n, slashAttestInvalidCheckpointProposalPenalty: 1000n, secondsBeforeInvalidatingBlockAsCommitteeMember: 0, secondsBeforeInvalidatingBlockAsNonCommitteeMember: 0, slashProposeInvalidAttestationsPenalty: 1000n, - slashAttestDescendantOfInvalidPenalty: 1000n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1000n, slashOffenseExpirationRounds: 4, slashMaxPayloadSize: 50, slashUnknownPenalty: 1000n, @@ -152,6 +161,12 @@ class MockAztecNodeAdmin implements AztecNodeAdmin { resumeSync(): Promise { return Promise.resolve(); } + pauseSequencer(): Promise { + return Promise.resolve(); + } + resumeSequencer(): Promise { + return Promise.resolve(); + } reloadKeystore(): Promise { return Promise.resolve(); } diff --git a/yarn-project/stdlib/src/interfaces/aztec-node-admin.ts b/yarn-project/stdlib/src/interfaces/aztec-node-admin.ts index 409acb28e569..66ce9d00ad76 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node-admin.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node-admin.ts @@ -48,6 +48,15 @@ export interface AztecNodeAdmin { /** Resumes archiver and world state syncing. */ resumeSync(): Promise; + /** + * Pauses block production. Pending txs remain in the mempool; no new blocks will be + * produced until {@link resumeSequencer} is called. Throws if no sequencer is running. + */ + pauseSequencer(): Promise; + + /** Resumes block production previously paused via {@link pauseSequencer}. */ + resumeSequencer(): Promise; + /** Returns all offenses applicable for the given round. */ getSlashOffenses(round: bigint | 'all' | 'current'): Promise; @@ -108,6 +117,8 @@ export const AztecNodeAdminApiSchema: ApiSchemaFor = { }), pauseSync: z.function({ input: z.tuple([]), output: z.void() }), resumeSync: z.function({ input: z.tuple([]), output: z.void() }), + pauseSequencer: z.function({ input: z.tuple([]), output: z.void() }), + resumeSequencer: z.function({ input: z.tuple([]), output: z.void() }), getSlashOffenses: z.function({ input: z.tuple([z.union([z.bigint(), z.literal('all'), z.literal('current')])]), output: z.array(OffenseSchema), diff --git a/yarn-project/stdlib/src/interfaces/aztec-node.test.ts b/yarn-project/stdlib/src/interfaces/aztec-node.test.ts index f7ba90236a4b..53edceea3df1 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node.test.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node.test.ts @@ -428,7 +428,7 @@ describe('AztecNodeApiSchema', () => { missedProposals: { currentStreak: 0, count: 0, total: 1 }, history: [{ slot: SlotNumber(1), status: 'checkpoint-mined' }], }, - allTimeProvenPerformance: [], + allTimeEpochPerformance: [], lastProcessedSlot: SlotNumber(10), initialSlot: SlotNumber(1), slotWindow: 100, @@ -453,7 +453,7 @@ describe('AztecNodeApiSchema', () => { missedProposals: { currentStreak: 0, count: 0, total: 0 }, history: [{ slot: SlotNumber(5), status: 'attestation-sent' }], }, - allTimeProvenPerformance: [], + allTimeEpochPerformance: [], lastProcessedSlot: SlotNumber(10), initialSlot: SlotNumber(5), slotWindow: 5, @@ -492,9 +492,10 @@ describe('AztecNodeApiSchema', () => { originalContractClassId: expect.any(Fr), deployer: expect.any(AztecAddress), initializationHash: expect.any(Fr), + immutablesHash: expect.any(Fr), publicKeys: expect.any(PublicKeys), salt: expect.any(Fr), - version: 1, + version: 2, }); }); @@ -845,11 +846,12 @@ class MockAztecNode implements AztecNode { async getContract(address: AztecAddress): Promise { expect(address).toBeInstanceOf(AztecAddress); const instance = { - version: 1 as const, + version: 2 as const, currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), deployer: await AztecAddress.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), salt: Fr.random(), address: await AztecAddress.random(), diff --git a/yarn-project/stdlib/src/interfaces/block-builder.ts b/yarn-project/stdlib/src/interfaces/block-builder.ts index 6a2f49bb4209..8e09e36c1320 100644 --- a/yarn-project/stdlib/src/interfaces/block-builder.ts +++ b/yarn-project/stdlib/src/interfaces/block-builder.ts @@ -45,6 +45,8 @@ export type PublicProcessorLimits = { maxBlobFields?: number; /** Deadline for processing the txs. Processor will stop as soon as it hits this time. */ deadline?: Date; + /** Signal for interrupting processing before the deadline. */ + signal?: AbortSignal; /** Whether this processor is building a proposal (as opposed to re-executing one). Skipping txs due to gas or blob limits is only done during proposal building. */ isBuildingProposal?: boolean; }; diff --git a/yarn-project/stdlib/src/interfaces/configs.ts b/yarn-project/stdlib/src/interfaces/configs.ts index c85ebc7a4f6e..83453f405fe4 100644 --- a/yarn-project/stdlib/src/interfaces/configs.ts +++ b/yarn-project/stdlib/src/interfaces/configs.ts @@ -64,6 +64,14 @@ export interface SequencerConfig { skipInvalidateBlockAsProposer?: boolean; /** Broadcast invalid block proposals with corrupted state (for testing only) */ broadcastInvalidBlockProposal?: boolean; + /** Broadcast an invalid block proposal only at this indexWithinCheckpoint (for testing only) */ + invalidBlockProposalIndexWithinCheckpoint?: number; + /** + * Broadcast invalid checkpoint proposals (with corrupted archive) while keeping the underlying + * block proposals valid (for testing only). When unset, the checkpoint follows + * `broadcastInvalidBlockProposal`. + */ + broadcastInvalidCheckpointProposalOnly?: boolean; /** Inject a fake attestation (for testing only) */ injectFakeAttestation?: boolean; /** Inject a malleable attestation with a high-s value (for testing only) */ @@ -121,6 +129,8 @@ export const SequencerConfigSchema = zodFor()( secondsBeforeInvalidatingBlockAsCommitteeMember: z.number(), secondsBeforeInvalidatingBlockAsNonCommitteeMember: z.number(), broadcastInvalidBlockProposal: z.boolean().optional(), + invalidBlockProposalIndexWithinCheckpoint: z.number().int().nonnegative().optional(), + broadcastInvalidCheckpointProposalOnly: z.boolean().optional(), injectFakeAttestation: z.boolean().optional(), injectHighSValueAttestation: z.boolean().optional(), injectUnrecoverableSignatureAttestation: z.boolean().optional(), @@ -149,6 +159,7 @@ type SequencerConfigOptionalKeys = | 'fakeThrowAfterProcessingTxCount' | 'l1PublishingTime' | 'txPublicSetupAllowListExtend' + | 'invalidBlockProposalIndexWithinCheckpoint' | 'minValidTxsPerBlock' | 'minBlocksForCheckpoint' | 'maxTxsPerBlock' diff --git a/yarn-project/stdlib/src/interfaces/p2p.ts b/yarn-project/stdlib/src/interfaces/p2p.ts index 111a3b9becb7..902bd069e41e 100644 --- a/yarn-project/stdlib/src/interfaces/p2p.ts +++ b/yarn-project/stdlib/src/interfaces/p2p.ts @@ -2,7 +2,9 @@ import type { CheckpointProposalHash, SlotNumber } from '@aztec/foundation/brand import { z } from 'zod'; +import type { BlockProposal } from '../p2p/block_proposal.js'; import { CheckpointAttestation } from '../p2p/checkpoint_attestation.js'; +import type { CheckpointProposalCore } from '../p2p/checkpoint_proposal.js'; import { type ApiSchemaFor, optional, schemas } from '../schemas/index.js'; import { Tx } from '../tx/tx.js'; import { TxHash } from '../tx/tx_hash.js'; @@ -67,6 +69,12 @@ export interface P2PApi { export interface P2PClient extends P2PApi { /** Manually adds checkpoint attestations to the p2p client attestation pool. */ addOwnCheckpointAttestations(attestations: CheckpointAttestation[]): Promise; + + /** Returns retained signed proposals for a slot. */ + getProposalsForSlot(slot: SlotNumber): Promise<{ + blockProposals: BlockProposal[]; + checkpointProposals: CheckpointProposalCore[]; + }>; } export const P2PApiSchema: ApiSchemaFor = { diff --git a/yarn-project/stdlib/src/interfaces/slasher.ts b/yarn-project/stdlib/src/interfaces/slasher.ts index 9e71e16e0f16..d3e99d003342 100644 --- a/yarn-project/stdlib/src/interfaces/slasher.ts +++ b/yarn-project/stdlib/src/interfaces/slasher.ts @@ -10,14 +10,20 @@ export interface SlasherConfig { slashValidatorsNever: EthAddress[]; // Array of validator addresses slashInactivityTargetPercentage: number; // 0-1, 0.9 means 90%. Must be greater than 0 slashInactivityConsecutiveEpochThreshold: number; // Number of consecutive epochs a validator must be inactive before slashing - slashPrunePenalty: bigint; slashDataWithholdingPenalty: bigint; + /** + * Number of full L2 slots that must elapse after a checkpoint's slot before declaring its + * txs missing and slashing the checkpoint's attesters for data withholding. With tolerance + * = N and checkpoint slot S, the check fires at the start of slot `S + N + 1`. + */ + slashDataWithholdingToleranceSlots: number; slashInactivityPenalty: bigint; slashBroadcastedInvalidBlockPenalty: bigint; + slashBroadcastedInvalidCheckpointProposalPenalty: bigint; slashDuplicateProposalPenalty: bigint; slashDuplicateAttestationPenalty: bigint; slashProposeInvalidAttestationsPenalty: bigint; - slashAttestDescendantOfInvalidPenalty: bigint; + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: bigint; slashAttestInvalidCheckpointProposalPenalty: bigint; slashUnknownPenalty: bigint; slashOffenseExpirationRounds: number; // Number of rounds after which pending offenses expire @@ -31,15 +37,20 @@ export const SlasherConfigSchema = zodFor()( slashOverridePayload: schemas.EthAddress.optional(), slashValidatorsAlways: z.array(schemas.EthAddress), slashValidatorsNever: z.array(schemas.EthAddress), - slashPrunePenalty: schemas.BigInt, slashDataWithholdingPenalty: schemas.BigInt, + // Tolerated as undefined to allow validating responses from older node images that + // predate the per-slot data-withholding watcher (PR #23116). + slashDataWithholdingToleranceSlots: z.number().default(3), slashInactivityTargetPercentage: z.number(), slashInactivityConsecutiveEpochThreshold: z.number(), slashInactivityPenalty: schemas.BigInt, slashProposeInvalidAttestationsPenalty: schemas.BigInt, + // Tolerated as undefined to allow validating responses from older node images that + // predate this slasher penalty being added. + slashBroadcastedInvalidCheckpointProposalPenalty: schemas.BigInt.default(0n), slashDuplicateProposalPenalty: schemas.BigInt, slashDuplicateAttestationPenalty: schemas.BigInt, - slashAttestDescendantOfInvalidPenalty: schemas.BigInt, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: schemas.BigInt, slashAttestInvalidCheckpointProposalPenalty: schemas.BigInt, slashUnknownPenalty: schemas.BigInt, slashOffenseExpirationRounds: z.number(), diff --git a/yarn-project/stdlib/src/interfaces/tx_provider.ts b/yarn-project/stdlib/src/interfaces/tx_provider.ts index 4113b69cae5f..b434b8052c42 100644 --- a/yarn-project/stdlib/src/interfaces/tx_provider.ts +++ b/yarn-project/stdlib/src/interfaces/tx_provider.ts @@ -7,6 +7,12 @@ import type { PeerId } from '@libp2p/interface'; export interface ITxProvider { getAvailableTxs(txHashes: TxHash[]): Promise<{ txs: Tx[]; missingTxs: TxHash[] }>; + /** + * Checks whether each tx hash is currently held by the local tx pool. Returns a parallel + * boolean array (one entry per input hash). Does not fetch from the network. + */ + hasTxs(txHashes: TxHash[]): Promise; + getTxsForBlockProposal( blockProposal: BlockProposal, blockNumber: number, diff --git a/yarn-project/stdlib/src/interfaces/validator.ts b/yarn-project/stdlib/src/interfaces/validator.ts index 1a8f9fddd19d..1c9b850ef613 100644 --- a/yarn-project/stdlib/src/interfaces/validator.ts +++ b/yarn-project/stdlib/src/interfaces/validator.ts @@ -66,6 +66,9 @@ export type ValidatorClientConfig = ValidatorHASignerConfig & /** Agree to attest to equivocated checkpoint proposals (for testing purposes only) */ attestToEquivocatedProposals?: boolean; + /** Accept proposal validation regardless of slot timing (for testing only) */ + skipProposalSlotValidation?: boolean; + /** Maximum L2 gas per block for validation. Proposals exceeding this limit are rejected. */ validateMaxL2BlockGas?: number; @@ -84,6 +87,7 @@ export type ValidatorClientFullConfig = ValidatorClientConfig & Pick< SlasherConfig, | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' @@ -107,6 +111,7 @@ export const ValidatorClientConfigSchema = zodFor { it('computing public keys hash matches Noir', async () => { - const masterNullifierPublicKey = new Point(new Fr(1), new Fr(2), false); - const masterIncomingViewingPublicKey = new Point(new Fr(3), new Fr(4), false); - const masterOutgoingViewingPublicKey = new Point(new Fr(5), new Fr(6), false); - const masterTaggingPublicKey = new Point(new Fr(7), new Fr(8), false); - const publicKeysHash = await new PublicKeys( - masterNullifierPublicKey, - masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, + new Fr(11n), + new PublicKey(new Fr(3n), new Fr(4n)), + new Fr(22n), + new Fr(33n), ).hash(); expect(publicKeysHash.toString()).toMatchInlineSnapshot( - `"0x056998309f6c119e4d753e404f94fef859dddfa530a9379634ceb0854b29bf7a"`, + `"0x0b8c7b67576d3ac859a7fab578b2b2e305c67eba9e133b0fa46af8d19a50b8fc"`, ); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data @@ -29,13 +24,12 @@ describe('🔑', () => { publicKeysHash.toString(), ); }); - it('Pre address from partial matches Noir', async () => { const publicKeysHash = new Fr(1n); const partialAddress = new Fr(2n); const address = await computePreaddress(publicKeysHash, partialAddress); expect(address.toString()).toMatchInlineSnapshot( - `"0x286c7755f2924b1e53b00bcaf1adaffe7287bd74bba7a02f4ab867e3892d28da"`, + `"0x0fa1c698858df1a99170cd39d5f4bfad6d0d60f1f8afa3dc92281ee60b36f3bb"`, ); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data @@ -45,26 +39,28 @@ describe('🔑', () => { address.toString(), ); }); - it('Address matches Noir', async () => { - const npkM = Point.fromString( + const npkM = PublicKey.fromString( '0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7', ); - const ivpkM = Point.fromString( + const ivpkM = PublicKey.fromString( '0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95', ); - const ovpkM = Point.fromString( + const ovpkM = PublicKey.fromString( '0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c4840c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b', ); - const tpkM = Point.fromString( + const tpkM = PublicKey.fromString( '0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a7622f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a', ); - - const publicKeys = new PublicKeys(npkM, ivpkM, ovpkM, tpkM); + const publicKeys = new PublicKeys( + await hashPublicKey(npkM), + ivpkM, + await hashPublicKey(ovpkM), + await hashPublicKey(tpkM), + ); const partialAddress = Fr.fromHexString('0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de'); - const address = (await computeAddress(publicKeys, partialAddress)).toString(); - expect(address).toMatchInlineSnapshot(`"0x2f66081d4bb077fbe8e8abe96a3516a713a3d7e34360b4e985da0da95092b37d"`); + expect(address).toMatchInlineSnapshot(`"0x05f9c48c02e4dbd18d7e165f999c3b8426abb1911476f48e68deef42475d6145"`); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data updateInlineTestData( diff --git a/yarn-project/stdlib/src/keys/derivation.ts b/yarn-project/stdlib/src/keys/derivation.ts index 0ed89aaeb438..9b4765a8aef3 100644 --- a/yarn-project/stdlib/src/keys/derivation.ts +++ b/yarn-project/stdlib/src/keys/derivation.ts @@ -7,6 +7,7 @@ import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin'; import { AztecAddress } from '../aztec-address/index.js'; import type { KeyPrefix } from './key_types.js'; +import { PublicKey, hashPublicKey } from './public_key.js'; import { PublicKeys } from './public_keys.js'; import { getKeyGenerator } from './utils.js'; @@ -44,18 +45,18 @@ export function deriveSigningKey(secretKey: Fr): GrumpkinScalar { } export function computePreaddress(publicKeysHash: Fr, partialAddress: Fr) { - return poseidon2HashWithSeparator([publicKeysHash, partialAddress], DomainSeparator.CONTRACT_ADDRESS_V1); + return poseidon2HashWithSeparator([publicKeysHash, partialAddress], DomainSeparator.CONTRACT_ADDRESS_V2); } export async function computeAddress(publicKeys: PublicKeys, partialAddress: Fr): Promise { // Given public keys and a partial address, we can compute our address in the following steps. - // 1. preaddress = poseidon2([publicKeysHash, partialAddress], DomainSeparator.CONTRACT_ADDRESS_V1); + // 1. preaddress = poseidon2([publicKeysHash, partialAddress], DomainSeparator.CONTRACT_ADDRESS_V2); // 2. addressPoint = (preaddress * G) + ivpk_m // 3. address = addressPoint.x const preaddress = await computePreaddress(await publicKeys.hash(), partialAddress); const address = await Grumpkin.add( await derivePublicKeyFromSecretKey(new Fq(preaddress.toBigInt())), - publicKeys.masterIncomingViewingPublicKey, + publicKeys.ivpkM, ); return new AztecAddress(address.x); @@ -83,7 +84,7 @@ export async function computeAddressSecret(preaddress: Fr, ivsk: Fq) { return addressSecretCandidate; } -export function derivePublicKeyFromSecretKey(secretKey: Fq) { +export function derivePublicKeyFromSecretKey(secretKey: Fq): Promise { return Grumpkin.mul(Grumpkin.generator, secretKey); } @@ -106,12 +107,15 @@ export async function deriveKeys(secretKey: Fr) { const masterOutgoingViewingPublicKey = await derivePublicKeyFromSecretKey(masterOutgoingViewingSecretKey); const masterTaggingPublicKey = await derivePublicKeyFromSecretKey(masterTaggingSecretKey); - // We hash the public keys to get the public keys hash + // The non-owner-visible PublicKeys carries hashes for npk/ovpk/tpk and the raw + // point only for ivpk_m. The npk/ovpk/tpk raw points are also returned alongside so the key + // store can persist them under `${account}-{n|ov|t}pk_m` (only their hashes live in publicKeys). + // The ivpk_m point isn't returned separately because it already lives in publicKeys.ivpkM. const publicKeys = new PublicKeys( - masterNullifierPublicKey, + await hashPublicKey(masterNullifierPublicKey), masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, + await hashPublicKey(masterOutgoingViewingPublicKey), + await hashPublicKey(masterTaggingPublicKey), ); return { @@ -119,6 +123,9 @@ export async function deriveKeys(secretKey: Fr) { masterIncomingViewingSecretKey, masterOutgoingViewingSecretKey, masterTaggingSecretKey, + masterNullifierPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, publicKeys, }; } diff --git a/yarn-project/stdlib/src/keys/public_key.ts b/yarn-project/stdlib/src/keys/public_key.ts index aa5f388ef9a3..1bc5fbc2966d 100644 --- a/yarn-project/stdlib/src/keys/public_key.ts +++ b/yarn-project/stdlib/src/keys/public_key.ts @@ -1,4 +1,28 @@ -import type { Point } from '@aztec/foundation/curves/grumpkin'; +import { DomainSeparator } from '@aztec/constants'; +import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { Point } from '@aztec/foundation/curves/grumpkin'; -/** Represents a user public key. */ +/** + * Hashes a public key. + * + * Mirrors Noir's `hash_public_key` in `noir-protocol-circuits/crates/types/src/public_keys.nr`: + * `Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, [pk.x, pk.y])`. + * + * This is distinct from Noir's generic `Hash` impl for `EmbeddedCurvePoint` (`noir_stdlib/src/embedded_curve_ops.nr`), + * which simply absorbs `x` then `y` into a `Hasher` state with no domain separator. That generic impl is unsuitable + * for hashing keys at the protocol boundary, where the domain separator is required to prevent collisions with hashes + * of other Grumpkin points (e.g. note commitments, nullifiers). + */ +export function hashPublicKey(pk: PublicKey): Promise { + return poseidon2HashWithSeparator([pk.x, pk.y], DomainSeparator.SINGLE_PUBLIC_KEY_HASH); +} + +/** + * Represents a user public key. + * + * Structurally identical to a Grumpkin `Point`; exposed as a distinct name so call sites read as "public key" where + * that's the domain meaning. + */ export type PublicKey = Point; +export const PublicKey = Point; diff --git a/yarn-project/stdlib/src/keys/public_keys.test.ts b/yarn-project/stdlib/src/keys/public_keys.test.ts index feba8ed89f1a..635fb05df198 100644 --- a/yarn-project/stdlib/src/keys/public_keys.test.ts +++ b/yarn-project/stdlib/src/keys/public_keys.test.ts @@ -1,7 +1,7 @@ import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import { updateInlineTestData } from '@aztec/foundation/testing/files'; +import { PublicKey } from './public_key.js'; import { PublicKeys } from './public_keys.js'; describe('PublicKeys', () => { @@ -19,16 +19,11 @@ describe('PublicKeys', () => { }); it('computes public keys hash', async () => { - const keys = new PublicKeys( - new Point(new Fr(1n), new Fr(2n), false), - new Point(new Fr(3n), new Fr(4n), false), - new Point(new Fr(5n), new Fr(6n), false), - new Point(new Fr(7n), new Fr(8n), false), - ); + const keys = new PublicKeys(new Fr(11n), new PublicKey(new Fr(3n), new Fr(4n)), new Fr(22n), new Fr(33n)); const hash = await keys.hash(); expect(hash.toString()).toMatchInlineSnapshot( - `"0x056998309f6c119e4d753e404f94fef859dddfa530a9379634ceb0854b29bf7a"`, + `"0x0b8c7b67576d3ac859a7fab578b2b2e305c67eba9e133b0fa46af8d19a50b8fc"`, ); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data @@ -44,7 +39,7 @@ describe('PublicKeys', () => { const hash = await keys.hash(); expect(hash.toString()).toMatchInlineSnapshot( - `"0x023547e676dba19784188825b901a0e70d8ad978300d21d6185a54281b734da0"`, + `"0x147a900f3e1abdfcc56355d65ab9bebb1016400cb9d81ee1c977d0df16bb198c"`, ); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data diff --git a/yarn-project/stdlib/src/keys/public_keys.ts b/yarn-project/stdlib/src/keys/public_keys.ts index 130fcf07c06d..9a0e2beb9c59 100644 --- a/yarn-project/stdlib/src/keys/public_keys.ts +++ b/yarn-project/stdlib/src/keys/public_keys.ts @@ -1,17 +1,13 @@ import { DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, - DEFAULT_NPK_M_X, - DEFAULT_NPK_M_Y, - DEFAULT_OVPK_M_X, - DEFAULT_OVPK_M_Y, - DEFAULT_TPK_M_X, - DEFAULT_TPK_M_Y, + DEFAULT_NPK_M_HASH, + DEFAULT_OVPK_M_HASH, + DEFAULT_TPK_M_HASH, DomainSeparator, } from '@aztec/constants'; import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { bufferToHex, withoutHexPrefix } from '@aztec/foundation/string'; @@ -19,108 +15,107 @@ import type { FieldsOf } from '@aztec/foundation/types'; import { z } from 'zod'; -import type { PublicKey } from './public_key.js'; +import { PublicKey, hashPublicKey } from './public_key.js'; +/** + * A non-owner's view of an account's master public keys. + * + * Only `ivpkM` is exposed as a point (since address derivation needs the curve + * point in-circuit); the other three keys are exposed as their `hashPublicKey` digests. + */ export class PublicKeys { public constructor( - /** Master nullifier public key */ - public masterNullifierPublicKey: PublicKey, + /** Hash of the master nullifier public key */ + public npkMHash: Fr, /** Master incoming viewing public key */ - public masterIncomingViewingPublicKey: PublicKey, - /** Master outgoing viewing public key */ - public masterOutgoingViewingPublicKey: PublicKey, - /** Master tagging viewing public key */ - public masterTaggingPublicKey: PublicKey, + public ivpkM: PublicKey, + /** Hash of the master outgoing viewing public key */ + public ovpkMHash: Fr, + /** Hash of the master tagging public key */ + public tpkMHash: Fr, ) {} static get schema() { return z .object({ - masterNullifierPublicKey: schemas.Point, - masterIncomingViewingPublicKey: schemas.Point, - masterOutgoingViewingPublicKey: schemas.Point, - masterTaggingPublicKey: schemas.Point, + npkMHash: schemas.Fr, + ivpkM: schemas.Point, + ovpkMHash: schemas.Fr, + tpkMHash: schemas.Fr, }) .transform(PublicKeys.from); } static from(fields: FieldsOf) { - return new PublicKeys( - fields.masterNullifierPublicKey, - fields.masterIncomingViewingPublicKey, - fields.masterOutgoingViewingPublicKey, - fields.masterTaggingPublicKey, - ); + return new PublicKeys(fields.npkMHash, fields.ivpkM, fields.ovpkMHash, fields.tpkMHash); } /** * Creates a PublicKeys from a plain object without Zod validation. - * This method is optimized for performance and skips validation, making it suitable - * for deserializing trusted data (e.g., from C++ via MessagePack). - * @param obj - Plain object containing PublicKeys fields - * @returns A PublicKeys instance + * Suitable for deserializing trusted data (e.g., from C++ via MessagePack). */ static fromPlainObject(obj: any): PublicKeys { if (obj instanceof PublicKeys) { return obj; } return new PublicKeys( - Point.fromPlainObject(obj.masterNullifierPublicKey), - Point.fromPlainObject(obj.masterIncomingViewingPublicKey), - Point.fromPlainObject(obj.masterOutgoingViewingPublicKey), - Point.fromPlainObject(obj.masterTaggingPublicKey), + Fr.fromPlainObject(obj.npkMHash), + PublicKey.fromPlainObject(obj.ivpkM), + Fr.fromPlainObject(obj.ovpkMHash), + Fr.fromPlainObject(obj.tpkMHash), ); } - hash() { - return this.isEmpty() - ? Fr.ZERO - : poseidon2HashWithSeparator( - [ - this.masterNullifierPublicKey, - this.masterIncomingViewingPublicKey, - this.masterOutgoingViewingPublicKey, - this.masterTaggingPublicKey, - ], - DomainSeparator.PUBLIC_KEYS_HASH, - ); + async hash() { + if (this.isEmpty()) { + return Fr.ZERO; + } + // Mirror Noir's `PublicKeys::hash`: hash the four single-key digests under + // DOM_SEP__PUBLIC_KEYS_HASH. `ivpk_m` must be reduced to its single-key digest first + // (Poseidon2 over [x, y]); passing the Point directly would omit the DOM_SEP__SINGLE_PUBLIC_KEY_HASH + const ivpkMHash = await hashPublicKey(this.ivpkM); + return poseidon2HashWithSeparator( + [this.npkMHash, ivpkMHash, this.ovpkMHash, this.tpkMHash], + DomainSeparator.PUBLIC_KEYS_HASH, + ); } isEmpty() { - return ( - this.masterNullifierPublicKey.isZero() && - this.masterIncomingViewingPublicKey.isZero() && - this.masterOutgoingViewingPublicKey.isZero() && - this.masterTaggingPublicKey.isZero() - ); + return this.npkMHash.isZero() && this.ivpkM.isZero() && this.ovpkMHash.isZero() && this.tpkMHash.isZero(); } static default(): PublicKeys { + // Precomputed `hash_public_key(Point { DEFAULT_*_X, DEFAULT_*_Y })` for npk/ovpk/tpk. + // Sourced from constants.gen.ts (originally defined in + // noir-protocol-circuits/crates/types/src/constants.nr); a self-test in public_keys.nr + // (`default_hashes_match_default_points`) catches drift between the *_HASH constants and + // the underlying X/Y points. return new PublicKeys( - new Point(new Fr(DEFAULT_NPK_M_X), new Fr(DEFAULT_NPK_M_Y), false), - new Point(new Fr(DEFAULT_IVPK_M_X), new Fr(DEFAULT_IVPK_M_Y), false), - new Point(new Fr(DEFAULT_OVPK_M_X), new Fr(DEFAULT_OVPK_M_Y), false), - new Point(new Fr(DEFAULT_TPK_M_X), new Fr(DEFAULT_TPK_M_Y), false), + new Fr(DEFAULT_NPK_M_HASH), + new PublicKey(new Fr(DEFAULT_IVPK_M_X), new Fr(DEFAULT_IVPK_M_Y)), + new Fr(DEFAULT_OVPK_M_HASH), + new Fr(DEFAULT_TPK_M_HASH), ); } static async random(): Promise { - return new PublicKeys(await Point.random(), await Point.random(), await Point.random(), await Point.random()); + const npkM = await PublicKey.random(); + const ovpkM = await PublicKey.random(); + const tpkM = await PublicKey.random(); + return new PublicKeys( + await hashPublicKey(npkM), + await PublicKey.random(), + await hashPublicKey(ovpkM), + await hashPublicKey(tpkM), + ); } - /** - * Determines if this PublicKeys instance is equal to the given PublicKeys instance. - * Equality is based on the content of their respective buffers. - * - * @param other - The PublicKeys instance to compare against. - * @returns True if the buffers of both instances are equal, false otherwise. - */ equals(other: PublicKeys): boolean { return ( - this.masterNullifierPublicKey.equals(other.masterNullifierPublicKey) && - this.masterIncomingViewingPublicKey.equals(other.masterIncomingViewingPublicKey) && - this.masterOutgoingViewingPublicKey.equals(other.masterOutgoingViewingPublicKey) && - this.masterTaggingPublicKey.equals(other.masterTaggingPublicKey) + this.npkMHash.equals(other.npkMHash) && + this.ivpkM.equals(other.ivpkM) && + this.ovpkMHash.equals(other.ovpkMHash) && + this.tpkMHash.equals(other.tpkMHash) ); } @@ -131,77 +126,46 @@ export class PublicKeys { * @returns A Buffer representation of the PublicKeys instance. */ toBuffer(): Buffer { - return serializeToBuffer([ - this.masterNullifierPublicKey, - this.masterIncomingViewingPublicKey, - this.masterOutgoingViewingPublicKey, - this.masterTaggingPublicKey, - ]); + return serializeToBuffer([this.npkMHash, this.ivpkM, this.ovpkMHash, this.tpkMHash]); } - /** - * Creates an PublicKeys instance from a given buffer or BufferReader. - * If the input is a Buffer, it wraps it in a BufferReader before processing. - * Throws an error if the input length is not equal to the expected size. - * - * @param buffer - The input buffer or BufferReader containing the address data. - * @returns - A new PublicKeys instance with the extracted address data. - */ static fromBuffer(buffer: Buffer | BufferReader): PublicKeys { const reader = BufferReader.asReader(buffer); - const masterNullifierPublicKey = reader.readObject(Point); - const masterIncomingViewingPublicKey = reader.readObject(Point); - const masterOutgoingViewingPublicKey = reader.readObject(Point); - const masterTaggingPublicKey = reader.readObject(Point); - return new PublicKeys( - masterNullifierPublicKey, - masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, - ); + const npkMHash = Fr.fromBuffer(reader); + const ivpkM = reader.readObject(PublicKey); + const ovpkMHash = Fr.fromBuffer(reader); + const tpkMHash = Fr.fromBuffer(reader); + return new PublicKeys(npkMHash, ivpkM, ovpkMHash, tpkMHash); } toNoirStruct() { - // We need to use lowercase identifiers as those are what the noir interface expects - + // We need to use lowercase identifiers as those are what the noir interface expects. + /* eslint-disable camelcase */ return { - // TODO(#6337): Directly dump account.publicKeys here - /* eslint-disable camelcase */ - npk_m: this.masterNullifierPublicKey.toWrappedNoirStruct(), - ivpk_m: this.masterIncomingViewingPublicKey.toWrappedNoirStruct(), - ovpk_m: this.masterOutgoingViewingPublicKey.toWrappedNoirStruct(), - tpk_m: this.masterTaggingPublicKey.toWrappedNoirStruct(), - /* eslint-enable camelcase */ + npk_m_hash: this.npkMHash, + ivpk_m: this.ivpkM.toWrappedNoirStruct(), + ovpk_m_hash: this.ovpkMHash, + tpk_m_hash: this.tpkMHash, }; + /* eslint-enable camelcase */ } /** - * Serializes the payload to an array of fields - * @returns The fields of the payload + * Wire-format fields matching Noir's struct flattening of `PublicKeys`: + * `[npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash]` (5 fields). */ toFields(): Fr[] { - return [ - ...this.masterNullifierPublicKey.toFields(), - ...this.masterIncomingViewingPublicKey.toFields(), - ...this.masterOutgoingViewingPublicKey.toFields(), - ...this.masterTaggingPublicKey.toFields(), - ]; + return [this.npkMHash, this.ivpkM.x, this.ivpkM.y, this.ovpkMHash, this.tpkMHash]; } - // TOOD: This is used in foundation/src/abi/encoder. This is probably non-optimal but I did not want - // to spend too much time on the encoder now. It probably needs a refactor. + // Used in foundation/src/abi/encoder. Probably non-optimal but the encoder needs a refactor. encodeToNoir(): Fr[] { return this.toFields(); } static fromFields(fields: Fr[] | FieldReader): PublicKeys { const reader = FieldReader.asReader(fields); - return new PublicKeys( - reader.readObject(Point), - reader.readObject(Point), - reader.readObject(Point), - reader.readObject(Point), - ); + return new PublicKeys(reader.readField(), reader.readObject(PublicKey), reader.readField(), reader.readField()); } toString() { diff --git a/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts b/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts index 2595068e7f6d..286be1c2b64f 100644 --- a/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts +++ b/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts @@ -27,6 +27,7 @@ import { type CoordinationSignatureType, EMPTY_COORDINATION_SIGNATURE_CONTEXT, type Signable, + coordinationSignatureContextEquals, getCoordinationSignatureTypedData, readCoordinationSignatureContext, recoverCoordinationSigner, @@ -99,9 +100,28 @@ export class CheckpointProposal extends Gossipable implements Signable { public readonly signatureContext: CoordinationSignatureContext, /** Optional last block info, including its own signature for BlockProposal extraction */ - public readonly lastBlock?: CheckpointLastBlock, + public readonly lastBlock?: CheckpointLastBlock | BlockProposal, ) { super(); + + // Check that last block properties match those of the checkpoint. + if (lastBlock && 'inHash' in lastBlock && !lastBlock.inHash.equals(checkpointHeader.inHash)) { + throw new Error( + `CheckpointProposal lastBlock inHash ${lastBlock.inHash} does not match checkpoint inHash ${checkpointHeader.inHash}`, + ); + } + if (lastBlock && 'archiveRoot' in lastBlock && !lastBlock.archiveRoot.equals(archive)) { + throw new Error( + `CheckpointProposal lastBlock archive ${lastBlock.archiveRoot} does not match checkpoint archive ${archive}`, + ); + } + if ( + lastBlock && + 'signatureContext' in lastBlock && + !coordinationSignatureContextEquals(lastBlock.signatureContext, signatureContext) + ) { + throw new Error(`CheckpointProposal lastBlock signatureContext does not match checkpoint signatureContext`); + } } override generateP2PMessageIdentifier(): Promise { diff --git a/yarn-project/stdlib/src/slashing/helpers.test.ts b/yarn-project/stdlib/src/slashing/helpers.test.ts index cc2d7c00e56d..5820e4aec091 100644 --- a/yarn-project/stdlib/src/slashing/helpers.test.ts +++ b/yarn-project/stdlib/src/slashing/helpers.test.ts @@ -178,7 +178,7 @@ describe('SlashingHelpers', () => { it('handles epoch-based offense that spans multiple rounds', () => { const offense = { epochOrSlot: 2n, // epoch 2 = slot 8 - offenseType: OffenseType.DATA_WITHHOLDING, + offenseType: OffenseType.INACTIVITY, }; const round = getRoundForOffense(offense, constants); expect(round).toEqual(0n); // slot 8 / roundSize 10 = round 0 @@ -187,7 +187,7 @@ describe('SlashingHelpers', () => { it('handles epoch-based offense when round is multiple of epoch duration', () => { const offense = { epochOrSlot: 2n, // epoch 2 = slot 8 - offenseType: OffenseType.DATA_WITHHOLDING, + offenseType: OffenseType.INACTIVITY, }; const round = getRoundForOffense(offense, { ...constants, slashingRoundSize: 8 }); expect(round).toEqual(1n); // slot 8 / roundSize 8 = round 1 @@ -197,12 +197,12 @@ describe('SlashingHelpers', () => { describe('getPenaltyForOffense', () => { it('returns the configured penalty for attesting to invalid checkpoint proposal', () => { const penalty = getPenaltyForOffense(OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, { - slashAttestDescendantOfInvalidPenalty: 1n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1n, slashBroadcastedInvalidBlockPenalty: 2n, + slashBroadcastedInvalidCheckpointProposalPenalty: 11n, slashDuplicateProposalPenalty: 3n, slashDuplicateAttestationPenalty: 4n, slashAttestInvalidCheckpointProposalPenalty: 5n, - slashPrunePenalty: 6n, slashDataWithholdingPenalty: 7n, slashUnknownPenalty: 8n, slashInactivityPenalty: 9n, @@ -211,5 +211,22 @@ describe('SlashingHelpers', () => { expect(penalty).toBe(5n); }); + + it('returns the configured penalty for broadcasting invalid checkpoint proposal', () => { + const penalty = getPenaltyForOffense(OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, { + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1n, + slashBroadcastedInvalidBlockPenalty: 2n, + slashBroadcastedInvalidCheckpointProposalPenalty: 11n, + slashDuplicateProposalPenalty: 3n, + slashDuplicateAttestationPenalty: 4n, + slashAttestInvalidCheckpointProposalPenalty: 5n, + slashDataWithholdingPenalty: 7n, + slashUnknownPenalty: 8n, + slashInactivityPenalty: 9n, + slashProposeInvalidAttestationsPenalty: 10n, + }); + + expect(penalty).toBe(11n); + }); }); }); diff --git a/yarn-project/stdlib/src/slashing/helpers.ts b/yarn-project/stdlib/src/slashing/helpers.ts index 21ca279597f1..24df1ee11617 100644 --- a/yarn-project/stdlib/src/slashing/helpers.ts +++ b/yarn-project/stdlib/src/slashing/helpers.ts @@ -48,12 +48,12 @@ export function getPenaltyForOffense( offense: OffenseType, config: Pick< SlasherConfig, - | 'slashAttestDescendantOfInvalidPenalty' + | 'slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty' | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' - | 'slashPrunePenalty' | 'slashDataWithholdingPenalty' | 'slashUnknownPenalty' | 'slashInactivityPenalty' @@ -61,8 +61,6 @@ export function getPenaltyForOffense( >, ) { switch (offense) { - case OffenseType.VALID_EPOCH_PRUNED: - return config.slashPrunePenalty; case OffenseType.DATA_WITHHOLDING: return config.slashDataWithholdingPenalty; case OffenseType.INACTIVITY: @@ -70,10 +68,12 @@ export function getPenaltyForOffense( case OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS: case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS: return config.slashProposeInvalidAttestationsPenalty; - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: - return config.slashAttestDescendantOfInvalidPenalty; + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: + return config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty; case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: return config.slashBroadcastedInvalidBlockPenalty; + case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: + return config.slashBroadcastedInvalidCheckpointProposalPenalty; case OffenseType.DUPLICATE_PROPOSAL: return config.slashDuplicateProposalPenalty; case OffenseType.DUPLICATE_ATTESTATION: @@ -92,8 +92,10 @@ export function getPenaltyForOffense( /** Returns whether the `epochOrSlot` field for an offense references an epoch or a slot */ export function getTimeUnitForOffense(offense: OffenseType): 'epoch' | 'slot' { switch (offense) { - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: + case OffenseType.DATA_WITHHOLDING: + case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: case OffenseType.DUPLICATE_PROPOSAL: case OffenseType.DUPLICATE_ATTESTATION: case OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL: @@ -101,9 +103,7 @@ export function getTimeUnitForOffense(offense: OffenseType): 'epoch' | 'slot' { case OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS: return 'slot'; case OffenseType.INACTIVITY: - case OffenseType.DATA_WITHHOLDING: case OffenseType.UNKNOWN: - case OffenseType.VALID_EPOCH_PRUNED: return 'epoch'; default: { const _exhaustiveCheck: never = offense; diff --git a/yarn-project/stdlib/src/slashing/serialization.test.ts b/yarn-project/stdlib/src/slashing/serialization.test.ts index 9c84b476a351..f4c6d664acd0 100644 --- a/yarn-project/stdlib/src/slashing/serialization.test.ts +++ b/yarn-project/stdlib/src/slashing/serialization.test.ts @@ -92,7 +92,7 @@ describe('slashing/serialization', () => { const validator2 = EthAddress.fromString('0x2222222222222222222222222222222222222222'); const offense1 = createOffense(validator1, 500n, OffenseType.DATA_WITHHOLDING, 25n); - const offense2 = createOffense(validator2, 750n, OffenseType.VALID_EPOCH_PRUNED, 30n); + const offense2 = createOffense(validator2, 750n, OffenseType.INACTIVITY, 30n); const serialized1 = serializeOffense(offense1); const deserialized1 = deserializeOffense(serialized1); @@ -107,7 +107,7 @@ describe('slashing/serialization', () => { expect(deserialized2.validator).toEqual(validator2); expect(deserialized2.amount).toEqual(750n); - expect(deserialized2.offenseType).toEqual(OffenseType.VALID_EPOCH_PRUNED); + expect(deserialized2.offenseType).toEqual(OffenseType.INACTIVITY); expect(deserialized2.epochOrSlot).toEqual(30n); // Ensure they produce different serialized data @@ -118,7 +118,7 @@ describe('slashing/serialization', () => { const originalOffense = createOffense( EthAddress.random(), 12345n, - OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, 98765n, ); @@ -160,7 +160,7 @@ describe('slashing/serialization', () => { const epochOffenses = [ OffenseType.INACTIVITY, OffenseType.DATA_WITHHOLDING, - OffenseType.VALID_EPOCH_PRUNED, + OffenseType.INACTIVITY, OffenseType.UNKNOWN, ]; @@ -168,7 +168,7 @@ describe('slashing/serialization', () => { const slotOffenses = [ OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS, OffenseType.PROPOSED_INCORRECT_ATTESTATIONS, - OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL, ]; diff --git a/yarn-project/stdlib/src/slashing/types.ts b/yarn-project/stdlib/src/slashing/types.ts index 6a72b45c061b..45aa9f31dddc 100644 --- a/yarn-project/stdlib/src/slashing/types.ts +++ b/yarn-project/stdlib/src/slashing/types.ts @@ -6,10 +6,8 @@ import { schemas, zodFor } from '../schemas/index.js'; export enum OffenseType { UNKNOWN = 0, - /** The data for proving an epoch was not publicly available, we slash its committee */ + /** The data for the txs in a published checkpoint was not available within the tolerance window, we slash the checkpoint's attesters */ DATA_WITHHOLDING = 1, - /** An epoch was not successfully proven in time, we slash its committee */ - VALID_EPOCH_PRUNED = 2, /** A proposer failed to attest or propose during an epoch according to the Sentinel */ INACTIVITY = 3, /** A proposer sent an invalid block proposal over the p2p network to the committee */ @@ -18,14 +16,16 @@ export enum OffenseType { PROPOSED_INSUFFICIENT_ATTESTATIONS = 5, /** A proposer pushed to L1 a block with incorrect committee attestations (ie signature from a non-committee member) */ PROPOSED_INCORRECT_ATTESTATIONS = 6, - /** A committee member attested to a block that was built as a descendent of an invalid block (as in a block with invalid attestations) */ - ATTESTED_DESCENDANT_OF_INVALID = 7, + /** A proposer published a checkpoint to L1 that builds on an invalid checkpoint (as in a checkpoint with invalid or insufficient attestations) */ + PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS = 7, /** A proposer sent duplicate proposals for the same position (slot, indexWithinCheckpoint for blocks or slot for checkpoints) */ DUPLICATE_PROPOSAL = 8, /** A validator signed attestations for different proposals at the same slot (equivocation) */ DUPLICATE_ATTESTATION = 9, /** A committee member attested to a checkpoint proposal in a slot with an invalid block proposal */ ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL = 10, + /** A proposer broadcast an invalid checkpoint proposal, detected by retained evidence or deterministic recomputation */ + BROADCASTED_INVALID_CHECKPOINT_PROPOSAL = 11, } export function getOffenseTypeName(offense: OffenseType) { @@ -34,8 +34,6 @@ export function getOffenseTypeName(offense: OffenseType) { return 'unknown'; case OffenseType.DATA_WITHHOLDING: return 'data_withholding'; - case OffenseType.VALID_EPOCH_PRUNED: - return 'valid_epoch_pruned'; case OffenseType.INACTIVITY: return 'inactivity'; case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: @@ -44,14 +42,16 @@ export function getOffenseTypeName(offense: OffenseType) { return 'proposed_insufficient_attestations'; case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS: return 'proposed_incorrect_attestations'; - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: - return 'attested_descendant_of_invalid'; + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: + return 'proposed_descendant_of_checkpoint_with_invalid_attestations'; case OffenseType.DUPLICATE_PROPOSAL: return 'duplicate_proposal'; case OffenseType.DUPLICATE_ATTESTATION: return 'duplicate_attestation'; case OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL: return 'attested_to_invalid_checkpoint_proposal'; + case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: + return 'broadcasted_invalid_checkpoint_proposal'; default: throw new Error(`Unknown offense type: ${offense}`); } @@ -62,15 +62,15 @@ export const OffenseTypeSchema = z.nativeEnum(OffenseType); export const OffenseToBigInt: Record = { [OffenseType.UNKNOWN]: 0n, [OffenseType.DATA_WITHHOLDING]: 1n, - [OffenseType.VALID_EPOCH_PRUNED]: 2n, [OffenseType.INACTIVITY]: 3n, [OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL]: 4n, [OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS]: 5n, [OffenseType.PROPOSED_INCORRECT_ATTESTATIONS]: 6n, - [OffenseType.ATTESTED_DESCENDANT_OF_INVALID]: 7n, + [OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS]: 7n, [OffenseType.DUPLICATE_PROPOSAL]: 8n, [OffenseType.DUPLICATE_ATTESTATION]: 9n, [OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL]: 10n, + [OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL]: 11n, }; export function bigIntToOffense(offense: bigint): OffenseType { @@ -79,8 +79,6 @@ export function bigIntToOffense(offense: bigint): OffenseType { return OffenseType.UNKNOWN; case 1n: return OffenseType.DATA_WITHHOLDING; - case 2n: - return OffenseType.VALID_EPOCH_PRUNED; case 3n: return OffenseType.INACTIVITY; case 4n: @@ -90,13 +88,15 @@ export function bigIntToOffense(offense: bigint): OffenseType { case 6n: return OffenseType.PROPOSED_INCORRECT_ATTESTATIONS; case 7n: - return OffenseType.ATTESTED_DESCENDANT_OF_INVALID; + return OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS; case 8n: return OffenseType.DUPLICATE_PROPOSAL; case 9n: return OffenseType.DUPLICATE_ATTESTATION; case 10n: return OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL; + case 11n: + return OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL; default: throw new Error(`Unknown offense: ${offense}`); } diff --git a/yarn-project/stdlib/src/slashing/votes.test.ts b/yarn-project/stdlib/src/slashing/votes.test.ts index 17cad2d71862..9cd770f16ca8 100644 --- a/yarn-project/stdlib/src/slashing/votes.test.ts +++ b/yarn-project/stdlib/src/slashing/votes.test.ts @@ -275,13 +275,13 @@ describe('SlashingHelpers', () => { { validator: mockValidator1, amount: 7n, - offenseType: OffenseType.DATA_WITHHOLDING, + offenseType: OffenseType.INACTIVITY, epochOrSlot: 3n, }, { validator: mockValidator1, amount: 5n, - offenseType: OffenseType.VALID_EPOCH_PRUNED, + offenseType: OffenseType.INACTIVITY, epochOrSlot: 3n, }, ]; @@ -530,10 +530,10 @@ describe('SlashingHelpers', () => { // Truncation must cut one validator (not one offense record). const offenses: Offense[] = [ { validator: mockValidator1, amount: 15n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, - { validator: mockValidator1, amount: 8n, offenseType: OffenseType.DATA_WITHHOLDING, epochOrSlot: 5n }, - { validator: mockValidator1, amount: 5n, offenseType: OffenseType.VALID_EPOCH_PRUNED, epochOrSlot: 5n }, + { validator: mockValidator1, amount: 8n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, + { validator: mockValidator1, amount: 5n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, { validator: mockValidator2, amount: 20n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, - { validator: mockValidator2, amount: 5n, offenseType: OffenseType.DATA_WITHHOLDING, epochOrSlot: 5n }, + { validator: mockValidator2, amount: 5n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, { validator: mockValidator3, amount: 10n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, ]; diff --git a/yarn-project/stdlib/src/tests/factories.ts b/yarn-project/stdlib/src/tests/factories.ts index e4a987249fca..a20585ad65ce 100644 --- a/yarn-project/stdlib/src/tests/factories.ts +++ b/yarn-project/stdlib/src/tests/factories.ts @@ -123,7 +123,7 @@ import { PublicCallRequest, PublicCallRequestArrayLengths, } from '../kernel/public_call_request.js'; -import { PublicKeys, computeAddress } from '../keys/index.js'; +import { PublicKey, PublicKeys, computeAddress, hashPublicKey } from '../keys/index.js'; import { ExtendedDirectionalAppTaggingSecret } from '../logs/extended_directional_app_tagging_secret.js'; import { ContractClassLog, ContractClassLogFields } from '../logs/index.js'; import { PrivateLog } from '../logs/private_log.js'; @@ -252,7 +252,7 @@ function makeScopedReadRequest(n: number): ScopedReadRequest { * @returns A KeyValidationRequest. */ function makeKeyValidationRequests(seed: number): KeyValidationRequest { - return new KeyValidationRequest(makePoint(seed), fr(seed + 2)); + return new KeyValidationRequest(fr(seed), fr(seed + 2)); } /** @@ -577,7 +577,7 @@ export function makeVerificationKeyAsFields(size: number): VerificationKeyAsFiel * @returns A point. */ export function makePoint(seed = 1): Point { - return new Point(fr(seed), fr(seed + 1), false); + return new Point(fr(seed), fr(seed + 1)); } /** @@ -1220,8 +1220,13 @@ export async function makeMapAsync(size: number, fn: (i: number) => Promise<[ export async function makePublicKeys(seed = 0): Promise { const f = (offset: number) => Grumpkin.mul(Grumpkin.generator, new Fq(seed + offset)); - - return new PublicKeys(await f(0), await f(1), await f(2), await f(3)); + const ivpkM = await f(1); + return new PublicKeys( + await hashPublicKey(await f(0)), + ivpkM, + await hashPublicKey(await f(2)), + await hashPublicKey(await f(3)), + ); } export async function makeContractInstanceFromClassId( @@ -1230,6 +1235,7 @@ export async function makeContractInstanceFromClassId( overrides?: { deployer?: AztecAddress; initializationHash?: Fr; + immutablesHash?: Fr; publicKeys?: PublicKeys; currentClassId?: Fr; }, @@ -1238,21 +1244,24 @@ export async function makeContractInstanceFromClassId( const initializationHash = overrides?.initializationHash ?? new Fr(seed + 1); const deployer = overrides?.deployer ?? new AztecAddress(new Fr(seed + 2)); const publicKeys = overrides?.publicKeys ?? (await makePublicKeys(seed + 3)); + const immutablesHash = overrides?.immutablesHash ?? new Fr(seed + 4); const partialAddress = await computePartialAddress({ originalContractClassId: classId, salt, initializationHash, + immutablesHash, deployer, }); const address = await computeAddress(publicKeys, partialAddress); return new SerializableContractInstance({ - version: 1, + version: 2, salt, deployer, currentContractClassId: overrides?.currentClassId ?? classId, originalContractClassId: classId, initializationHash, + immutablesHash, publicKeys, }).withAddress(address); } @@ -1430,11 +1439,12 @@ export function makeAvmContractInstanceHint(seed = 0): AvmContractInstanceHint { new Fr(seed + 0x4), new Fr(seed + 0x5), new Fr(seed + 0x6), + new Fr(seed + 0x7), new PublicKeys( - new Point(new Fr(seed + 0x7), new Fr(seed + 0x8), false), - new Point(new Fr(seed + 0x9), new Fr(seed + 0x10), false), - new Point(new Fr(seed + 0x11), new Fr(seed + 0x12), false), - new Point(new Fr(seed + 0x13), new Fr(seed + 0x14), false), + new Fr(seed + 0x7), + new PublicKey(new Fr(seed + 0x9), new Fr(seed + 0x10)), + new Fr(seed + 0x11), + new Fr(seed + 0x13), ), ); } diff --git a/yarn-project/stdlib/src/tx/tx_receipt.test.ts b/yarn-project/stdlib/src/tx/tx_receipt.test.ts index 8be605399c4f..0c2044f37fad 100644 --- a/yarn-project/stdlib/src/tx/tx_receipt.test.ts +++ b/yarn-project/stdlib/src/tx/tx_receipt.test.ts @@ -42,22 +42,12 @@ describe('TxReceipt', () => { }); it('isSuccess returns false for reverted execution', () => { - const receipt = new TxReceipt( - TxHash.random(), - TxStatus.PROPOSED, - TxExecutionResult.APP_LOGIC_REVERTED, - undefined, - ); + const receipt = new TxReceipt(TxHash.random(), TxStatus.PROPOSED, TxExecutionResult.REVERTED, undefined); expect(receipt.hasExecutionSucceeded()).toBe(false); }); it('isReverted returns true for reverted execution', () => { - const receipt = new TxReceipt( - TxHash.random(), - TxStatus.PROPOSED, - TxExecutionResult.APP_LOGIC_REVERTED, - undefined, - ); + const receipt = new TxReceipt(TxHash.random(), TxStatus.PROPOSED, TxExecutionResult.REVERTED, undefined); expect(receipt.hasExecutionReverted()).toBe(true); }); diff --git a/yarn-project/stdlib/src/tx/tx_receipt.ts b/yarn-project/stdlib/src/tx/tx_receipt.ts index 348806510344..446855f44237 100644 --- a/yarn-project/stdlib/src/tx/tx_receipt.ts +++ b/yarn-project/stdlib/src/tx/tx_receipt.ts @@ -32,15 +32,6 @@ export const SortedTxStatuses: TxStatus[] = [ export enum TxExecutionResult { SUCCESS = 'success', REVERTED = 'reverted', - /** @deprecated Use REVERTED instead. */ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - APP_LOGIC_REVERTED = 'reverted', - /** @deprecated Use REVERTED instead. */ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - TEARDOWN_REVERTED = 'reverted', - /** @deprecated Use REVERTED instead. */ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - BOTH_REVERTED = 'reverted', } /** diff --git a/yarn-project/stdlib/src/validators/schemas.ts b/yarn-project/stdlib/src/validators/schemas.ts index 33a8de976c86..15bc07beb498 100644 --- a/yarn-project/stdlib/src/validators/schemas.ts +++ b/yarn-project/stdlib/src/validators/schemas.ts @@ -14,7 +14,9 @@ import type { export const ValidatorStatusInSlotSchema = zodFor()( z.enum([ 'checkpoint-mined', - 'checkpoint-proposed', + 'checkpoint-valid', + 'checkpoint-invalid', + 'checkpoint-unvalidated', 'checkpoint-missed', 'blocks-missed', 'attestation-sent', @@ -74,7 +76,7 @@ export const ValidatorsStatsSchema = zodFor()( export const SingleValidatorStatsSchema = zodFor()( z.object({ validator: ValidatorStatsSchema, - allTimeProvenPerformance: z.array( + allTimeEpochPerformance: z.array( z.object({ missed: schemas.Integer, total: schemas.Integer, diff --git a/yarn-project/stdlib/src/validators/types.ts b/yarn-project/stdlib/src/validators/types.ts index bf005e4537d1..4adedf0dab43 100644 --- a/yarn-project/stdlib/src/validators/types.ts +++ b/yarn-project/stdlib/src/validators/types.ts @@ -3,9 +3,28 @@ import type { EthAddress } from '@aztec/foundation/eth-address'; export type ValidatorStatusType = 'proposer' | 'attestation'; +/** + * Per-slot status for a validator. + * + * Proposer statuses (six-case taxonomy): + * - `blocks-missed` — no block proposals seen for the slot (case 1). + * - `checkpoint-missed` — block proposals seen but no checkpoint proposal (case 2). + * - `checkpoint-unvalidated` — checkpoint proposal seen but local re-execution couldn't + * validate (missing txs, timeouts, etc.) (case 3). + * - `checkpoint-invalid` — checkpoint proposal re-executed and rejected as invalid (case 4). + * - `checkpoint-valid` — checkpoint proposal re-executed locally as valid (case 5). + * - `checkpoint-mined` — checkpoint published on L1 (case 6). + * + * Attestor statuses: + * - `attestation-sent` — attestation observed on P2P or in the published checkpoint. + * - `attestation-missed` — committee member did not attest to a checkpoint proposal that + * was observed locally or published on L1. + */ export type ValidatorStatusInSlot = | 'checkpoint-mined' - | 'checkpoint-proposed' + | 'checkpoint-valid' + | 'checkpoint-invalid' + | 'checkpoint-unvalidated' | 'checkpoint-missed' | 'blocks-missed' | 'attestation-sent' @@ -41,7 +60,7 @@ export type ValidatorsEpochPerformance = Record<`0x${string}`, { missed: number; export type SingleValidatorStats = { validator: ValidatorStats; - allTimeProvenPerformance: { missed: number; total: number; epoch: EpochNumber }[]; + allTimeEpochPerformance: { missed: number; total: number; epoch: EpochNumber }[]; lastProcessedSlot?: SlotNumber; initialSlot?: SlotNumber; slotWindow: number; diff --git a/yarn-project/telemetry-client/src/attributes.ts b/yarn-project/telemetry-client/src/attributes.ts index df2686e844f3..adf11f85dced 100644 --- a/yarn-project/telemetry-client/src/attributes.ts +++ b/yarn-project/telemetry-client/src/attributes.ts @@ -96,7 +96,6 @@ export const VALIDATOR_STATUS = 'aztec.validator_status'; export const P2P_ID = 'aztec.p2p.id'; export const P2P_REQ_RESP_PROTOCOL = 'aztec.p2p.req_resp.protocol'; -export const P2P_REQ_RESP_BATCH_REQUESTS_COUNT = 'aztec.p2p.req_resp.batch_requests_count'; /** The state of a peer (Healthy, Disconnect, Banned) */ export const P2P_PEER_SCORE_STATE = 'aztec.p2p.peer_score_state'; export const POOL_NAME = 'aztec.pool.name'; diff --git a/yarn-project/telemetry-client/src/config.ts b/yarn-project/telemetry-client/src/config.ts index 4e705c7a6fcf..814aa2474ba8 100644 --- a/yarn-project/telemetry-client/src/config.ts +++ b/yarn-project/telemetry-client/src/config.ts @@ -17,6 +17,8 @@ export interface TelemetryClientConfig { otelExportTimeoutMs: number; otelExcludeMetrics: string[]; otelIncludeMetrics: string[]; + otelMinTraceDurationMs: number; + otelBspMaxQueueSize: number; } export const telemetryClientConfigMappings: ConfigMappingsType = { @@ -57,6 +59,16 @@ export const telemetryClientConfigMappings: ConfigMappingsType[1]): void { + this.spans.push(...spans); + resultCallback({ code: ExportResultCode.SUCCESS }); + } + + shutdown(): Promise { + return Promise.resolve(); + } +} + +const log = { warn: () => {} } as any; + +function makeSpan(durationMs: number, statusCode = SpanStatusCode.OK): ReadableSpan { + const seconds = Math.floor(durationMs / 1000); + const nanos = (durationMs - seconds * 1000) * 1_000_000; + return { + attributes: {}, + droppedAttributesCount: 0, + droppedEventsCount: 0, + droppedLinksCount: 0, + duration: [seconds, nanos], + ended: true, + endTime: [seconds, nanos], + events: [], + instrumentationLibrary: {} as any, + kind: SpanKind.INTERNAL, + links: [], + name: `span-${durationMs}`, + resource: {} as any, + spanContext: () => ({ spanId: '0'.repeat(16), traceFlags: 1, traceId: '0'.repeat(32) }), + startTime: [0, 0], + status: { code: statusCode }, + }; +} + +describe('MonitoredBatchSpanProcessor', () => { + it('does not export successful spans shorter than the configured duration', async () => { + const exporter = new CollectingSpanExporter(); + const processor = new MonitoredBatchSpanProcessor(exporter, log, { minTraceDurationMs: 10 }); + + processor.onEnd(makeSpan(9)); + processor.onEnd(makeSpan(10)); + await processor.forceFlush(); + + expect(exporter.spans.map(span => span.name)).toEqual(['span-10']); + }); + + it('exports short error spans', async () => { + const exporter = new CollectingSpanExporter(); + const processor = new MonitoredBatchSpanProcessor(exporter, log, { minTraceDurationMs: 10 }); + + processor.onEnd(makeSpan(1, SpanStatusCode.ERROR)); + await processor.forceFlush(); + + expect(exporter.spans.map(span => span.name)).toEqual(['span-1']); + }); + + it('allows short successful spans when the minimum duration is disabled', async () => { + const exporter = new CollectingSpanExporter(); + const processor = new MonitoredBatchSpanProcessor(exporter, log, { minTraceDurationMs: 0 }); + + processor.onEnd(makeSpan(1)); + await processor.forceFlush(); + + expect(exporter.spans.map(span => span.name)).toEqual(['span-1']); + }); +}); diff --git a/yarn-project/telemetry-client/src/monitored_batch_span_processor.ts b/yarn-project/telemetry-client/src/monitored_batch_span_processor.ts index 669c136f8aaf..c5fd7bb81918 100644 --- a/yarn-project/telemetry-client/src/monitored_batch_span_processor.ts +++ b/yarn-project/telemetry-client/src/monitored_batch_span_processor.ts @@ -1,12 +1,19 @@ import type { Logger } from '@aztec/foundation/log'; -import type { Context } from '@opentelemetry/api'; +import { type Context, SpanStatusCode } from '@opentelemetry/api'; +import { hrTimeToMilliseconds } from '@opentelemetry/core'; import type { SpanExporter } from '@opentelemetry/sdk-trace-base'; import { BatchSpanProcessor, type BufferConfig, type ReadableSpan, type Span } from '@opentelemetry/sdk-trace-node'; /** Minimum interval between drop warnings to avoid log spam. */ const DROP_WARNING_INTERVAL_MS = 30_000; +const DEFAULT_MIN_TRACE_DURATION_MS = 10; + +export type MonitoredBatchSpanProcessorConfig = BufferConfig & { + minTraceDurationMs?: number; +}; + /** * Wraps BatchSpanProcessor to emit warnings when spans are dropped due to a full queue. * The standard BatchSpanProcessor silently discards spans when its internal queue reaches @@ -14,6 +21,7 @@ const DROP_WARNING_INTERVAL_MS = 30_000; */ export class MonitoredBatchSpanProcessor extends BatchSpanProcessor { private readonly maxQueueSize: number; + private readonly minTraceDurationMs: number; private readonly log: Logger; private approxQueueSize = 0; @@ -21,10 +29,11 @@ export class MonitoredBatchSpanProcessor extends BatchSpanProcessor { private totalDropped = 0; private lastWarningTime = 0; - constructor(exporter: SpanExporter, log: Logger, config?: BufferConfig) { + constructor(exporter: SpanExporter, log: Logger, config?: MonitoredBatchSpanProcessorConfig) { const maxQueueSize = config?.maxQueueSize ?? 2048; super(exporter, { ...config, maxQueueSize }); this.maxQueueSize = maxQueueSize; + this.minTraceDurationMs = Math.max(0, config?.minTraceDurationMs ?? DEFAULT_MIN_TRACE_DURATION_MS); this.log = log; } @@ -33,6 +42,10 @@ export class MonitoredBatchSpanProcessor extends BatchSpanProcessor { } override onEnd(span: ReadableSpan): void { + if (this.shouldDropShortSpan(span)) { + return; + } + if (this.approxQueueSize >= this.maxQueueSize) { this.droppedSinceLastWarning++; this.totalDropped++; @@ -57,6 +70,14 @@ export class MonitoredBatchSpanProcessor extends BatchSpanProcessor { await super.shutdown(); } + private shouldDropShortSpan(span: ReadableSpan): boolean { + return ( + this.minTraceDurationMs > 0 && + span.status.code !== SpanStatusCode.ERROR && + hrTimeToMilliseconds(span.duration) < this.minTraceDurationMs + ); + } + private maybeLogDropWarning(): void { const now = Date.now(); if (now - this.lastWarningTime >= DROP_WARNING_INTERVAL_MS) { diff --git a/yarn-project/telemetry-client/src/otel.ts b/yarn-project/telemetry-client/src/otel.ts index 42d698ab6ed0..a67cb76ef637 100644 --- a/yarn-project/telemetry-client/src/otel.ts +++ b/yarn-project/telemetry-client/src/otel.ts @@ -374,7 +374,12 @@ export class OpenTelemetryClient implements TelemetryClient { const tracerProvider = new NodeTracerProvider({ resource, spanProcessors: config.tracesCollectorUrl - ? [new MonitoredBatchSpanProcessor(new OTLPTraceExporter({ url: config.tracesCollectorUrl.href }), log)] + ? [ + new MonitoredBatchSpanProcessor(new OTLPTraceExporter({ url: config.tracesCollectorUrl.href }), log, { + maxQueueSize: config.otelBspMaxQueueSize, + minTraceDurationMs: config.otelMinTraceDurationMs, + }), + ] : [], }); diff --git a/yarn-project/telemetry-client/src/otel_propagation.ts b/yarn-project/telemetry-client/src/otel_propagation.ts index dad50b793829..4e0751d2d442 100644 --- a/yarn-project/telemetry-client/src/otel_propagation.ts +++ b/yarn-project/telemetry-client/src/otel_propagation.ts @@ -1,3 +1,5 @@ +import type { DiagnosticsMiddleware } from '@aztec/foundation/json-rpc/server'; + import { ROOT_CONTEXT, type Span, SpanKind, SpanStatusCode, propagation } from '@opentelemetry/api'; import type Koa from 'koa'; @@ -17,7 +19,7 @@ export function getOtelJsonRpcPropagationMiddleware( const context = propagation.extract(ROOT_CONTEXT, ctx.request.headers); const method = (ctx.request.body as any)?.method; return tracer.startActiveSpan( - `JsonRpcServer.${method ?? 'unknown'}`, + `JsonRpcServer.${method ?? 'batch'}`, { kind: SpanKind.SERVER }, context, async (span: Span): Promise => { @@ -48,3 +50,42 @@ export function getOtelJsonRpcPropagationMiddleware( ); }; } + +export function getOtelJsonRpcDiagnosticsMiddleware(): DiagnosticsMiddleware { + return function otelJsonRpcDiagnostics(ctx, next) { + const [namespace, method] = splitNamespace(ctx.method); + const scope = namespace ?? 'UnknownHandler'; + const tracer = getTelemetryClient().getTracer(scope); + return tracer.startActiveSpan( + `${scope}.${method}`, + { kind: SpanKind.INTERNAL, attributes: { [ATTR_JSONRPC_METHOD]: ctx.method } }, + async span => { + if (ctx.id !== null) { + span.setAttribute(ATTR_JSONRPC_REQUEST_ID, ctx.id); + } + + try { + await next(); + span.setStatus({ code: SpanStatusCode.OK }); + } catch (err) { + span.setStatus({ code: SpanStatusCode.ERROR, message: err instanceof Error ? err.message : String(err) }); + if (typeof err === 'string' || err instanceof Error) { + span.recordException(err); + } + throw err; + } finally { + span.end(); + } + }, + ); + }; +} + +function splitNamespace(fullMethod: string): [namespace: string | undefined, method: string] { + const idx = fullMethod.indexOf('_'); + if (idx > -1) { + return [fullMethod.slice(0, idx), fullMethod.slice(idx + 1)]; + } else { + return [undefined, fullMethod]; + } +} diff --git a/yarn-project/telemetry-client/src/start.ts b/yarn-project/telemetry-client/src/start.ts index 6006b001dd9f..4204cede80ce 100644 --- a/yarn-project/telemetry-client/src/start.ts +++ b/yarn-project/telemetry-client/src/start.ts @@ -19,7 +19,12 @@ export async function initTelemetryClient( return telemetry; } - if (config.metricsCollectorUrl || config.publicMetricsCollectorUrl) { + if ( + config.metricsCollectorUrl || + config.publicMetricsCollectorUrl || + config.tracesCollectorUrl || + config.logsCollectorUrl + ) { log.info(`Using OpenTelemetry client with custom collector`); // Lazy load OpenTelemetry to avoid loading heavy deps at startup const { OpenTelemetryClient } = await import('./otel.js'); diff --git a/yarn-project/telemetry-client/src/telemetry.ts b/yarn-project/telemetry-client/src/telemetry.ts index 5e304b61619c..25e1fd07149c 100644 --- a/yarn-project/telemetry-client/src/telemetry.ts +++ b/yarn-project/telemetry-client/src/telemetry.ts @@ -48,7 +48,6 @@ type BannedMetricAttributeNames = (typeof Attributes)[ | 'TX_HASH' | 'PROVING_JOB_ID' | 'P2P_ID' - | 'P2P_REQ_RESP_BATCH_REQUESTS_COUNT' | 'TARGET_ADDRESS' | 'MANA_USED' | 'TOTAL_INSTRUCTIONS']; diff --git a/yarn-project/txe/src/index.ts b/yarn-project/txe/src/index.ts index 225e77f85a86..d745b11df297 100644 --- a/yarn-project/txe/src/index.ts +++ b/yarn-project/txe/src/index.ts @@ -200,10 +200,7 @@ class TXEDispatcher { if (!TXEArtifactsCacheInFlight.has(cacheKey)) { const compute = async () => { const keys = await deriveKeys(secret); - const args = [ - keys.publicKeys.masterIncomingViewingPublicKey.x, - keys.publicKeys.masterIncomingViewingPublicKey.y, - ]; + const args = [keys.publicKeys.ivpkM.x, keys.publicKeys.ivpkM.y]; const computedArtifact: ContractArtifactWithHash = { ...SchnorrAccountContractArtifact, // Artifact hash is *very* expensive to compute, so we do it here once diff --git a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts index 0b0bf3316f2f..8338c84defae 100644 --- a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts +++ b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts @@ -63,6 +63,7 @@ import { PrivateToPublicAccumulatedData, PublicCallRequest, } from '@aztec/stdlib/kernel'; +import { hashPublicKey } from '@aztec/stdlib/keys'; import { ChonkProof } from '@aztec/stdlib/proofs'; import { makeGlobalVariables } from '@aztec/stdlib/testing'; import { MerkleTreeId } from '@aztec/stdlib/trees'; @@ -282,7 +283,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl async addAuthWitness(address: AztecAddress, messageHash: Fr) { const account = await this.accountStore.getAccount(address); - const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey); + const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM); + const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash); const schnorr = new Schnorr(); const signature = await schnorr.constructSignature(messageHash, privateKey); diff --git a/yarn-project/txe/src/rpc_translator.ts b/yarn-project/txe/src/rpc_translator.ts index bef1d2f19ce2..de4c456f42ea 100644 --- a/yarn-project/txe/src/rpc_translator.ts +++ b/yarn-project/txe/src/rpc_translator.ts @@ -245,6 +245,7 @@ export class RPCTranslator { instance.deployer.toField(), instance.currentContractClassId, instance.initializationHash, + instance.immutablesHash, ...instance.publicKeys.toFields(), ]), ]); @@ -647,6 +648,7 @@ export class RPCTranslator { instance.deployer.toField(), instance.currentContractClassId, instance.initializationHash, + instance.immutablesHash, ...instance.publicKeys.toFields(), ].map(toSingle), ); @@ -662,12 +664,24 @@ export class RPCTranslator { // with two fields: `some` (a boolean) and `value` (a field array in this case). if (result === undefined) { // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size. - return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(13).fill(new Fr(0)))]); + // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, partial_address] = 6 fields. + return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(6).fill(new Fr(0)))]); } else { - // Data was found so we set `some` to 1 and return it along with `value`. + // The Noir side hand-decodes a `[Field; 6]` here (see aztec-nr/aztec/src/oracle/keys.nr), so we + // emit the 5-field PublicKeys shape + partial_address explicitly + // rather than going through `publicKeys.toFields()` (which is the struct-flattened 6-field + // wire for oracle returns that decode via struct shape). + const { publicKeys, partialAddress } = result; return toForeignCallResult([ toSingle(new Fr(1)), - toArray([...result.publicKeys.toFields(), result.partialAddress]), + toArray([ + publicKeys.npkMHash, + publicKeys.ivpkM.x, + publicKeys.ivpkM.y, + publicKeys.ovpkMHash, + publicKeys.tpkMHash, + partialAddress, + ]), ]); } } @@ -1116,6 +1130,19 @@ export class RPCTranslator { ]); } + // eslint-disable-next-line camelcase + async aztec_avm_getContractInstanceImmutablesHash(foreignAddress: ForeignCallSingle) { + const address = addressFromSingle(foreignAddress); + + const instance = await this.handlerAsUtility().getContractInstance(address); + + return toForeignCallResult([ + toSingle(instance.immutablesHash), + // AVM requires an extra boolean indicating the instance was found + toSingle(new Fr(1)), + ]); + } + // eslint-disable-next-line camelcase async aztec_avm_sender() { const sender = await this.handlerAsAvm().sender(); diff --git a/yarn-project/txe/src/state_machine/dummy_p2p_client.ts b/yarn-project/txe/src/state_machine/dummy_p2p_client.ts index 25bc4085dc75..db5b1c2626c1 100644 --- a/yarn-project/txe/src/state_machine/dummy_p2p_client.ts +++ b/yarn-project/txe/src/state_machine/dummy_p2p_client.ts @@ -13,12 +13,17 @@ import type { PeerId, ReqRespSubProtocol, ReqRespSubProtocolHandler, - ReqRespSubProtocolValidators, StatusMessage, } from '@aztec/p2p'; import type { EthAddress, L2BlockStreamEvent, L2Tips } from '@aztec/stdlib/block'; import type { ITxProvider, PeerInfo } from '@aztec/stdlib/interfaces/server'; -import type { BlockProposal, CheckpointAttestation, CheckpointProposal, TopicType } from '@aztec/stdlib/p2p'; +import type { + BlockProposal, + CheckpointAttestation, + CheckpointProposal, + CheckpointProposalCore, + TopicType, +} from '@aztec/stdlib/p2p'; import type { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx'; export class DummyP2P implements P2P { @@ -159,6 +164,13 @@ export class DummyP2P implements P2P { throw new Error('DummyP2P does not implement "addOwnCheckpointAttestations"'); } + public getProposalsForSlot(_slot: SlotNumber): Promise<{ + blockProposals: BlockProposal[]; + checkpointProposals: CheckpointProposalCore[]; + }> { + return Promise.resolve({ blockProposals: [], checkpointProposals: [] }); + } + public getL2BlockHash(_number: number): Promise { throw new Error('DummyP2P does not implement "getL2BlockHash"'); } @@ -207,11 +219,7 @@ export class DummyP2P implements P2P { return Promise.resolve(); } - addReqRespSubProtocol( - _subProtocol: ReqRespSubProtocol, - _handler: ReqRespSubProtocolHandler, - _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { + addReqRespSubProtocol(_subProtocol: ReqRespSubProtocol, _handler: ReqRespSubProtocolHandler): Promise { throw new Error('DummyP2P does not implement "addReqRespSubProtocol".'); } handleAuthRequestFromPeer(_authRequest: AuthRequest, _peerId: PeerId): Promise { diff --git a/yarn-project/validator-client/README.md b/yarn-project/validator-client/README.md index 73f08f82fd69..4205a31e117e 100644 --- a/yarn-project/validator-client/README.md +++ b/yarn-project/validator-client/README.md @@ -156,15 +156,16 @@ Time | Proposer | Validator ## Configuration -| Flag | Purpose | -| ------------------------------------- | -------------------------------------------------------------------------------------- | -| `fishermanMode` | Validate proposals but don't broadcast attestations (monitoring only) | -| `alwaysReexecuteBlockProposals` | Force re-execution even when not in committee | -| `slashBroadcastedInvalidBlockPenalty` | Penalty amount for invalid proposals (0 = disabled) | -| `slashDuplicateProposalPenalty` | Penalty amount for duplicate proposals (0 = disabled) | -| `slashDuplicateAttestationPenalty` | Penalty amount for duplicate attestations (0 = disabled) | -| `attestationPollingIntervalMs` | How often to poll for attestations when collecting | -| `disabledValidators` | Validator addresses to exclude from duties | +| Flag | Purpose | +| -------------------------------------------------- | -------------------------------------------------------------------- | +| `fishermanMode` | Validate proposals but don't broadcast attestations (monitoring only) | +| `alwaysReexecuteBlockProposals` | Force re-execution even when not in committee | +| `slashBroadcastedInvalidBlockPenalty` | Penalty amount for invalid proposals (0 = disabled) | +| `slashBroadcastedInvalidCheckpointProposalPenalty` | Penalty amount for invalid checkpoint proposals (0 = disabled) | +| `slashDuplicateProposalPenalty` | Penalty amount for duplicate proposals (0 = disabled) | +| `slashDuplicateAttestationPenalty` | Penalty amount for duplicate attestations (0 = disabled) | +| `attestationPollingIntervalMs` | How often to poll for attestations when collecting | +| `disabledValidators` | Validator addresses to exclude from duties | ### High Availability (HA) Keystore diff --git a/yarn-project/validator-client/src/config.ts b/yarn-project/validator-client/src/config.ts index be8df0c0dd84..c283154fa2d5 100644 --- a/yarn-project/validator-client/src/config.ts +++ b/yarn-project/validator-client/src/config.ts @@ -79,6 +79,10 @@ export const validatorClientConfigMappings: ConfigMappingsType { - // For testing: change the archive to trigger state_mismatch validation failure. - // If there's a last block proposal, use its (already invalid) archive to keep signatures consistent - // so P2P validation passes and the slasher can detect the offense. + // For testing: corrupt the checkpoint so observers' checkpoint validation fails. + // + // Keep `archive` aligned with `lastBlockProposal.archiveRoot` so the archive-based lookup + // in `validateCheckpointProposal` (`getBlockData({ archive })`) still succeeds if (options.broadcastInvalidCheckpointProposal) { archive = lastBlockProposal?.archiveRoot ?? Fr.random(); + checkpointHeader = CheckpointHeader.from({ + ...checkpointHeader, + epochOutHash: Fr.random(), + }); this.log.warn(`Creating INVALID checkpoint proposal for slot ${checkpointHeader.slotNumber}`); } diff --git a/yarn-project/validator-client/src/factory.ts b/yarn-project/validator-client/src/factory.ts index 9917d528ca9f..02325c937789 100644 --- a/yarn-project/validator-client/src/factory.ts +++ b/yarn-project/validator-client/src/factory.ts @@ -4,6 +4,7 @@ import type { DateProvider } from '@aztec/foundation/timer'; import type { KeystoreManager } from '@aztec/node-keystore'; import { BlockProposalValidator, type P2PClient } from '@aztec/p2p'; import type { L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import type { TelemetryClient } from '@aztec/telemetry-client'; @@ -26,6 +27,7 @@ export function createProposalHandler( blobClient: BlobClientInterface; dateProvider: DateProvider; telemetry: TelemetryClient; + reexecutionTracker: CheckpointReexecutionTracker; }, ) { const metrics = new ValidatorMetrics(deps.telemetry); @@ -48,6 +50,7 @@ export function createProposalHandler( deps.epochCache, config, deps.blobClient, + deps.reexecutionTracker, metrics, deps.dateProvider, deps.telemetry, @@ -68,6 +71,7 @@ export function createValidatorClient( epochCache: EpochCache; keyStoreManager: KeystoreManager | undefined; blobClient: BlobClientInterface; + reexecutionTracker: CheckpointReexecutionTracker; slashingProtectionDb?: SlashingProtectionDatabase; }, ) { @@ -87,6 +91,7 @@ export function createValidatorClient( txProvider, deps.keyStoreManager, deps.blobClient, + deps.reexecutionTracker, deps.dateProvider, deps.telemetry, deps.slashingProtectionDb, diff --git a/yarn-project/validator-client/src/proposal_handler.test.ts b/yarn-project/validator-client/src/proposal_handler.test.ts index b464dd7cd7a9..e6634968ee6d 100644 --- a/yarn-project/validator-client/src/proposal_handler.test.ts +++ b/yarn-project/validator-client/src/proposal_handler.test.ts @@ -9,7 +9,7 @@ import { type FieldsOf, unfreeze } from '@aztec/foundation/types'; import type { P2P } from '@aztec/p2p'; import type { BlockProposalValidator } from '@aztec/p2p/msg_validators'; import type { BlockData, L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; -import type { Checkpoint } from '@aztec/stdlib/checkpoint'; +import { type Checkpoint, CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; import type { ITxProvider, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; @@ -98,6 +98,7 @@ describe('ProposalHandler checkpoint validation', () => { epochCache, config, mock(), + new CheckpointReexecutionTracker(), metrics, dateProvider, ); @@ -167,6 +168,7 @@ describe('ProposalHandler checkpoint validation', () => { epochCache, config, mock(), + new CheckpointReexecutionTracker(), metrics, dateProvider, ); @@ -328,7 +330,11 @@ describe('ProposalHandler checkpoint validation', () => { const proposal = await makeProposal({ archiveRoot, checkpointHeader: proposalHeader }); const result = await handler.handleCheckpointProposal(proposal, proposalInfo); - expect(result).toEqual({ isValid: false, reason: 'checkpoint_header_mismatch' }); + expect(result).toEqual({ + isValid: false, + reason: 'checkpoint_header_mismatch', + checkpointNumber: CheckpointNumber(1), + }); expect(mockDispose).toHaveBeenCalled(); }); @@ -342,7 +348,7 @@ describe('ProposalHandler checkpoint validation', () => { const proposal = await makeProposal({ archiveRoot, checkpointHeader: header }); const result = await handler.handleCheckpointProposal(proposal, proposalInfo); - expect(result).toEqual({ isValid: false, reason: 'archive_mismatch' }); + expect(result).toEqual({ isValid: false, reason: 'archive_mismatch', checkpointNumber: CheckpointNumber(1) }); }); it('returns out_hash_mismatch when epoch out hash differs', async () => { @@ -355,7 +361,7 @@ describe('ProposalHandler checkpoint validation', () => { const proposal = await makeProposal({ archiveRoot, checkpointHeader: header }); const result = await handler.handleCheckpointProposal(proposal, proposalInfo); - expect(result).toEqual({ isValid: false, reason: 'out_hash_mismatch' }); + expect(result).toEqual({ isValid: false, reason: 'out_hash_mismatch', checkpointNumber: CheckpointNumber(1) }); }); it('returns checkpoint_validation_failed when validateCheckpoint throws', async () => { @@ -370,7 +376,11 @@ describe('ProposalHandler checkpoint validation', () => { const proposal = await makeProposal({ archiveRoot, checkpointHeader: header }); const result = await handler.handleCheckpointProposal(proposal, proposalInfo); - expect(result).toEqual({ isValid: false, reason: 'checkpoint_validation_failed' }); + expect(result).toEqual({ + isValid: false, + reason: 'checkpoint_validation_failed', + checkpointNumber: CheckpointNumber(1), + }); }); it('returns isValid true when everything matches', async () => { diff --git a/yarn-project/validator-client/src/proposal_handler.ts b/yarn-project/validator-client/src/proposal_handler.ts index 34106e89a7f5..5eb403170670 100644 --- a/yarn-project/validator-client/src/proposal_handler.ts +++ b/yarn-project/validator-client/src/proposal_handler.ts @@ -20,6 +20,7 @@ import { DateProvider, Timer } from '@aztec/foundation/timer'; import type { P2P, PeerId } from '@aztec/p2p'; import { BlockProposalValidator } from '@aztec/p2p/msg_validators'; import type { BlockData, L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker, ReexecutionOutcome } from '@aztec/stdlib/checkpoint'; import { getPreviousCheckpointOutHashes, validateCheckpoint } from '@aztec/stdlib/checkpoint'; import { getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { Gas } from '@aztec/stdlib/gas'; @@ -45,6 +46,7 @@ import type { FullNodeCheckpointsBuilder } from './checkpoint_builder.js'; import type { ValidatorMetrics } from './metrics.js'; export type BlockProposalValidationFailureReason = + | 'invalid_signature' | 'invalid_proposal' | 'parent_block_not_found' | 'block_source_not_synced' @@ -57,6 +59,8 @@ export type BlockProposalValidationFailureReason = | 'failed_txs' | 'initial_state_mismatch' | 'timeout' + | 'block_proposal_beyond_checkpoint' + | 'checkpoint_proposal_equivocation' | 'unknown_error'; type ReexecuteTransactionsResult = { @@ -81,14 +85,73 @@ export type BlockProposalValidationFailureResult = { export type BlockProposalValidationResult = BlockProposalValidationSuccessResult | BlockProposalValidationFailureResult; +export type CheckpointProposalValidationFailureReason = + | 'invalid_signature' + | 'invalid_fee_asset_price_modifier' + | 'last_block_not_found' + | 'block_fetch_error' + | 'checkpoint_already_published' + | 'no_blocks_for_slot' + | 'last_block_archive_mismatch' + | 'too_many_blocks_in_checkpoint' + | 'checkpoint_header_mismatch' + | 'archive_mismatch' + | 'out_hash_mismatch' + | 'checkpoint_validation_failed'; + +/** + * Mapping from a checkpoint-proposal validation failure reason to the tracker outcome that + * `handleCheckpointProposal` should record. `undefined` means do not record (signature + * couldn't be verified, or the checkpoint is already on L1 so the question is moot). + */ +/* eslint-disable camelcase */ +const CHECKPOINT_VALIDATION_REASON_TO_OUTCOME: Record< + CheckpointProposalValidationFailureReason, + ReexecutionOutcome | undefined +> = { + invalid_signature: undefined, + invalid_fee_asset_price_modifier: 'invalid', + checkpoint_already_published: undefined, + last_block_not_found: 'unvalidated', + block_fetch_error: 'unvalidated', + no_blocks_for_slot: 'unvalidated', + last_block_archive_mismatch: 'invalid', + too_many_blocks_in_checkpoint: 'invalid', + checkpoint_header_mismatch: 'invalid', + archive_mismatch: 'invalid', + out_hash_mismatch: 'invalid', + checkpoint_validation_failed: 'invalid', +}; + +export type CheckpointProposalValidationSuccessResult = { + isValid: true; + checkpointNumber: CheckpointNumber; +}; + +export type CheckpointProposalValidationFailureResult = { + isValid: false; + reason: CheckpointProposalValidationFailureReason; + checkpointNumber?: CheckpointNumber; +}; + export type CheckpointProposalValidationResult = - | { isValid: true; checkpointNumber: CheckpointNumber } - | { isValid: false; reason: string }; + | CheckpointProposalValidationSuccessResult + | CheckpointProposalValidationFailureResult; + +export type CheckpointProposalValidationFailureCallback = ( + proposal: CheckpointProposalCore, + result: CheckpointProposalValidationFailureResult, + proposalInfo: LogData, +) => void | Promise; type CheckpointComputationResult = | { checkpointNumber: CheckpointNumber; reason?: undefined } | { checkpointNumber?: undefined; reason: 'invalid_proposal' | 'global_variables_mismatch' }; +type BlockProposalSlotValidationResult = + | { isValid: true } + | { isValid: false; reason: 'block_proposal_beyond_checkpoint' | 'checkpoint_proposal_equivocation' }; + /** Handles block and checkpoint proposals for both validator and non-validator nodes. */ export class ProposalHandler { public readonly tracer: Tracer; @@ -107,6 +170,11 @@ export class ProposalHandler { /** Returns current validator addresses for own-proposal detection. Set via register(). */ private getOwnValidatorAddresses?: () => string[]; + /** P2P proposal pool access for deciding when retained proposals should block archiver processing. */ + private p2pClient?: Pick; + + private checkpointProposalValidationFailureCallback?: CheckpointProposalValidationFailureCallback; + constructor( private checkpointsBuilder: FullNodeCheckpointsBuilder, private worldState: WorldStateSynchronizer, @@ -117,6 +185,7 @@ export class ProposalHandler { private epochCache: EpochCache, private config: ValidatorClientFullConfig, private blobClient: BlobClientInterface, + private reexecutionTracker: CheckpointReexecutionTracker, private metrics?: ValidatorMetrics, private dateProvider: DateProvider = new DateProvider(), telemetry: TelemetryClient = getTelemetryClient(), @@ -128,8 +197,32 @@ export class ProposalHandler { this.tracer = telemetry.getTracer('ProposalHandler'); } + public updateConfig(config: Partial): void { + this.config = { ...this.config, ...config }; + } + + public setCheckpointProposalValidationFailureCallback(callback?: CheckpointProposalValidationFailureCallback): void { + this.checkpointProposalValidationFailureCallback = callback; + } + + /** + * Records the proposer's own checkpoint proposal as a `valid` outcome in the re-execution + * tracker. Without this, the node's own checkpoint proposals never flow through + * `handleCheckpointProposal` (proposers don't validate their own proposals), so its sentinel + * sees no outcome for slots where it was the proposer and reports itself as inactive. + * + * `archive` should be the locally-computed archive (NOT the broadcast archive, which may have + * been deliberately corrupted in tests via `broadcastInvalidBlockProposal` / + * `broadcastInvalidCheckpointProposalOnly`). Recording the local archive correctly models the + * proposer's own view of its own work. + */ + public recordOwnCheckpointProposalAsValid(slot: SlotNumber, archive: Fr, checkpointNumber: CheckpointNumber): void { + this.reexecutionTracker.recordOutcome(slot, archive, 'valid', checkpointNumber); + } + /** * Registers handlers for block and checkpoint proposals on the p2p client. + * Records the p2p client so validation can inspect retained proposals. * Block proposals are registered for non-validator nodes (validators register their own enhanced handler). * The all-nodes checkpoint proposal handler is always registered for validation, caching, and pipelining. * @param archiver - Archiver reference for setting proposed checkpoints (pipelining) @@ -141,6 +234,7 @@ export class ProposalHandler { archiver?: Pick, getOwnValidatorAddresses?: () => string[], ): ProposalHandler { + this.p2pClient = p2pClient; this.archiver = archiver; this.getOwnValidatorAddresses = getOwnValidatorAddresses; @@ -190,6 +284,19 @@ export class ProposalHandler { proposer: proposal.getSender()?.toString(), }; + if (this.config.skipCheckpointProposalValidation) { + this.log.warn(`Skipping checkpoint proposal validation for slot ${proposal.slotNumber}`, proposalInfo); + return undefined; + } + + if (await this.epochCache.isEscapeHatchOpenAtSlot(proposal.slotNumber)) { + this.log.warn( + `Escape hatch open for slot ${proposal.slotNumber}, skipping checkpoint proposal validation`, + proposalInfo, + ); + return undefined; + } + // For own proposals, skip validation — the proposer already built and validated the checkpoint const proposer = proposal.getSender(); const ownAddresses = this.getOwnValidatorAddresses?.(); @@ -203,8 +310,18 @@ export class ProposalHandler { return undefined; } + if (this.config.skipCheckpointProposalValidation) { + this.log.warn( + `Skipping all-nodes checkpoint proposal validation for slot ${proposal.slotNumber}`, + proposalInfo, + ); + return undefined; + } + const result = await this.handleCheckpointProposal(proposal, proposalInfo); - if (result.isValid && this.archiver && this.epochCache.isProposerPipeliningEnabled()) { + if (!result.isValid) { + await this.checkpointProposalValidationFailureCallback?.(proposal, result, proposalInfo); + } else if (this.archiver && this.epochCache.isProposerPipeliningEnabled()) { const set = await this.setProposedCheckpointFromValidation(proposal); if (set) { this.metrics?.recordCheckpointProposalToPipelinedStateDuration(pipeliningTimer.ms()); @@ -233,7 +350,7 @@ export class ProposalHandler { // Reject proposals with invalid signatures if (!proposer) { this.log.warn(`Received proposal with invalid signature for slot ${slotNumber}`); - return { isValid: false, reason: 'invalid_proposal' }; + return { isValid: false, reason: 'invalid_signature' }; } const proposalInfo = { @@ -256,6 +373,16 @@ export class ProposalHandler { return { isValid: false, reason: 'invalid_proposal' }; } + const retainedSlotValidation = await this.validateNewBlockInSlot(proposal); + if (!retainedSlotValidation.isValid) { + this.log.info(`Block proposal conflicts with retained proposals, skipping archiver processing`, { + ...proposalInfo, + indexWithinCheckpoint: proposal.indexWithinCheckpoint, + reason: retainedSlotValidation.reason, + }); + return { isValid: false, blockNumber: proposal.blockNumber, reason: retainedSlotValidation.reason }; + } + // Ensure the block source is synced before checking for existing blocks, // since a proposed checkpoint prune may remove blocks we'd otherwise find. // This affects mostly the block_number_already_exists check, since a pending @@ -311,6 +438,9 @@ export class ProposalHandler { deadline: this.getReexecutionDeadline(slotNumber, config), }); + // Record the tx-collection outcome on the re-execution tracker + this.reexecutionTracker.recordTxsCollected(slotNumber, proposal.indexWithinCheckpoint, missingTxs.length === 0); + // If reexecution is disabled, bail. We were just interested in triggering tx collection. if (!shouldReexecute) { this.log.info( @@ -391,6 +521,26 @@ export class ProposalHandler { return { isValid: true, blockNumber, reexecutionResult }; } + private async validateNewBlockInSlot(blockProposal: BlockProposal): Promise { + if (!this.p2pClient) { + return { isValid: true }; + } + + const { blockProposals, checkpointProposals } = await this.p2pClient.getProposalsForSlot(blockProposal.slotNumber); + + if (checkpointProposals.length === 0) { + return { isValid: true }; + } else if (checkpointProposals.length > 1) { + return { isValid: false, reason: 'checkpoint_proposal_equivocation' }; + } else { + const checkpointProposal = checkpointProposals[0]; + const terminalBlock = blockProposals.find(block => block.archive.equals(checkpointProposal.archive)); + return terminalBlock !== undefined && blockProposal.indexWithinCheckpoint > terminalBlock.indexWithinCheckpoint + ? { isValid: false, reason: 'block_proposal_beyond_checkpoint' } + : { isValid: true }; + } + } + private async getParentBlock(proposal: BlockProposal): Promise<'genesis' | BlockData | undefined> { const parentArchive = proposal.blockHeader.lastArchive.root; const config = this.checkpointsBuilder.getConfig(); @@ -757,25 +907,38 @@ export class ProposalHandler { } const proposer = proposal.getSender(); + let result: CheckpointProposalValidationResult; if (!proposer) { this.log.warn(`Received checkpoint proposal with invalid signature for slot ${proposal.slotNumber}`); - const result: CheckpointProposalValidationResult = { isValid: false, reason: 'invalid_signature' }; - this.lastCheckpointValidationResult = { payloadHash, result }; - return result; - } - - if (!validateFeeAssetPriceModifier(proposal.feeAssetPriceModifier)) { + result = { isValid: false as const, reason: 'invalid_signature' }; + } else if (!validateFeeAssetPriceModifier(proposal.feeAssetPriceModifier)) { this.log.warn( `Received checkpoint proposal with invalid feeAssetPriceModifier ${proposal.feeAssetPriceModifier} for slot ${proposal.slotNumber}`, ); - const result: CheckpointProposalValidationResult = { isValid: false, reason: 'invalid_fee_asset_price_modifier' }; - this.lastCheckpointValidationResult = { payloadHash, result }; - return result; + result = { isValid: false, reason: 'invalid_fee_asset_price_modifier' }; + } else { + result = await this.validateCheckpointProposal(proposal, proposalInfo); } - const result = await this.validateCheckpointProposal(proposal, proposalInfo); this.lastCheckpointValidationResult = { payloadHash, result }; + // Record the outcome on the re-execution tracker. + const outcome = result.isValid ? ('valid' as const) : CHECKPOINT_VALIDATION_REASON_TO_OUTCOME[result.reason]; + if (outcome !== undefined) { + this.reexecutionTracker.recordOutcome(slot, proposal.archive, outcome, result.checkpointNumber); + } + + // Drop tracker entries for checkpoints that have reached L1 finality. + try { + const tips = await this.blockSource.getL2Tips(); + const finalizedCheckpointNumber = tips.finalized.checkpoint.number; + if (finalizedCheckpointNumber > 0) { + this.reexecutionTracker.removeBefore(CheckpointNumber(finalizedCheckpointNumber + 1)); + } + } catch (err) { + this.log.error(`Error pruning reexecution tracker`, err, proposalInfo); + } + // Upload blobs to filestore if validation passed (fire and forget) if (result.isValid) { this.tryUploadBlobsForCheckpoint(proposal, proposalInfo); @@ -794,18 +957,21 @@ export class ProposalHandler { ): Promise { const slot = proposal.slotNumber; - // Timeout block syncing at the start of the next slot + // Block-sync deadline = the moment the proposer can no longer publish this checkpoint to L1. + // With pipelining off that's the end of the proposal's own slot; with pipelining on the + // proposal is built one slot ahead, so the publication deadline is the start of the target + // slot. `getReexecutionDeadline` handles both cases. const config = this.checkpointsBuilder.getConfig(); - const nextSlotTimestampSeconds = Number(getTimestampForSlot(SlotNumber(slot + 1), config)); - const timeoutSeconds = Math.max(1, nextSlotTimestampSeconds - Math.floor(this.dateProvider.now() / 1000)); + const deadline = this.getReexecutionDeadline(slot, config); + const timeoutSeconds = Math.max(1, Math.floor((deadline.getTime() - this.dateProvider.now()) / 1000)); // Wait for last block to sync by archive - let lastBlockHeader; + let lastBlockData; try { - lastBlockHeader = await retryUntil( + lastBlockData = await retryUntil( async () => { await this.blockSource.syncImmediate(); - return (await this.blockSource.getBlockData({ archive: proposal.archive }))?.header; + return await this.blockSource.getBlockData({ archive: proposal.archive }); }, `waiting for block with archive ${proposal.archive.toString()} for slot ${slot}`, timeoutSeconds, @@ -820,22 +986,40 @@ export class ProposalHandler { return { isValid: false, reason: 'block_fetch_error' }; } - if (!lastBlockHeader) { + if (!lastBlockData) { this.log.warn(`Last block not found for checkpoint proposal`, proposalInfo); return { isValid: false, reason: 'last_block_not_found' }; } + // Refuse to attest if the block's enclosing checkpoint has already been published to L1. + const existingCheckpoint = await this.blockSource.getCheckpointData({ number: lastBlockData.checkpointNumber }); + if (existingCheckpoint) { + this.log.warn(`Refusing to attest to checkpoint proposal whose checkpoint is already on L1`, { + ...proposalInfo, + checkpointNumber: lastBlockData.checkpointNumber, + }); + return { + isValid: false, + reason: 'checkpoint_already_published', + checkpointNumber: lastBlockData.checkpointNumber, + }; + } + // Get all full blocks for the slot and checkpoint const blocks = await this.blockSource.getBlocksForSlot(slot); if (blocks.length === 0) { this.log.warn(`No blocks found for slot ${slot}`, proposalInfo); - return { isValid: false, reason: 'no_blocks_for_slot' }; + return { isValid: false, reason: 'no_blocks_for_slot', checkpointNumber: lastBlockData.checkpointNumber }; } // Ensure the last block for this slot matches the archive in the checkpoint proposal if (!blocks.at(-1)?.archive.root.equals(proposal.archive)) { this.log.warn(`Last block archive mismatch for checkpoint proposal`, proposalInfo); - return { isValid: false, reason: 'last_block_archive_mismatch' }; + return { + isValid: false, + reason: 'last_block_archive_mismatch', + checkpointNumber: lastBlockData.checkpointNumber, + }; } const maxBlocksPerCheckpoint = this.config.maxBlocksPerCheckpoint; @@ -845,7 +1029,11 @@ export class ProposalHandler { blocksInProposal: blocks.length, maxBlocksPerCheckpoint, }); - return { isValid: false, reason: 'too_many_blocks_in_checkpoint' }; + return { + isValid: false, + reason: 'too_many_blocks_in_checkpoint', + checkpointNumber: lastBlockData.checkpointNumber, + }; } this.log.debug(`Found ${blocks.length} blocks for slot ${slot}`, { @@ -899,7 +1087,7 @@ export class ProposalHandler { computed: computedCheckpoint.header.toInspect(), proposal: proposal.checkpointHeader.toInspect(), }); - return { isValid: false, reason: 'checkpoint_header_mismatch' }; + return { isValid: false, reason: 'checkpoint_header_mismatch', checkpointNumber }; } // Compare archive root with proposal @@ -909,7 +1097,7 @@ export class ProposalHandler { computed: computedCheckpoint.archive.root.toString(), proposal: proposal.archive.toString(), }); - return { isValid: false, reason: 'archive_mismatch' }; + return { isValid: false, reason: 'archive_mismatch', checkpointNumber }; } // Check that the accumulated epoch out hash matches the value in the proposal. @@ -925,7 +1113,7 @@ export class ProposalHandler { previousCheckpointOutHashes: previousCheckpointOutHashes.map(h => h.toString()), ...proposalInfo, }); - return { isValid: false, reason: 'out_hash_mismatch' }; + return { isValid: false, reason: 'out_hash_mismatch', checkpointNumber }; } // Final round of validations on the checkpoint, just in case. @@ -939,10 +1127,11 @@ export class ProposalHandler { }); } catch (err) { this.log.warn(`Checkpoint validation failed: ${err}`, proposalInfo); - return { isValid: false, reason: 'checkpoint_validation_failed' }; + return { isValid: false, reason: 'checkpoint_validation_failed', checkpointNumber }; } this.log.verbose(`Checkpoint proposal validation successful for slot ${slot}`, proposalInfo); + return { isValid: true, checkpointNumber }; } diff --git a/yarn-project/validator-client/src/validator.ha.integration.test.ts b/yarn-project/validator-client/src/validator.ha.integration.test.ts index 186561fd920b..070d48f2e365 100644 --- a/yarn-project/validator-client/src/validator.ha.integration.test.ts +++ b/yarn-project/validator-client/src/validator.ha.integration.test.ts @@ -17,6 +17,7 @@ import type { P2P, TxProvider } from '@aztec/p2p'; import { BlockProposalValidator } from '@aztec/p2p'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; +import { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { SlasherConfig, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; @@ -136,6 +137,7 @@ describe('ValidatorClient HA Integration', () => { Pick< SlasherConfig, | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' @@ -145,6 +147,7 @@ describe('ValidatorClient HA Integration', () => { disableValidator: false, disabledValidators: [], slashBroadcastedInvalidBlockPenalty: 1n, + slashBroadcastedInvalidCheckpointProposalPenalty: 1n, rollupAddress, l1ChainId: TEST_COORDINATION_SIGNATURE_CONTEXT.chainId, slashDuplicateProposalPenalty: 1n, @@ -193,6 +196,7 @@ describe('ValidatorClient HA Integration', () => { Pick< SlasherConfig, | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' @@ -226,6 +230,7 @@ describe('ValidatorClient HA Integration', () => { epochCache, config, blobClient, + new CheckpointReexecutionTracker(), metrics, dateProvider, getTelemetryClient(), diff --git a/yarn-project/validator-client/src/validator.integration.test.ts b/yarn-project/validator-client/src/validator.integration.test.ts index da2ff3670674..99d4caf2e609 100644 --- a/yarn-project/validator-client/src/validator.integration.test.ts +++ b/yarn-project/validator-client/src/validator.integration.test.ts @@ -21,7 +21,7 @@ import { TestTxProvider } from '@aztec/p2p/test-helpers'; import { protocolContractsHash } from '@aztec/protocol-contracts'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block'; -import { L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import { CheckpointReexecutionTracker, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; import { type L1RollupConstants, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { Gas, GasFees } from '@aztec/stdlib/gas'; import { tryStop } from '@aztec/stdlib/interfaces/server'; @@ -177,6 +177,7 @@ describe('ValidatorClient Integration', () => { disableValidator: false, disabledValidators: [], slashBroadcastedInvalidBlockPenalty: 10n, + slashBroadcastedInvalidCheckpointProposalPenalty: 10n, slashDuplicateProposalPenalty: 10n, slashDuplicateAttestationPenalty: 10n, slashAttestInvalidCheckpointProposalPenalty: 10n, @@ -197,6 +198,7 @@ describe('ValidatorClient Integration', () => { txProvider, keyStoreManager, blobClient, + new CheckpointReexecutionTracker(), dateProvider, ); diff --git a/yarn-project/validator-client/src/validator.test.ts b/yarn-project/validator-client/src/validator.test.ts index 6e3bc422f65e..d582a73c3575 100644 --- a/yarn-project/validator-client/src/validator.test.ts +++ b/yarn-project/validator-client/src/validator.test.ts @@ -30,6 +30,7 @@ import { import { OffenseType, WANT_TO_CLEAR_SLASH_EVENT, WANT_TO_SLASH_EVENT } from '@aztec/slasher'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { type BlockData, BlockHash, L2Block, type L2BlockSink, type L2BlockSource } from '@aztec/stdlib/block'; +import { type Checkpoint, CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import { type getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import type { SlasherConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; @@ -58,7 +59,7 @@ import type { } from './checkpoint_builder.js'; import { type ValidatorClientConfig, validatorClientConfigMappings } from './config.js'; import { HAKeyStore } from './key_store/ha_key_store.js'; -import { ProposalHandler } from './proposal_handler.js'; +import { type CheckpointProposalValidationFailureReason, ProposalHandler } from './proposal_handler.js'; import { ValidatorClient } from './validator.js'; function makeKeyStore(validator: { @@ -89,6 +90,7 @@ describe('ValidatorClient', () => { Pick< SlasherConfig, | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' @@ -115,6 +117,7 @@ describe('ValidatorClient', () => { p2pClient.getCheckpointAttestationsForSlot.mockImplementation(() => Promise.resolve([])); p2pClient.handleAuthRequestFromPeer.mockResolvedValue(StatusMessage.random()); p2pClient.broadcastCheckpointAttestations.mockResolvedValue(); + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); checkpointsBuilder = mock(); checkpointsBuilder.getConfig.mockReturnValue({ l1GenesisTime: 1n, @@ -182,6 +185,7 @@ describe('ValidatorClient', () => { disableValidator: false, disabledValidators: [], slashBroadcastedInvalidBlockPenalty: 1n, + slashBroadcastedInvalidCheckpointProposalPenalty: 1n, slashDuplicateProposalPenalty: 1n, slashDuplicateAttestationPenalty: 1n, slashAttestInvalidCheckpointProposalPenalty: 1n, @@ -209,6 +213,7 @@ describe('ValidatorClient', () => { txProvider, keyStoreManager, blobClient, + new CheckpointReexecutionTracker(), dateProvider, )) as ValidatorClient; }); @@ -343,6 +348,75 @@ describe('ValidatorClient', () => { const makeTxFromHash = (txHash: TxHash) => ({ getTxHash: () => txHash, txHash }) as Tx; const getExpectedWallClockDeadline = (currentSlot: SlotNumber) => new Date(Number(getTimestampForSlot(SlotNumber(currentSlot + 1), checkpointsBuilder.getConfig())) * 1000); + const makeCheckpointProposalForSlot = () => + makeCheckpointProposal({ + archiveRoot: proposal.archive, + checkpointHeader: makeCheckpointHeader(0, { slotNumber: proposal.slotNumber }), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber: BlockNumber(123), slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + const makeCheckpointProposalWithHeaderMismatch = async () => { + const proposalHeader = makeCheckpointHeader(0, { slotNumber: proposal.slotNumber }); + const computedHeader = makeCheckpointHeader(0, { + slotNumber: proposal.slotNumber, + totalManaUsed: new Fr(999), + }); + const checkpointProposal = await makeCheckpointProposal({ + archiveRoot: proposal.archive, + checkpointHeader: proposalHeader, + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + const checkpointBlock = { + ...blockBuildResult.block, + number: blockNumber, + header: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + archive: new AppendOnlyTreeSnapshot(proposal.archive, blockNumber), + checkpointNumber: CheckpointNumber(1), + } as unknown as L2Block; + const disposeFork = jest.fn(); + blockSource.getBlocksForSlot.mockResolvedValue([checkpointBlock]); + checkpointsBuilder.getFork.mockResolvedValue({ [Symbol.asyncDispose]: disposeFork } as any); + mockCheckpointBuilder.completeCheckpoint.mockResolvedValue({ + header: computedHeader, + archive: new AppendOnlyTreeSnapshot(proposal.archive, blockNumber), + getCheckpointOutHash: () => Fr.random(), + blocks: [checkpointBlock], + number: CheckpointNumber(1), + slot: proposal.slotNumber, + } as unknown as Checkpoint); + return { checkpointProposal, disposeFork }; + }; + const registerAllNodesCheckpointHandler = () => { + let checkpointHandler: Parameters[0] | undefined; + p2pClient.registerAllNodesCheckpointProposalHandler.mockImplementation(handler => { + checkpointHandler = handler; + }); + + validatorClient + .getProposalHandler() + .register(p2pClient, true, undefined, () => + validatorClient.getValidatorAddresses().map(address => address.toString()), + ); + + expect(checkpointHandler).toBeDefined(); + return checkpointHandler!; + }; + const getBroadcastedInvalidCheckpointProposalSlashEvents = ( + emitSpy: jest.SpiedFunction, + ) => + emitSpy.mock.calls.filter( + ([event, args]) => + event === WANT_TO_SLASH_EVENT && + Array.isArray(args) && + args[0]?.offenseType === OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + ); beforeEach(async () => { const emptyInHash = computeInHashFromL1ToL2Messages([]); @@ -447,6 +521,121 @@ describe('ValidatorClient', () => { expect(isValid).toBe(true); }); + it('does not push a block proposal beyond a retained checkpoint terminal block to the archiver', async () => { + validatorClient.updateConfig({ skipPushProposedBlocksToArchiver: false }); + validatorClient.getProposalHandler().register(p2pClient, true); + + const signer = Secp256k1Signer.random(); + const emptyInHash = computeInHashFromL1ToL2Messages([]); + const checkpointProposal = await makeCheckpointProposal({ + signer, + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + archiveRoot: Fr.random(), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + const terminalBlock = checkpointProposal.getBlockProposal()!; + + const terminalGlobals = terminalBlock.blockHeader.globalVariables; + const laterBlockHeader = makeBlockHeader(2, { + lastArchive: new AppendOnlyTreeSnapshot(terminalBlock.archive, terminalBlock.blockNumber), + blockNumber: BlockNumber(terminalBlock.blockNumber + 1), + slotNumber: proposal.slotNumber, + chainId: terminalGlobals.chainId, + version: terminalGlobals.version, + timestamp: terminalGlobals.timestamp, + coinbase: terminalGlobals.coinbase, + feeRecipient: terminalGlobals.feeRecipient, + gasFees: terminalGlobals.gasFees, + }); + const laterBlock = await makeBlockProposal({ + signer, + blockHeader: laterBlockHeader, + indexWithinCheckpoint: IndexWithinCheckpoint(1), + inHash: emptyInHash, + archiveRoot: Fr.random(), + }); + + epochCache.getProposerAttesterAddressInSlot.mockResolvedValue(signer.address); + p2pClient.getProposalsForSlot.mockResolvedValue({ + blockProposals: [terminalBlock, laterBlock], + checkpointProposals: [checkpointProposal.toCore()], + }); + + const terminalBlockData = { + header: terminalBlock.blockHeader, + archive: new AppendOnlyTreeSnapshot(terminalBlock.archive, terminalBlock.blockNumber), + blockHash: BlockHash.random(), + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: terminalBlock.indexWithinCheckpoint, + } as unknown as BlockData; + blockSource.getBlockData.mockImplementation(query => + Promise.resolve('number' in query ? undefined : terminalBlockData), + ); + + const blockAddedIfProcessed = { + ...blockBuildResult.block, + header: laterBlock.blockHeader, + body: { txEffects: times(laterBlock.txHashes.length, () => TxEffect.empty()) }, + archive: new AppendOnlyTreeSnapshot(laterBlock.archive, laterBlock.blockNumber), + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: laterBlock.indexWithinCheckpoint, + } as unknown as L2Block; + mockCheckpointBuilder.buildBlock.mockResolvedValue({ + ...blockBuildResult, + block: blockAddedIfProcessed, + numTxs: laterBlock.txHashes.length, + }); + worldState.fork.mockResolvedValue({ + close: () => Promise.resolve(), + [Symbol.asyncDispose]: () => Promise.resolve(), + getTreeInfo: () => Promise.resolve({ root: laterBlock.blockHeader.lastArchive.root.toBuffer() }), + } as never); + + const result = await validatorClient.getProposalHandler().handleBlockProposal(laterBlock, sender, true); + + expect(result).toMatchObject({ isValid: false, reason: 'block_proposal_beyond_checkpoint' }); + expect(blockSource.addBlock).not.toHaveBeenCalled(); + }); + + it('does not push a block proposal to the archiver when retained checkpoint proposals equivocate', async () => { + validatorClient.updateConfig({ skipPushProposedBlocksToArchiver: false }); + validatorClient.getProposalHandler().register(p2pClient, true); + + const emptyInHash = computeInHashFromL1ToL2Messages([]); + const checkpointProposal = await makeCheckpointProposal({ + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + archiveRoot: Fr.random(), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + const equivocatedCheckpointProposal = await makeCheckpointProposal({ + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + archiveRoot: Fr.random(), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + + p2pClient.getProposalsForSlot.mockResolvedValue({ + blockProposals: [proposal], + checkpointProposals: [checkpointProposal.toCore(), equivocatedCheckpointProposal.toCore()], + }); + + const result = await validatorClient.getProposalHandler().handleBlockProposal(proposal, sender, true); + + expect(result).toMatchObject({ isValid: false, reason: 'checkpoint_proposal_equivocation' }); + expect(blockSource.addBlock).not.toHaveBeenCalled(); + }); + it('uses the next wall-clock slot as the tx collection deadline for pipelined proposals', async () => { const pipelineOffsetInSlots = 1; epochCache.isProposerPipeliningEnabled.mockReturnValue(true); @@ -821,6 +1010,167 @@ describe('ValidatorClient', () => { expect(emitSpy).not.toHaveBeenCalled(); }); + it('emits WANT_TO_SLASH_EVENT for checkpoint_header_mismatch checkpoint proposals', async () => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal, disposeFork } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + const proposer = checkpointProposal.getSender(); + expect(proposer).toBeDefined(); + expect(disposeFork).toHaveBeenCalled(); + expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ + { + validator: proposer!, + amount: config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: BigInt(checkpointProposal.slotNumber), + }, + ]); + }); + + it('emits WANT_TO_SLASH_EVENT for invalid fee asset price modifiers', async () => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const checkpointProposal = await makeCheckpointProposal({ + archiveRoot: proposal.archive, + checkpointHeader: makeCheckpointHeader(0, { slotNumber: proposal.slotNumber }), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber: BlockNumber(123), slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + feeAssetPriceModifier: MAX_FEE_ASSET_PRICE_MODIFIER_BPS + 1n, + }); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + const proposer = checkpointProposal.getSender(); + expect(proposer).toBeDefined(); + expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ + { + validator: proposer!, + amount: config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: BigInt(checkpointProposal.slotNumber), + }, + ]); + }); + + it.each([ + 'archive_mismatch', + 'out_hash_mismatch', + 'last_block_archive_mismatch', + 'checkpoint_validation_failed', + ])('emits checkpoint proposal slash event for %s', async reason => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const checkpointProposal = await makeCheckpointProposalForSlot(); + jest.spyOn(validatorClient.getProposalHandler(), 'handleCheckpointProposal').mockResolvedValue({ + isValid: false, + reason, + }); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + const proposer = checkpointProposal.getSender(); + expect(proposer).toBeDefined(); + expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ + { + validator: proposer!, + amount: config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: BigInt(checkpointProposal.slotNumber), + }, + ]); + }); + + it('does not emit checkpoint proposal slash event when the penalty is disabled', async () => { + validatorClient.updateConfig({ slashBroadcastedInvalidCheckpointProposalPenalty: 0n }); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + const attestations = await validatorClient.attestToCheckpointProposal(checkpointProposal, sender); + + expect(attestations).toBeUndefined(); + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(0); + }); + + it.each(['last_block_not_found', 'checkpoint_already_published'])( + 'does not emit checkpoint proposal slash event for %s', + async reason => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const checkpointProposal = await makeCheckpointProposalForSlot(); + jest.spyOn(validatorClient.getProposalHandler(), 'handleCheckpointProposal').mockResolvedValue({ + isValid: false, + reason, + }); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(0); + }, + ); + + it('emits checkpoint proposal slash event once for repeated invalid proposals', async () => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(1); + }); + + it('emits slash event even if validator is not in the current committee', async () => { + epochCache.filterInCommittee.mockResolvedValue([]); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(1); + }); + + it('emits checkpoint proposal slash event in fisherman mode', async () => { + validatorClient.updateConfig({ fishermanMode: true }); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(1); + }); + + it('does not emit checkpoint proposal slash event while escape hatch is open', async () => { + epochCache.isEscapeHatchOpenAtSlot.mockResolvedValue(true); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(0); + }); + + it('does not emit checkpoint proposal slash event when checkpoint validation is skipped', async () => { + validatorClient.updateConfig({ skipCheckpointProposalValidation: true }); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(0); + }); + it('should request txs for validating pinning the sender', async () => { const isValid = await validatorClient.validateBlockProposal(proposal, sender); expect(isValid).toBe(true); diff --git a/yarn-project/validator-client/src/validator.ts b/yarn-project/validator-client/src/validator.ts index cf8d510edd3a..c7721e1ea66f 100644 --- a/yarn-project/validator-client/src/validator.ts +++ b/yarn-project/validator-client/src/validator.ts @@ -5,6 +5,7 @@ import { CheckpointNumber, EpochNumber, IndexWithinCheckpoint, SlotNumber } from import { Fr } from '@aztec/foundation/curves/bn254'; import type { EthAddress } from '@aztec/foundation/eth-address'; import type { Signature } from '@aztec/foundation/eth-signature'; +import { FifoSet } from '@aztec/foundation/fifo-set'; import { type LogData, type Logger, createLogger } from '@aztec/foundation/log'; import { RunningPromise } from '@aztec/foundation/running-promise'; import { sleep } from '@aztec/foundation/sleep'; @@ -21,6 +22,7 @@ import { } from '@aztec/slasher'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { CommitteeAttestationsAndSigners, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers'; import type { ITxProvider, @@ -59,20 +61,50 @@ import { HAKeyStore } from './key_store/ha_key_store.js'; import type { ExtendedValidatorKeyStore } from './key_store/interface.js'; import { NodeKeystoreAdapter } from './key_store/node_keystore_adapter.js'; import { ValidatorMetrics } from './metrics.js'; -import { type BlockProposalValidationFailureReason, ProposalHandler } from './proposal_handler.js'; +import { + type BlockProposalValidationFailureReason, + type CheckpointProposalValidationFailureReason, + type CheckpointProposalValidationFailureResult, + ProposalHandler, +} from './proposal_handler.js'; // We maintain a set of proposers who have proposed invalid blocks. // Just cap the set to avoid unbounded growth. const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000; const MAX_TRACKED_INVALID_PROPOSAL_SLOTS = 1000; +const MAX_TRACKED_INVALID_CHECKPOINT_PROPOSALS = 1000; const MAX_TRACKED_BAD_ATTESTATIONS = 10_000; // What errors from the block proposal handler result in slashing const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT: BlockProposalValidationFailureReason[] = [ 'state_mismatch', 'failed_txs', + 'global_variables_mismatch', + 'invalid_proposal', + 'parent_block_wrong_slot', + 'in_hash_mismatch', ]; +const SLASHABLE_CHECKPOINT_PROPOSAL_VALIDATION_RESULT: Record = { + // enabled + ['invalid_fee_asset_price_modifier']: true, + ['checkpoint_header_mismatch']: true, + // These late mismatches should normally be caught by earlier checks, but if reached after validating the local + // checkpoint inputs, the proposer-signed payload disagrees with deterministic recomputation. + ['archive_mismatch']: true, + ['out_hash_mismatch']: true, + ['no_blocks_for_slot']: true, + ['too_many_blocks_in_checkpoint']: true, + ['checkpoint_validation_failed']: true, + ['last_block_archive_mismatch']: true, + + // disabled + ['invalid_signature']: false, + ['last_block_not_found']: false, + ['block_fetch_error']: false, + ['checkpoint_already_published']: false, +}; + /** * Validator Client */ @@ -95,10 +127,11 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) /** Tracks the last epoch in which each attester successfully submitted at least one attestation. */ private lastAttestedEpochByAttester: Map = new Map(); - private proposersOfInvalidBlocks: Set = new Set(); - private slotsWithInvalidBlockProposals: Set = new Set(); - private slotsWithProposalEquivocation: Set = new Set(); - private badAttestationOffenseKeys: Set = new Set(); + private proposersOfInvalidBlocks = FifoSet.withLimit(MAX_PROPOSERS_OF_INVALID_BLOCKS); + private slotsWithInvalidBlockProposals = FifoSet.withLimit(MAX_TRACKED_INVALID_PROPOSAL_SLOTS); + private invalidCheckpointProposalOffenseKeys = FifoSet.withLimit(MAX_TRACKED_INVALID_CHECKPOINT_PROPOSALS); + private slotsWithProposalEquivocation = FifoSet.withLimit(MAX_TRACKED_INVALID_PROPOSAL_SLOTS); + private badAttestationOffenseKeys = FifoSet.withLimit(MAX_TRACKED_BAD_ATTESTATIONS); /** Tracks the last checkpoint proposal we attested to, to prevent equivocation. */ private lastAttestedProposal?: CheckpointProposalCore; @@ -132,6 +165,9 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) this.getSignatureContext(), this.log.createChild('validation-service'), ); + this.proposalHandler.setCheckpointProposalValidationFailureCallback((proposal, result, proposalInfo) => + this.handleInvalidCheckpointProposal(proposal, result, proposalInfo), + ); // Refresh epoch cache every second to trigger alert if participation in committee changes this.epochCacheUpdateLoop = new RunningPromise(this.handleEpochCommitteeUpdate.bind(this), this.log, 1000); @@ -204,6 +240,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) txProvider: ITxProvider, keyStoreManager: KeystoreManager, blobClient: BlobClientInterface, + reexecutionTracker: CheckpointReexecutionTracker, dateProvider: DateProvider = new DateProvider(), telemetry: TelemetryClient = getTelemetryClient(), slashingProtectionDb?: SlashingProtectionDatabase, @@ -213,6 +250,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) txsPermitted: !config.disableTransactions, maxTxsPerBlock: config.validateMaxTxsPerBlock, maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint, + skipSlotValidation: config.skipProposalSlotValidation, signatureContext: { chainId: config.l1ChainId, rollupAddress: config.rollupAddress, @@ -228,6 +266,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) epochCache, config, blobClient, + reexecutionTracker, metrics, dateProvider, telemetry, @@ -317,6 +356,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) public updateConfig(config: Partial) { this.config = { ...this.config, ...config }; + this.proposalHandler.updateConfig(config); } public reloadKeystore(newManager: KeystoreManager): void { @@ -528,6 +568,11 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) return undefined; } + // Early-out for equivocation: refuses if we've already attested to a higher slot. + if (!this.shouldAttestToSlot(proposalSlotNumber)) { + return undefined; + } + // Ignore proposals from ourselves (may happen in HA setups) if (proposer && this.getValidatorAddresses().some(addr => addr.equals(proposer))) { this.log.debug(`Ignoring block proposal from self for slot ${proposalSlotNumber}`, { @@ -702,12 +747,6 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) return; } - // Trim the set if it's too big. - if (this.proposersOfInvalidBlocks.size > MAX_PROPOSERS_OF_INVALID_BLOCKS) { - // remove oldest proposer. `values` is guaranteed to be in insertion order. - this.proposersOfInvalidBlocks.delete(this.proposersOfInvalidBlocks.values().next().value!); - } - this.proposersOfInvalidBlocks.add(proposer.toString()); this.emit(WANT_TO_SLASH_EVENT, [ @@ -720,9 +759,57 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) ]); } + private handleInvalidCheckpointProposal( + proposal: CheckpointProposalCore, + result: CheckpointProposalValidationFailureResult, + proposalInfo: LogData, + ): void { + if (!SLASHABLE_CHECKPOINT_PROPOSAL_VALIDATION_RESULT[result.reason]) { + return; + } + + if (this.slashInvalidCheckpointProposal(proposal)) { + this.log.warn(`Slashing proposer for invalid checkpoint proposal`, { + ...proposalInfo, + reason: result.reason, + }); + } + } + + private slashInvalidCheckpointProposal(proposal: CheckpointProposalCore): boolean { + if (this.config.slashBroadcastedInvalidCheckpointProposalPenalty <= 0n) { + return false; + } + + const proposer = proposal.getSender(); + if (!proposer) { + this.log.warn(`Cannot slash checkpoint proposal with invalid signature`, { + slotNumber: proposal.slotNumber, + archive: proposal.archive.toString(), + }); + return false; + } + + const offenseType = OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL; + const offenseKey = `${proposer.toString()}:${offenseType}:${this.getSlotKey(proposal.slotNumber)}`; + if (!this.invalidCheckpointProposalOffenseKeys.addIfAbsent(offenseKey)) { + return false; + } + + this.emit(WANT_TO_SLASH_EVENT, [ + { + validator: proposer, + amount: this.config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType, + epochOrSlot: BigInt(proposal.slotNumber), + }, + ]); + return true; + } + private markInvalidProposalSlot(slotNumber: SlotNumber): void { const slotKey = this.getSlotKey(slotNumber); - this.addToBoundedSet(this.slotsWithInvalidBlockProposals, slotKey, MAX_TRACKED_INVALID_PROPOSAL_SLOTS); + this.slotsWithInvalidBlockProposals.add(slotKey); } private handleCheckpointAttestation(attestation: CheckpointAttestation): void { @@ -750,7 +837,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) } const offenseKey = `${this.getSlotKey(slotNumber)}:${attester.toString()}`; - if (!this.addToBoundedSet(this.badAttestationOffenseKeys, offenseKey, MAX_TRACKED_BAD_ATTESTATIONS)) { + if (!this.badAttestationOffenseKeys.addIfAbsent(offenseKey)) { return; } @@ -776,7 +863,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) private handleDuplicateProposal(info: DuplicateProposalInfo): void { const { slot, proposer, type } = info; const slotKey = this.getSlotKey(slot); - this.addToBoundedSet(this.slotsWithProposalEquivocation, slotKey, MAX_TRACKED_INVALID_PROPOSAL_SLOTS); + this.slotsWithProposalEquivocation.add(slotKey); this.log.warn(`Triggering slash event for duplicate ${type} proposal from ${proposer.toString()} at slot ${slot}`, { proposer: proposer.toString(), @@ -828,17 +915,6 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) return slot.toString(); } - private addToBoundedSet(set: Set, value: string, maxSize: number): boolean { - if (set.has(value)) { - return false; - } - if (set.size >= maxSize) { - set.delete(set.values().next().value!); - } - set.add(value); - return true; - } - async createBlockProposal( blockHeader: BlockHeader, checkpointNumber: CheckpointNumber, @@ -876,7 +952,8 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) proposerAddress, { ...options, - broadcastInvalidBlockProposal: this.config.broadcastInvalidBlockProposal, + broadcastInvalidBlockProposal: + options.broadcastInvalidBlockProposal || this.config.broadcastInvalidBlockProposal, }, ); this.lastProposedBlock = newProposal; @@ -916,6 +993,13 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) options, ); this.lastProposedCheckpoint = newProposal; + // Self-record this slot's outcome on the re-execution tracker. Proposers don't run their + // own proposals through `handleCheckpointProposal`, so without this call the proposer's + // sentinel would see no outcome for slots it proposed and would mis-attribute itself as + // inactive. We pass the locally-computed `archive` (not `newProposal.archive`, which may + // be intentionally corrupted under test-only flags); from the proposer's local-view + // perspective the work it just completed is valid by definition. + this.proposalHandler.recordOwnCheckpointProposalAsValid(checkpointHeader.slotNumber, archive, checkpointNumber); return newProposal; } diff --git a/yarn-project/world-state/src/native/ipc_world_state_instance.ts b/yarn-project/world-state/src/native/ipc_world_state_instance.ts index 5489c80c37ce..cd4d20f1a003 100644 --- a/yarn-project/world-state/src/native/ipc_world_state_instance.ts +++ b/yarn-project/world-state/src/native/ipc_world_state_instance.ts @@ -279,28 +279,33 @@ export class IpcWorldState implements NativeWorldStateInstance { this.queues.set(forkId, requestQueue); } - const response = await requestQueue.execute( - async () => { - assert.notEqual(messageType, WorldStateMessageType.CLOSE, 'Use close() to close the IPC instance'); - assert.equal(this.open, true, 'IPC instance is closed'); - let response: WorldStateResponse[T]; - try { - response = await this._sendMessage(messageType, body); - } catch (error: any) { - errorHandler(error.message); - throw error; - } - return responseHandler(response); - }, - messageType, - committedOnly, - ); - - if (messageType === WorldStateMessageType.DELETE_FORK) { - await requestQueue.stop(); - this.queues.delete(forkId); + // The per-fork queue is cleaned up in `finally` even on error, so the JS-side queues map cannot outlive + // the native fork (e.g. when the native fork was already destroyed by an unwind/historical-prune and + // DELETE_FORK rejects with "Fork not found"). + try { + const response = await requestQueue.execute( + async () => { + assert.notEqual(messageType, WorldStateMessageType.CLOSE, 'Use close() to close the IPC instance'); + assert.equal(this.open, true, 'IPC instance is closed'); + let response: WorldStateResponse[T]; + try { + response = await this._sendMessage(messageType, body); + } catch (error: any) { + errorHandler(error.message); + throw error; + } + return responseHandler(response); + }, + messageType, + committedOnly, + ); + return response; + } finally { + if (messageType === WorldStateMessageType.DELETE_FORK) { + await requestQueue.stop(); + this.queues.delete(forkId); + } } - return response; } async close(): Promise { diff --git a/yarn-project/world-state/src/native/merkle_trees_facade.ts b/yarn-project/world-state/src/native/merkle_trees_facade.ts index 2cc687575e8f..2d32a8def90e 100644 --- a/yarn-project/world-state/src/native/merkle_trees_facade.ts +++ b/yarn-project/world-state/src/native/merkle_trees_facade.ts @@ -208,6 +208,7 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations { export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTreeWriteOperations { private log = createLogger('world-state:merkle-trees-fork-facade'); + private closePromise: Promise | undefined; constructor( instance: NativeWorldStateInstance, @@ -291,8 +292,17 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr }; } - public async close(): Promise { + public close(): Promise { assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set'); + // Share the in-flight close promise across duplicate dispose calls so DELETE_FORK is sent at most once. + if (this.closePromise) { + return this.closePromise; + } + this.closePromise = this.doClose(); + return this.closePromise; + } + + private async doClose(): Promise { try { await this.instance.call(WorldStateMessageType.DELETE_FORK, { forkId: this.revision.forkId }); } catch (err: any) { @@ -301,6 +311,12 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr if (err?.message === 'Native instance is closed') { return; } + // Ignore "Fork not found": the native fork was already destroyed by a pending-chain unwind or a + // historical prune (both call C++ remove_forks_for_block). Fork IDs are monotonic and never reused, + // so swallowing this on close cannot mask a deletion of a different fork. + if (err?.message === 'Fork not found') { + return; + } throw err; } } @@ -310,9 +326,6 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr void sleep(this.opts.closeDelayMs) .then(() => this.close()) .catch(err => { - if (err && 'message' in err && err.message === 'Native instance is closed') { - return; // Ignore errors due to native instance being closed - } this.log.warn('Error closing MerkleTreesForkFacade after delay', { err }); }); } else { diff --git a/yarn-project/world-state/src/native/native_world_state.test.ts b/yarn-project/world-state/src/native/native_world_state.test.ts index 47ff292af6c8..5acafa7d67b6 100644 --- a/yarn-project/world-state/src/native/native_world_state.test.ts +++ b/yarn-project/world-state/src/native/native_world_state.test.ts @@ -14,6 +14,7 @@ import { timesAsync } from '@aztec/foundation/collection'; import { randomBytes } from '@aztec/foundation/crypto/random'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { sleep } from '@aztec/foundation/sleep'; import type { SiblingPath } from '@aztec/foundation/trees'; import { PublicDataWrite } from '@aztec/stdlib/avm'; import { L2Block } from '@aztec/stdlib/block'; @@ -937,6 +938,33 @@ describe('NativeWorldState', () => { } } }); + + // Regression test for A-1055: a delayed-close fork that the C++ side has already destroyed (via + // remove_forks_for_block on an unwind or historical prune) must dispose silently rather than logging a + // warning, and its JS-side per-fork queue entry must be cleaned up. + it('does not fail when a delayed-close fork is destroyed by a reorg before its close fires', async () => { + const baseFork = await ws.fork(); + for (let i = 0; i < 3; i++) { + const { block, messages } = await mockBlock(BlockNumber(i + 1), 1, baseFork); + await ws.handleL2BlockAndMessages(block, messages); + } + await baseFork.close(); + + const closeDelayMs = 1000; + const delayedFork = await ws.fork(undefined, { closeDelayMs }); + const forkId = (delayedFork as any).revision.forkId; + const warnSpy = jest.spyOn((delayedFork as any).log, 'warn'); + + await (delayedFork as any)[Symbol.asyncDispose](); + + await ws.unwindBlocks(BlockNumber.fromBigInt(2n)); + await expect(delayedFork.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, 0n)).rejects.toThrow('Fork not found'); + + await sleep(closeDelayMs * 3); + + expect(warnSpy).not.toHaveBeenCalled(); + expect((ws as any).instance.queues.has(forkId)).toBe(false); + }); }); describe('Invalid Blocks', () => { diff --git a/yarn-project/world-state/src/native/native_world_state_instance.ts b/yarn-project/world-state/src/native/native_world_state_instance.ts index 6f4d60d0fd33..c4016ba1e477 100644 --- a/yarn-project/world-state/src/native/native_world_state_instance.ts +++ b/yarn-project/world-state/src/native/native_world_state_instance.ts @@ -184,30 +184,33 @@ export class NativeWorldState implements NativeWorldStateInstance { this.queues.set(forkId, requestQueue); } - // Enqueue the request and wait for the response - const response = await requestQueue.execute( - async () => { - assert.notEqual(messageType, WorldStateMessageType.CLOSE, 'Use close() to close the native instance'); - assert.equal(this.open, true, 'Native instance is closed'); - let response: WorldStateResponse[T]; - try { - response = await this._sendMessage(messageType, body); - } catch (error: any) { - errorHandler(error.message); - throw error; - } - return responseHandler(response); - }, - messageType, - committedOnly, - ); - - // If the request was to delete the fork then we clean it up here - if (messageType === WorldStateMessageType.DELETE_FORK) { - await requestQueue.stop(); - this.queues.delete(forkId); + // Enqueue the request and wait for the response. The per-fork queue is cleaned up in `finally` even on + // error, so the JS-side queues map cannot outlive the native fork (e.g. when the native fork was already + // destroyed by an unwind/historical-prune and DELETE_FORK rejects with "Fork not found"). + try { + const response = await requestQueue.execute( + async () => { + assert.notEqual(messageType, WorldStateMessageType.CLOSE, 'Use close() to close the native instance'); + assert.equal(this.open, true, 'Native instance is closed'); + let response: WorldStateResponse[T]; + try { + response = await this._sendMessage(messageType, body); + } catch (error: any) { + errorHandler(error.message); + throw error; + } + return responseHandler(response); + }, + messageType, + committedOnly, + ); + return response; + } finally { + if (messageType === WorldStateMessageType.DELETE_FORK) { + await requestQueue.stop(); + this.queues.delete(forkId); + } } - return response; } /** From 74cea7f8ac28d0adc350c35ac019817b0c2bbd76 Mon Sep 17 00:00:00 2001 From: Gregorio Juliana Date: Mon, 25 May 2026 11:50:07 +0200 Subject: [PATCH 13/13] fix: merge train conflicts (#23548) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just pulling from next --------- Co-authored-by: Facundo Co-authored-by: Santiago Palladino Co-authored-by: AztecBot Co-authored-by: critesjosh Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: Alex Gherghisan Co-authored-by: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Co-authored-by: PhilWindle <60546371+PhilWindle@users.noreply.github.com> Co-authored-by: Ilyas Ridhuan Co-authored-by: Jean M <132435771+jeanmon@users.noreply.github.com> Co-authored-by: jeanmon Co-authored-by: Nicolás Venturo Co-authored-by: Miranda Wood Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: AztecBot Co-authored-by: sergei iakovenko <105737703+iakovenkos@users.noreply.github.com> Co-authored-by: ledwards2225 Co-authored-by: critesjosh Co-authored-by: ludamad Co-authored-by: Phil Windle Co-authored-by: spypsy <6403450+spypsy@users.noreply.github.com> Co-authored-by: spypsy Co-authored-by: MirandaWood Co-authored-by: Santiago Palladino Co-authored-by: critesjosh <18372439+critesjosh@users.noreply.github.com> --- .github/workflows/deploy-irm.yml | 4 +- .github/workflows/deploy-network.yml | 14 +- .github/workflows/deploy-staging-public.yml | 4 - .../workflows/ensure-funded-environment.yml | 3 +- .github/workflows/metrics-deploy.yml | 3 - .github/workflows/nightly-bench-10tps.yml | 122 +- .github/workflows/nightly-spartan-bench.yml | 375 +- .github/workflows/weekly-proving-bench.yml | 121 +- .test_patterns.yml | 73 +- avm-transpiler/src/procedures/compiler.rs | 2 - avm-transpiler/src/procedures/msm.rs | 24 +- avm-transpiler/src/transpile.rs | 21 +- aztec-up/bootstrap.sh | 19 + aztec-up/test/amm_flow.sh | 2 + aztec-up/test/basic_install.sh | 1 + aztec-up/test/bridge_and_claim.sh | 2 + .../pil/vm2/bytecode/address_derivation.pil | 201 +- .../bytecode/contract_instance_retrieval.pil | 44 +- barretenberg/cpp/pil/vm2/constants_gen.pil | 3 +- barretenberg/cpp/pil/vm2/ecc.pil | 39 +- barretenberg/cpp/pil/vm2/ecc_mem.pil | 122 +- barretenberg/cpp/pil/vm2/execution.pil | 14 +- barretenberg/cpp/pil/vm2/memory.pil | 5 +- .../pil/vm2/opcodes/get_contract_instance.pil | 39 +- barretenberg/cpp/pil/vm2/precomputed.pil | 3 +- barretenberg/cpp/pil/vm2/scalar_mul.pil | 14 +- barretenberg/cpp/scripts/chonk-inputs.hash | 2 +- .../avm_fuzzer/common/interfaces/dbs.cpp | 6 +- .../avm_fuzzer/fuzz_lib/fuzzer_context.cpp | 6 +- .../avm_fuzzer/fuzz_lib/instruction.hpp | 8 +- .../avm_fuzzer/fuzz_lib/program_block.cpp | 12 +- .../barretenberg/avm_fuzzer/fuzzer_lib.cpp | 6 +- .../avm_fuzzer/harness/ecc.fuzzer.cpp | 38 +- .../avm_fuzzer/mutations/bytecode.cpp | 6 +- .../mutations/instructions/instruction.cpp | 37 +- .../barretenberg/aztec/aztec_constants.hpp | 5 +- .../cpp/src/barretenberg/bbapi/bbapi_ecc.cpp | 12 +- .../src/barretenberg/bbapi/bbapi_ecdsa.cpp | 8 +- .../src/barretenberg/bbapi/bbapi_schnorr.cpp | 5 +- .../barretenberg/crypto/ecdsa/ecdsa_impl.hpp | 4 +- .../barretenberg/crypto/schnorr/schnorr.tcc | 2 +- .../acir_format/acir_to_constraint_buf.cpp | 45 +- .../dsl/acir_format/block_constraint.test.cpp | 43 +- .../dsl/acir_format/ec_operations.cpp | 19 +- .../dsl/acir_format/ec_operations.hpp | 13 +- .../dsl/acir_format/ec_operations.test.cpp | 81 +- .../dsl/acir_format/gate_count_constants.hpp | 4 +- .../dsl/acir_format/multi_scalar_mul.cpp | 20 +- .../dsl/acir_format/multi_scalar_mul.hpp | 1 - .../dsl/acir_format/multi_scalar_mul.test.cpp | 75 +- .../acir_format/opcode_gate_count.test.cpp | 46 +- .../dsl/acir_format/serde/acir.hpp | 73 +- .../dsl/acir_format/test_class.hpp | 48 +- .../barretenberg/dsl/acir_format/utils.hpp | 2 - .../dsl/acir_format/witness_constant.cpp | 27 +- .../dsl/acir_format/witness_constant.hpp | 1 - .../ecc/curves/invert_differential.fuzzer.cpp | 240 + .../ecc/fields/bernstein_yang_inverse.hpp | 369 + .../ecc/fields/bernstein_yang_inverse.md | 392 + .../fields/bernstein_yang_inverse.test.cpp | 150 + .../fields/bernstein_yang_inverse_wasm.hpp | 280 + .../ecc/fields/field_declarations.hpp | 1 + .../barretenberg/ecc/fields/field_impl.hpp | 25 + .../src/barretenberg/ecc/groups/element.hpp | 2 + .../barretenberg/ecc/groups/element_impl.hpp | 29 + .../nodejs_module/util/async_op.hpp | 52 +- .../src/barretenberg/vm2/common/avm_io.hpp | 16 +- .../barretenberg/vm2/common/aztec_types.hpp | 37 +- .../vm2/common/instruction_spec.cpp | 10 +- .../vm2/common/standard_affine_point.hpp | 35 +- .../vm2/common/standard_affine_point.test.cpp | 37 +- .../vm2/constraining/avm_fixed_vk.hpp | 62 +- .../relations/address_derivation.test.cpp | 67 +- .../contract_instance_retrieval.test.cpp | 117 +- .../vm2/constraining/relations/ecc.test.cpp | 184 +- .../relations/get_contract_instance.test.cpp | 11 +- .../relations/instr_fetching.test.cpp | 4 +- .../barretenberg/vm2/generated/columns.hpp | 18 +- .../vm2/generated/flavor_variables.hpp | 13 +- .../relations/address_derivation.hpp | 4 +- .../relations/address_derivation_impl.hpp | 40 +- .../relations/contract_instance_retrieval.hpp | 7 +- .../contract_instance_retrieval_impl.hpp | 11 +- .../vm2/generated/relations/ecc.hpp | 21 +- .../vm2/generated/relations/ecc_impl.hpp | 57 +- .../vm2/generated/relations/ecc_mem.hpp | 25 +- .../vm2/generated/relations/ecc_mem_impl.hpp | 81 +- .../relations/get_contract_instance_impl.hpp | 4 +- .../relations/lookups_address_derivation.cpp | 4 +- .../relations/lookups_address_derivation.hpp | 151 +- .../lookups_contract_instance_retrieval.hpp | 22 +- .../generated/relations/lookups_ecc_mem.hpp | 12 +- .../lookups_get_contract_instance.hpp | 21 +- .../relations/lookups_scalar_mul.hpp | 4 +- .../vm2/generated/relations/memory.hpp | 32 +- .../vm2/generated/relations/memory_impl.hpp | 73 +- .../vm2/generated/relations/perms_ecc_mem.hpp | 24 - .../generated/relations/perms_execution.hpp | 8 +- .../events/address_derivation_event.hpp | 1 + .../events/get_contract_instance_event.hpp | 3 +- .../simulation/gadgets/address_derivation.cpp | 58 +- .../gadgets/address_derivation.test.cpp | 24 +- .../vm2/simulation/gadgets/ecc.cpp | 46 +- .../vm2/simulation/gadgets/ecc.test.cpp | 42 +- .../vm2/simulation/gadgets/execution.cpp | 14 +- .../vm2/simulation/gadgets/execution.hpp | 2 - .../vm2/simulation/gadgets/execution.test.cpp | 11 +- .../gadgets/get_contract_instance.cpp | 30 +- .../vm2/simulation/lib/contract_crypto.cpp | 24 +- .../vm2/simulation/lib/hinting_dbs.cpp | 10 +- .../vm2/simulation/lib/raw_data_dbs.cpp | 9 +- .../vm2/simulation/lib/serialization.cpp | 2 - .../vm2/testing/avm_inputs.testdata.bin | Bin 2084088 -> 2081088 bytes .../src/barretenberg/vm2/testing/fixtures.cpp | 7 +- .../vm2/testing/minimal_tx.testdata.bin | Bin 189007 -> 190583 bytes .../vm2/tracegen/address_derivation_trace.cpp | 43 +- .../address_derivation_trace.test.cpp | 21 +- .../contract_instance_retrieval_trace.cpp | 18 +- ...contract_instance_retrieval_trace.test.cpp | 19 +- .../barretenberg/vm2/tracegen/ecc_trace.cpp | 27 +- .../vm2/tracegen/ecc_trace.test.cpp | 31 +- .../lib/get_contract_instance_spec.cpp | 7 +- .../lib/get_contract_instance_spec.hpp | 1 + .../vm2/tracegen/lib/interaction_builder.cpp | 19 +- .../vm2/tracegen/lib/interaction_builder.hpp | 21 +- .../vm2/tracegen/lib/interaction_def.hpp | 11 +- ...clk.hpp => lookup_into_indexed_by_row.hpp} | 0 .../lib/multi_permutation_builder.hpp | 10 +- .../vm2/tracegen/lib/shared_index_cache.hpp | 16 +- .../tracegen/lib/test_interaction_builder.hpp | 16 +- .../vm2/tracegen/memory_trace.cpp | 1 - .../opcodes/get_contract_instance_trace.cpp | 13 +- .../get_contract_instance_trace.test.cpp | 74 + .../vm2/tracegen/precomputed_trace.cpp | 3 +- bootstrap.sh | 84 +- ci.sh | 23 +- ci3/bootstrap_ec2 | 1 + .../version-v4.3.0/docs/aztec-nr/debugging.md | 2 +- .../docs/aztec-js/how_to_read_data.md | 4 + .../how_to_simulate_without_signing.md | 112 + .../framework-description/custom_notes.md | 6 +- .../docs/foundational-topics/accounts/keys.md | 18 +- .../docs/foundational-topics/pxe/index.md | 6 +- .../pxe/kernelless_simulations.md | 98 + .../docs/foundational-topics/wallets.md | 2 +- .../docs/resources/migration_notes.md | 92 +- .../reference/ethereum-rpc-reference.md | 2 +- .../slashing-configuration.md | 2 +- .../operators/setup/registering-sequencer.md | 6 +- docs/docs-words.txt | 2 + docs/examples/bootstrap.sh | 5 +- .../aztecjs_kernelless_simulation/config.yaml | 16 + .../ts/aztecjs_kernelless_simulation/index.ts | 167 + .../aztecjs_kernelless_simulation/yarn.lock | 0 docs/examples/ts/aztecjs_runner/run.sh | 26 +- docs/examples/ts/docker-compose.yml | 1 + .../reference/ethereum-rpc-reference.md | 2 +- .../operators/setup/registering-sequencer.md | 6 +- .../typescript-api/mainnet/foundation.md | 2 +- l1-contracts/bootstrap.sh | 7 +- .../src/core/slashing/SlashingProposer.sol | 11 +- .../aztec/src/context/private_context.nr | 45 +- .../aztec/src/keys/ecdh_shared_secret.nr | 26 +- .../aztec-nr/aztec/src/keys/ephemeral.nr | 14 +- .../aztec-nr/aztec/src/keys/getters/mod.nr | 29 +- .../aztec-nr/aztec/src/macros/notes.nr | 10 +- .../src/messages/encryption/poseidon2.nr | 17 +- .../aztec/src/oracle/get_contract_instance.nr | 19 + .../aztec-nr/aztec/src/oracle/keys.nr | 26 +- .../aztec/src/oracle/shared_secret.nr | 24 +- .../aztec/src/publish_contract_instance.nr | 20 +- .../aztec/src/state_vars/private_immutable.nr | 12 +- .../aztec/src/state_vars/private_mutable.nr | 12 +- .../state_vars/single_private_immutable.nr | 10 +- .../src/state_vars/single_private_mutable.nr | 12 +- .../aztec/src/state_vars/single_use_claim.nr | 7 +- .../helpers/test_environment/test/misc.nr | 5 +- .../aztec-nr/aztec/src/utils/point.nr | 30 +- .../aztec-nr/uint-note/src/uint_note.nr | 8 +- noir-projects/bootstrap.sh | 11 +- .../app/card_game_contract/src/cards.nr | 4 +- .../app/nft_contract/src/types/nft_note.nr | 8 +- .../src/handshake_note.nr | 6 +- .../src/main.nr | 57 +- .../src/main.nr | 1 + .../test/avm_test_contract/Nargo.toml | 1 + .../test/avm_test_contract/src/main.nr | 100 +- .../test/returning_tuple_contract/src/main.nr | 10 +- .../test/scope_test_contract/src/main.nr | 6 +- .../crates/private-kernel-init-2/Prover.toml | 4016 ++++++ .../crates/private-kernel-init-3/Prover.toml | 5989 ++++++++ .../crates/private-kernel-init/Prover.toml | 496 +- .../crates/private-kernel-inner-2/Prover.toml | 10000 +++++++++++++ .../crates/private-kernel-inner-3/Prover.toml | 11973 ++++++++++++++++ .../crates/private-kernel-inner/Prover.toml | 1326 +- .../key_validation_request_validator_tests.nr | 7 +- .../reset/key_validation_request/tests/mod.nr | 8 +- .../validate_key_validation_request.nr | 46 +- .../validate_contract_address_tests.nr | 2 +- .../output_composition_tests.nr | 3 +- .../key_validation_tests.nr | 2 +- .../src/tests/private_kernel_reset/mod.nr | 12 +- .../previous_kernel_validation_tests.nr | 7 +- .../previous_kernel_validation_tests.nr | 7 +- .../crates/private-kernel-reset/Prover.toml | 796 +- .../private-kernel-tail-to-public/Prover.toml | 702 +- .../crates/private-kernel-tail/Prover.toml | 838 +- .../src/fixture_builder.nr | 10 +- .../src/fixtures/contracts.nr | 18 +- .../crates/rollup-block-merge/Prover.toml | 518 +- .../Prover.toml | 246 +- .../Prover.toml | 284 +- .../rollup-block-root-first/Prover.toml | 360 +- .../rollup-block-root-single-tx/Prover.toml | 266 +- .../crates/rollup-block-root/Prover.toml | 516 +- .../rollup-checkpoint-merge/Prover.toml | 214 +- .../Prover.toml | 464 +- .../crates/rollup-checkpoint-root/Prover.toml | 562 +- .../crates/rollup-root/Prover.toml | 430 +- .../crates/rollup-tx-base-private/Prover.toml | 2444 ++-- .../crates/rollup-tx-base-public/Prover.toml | 338 +- .../crates/rollup-tx-merge/Prover.toml | 516 +- .../key_validation_request.nr | 16 +- .../key_validation_request_and_separator.nr | 3 +- .../crates/types/src/address/aztec_address.nr | 100 +- .../types/src/address/partial_address.nr | 3 +- .../src/address/salted_initialization_hash.nr | 9 +- .../crates/types/src/constants.nr | 19 +- .../crates/types/src/constants_tests.nr | 18 +- .../crates/types/src/contract_instance.nr | 3 + .../crates/types/src/point.nr | 172 +- .../crates/types/src/public_keys.nr | 209 +- .../crates/types/src/type_packing.nr | 14 +- noir/noir-repo | 2 +- playground/docker-compose.yml | 1 + .../aztec-node/templates/_pod-template.yaml | 18 +- spartan/aztec-node/values.yaml | 5 +- spartan/bootstrap.sh | 16 +- spartan/environments/alpha-net.env | 91 - spartan/environments/bench-10tps.env | 7 +- spartan/environments/block-capacity.env | 3 +- spartan/environments/devnet.env | 1 + spartan/environments/five-tps-long-epoch.env | 75 - spartan/environments/five-tps-short-epoch.env | 75 - spartan/environments/kind-minimal.env | 1 + spartan/environments/kind-provers.env | 1 + spartan/environments/mainnet.env | 7 +- spartan/environments/mbps-net.env | 68 - spartan/environments/mbps-pipeline.env | 69 - spartan/environments/network-defaults.yml | 22 +- spartan/environments/next-net-clone.env | 79 - spartan/environments/next-net.env | 5 +- spartan/environments/next-scenario.env | 3 +- spartan/environments/prove-n-tps-fake.env | 3 +- spartan/environments/prove-n-tps-real.env | 1 + spartan/environments/scenario.local.env | 1 + spartan/environments/staging-ignition.env | 42 - spartan/environments/staging-public.env | 3 +- spartan/environments/staging.local.env | 21 - spartan/environments/ten-tps-long-epoch.env | 76 - spartan/environments/ten-tps-short-epoch.env | 76 - spartan/environments/testnet.env | 3 +- spartan/environments/tps-scenario.env | 7 +- spartan/metrics/grafana/alerts/policies.yaml | 12 - .../grafana/dashboards/aztec_network.json | 185 +- .../metrics/grafana/dashboards/bootnodes.json | 4 +- .../irm-monitor/alerting/alert-rules.yml | 4 +- spartan/metrics/values.yaml | 3 +- .../bench_10tps/bench_output.schema.json | 545 +- spartan/scripts/bench_10tps/bench_scrape.ts | 186 +- spartan/scripts/check_env_vars.sh | 1 - spartan/scripts/deploy_network.sh | 7 +- spartan/scripts/network_pause.sh | 2 +- spartan/scripts/wait_for_l2_block.sh | 48 +- spartan/terraform/deploy-aztec-infra/main.tf | 21 +- .../values/blob-sink-resources-mainnet.yaml | 41 - .../values/bot-resources-dev.yaml | 21 +- .../values/bot-resources-prod.yaml | 10 +- .../full-node-resources-2-core-spot.yaml | 52 - .../values/full-node-resources-prod.yaml | 13 - ....yaml => prover-resources-dev-hi-tps.yaml} | 13 - .../values/prover-resources-mainnet.yaml | 83 - .../values/prover-resources-prod-hi-tps.yaml | 43 +- .../values/prover-resources-prod.yaml | 13 +- .../values/rpc-resources-mainnet.yaml | 39 - .../validator-resources-2-core-dedicated.yaml | 22 - .../values/validator-resources-ha.yaml | 10 + .../validator-resources-prod-hi-tps.yaml | 23 - ...pot.yaml => validator-resources-spot.yaml} | 19 - .../terraform/deploy-aztec-infra/variables.tf | 26 +- spartan/terraform/deploy-metrics/main.tf | 1 - spartan/terraform/deploy-metrics/variables.tf | 6 - spartan/testnet-runbook.md | 2 +- yarn-project/BRANCHING.md | 3 +- yarn-project/CLAUDE.md | 4 +- yarn-project/archiver/src/index.ts | 1 + .../src/modules/data_store_updater.test.ts | 129 + .../src/modules/data_store_updater.ts | 47 +- .../archiver/src/modules/l1_synchronizer.ts | 13 + .../archiver/src/store/block_store.ts | 203 +- .../archiver/src/store/l2_tips_cache.ts | 125 +- .../aztec-node/src/aztec-node/config.ts | 11 + .../aztec-node/src/aztec-node/server.test.ts | 75 + .../aztec-node/src/aztec-node/server.ts | 235 +- .../aztec-node/src/sentinel/README.md | 103 + .../aztec-node/src/sentinel/config.ts | 24 +- .../aztec-node/src/sentinel/factory.ts | 8 +- .../aztec-node/src/sentinel/sentinel.test.ts | 221 +- .../aztec-node/src/sentinel/sentinel.ts | 275 +- .../aztec-node/src/sentinel/store.test.ts | 66 +- yarn-project/aztec-node/src/sentinel/store.ts | 44 +- yarn-project/aztec-node/src/test/index.ts | 4 +- .../src/deployment/publish_instance.ts | 1 + yarn-project/aztec.js/src/utils/node.test.ts | 4 +- .../aztec.js/src/wallet/wallet.test.ts | 12 +- .../aztec/src/cli/aztec_start_action.ts | 4 +- yarn-project/aztec/src/cli/util.ts | 14 +- .../aztec/src/local-network/local-network.ts | 15 + .../aztec/src/testing/anvil_test_watcher.ts | 32 + yarn-project/aztec/src/testing/cheat_codes.ts | 21 +- yarn-project/bootstrap.sh | 6 +- yarn-project/cli-wallet/package.json | 2 +- yarn-project/constants/src/constants.gen.ts | 22 +- .../constants/src/scripts/constants.in.ts | 6 +- yarn-project/end-to-end/bootstrap.sh | 18 +- .../end-to-end/scripts/docker-compose.yml | 1 + .../end-to-end/scripts/test_simple.sh | 2 +- .../src/bench/tx_stats_bench.test.ts | 2 +- .../src/composed/e2e_cheat_codes.test.ts | 32 +- .../e2e_local_network_example.test.ts | 4 +- .../src/composed/e2e_persistence.test.ts | 38 +- .../e2e_token_bridge_tutorial_test.test.ts | 2 +- .../src/composed/ha/e2e_ha_full.test.ts | 230 +- .../uniswap_trade_on_l1_from_l2.test.ts | 3 +- ...e2e_multi_validator_node_key_store.test.ts | 7 +- .../end-to-end/src/e2e_2_pxes.test.ts | 3 +- .../end-to-end/src/e2e_abi_types.test.ts | 5 +- .../src/e2e_account_contracts.test.ts | 6 +- yarn-project/end-to-end/src/e2e_amm.test.ts | 10 +- .../end-to-end/src/e2e_authwit.test.ts | 6 +- .../end-to-end/src/e2e_automine_smoke.test.ts | 137 + .../end-to-end/src/e2e_avm_simulator.test.ts | 400 +- .../access_control.test.ts | 3 +- .../blacklist_token_contract_test.ts | 23 +- .../e2e_blacklist_token_contract/burn.test.ts | 6 +- .../minting.test.ts | 6 +- .../shielding.test.ts | 6 +- .../transfer_private.test.ts | 7 +- .../transfer_public.test.ts | 6 +- .../unshielding.test.ts | 7 +- .../end-to-end/src/e2e_block_building.test.ts | 133 +- yarn-project/end-to-end/src/e2e_bot.test.ts | 14 +- .../end-to-end/src/e2e_card_game.test.ts | 3 +- .../src/e2e_circuit_recorder.test.ts | 5 +- .../src/e2e_contract_updates.test.ts | 15 +- .../cross_chain_messaging_test.ts | 51 +- .../l1_to_l2.parallel.test.ts | 324 + .../l1_to_l2.test.ts | 288 - .../l2_to_l1.test.ts | 38 +- .../token_bridge_failure_cases.test.ts | 8 +- .../token_bridge_private.test.ts | 9 +- .../token_bridge_public.test.ts | 12 +- .../src/e2e_crowdfunding_and_claim.test.ts | 16 +- .../end-to-end/src/e2e_custom_message.test.ts | 5 +- .../end-to-end/src/e2e_debug_trace.test.ts | 11 +- .../contract_class_registration.test.ts | 53 +- .../e2e_deploy_contract/deploy_method.test.ts | 3 +- .../src/e2e_deploy_contract/deploy_test.ts | 5 +- .../src/e2e_deploy_contract/legacy.test.ts | 5 +- .../private_initialization.test.ts | 3 +- .../end-to-end/src/e2e_double_spend.test.ts | 5 +- .../e2e_epochs/epochs_equivocation.test.ts | 49 +- .../epochs_invalidate_block.parallel.test.ts | 13 +- .../e2e_epochs/epochs_mbps.parallel.test.ts | 4 +- .../e2e_epochs/epochs_missed_l1_slot.test.ts | 6 +- .../epochs_proof_at_boundary.parallel.test.ts | 30 +- .../epochs_proof_public_cross_chain.test.ts | 2 +- .../end-to-end/src/e2e_epochs/epochs_test.ts | 8 + .../src/e2e_escrow_contract.test.ts | 3 +- .../end-to-end/src/e2e_event_logs.test.ts | 5 +- .../end-to-end/src/e2e_event_only.test.ts | 5 +- .../src/e2e_expiration_timestamp.test.ts | 70 +- .../src/e2e_fee_asset_price_oracle.test.ts | 6 +- .../src/e2e_fees/account_init.test.ts | 8 +- .../end-to-end/src/e2e_fees/failures.test.ts | 42 +- .../src/e2e_fees/fee_juice_payments.test.ts | 9 +- .../src/e2e_fees/fee_settings.test.ts | 170 +- .../end-to-end/src/e2e_fees/fees_test.ts | 26 +- .../src/e2e_fees/gas_estimation.test.ts | 17 +- .../src/e2e_fees/private_payments.test.ts | 27 +- .../src/e2e_fees/public_payments.test.ts | 11 +- .../src/e2e_fees/sponsored_payments.test.ts | 11 +- .../src/e2e_genesis_timestamp.test.ts | 37 +- .../src/e2e_kernelless_simulation.test.ts | 3 +- yarn-project/end-to-end/src/e2e_keys.test.ts | 14 +- .../e2e_l1_publisher/e2e_l1_publisher.test.ts | 134 +- .../src/e2e_l1_with_wall_time.test.ts | 14 +- .../src/e2e_large_public_event.test.ts | 5 +- .../src/e2e_lending_contract.test.ts | 90 +- .../end-to-end/src/e2e_mempool_limit.test.ts | 7 +- .../end-to-end/src/e2e_multi_eoa.test.ts | 33 +- .../e2e_multi_validator_node.test.ts | 87 +- .../e2e_multiple_accounts_1_enc_key.test.ts | 8 +- .../end-to-end/src/e2e_multiple_blobs.test.ts | 3 +- .../src/e2e_nested_contract/importer.test.ts | 3 +- .../manual_private_call.test.ts | 3 +- .../manual_private_enqueue.test.ts | 3 +- .../e2e_nested_contract/manual_public.test.ts | 3 +- .../nested_contract_test.ts | 4 +- .../src/e2e_nested_utility_calls.test.ts | 6 +- yarn-project/end-to-end/src/e2e_nft.test.ts | 5 +- .../end-to-end/src/e2e_note_getter.test.ts | 3 +- .../src/e2e_offchain_effect.test.ts | 5 +- .../src/e2e_offchain_payment.test.ts | 80 +- .../end-to-end/src/e2e_option_params.test.ts | 5 +- .../end-to-end/src/e2e_orderbook.test.ts | 5 +- .../end-to-end/src/e2e_ordering.test.ts | 14 +- .../end-to-end/src/e2e_p2p/add_rollup.test.ts | 7 +- ...asted_invalid_block_proposal_slash.test.ts | 93 +- .../e2e_p2p/data_withholding_slash.test.ts | 291 +- .../duplicate_attestation_slash.test.ts | 12 + .../fee_asset_price_oracle_gossip.test.ts | 2 + ...tiple_validators_sentinel.parallel.test.ts | 4 +- .../src/e2e_p2p/reqresp/reqresp.test.ts | 6 + .../reqresp/reqresp_no_handshake.test.ts | 6 + .../end-to-end/src/e2e_p2p/reqresp/utils.ts | 27 +- .../sentinel_status_slash.parallel.test.ts | 414 + .../e2e_p2p/valid_epoch_pruned_slash.test.ts | 193 - .../end-to-end/src/e2e_partial_notes.test.ts | 5 +- .../e2e_pending_note_hashes_contract.test.ts | 24 +- .../end-to-end/src/e2e_phase_check.test.ts | 3 +- .../src/e2e_private_voting_contract.test.ts | 3 +- .../end-to-end/src/e2e_prover/client.test.ts | 42 +- .../end-to-end/src/e2e_prover/full.test.ts | 56 +- .../end-to-end/src/e2e_pruned_blocks.test.ts | 42 +- .../e2e_public_testnet_transfer.test.ts | 2 + .../src/e2e_publisher_funding_multi.test.ts | 10 +- yarn-project/end-to-end/src/e2e_pxe.test.ts | 3 +- .../src/e2e_scope_isolation.test.ts | 3 +- .../escape_hatch_vote_only.test.ts | 83 +- .../gov_proposal.parallel.test.ts | 59 +- .../src/e2e_sequencer/reload_keystore.test.ts | 2 + .../src/e2e_sequencer/slasher_config.test.ts | 2 + .../src/e2e_sequencer_config.test.ts | 7 +- .../end-to-end/src/e2e_simple.test.ts | 4 +- .../attested_invalid_proposal.test.ts | 574 + ..._invalid_checkpoint_proposal_slash.test.ts | 489 + .../end-to-end/src/e2e_snapshot_sync.test.ts | 3 +- .../end-to-end/src/e2e_state_vars.test.ts | 56 +- .../end-to-end/src/e2e_static_calls.test.ts | 8 +- .../e2e_storage_proof.test.ts | 3 +- .../end-to-end/src/e2e_synching.test.ts | 3 + .../e2e_token_contract/access_control.test.ts | 3 +- .../src/e2e_token_contract/burn.test.ts | 4 +- .../src/e2e_token_contract/minting.test.ts | 4 +- .../private_transfer_recursion.test.ts | 3 +- .../reading_constants.test.ts | 3 +- .../e2e_token_contract/token_contract_test.ts | 12 +- .../src/e2e_token_contract/transfer.test.ts | 3 +- .../transfer_in_private.test.ts | 4 +- .../transfer_in_public.test.ts | 4 +- .../transfer_to_private.test.ts | 4 +- .../transfer_to_public.test.ts | 4 +- .../src/e2e_tx_effect_oracle.test.ts | 3 +- .../src/fixtures/e2e_prover_test.ts | 4 +- .../end-to-end/src/fixtures/fixtures.ts | 64 + yarn-project/end-to-end/src/fixtures/setup.ts | 39 +- .../end-to-end/src/fixtures/setup_p2p_test.ts | 4 + .../writing_an_account_contract.test.ts | 3 +- .../end-to-end/src/shared/uniswap_l1_l2.ts | 2 +- .../src/simulators/lending_simulator.ts | 40 +- .../src/spartan/invalidate_blocks.test.ts | 10 +- .../end-to-end/src/spartan/n_tps.test.ts | 52 +- .../end-to-end/src/spartan/tx_metrics.ts | 98 +- .../end-to-end/src/test-wallet/utils.ts | 3 +- .../contracts/chain_state_override.test.ts | 24 + .../src/contracts/chain_state_override.ts | 35 +- .../src/contracts/governance_proposer.ts | 30 + .../ethereum/src/contracts/multicall.test.ts | 82 +- .../ethereum/src/contracts/multicall.ts | 284 +- .../ethereum/src/l1_tx_utils/l1_tx_utils.ts | 41 +- .../ethereum/src/test/eth_cheat_codes.ts | 10 + .../ethereum/src/test/rollup_cheat_codes.ts | 15 + yarn-project/ethereum/src/utils.ts | 18 + yarn-project/foundation/package.json | 1 + yarn-project/foundation/src/config/env_var.ts | 13 +- .../foundation/src/config/network_name.ts | 3 - .../src/curves/grumpkin/point.test.ts | 5 +- .../foundation/src/curves/grumpkin/point.ts | 68 +- .../foundation/src/fifo_set/fifo_set.test.ts | 62 + .../foundation/src/fifo_set/fifo_set.ts | 52 + yarn-project/foundation/src/fifo_set/index.ts | 1 + .../server/safe_json_rpc_server.test.ts | 58 + .../json-rpc/server/safe_json_rpc_server.ts | 34 +- yarn-project/foundation/src/timer/index.ts | 2 +- .../foundation/src/timer/timeout.test.ts | 30 +- yarn-project/foundation/src/timer/timeout.ts | 31 + yarn-project/key-store/src/key_store.test.ts | 56 +- yarn-project/key-store/src/key_store.ts | 62 +- .../__snapshots__/noir_test_gen.test.ts.snap | 24 +- .../src/conversion/client.ts | 19 +- .../src/conversion/common.ts | 5 +- .../src/conversion/type_conversion.test.ts | 2 +- .../src/noir_test_gen.test.ts | 7 +- yarn-project/p2p/src/client/interface.ts | 12 +- .../p2p/src/client/p2p_client.test.ts | 2 +- yarn-project/p2p/src/client/p2p_client.ts | 48 +- ...client.batch_tx_requester.bench.README.md} | 76 +- ...p_client.batch_tx_requester.bench.test.ts} | 8 +- .../p2p_client.integration_batch_txs.test.ts | 13 +- .../p2p_client.integration_reqresp.test.ts | 70 - .../proposal_tx_collector_worker.ts | 345 - .../proposal_tx_collector_worker_protocol.ts | 40 - yarn-project/p2p/src/config.ts | 37 +- yarn-project/p2p/src/errors/reqresp.error.ts | 25 - .../attestation_pool/attestation_pool.ts | 240 +- .../attestation_pool_test_suite.ts | 79 +- .../mem_pools/tx_pool_v2/tx_pool_v2_impl.ts | 16 +- .../block_proposal_validator.ts | 1 + .../checkpoint_proposal_validator.ts | 1 + .../proposal_validator/proposal_validator.ts | 5 +- .../contract_instance_validator.test.ts | 14 +- .../p2p/src/services/dummy_service.ts | 54 +- .../services/libp2p/libp2p_service.test.ts | 64 +- .../p2p/src/services/libp2p/libp2p_service.ts | 114 +- .../p2p/src/services/reqresp/README.md | 14 - .../batch_tx_requester.test.ts | 109 +- .../batch-tx-requester/batch_tx_requester.ts | 27 +- .../reqresp/batch-tx-requester/interface.ts | 13 +- .../batch-tx-requester/tx_validator.ts | 32 +- .../batch_connection_sampler.test.ts | 256 - .../batch_connection_sampler.ts | 161 - .../p2p/src/services/reqresp/interface.ts | 40 +- .../p2p/src/services/reqresp/reqresp.test.ts | 130 +- .../p2p/src/services/reqresp/reqresp.ts | 262 +- yarn-project/p2p/src/services/service.ts | 29 +- .../p2p/src/services/tx_collection/config.ts | 4 +- .../tx_collection/fast_tx_collection.ts | 379 - .../file_store_tx_collection.test.ts | 166 +- .../tx_collection/file_store_tx_collection.ts | 157 +- .../p2p/src/services/tx_collection/index.ts | 3 +- .../tx_collection/tx_collection.test.ts | 87 +- .../services/tx_collection/tx_collection.ts | 395 +- .../services/tx_file_store/tx_file_store.ts | 22 +- yarn-project/p2p/src/services/tx_provider.ts | 5 + .../p2p/src/test-helpers/mock-pubsub.ts | 70 +- .../p2p/src/test-helpers/reqresp-nodes.ts | 21 +- .../p2p/src/test-helpers/test_tx_provider.ts | 5 + .../p2p/src/test-helpers/testbench-utils.ts | 30 +- .../testbench/p2p_client_testbench_worker.ts | 9 +- .../ContractClassPublishedEventData.hex | 2 +- .../ContractInstancePublishedEventData.hex | 2 +- ...ontract_class_published_event.test.ts.snap | 8 +- ...ract_instance_published_event.test.ts.snap | 19 +- .../contract_instance_published_event.ts | 6 +- .../src/make_protocol_contract.ts | 4 +- .../src/scripts/generate_data.ts | 3 +- yarn-project/prover-client/package.json | 2 +- .../src/orchestrator/orchestrator.ts | 2 +- .../src/proving_broker/proving_broker.test.ts | 19 +- .../src/proving_broker/proving_broker.ts | 8 +- .../src/job/epoch-proving-job.test.ts | 100 +- .../prover-node/src/job/epoch-proving-job.ts | 98 +- .../src/prover-node-publisher.test.ts | 76 + .../prover-node/src/prover-node-publisher.ts | 54 + yarn-project/prover-node/src/prover-node.ts | 4 +- .../oracle/oracle.ts | 21 +- .../oracle/private_execution.test.ts | 24 +- .../oracle/utility_execution.test.ts | 17 +- .../oracle/utility_execution_oracle.ts | 10 +- ...ate_kernel_reset_private_inputs_builder.ts | 2 +- .../src/private_kernel/hints/test_utils.ts | 11 +- .../private_kernel_execution_prover.test.ts | 3 +- .../private_kernel/private_kernel_oracle.ts | 12 +- .../address_store/address_store.test.ts | 3 +- .../__snapshots__/AddressStore.json | 12 +- .../__snapshots__/ContractStore.json | 2 +- .../__snapshots__/KeyStore.json | 32 +- .../__snapshots__/opened_stores.json | 2 +- .../schema_tests.ts | 16 +- yarn-project/pxe/src/storage/metadata.ts | 2 +- .../sender_tagging_store.test.ts | 2 +- .../sync_sender_tagging_indexes.test.ts | 6 +- .../get_status_change_of_pending.test.ts | 6 +- yarn-project/sequencer-client/README.md | 98 +- yarn-project/sequencer-client/src/config.ts | 10 + yarn-project/sequencer-client/src/index.ts | 11 +- .../publisher/sequencer-bundle-simulator.ts | 253 + .../src/publisher/sequencer-publisher.test.ts | 389 +- .../src/publisher/sequencer-publisher.ts | 755 +- .../sequencer-client/src/sequencer/README.md | 10 +- .../src/sequencer/automine/README.md | 46 + .../sequencer/automine/automine_factory.ts | 145 + .../sequencer/automine/automine_sequencer.ts | 592 + .../src/sequencer/chain_state_overrides.ts | 213 +- .../sequencer/checkpoint_proposal_job.test.ts | 234 +- .../checkpoint_proposal_job.timing.test.ts | 4 +- .../src/sequencer/checkpoint_proposal_job.ts | 97 +- .../checkpoint_voter.ha.integration.test.ts | 7 +- .../sequencer-client/src/sequencer/events.ts | 35 +- .../sequencer-client/src/sequencer/index.ts | 2 + .../src/sequencer/sequencer.test.ts | 100 +- .../src/sequencer/sequencer.ts | 140 +- .../docs/avm/avm-isa-quick-reference.md | 6 +- .../docs/avm/opcodes/getcontractinstance.md | 3 +- .../docs/avm/public-tx-simulation.md | 2 +- .../public/avm/apps_tests/avm_test.test.ts | 15 + .../src/public/avm/avm_simulator.test.ts | 34 +- .../src/public/avm/fixtures/utils.ts | 3 + .../src/public/avm/opcodes/contract.test.ts | 6 +- .../src/public/avm/opcodes/contract.ts | 6 +- .../src/public/avm/opcodes/ec_add.test.ts | 268 +- .../src/public/avm/opcodes/ec_add.ts | 43 +- .../src/public/fixtures/bulk_test.ts | 26 + .../src/public/fixtures/opcode_spammer.ts | 12 +- .../simulator/src/public/fixtures/utils.ts | 17 +- .../src/public/hinting_db_sources.ts | 1 + .../apps_tests/deployments.test.ts | 2 +- .../public_processor/public_processor.test.ts | 34 +- .../public_processor/public_processor.ts | 68 +- .../public_tx_simulator.test.ts | 12 +- yarn-project/slasher/README.md | 80 +- yarn-project/slasher/src/config.ts | 31 +- yarn-project/slasher/src/index.ts | 4 +- .../src/slash_offenses_collector.test.ts | 4 +- .../slasher/src/stores/offenses_store.test.ts | 13 +- .../attestations_block_watcher.test.ts | 8 +- .../watchers/attestations_block_watcher.ts | 29 +- ...nvalid_checkpoint_proposal_watcher.test.ts | 290 + ...ted_invalid_checkpoint_proposal_watcher.ts | 199 + .../checkpoint_equivocation_watcher.test.ts | 120 + .../checkpoint_equivocation_watcher.ts | 98 + .../watchers/data_withholding_watcher.test.ts | 340 + .../src/watchers/data_withholding_watcher.ts | 227 + .../src/watchers/epoch_prune_watcher.test.ts | 260 - .../src/watchers/epoch_prune_watcher.ts | 256 - yarn-project/sqlite3mc-wasm/scripts/vendor.sh | 6 +- yarn-project/stdlib/src/abi/decoder.test.ts | 17 +- yarn-project/stdlib/src/abi/utils.ts | 6 +- yarn-project/stdlib/src/avm/avm.ts | 5 + yarn-project/stdlib/src/avm/message_pack.ts | 15 +- yarn-project/stdlib/src/avm/revert_code.ts | 6 - .../src/aztec-address/aztec-address.test.ts | 2 +- .../stdlib/src/block/l2_block_source.ts | 14 + .../l2_block_stream/l2_tips_store_base.ts | 25 +- .../checkpoint_reexecution_tracker.test.ts | 168 + .../checkpoint_reexecution_tracker.ts | 167 + yarn-project/stdlib/src/checkpoint/index.ts | 1 + .../src/contract/complete_address.test.ts | 8 +- .../stdlib/src/contract/complete_address.ts | 10 +- .../src/contract/contract_address.test.ts | 14 +- .../stdlib/src/contract/contract_address.ts | 10 +- .../stdlib/src/contract/contract_instance.ts | 13 +- .../contract/interfaces/contract_instance.ts | 8 +- .../stdlib/src/interfaces/archiver.test.ts | 6 +- .../src/interfaces/aztec-node-admin.test.ts | 19 +- .../stdlib/src/interfaces/aztec-node-admin.ts | 11 + .../stdlib/src/interfaces/aztec-node.test.ts | 10 +- .../stdlib/src/interfaces/block-builder.ts | 2 + yarn-project/stdlib/src/interfaces/configs.ts | 11 + yarn-project/stdlib/src/interfaces/p2p.ts | 8 + yarn-project/stdlib/src/interfaces/slasher.ts | 19 +- .../stdlib/src/interfaces/tx_provider.ts | 6 + .../stdlib/src/interfaces/validator.ts | 6 + .../kernel/hints/key_validation_request.ts | 34 +- .../stdlib/src/keys/derivation.test.ts | 40 +- yarn-project/stdlib/src/keys/derivation.ts | 23 +- yarn-project/stdlib/src/keys/public_key.ts | 28 +- .../stdlib/src/keys/public_keys.test.ts | 13 +- yarn-project/stdlib/src/keys/public_keys.ts | 196 +- .../stdlib/src/p2p/checkpoint_proposal.ts | 22 +- .../stdlib/src/slashing/helpers.test.ts | 25 +- yarn-project/stdlib/src/slashing/helpers.ts | 18 +- .../stdlib/src/slashing/serialization.test.ts | 10 +- yarn-project/stdlib/src/slashing/types.ts | 28 +- .../stdlib/src/slashing/votes.test.ts | 10 +- yarn-project/stdlib/src/tests/factories.ts | 30 +- yarn-project/stdlib/src/tx/tx_receipt.test.ts | 14 +- yarn-project/stdlib/src/tx/tx_receipt.ts | 9 - yarn-project/stdlib/src/validators/schemas.ts | 6 +- yarn-project/stdlib/src/validators/types.ts | 23 +- .../telemetry-client/src/attributes.ts | 1 - yarn-project/telemetry-client/src/config.ts | 12 + .../monitored_batch_span_processor.test.ts | 76 + .../src/monitored_batch_span_processor.ts | 25 +- yarn-project/telemetry-client/src/otel.ts | 7 +- .../telemetry-client/src/otel_propagation.ts | 43 +- yarn-project/telemetry-client/src/start.ts | 7 +- .../telemetry-client/src/telemetry.ts | 1 - yarn-project/txe/src/index.ts | 5 +- .../oracle/txe_oracle_top_level_context.ts | 4 +- yarn-project/txe/src/rpc_translator.ts | 33 +- .../txe/src/state_machine/dummy_p2p_client.ts | 22 +- yarn-project/validator-client/README.md | 19 +- yarn-project/validator-client/src/config.ts | 4 + .../src/duties/validation_service.ts | 13 +- yarn-project/validator-client/src/factory.ts | 5 + .../src/proposal_handler.test.ts | 20 +- .../validator-client/src/proposal_handler.ts | 245 +- .../src/validator.ha.integration.test.ts | 5 + .../src/validator.integration.test.ts | 4 +- .../validator-client/src/validator.test.ts | 352 +- .../validator-client/src/validator.ts | 136 +- .../src/native/ipc_world_state_instance.ts | 47 +- .../src/native/merkle_trees_facade.ts | 21 +- .../src/native/native_world_state.test.ts | 28 + .../src/native/native_world_state_instance.ts | 49 +- 707 files changed, 56066 insertions(+), 17732 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/ecc/curves/invert_differential.fuzzer.cpp create mode 100644 barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.hpp create mode 100644 barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.md create mode 100644 barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.test.cpp create mode 100644 barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp rename barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/{lookup_into_indexed_by_clk.hpp => lookup_into_indexed_by_row.hpp} (100%) create mode 100644 docs/docs-developers/docs/aztec-js/how_to_simulate_without_signing.md create mode 100644 docs/docs-developers/docs/foundational-topics/pxe/kernelless_simulations.md create mode 100644 docs/examples/ts/aztecjs_kernelless_simulation/config.yaml create mode 100644 docs/examples/ts/aztecjs_kernelless_simulation/index.ts create mode 100644 docs/examples/ts/aztecjs_kernelless_simulation/yarn.lock create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-init-2/Prover.toml create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-init-3/Prover.toml create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-inner-2/Prover.toml create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-inner-3/Prover.toml delete mode 100644 spartan/environments/alpha-net.env delete mode 100644 spartan/environments/five-tps-long-epoch.env delete mode 100644 spartan/environments/five-tps-short-epoch.env delete mode 100644 spartan/environments/mbps-net.env delete mode 100644 spartan/environments/mbps-pipeline.env delete mode 100644 spartan/environments/next-net-clone.env delete mode 100644 spartan/environments/staging-ignition.env delete mode 100644 spartan/environments/staging.local.env delete mode 100644 spartan/environments/ten-tps-long-epoch.env delete mode 100644 spartan/environments/ten-tps-short-epoch.env delete mode 100644 spartan/terraform/deploy-aztec-infra/values/blob-sink-resources-mainnet.yaml delete mode 100644 spartan/terraform/deploy-aztec-infra/values/full-node-resources-2-core-spot.yaml rename spartan/terraform/deploy-aztec-infra/values/{prover-resources-hi-tps.yaml => prover-resources-dev-hi-tps.yaml} (82%) delete mode 100644 spartan/terraform/deploy-aztec-infra/values/prover-resources-mainnet.yaml delete mode 100644 spartan/terraform/deploy-aztec-infra/values/rpc-resources-mainnet.yaml delete mode 100644 spartan/terraform/deploy-aztec-infra/values/validator-resources-2-core-dedicated.yaml create mode 100644 spartan/terraform/deploy-aztec-infra/values/validator-resources-ha.yaml delete mode 100644 spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-hi-tps.yaml rename spartan/terraform/deploy-aztec-infra/values/{validator-resources-prod-spot.yaml => validator-resources-spot.yaml} (57%) create mode 100644 yarn-project/aztec-node/src/sentinel/README.md create mode 100644 yarn-project/end-to-end/src/e2e_automine_smoke.test.ts create mode 100644 yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.parallel.test.ts delete mode 100644 yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts create mode 100644 yarn-project/end-to-end/src/e2e_p2p/sentinel_status_slash.parallel.test.ts delete mode 100644 yarn-project/end-to-end/src/e2e_p2p/valid_epoch_pruned_slash.test.ts create mode 100644 yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts create mode 100644 yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts create mode 100644 yarn-project/foundation/src/fifo_set/fifo_set.test.ts create mode 100644 yarn-project/foundation/src/fifo_set/fifo_set.ts create mode 100644 yarn-project/foundation/src/fifo_set/index.ts rename yarn-project/p2p/src/client/test/{tx_proposal_collector/README.md => p2p_client.batch_tx_requester.bench.README.md} (71%) rename yarn-project/p2p/src/client/test/{tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts => p2p_client.batch_tx_requester.bench.test.ts} (96%) delete mode 100644 yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts delete mode 100644 yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts delete mode 100644 yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.test.ts delete mode 100644 yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.ts delete mode 100644 yarn-project/p2p/src/services/tx_collection/fast_tx_collection.ts create mode 100644 yarn-project/sequencer-client/src/publisher/sequencer-bundle-simulator.ts create mode 100644 yarn-project/sequencer-client/src/sequencer/automine/README.md create mode 100644 yarn-project/sequencer-client/src/sequencer/automine/automine_factory.ts create mode 100644 yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts create mode 100644 yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.test.ts create mode 100644 yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts create mode 100644 yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.test.ts create mode 100644 yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.ts create mode 100644 yarn-project/slasher/src/watchers/data_withholding_watcher.test.ts create mode 100644 yarn-project/slasher/src/watchers/data_withholding_watcher.ts delete mode 100644 yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts delete mode 100644 yarn-project/slasher/src/watchers/epoch_prune_watcher.ts create mode 100644 yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.test.ts create mode 100644 yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.ts create mode 100644 yarn-project/telemetry-client/src/monitored_batch_span_processor.test.ts diff --git a/.github/workflows/deploy-irm.yml b/.github/workflows/deploy-irm.yml index b9f18c59cb93..873ed74dcb51 100644 --- a/.github/workflows/deploy-irm.yml +++ b/.github/workflows/deploy-irm.yml @@ -6,7 +6,7 @@ on: workflow_call: inputs: network: - description: "Network that IRM will be monitoring e.g. testnet, staging-ignition..." + description: "Network that IRM will be monitoring e.g. testnet..." required: true type: string default: "testnet" @@ -41,7 +41,7 @@ on: workflow_dispatch: inputs: network: - description: "Network that IRM will be monitoring e.g. testnet, staging-ignition..." + description: "Network that IRM will be monitoring e.g. testnet..." required: true type: string default: "testnet" diff --git a/.github/workflows/deploy-network.yml b/.github/workflows/deploy-network.yml index d25e6a76d04c..0a278740d88d 100644 --- a/.github/workflows/deploy-network.yml +++ b/.github/workflows/deploy-network.yml @@ -38,10 +38,15 @@ on: description: "Source tag that triggered this deploy" required: false type: string + notify_on_failure: + description: "Whether this workflow should send its own failure notification" + required: false + type: boolean + default: true workflow_dispatch: inputs: network: - description: "Network to deploy (e.g., staging-public, staging-ignition, testnet, next-net)" + description: "Network to deploy (e.g., staging-public, testnet, next-net)" required: true type: choice options: @@ -74,6 +79,11 @@ on: description: "Source tag that triggered this deploy" required: false type: string + notify_on_failure: + description: "Whether this workflow should send its own failure notification" + required: false + type: boolean + default: true concurrency: group: deploy-network-${{ inputs.network }}-${{ inputs.namespace || inputs.network }}-${{ inputs.aztec_docker_image || inputs.semver }}-${{ github.ref || github.ref_name }} @@ -242,7 +252,7 @@ jobs: } >> "$GITHUB_STEP_SUMMARY" - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() + if: failure() && inputs.notify_on_failure env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} diff --git a/.github/workflows/deploy-staging-public.yml b/.github/workflows/deploy-staging-public.yml index f7252194354c..a22aa33d054a 100644 --- a/.github/workflows/deploy-staging-public.yml +++ b/.github/workflows/deploy-staging-public.yml @@ -1,10 +1,6 @@ name: Deploy to staging-public on: - workflow_run: - workflows: ["Nightly Release Tag (v4-next)"] - types: - - completed workflow_dispatch: inputs: tag: diff --git a/.github/workflows/ensure-funded-environment.yml b/.github/workflows/ensure-funded-environment.yml index de5a20cec116..e06fef5b7039 100644 --- a/.github/workflows/ensure-funded-environment.yml +++ b/.github/workflows/ensure-funded-environment.yml @@ -6,7 +6,7 @@ on: workflow_call: inputs: environment: - description: 'Environment to fund (e.g., staging-public, next-net, staging-ignition, testnet)' + description: 'Environment to fund (e.g., staging-public, next-net, testnet)' required: true type: string low_watermark: @@ -32,7 +32,6 @@ on: options: - staging-public - next-net - - staging-ignition - testnet - devnet - tps-scenario diff --git a/.github/workflows/metrics-deploy.yml b/.github/workflows/metrics-deploy.yml index b8774a1a7e96..4350f6fb7054 100644 --- a/.github/workflows/metrics-deploy.yml +++ b/.github/workflows/metrics-deploy.yml @@ -100,7 +100,6 @@ jobs: GRAFANA_DASHBOARD_PASSWORD_SECRET_NAME: ${{ inputs.grafana_dashboard_password_secret_name }} SLACK_WEBHOOK_URL_SECRET_NAME: slack-webhook-url SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME: slack-webhook-staging-public-url - SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME: slack-webhook-staging-ignition-url SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME: slack-webhook-next-scenario-url SLACK_WEBHOOK_NEXT_NET_SECRET_NAME: slack-webhook-next-net-url SLACK_WEBHOOK_TESTNET_SECRET_NAME: slack-webhook-testnet-url @@ -164,7 +163,6 @@ jobs: -var="GRAFANA_PASSWORD_SECRET_NAME=${{ env.GRAFANA_DASHBOARD_PASSWORD_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_SECRET_NAME=${{ env.SLACK_WEBHOOK_URL_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME=${{ env.SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME }}" \ - -var="SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME=${{ env.SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME=${{ env.SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_NEXT_NET_SECRET_NAME=${{ env.SLACK_WEBHOOK_NEXT_NET_SECRET_NAME }}" \ -lock=${{ inputs.respect_tf_lock }} @@ -179,7 +177,6 @@ jobs: -var="GRAFANA_PASSWORD_SECRET_NAME=${{ env.GRAFANA_DASHBOARD_PASSWORD_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_SECRET_NAME=${{ env.SLACK_WEBHOOK_URL_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME=${{ env.SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME }}" \ - -var="SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME=${{ env.SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME=${{ env.SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME }}" \ -var="SLACK_WEBHOOK_NEXT_NET_SECRET_NAME=${{ env.SLACK_WEBHOOK_NEXT_NET_SECRET_NAME }}" \ -out=tfplan \ diff --git a/.github/workflows/nightly-bench-10tps.yml b/.github/workflows/nightly-bench-10tps.yml index 89675dc16e65..68d79cb190cb 100644 --- a/.github/workflows/nightly-bench-10tps.yml +++ b/.github/workflows/nightly-bench-10tps.yml @@ -5,8 +5,12 @@ on: - cron: "30 6 * * *" workflow_dispatch: inputs: + docker_image: + description: "Full Docker image (e.g., aztecprotocol/aztec:my-tag). Takes precedence over nightly_tag." + required: false + type: string nightly_tag: - description: "Nightly tag to use (e.g., 2.3.4-nightly.20251209). Leave empty to auto-detect." + description: "Nightly tag to use (e.g., 2.3.4-nightly.20251209). Ignored if docker_image is set. Leave empty to auto-detect." required: false type: string @@ -15,29 +19,40 @@ concurrency: cancel-in-progress: true jobs: - benchmark: + select-image: runs-on: ubuntu-latest + outputs: + docker_image: ${{ steps.docker-image.outputs.docker_image }} + image_label: ${{ steps.docker-image.outputs.image_label }} steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: ref: next - - name: Determine nightly tag - id: nightly-tag + - name: Determine docker image + id: docker-image run: | - if [[ -n "${{ inputs.nightly_tag }}" ]]; then + if [[ -n "${{ inputs.docker_image }}" ]]; then + docker_image="${{ inputs.docker_image }}" + image_label="${{ inputs.docker_image }}" + elif [[ -n "${{ inputs.nightly_tag }}" ]]; then nightly_tag="${{ inputs.nightly_tag }}" + docker_image="aztecprotocol/aztec:${nightly_tag}" + image_label="${nightly_tag}" else current_version=$(jq -r '."."' .release-please-manifest.json) nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" + docker_image="aztecprotocol/aztec:${nightly_tag}" + image_label="${nightly_tag}" fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT - echo "Using nightly tag: $nightly_tag" + echo "docker_image=$docker_image" >> "$GITHUB_OUTPUT" + echo "image_label=$image_label" >> "$GITHUB_OUTPUT" + echo "Using docker image: $docker_image" - name: Check if Docker image exists run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" + DOCKER_IMAGE="${{ steps.docker-image.outputs.docker_image }}" echo "Checking if Docker image exists: $DOCKER_IMAGE" if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then echo "Docker image exists: $DOCKER_IMAGE" @@ -46,7 +61,56 @@ jobs: exit 1 fi - - name: Deploy and run 10 TPS benchmark + deploy-bench-10tps-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: bench-10tps + namespace: bench-10tps + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-for-first-l2-block: + needs: deploy-bench-10tps-network + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} + + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + run: | + cd spartan + ./bootstrap.sh wait_for_l2_block bench-10tps + + benchmark: + needs: + - select-image + - wait-for-first-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Run 10 TPS benchmark timeout-minutes: 240 env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} @@ -59,11 +123,25 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 240 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | - ./.github/ci3.sh network-bench-10tps bench-10tps bench-10tps "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" + ./.github/ci3.sh network-bench-10tps bench-10tps bench-10tps "${{ needs.select-image.outputs.docker_image }}" + + cleanup: + if: always() + needs: + - select-image + - deploy-bench-10tps-network + - wait-for-first-l2-block + - benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next - name: Cleanup network resources - if: always() env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -74,15 +152,29 @@ jobs: NO_SPOT: 1 run: ./.github/ci3.sh network-teardown bench-10tps bench-10tps + notify-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-bench-10tps-network + - wait-for-first-l2-block + - benchmark + - cleanup + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + IMAGE="${{ needs.select-image.outputs.image_label || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ - "Nightly 10 TPS benchmark FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ - "Nightly 10 TPS benchmark failed (nightly tag ${TAG}). CI run: ${RUN_URL}. Investigate the benchmark failure and identify the root cause." \ + "Nightly 10 TPS benchmark FAILED (image ${IMAGE}): <${RUN_URL}|View Run> (🤖)" \ + "Nightly 10 TPS benchmark failed (image ${IMAGE}). CI run: ${RUN_URL}. Investigate the benchmark failure and identify the root cause." \ --link "$RUN_URL" diff --git a/.github/workflows/nightly-spartan-bench.yml b/.github/workflows/nightly-spartan-bench.yml index 61d6f43abaf7..8b2c83f487d3 100644 --- a/.github/workflows/nightly-spartan-bench.yml +++ b/.github/workflows/nightly-spartan-bench.yml @@ -15,8 +15,11 @@ concurrency: cancel-in-progress: true jobs: - benchmark: + select-image: runs-on: ubuntu-latest + outputs: + nightly_tag: ${{ steps.nightly-tag.outputs.nightly_tag }} + docker_image: ${{ steps.nightly-tag.outputs.docker_image }} steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd @@ -32,12 +35,14 @@ jobs: current_version=$(jq -r '."."' .release-please-manifest.json) nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT + docker_image="aztecprotocol/aztec:${nightly_tag}" + echo "nightly_tag=$nightly_tag" >> "$GITHUB_OUTPUT" + echo "docker_image=$docker_image" >> "$GITHUB_OUTPUT" echo "Using nightly tag: $nightly_tag" - name: Check if Docker image exists run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" + DOCKER_IMAGE="${{ steps.nightly-tag.outputs.docker_image }}" echo "Checking if Docker image exists: $DOCKER_IMAGE" if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then echo "Docker image exists: $DOCKER_IMAGE" @@ -46,6 +51,59 @@ jobs: exit 1 fi + # --------------------------------------------------------------------------- + # TPS benchmark (env tps-scenario, namespace nightly-bench) + # --------------------------------------------------------------------------- + deploy-bench-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: tps-scenario + namespace: nightly-bench + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-bench-l2-block: + needs: deploy-bench-network + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} + + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NAMESPACE: nightly-bench + run: | + cd spartan + ./bootstrap.sh wait_for_l2_block tps-scenario + + benchmark: + needs: + - select-image + - wait-bench-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Run benchmarks timeout-minutes: 240 env: @@ -59,21 +117,10 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 240 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | # Pass the arguments expected in ./bootstrap.sh ci-network-bench - ./.github/ci3.sh network-bench tps-scenario nightly-bench "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - - - name: Cleanup network resources - if: always() - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} - BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} - GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - NO_SPOT: 1 - run: ./.github/ci3.sh network-teardown tps-scenario nightly-bench + ./.github/ci3.sh network-bench tps-scenario nightly-bench "${{ needs.select-image.outputs.docker_image }}" - name: Download benchmarks if: always() @@ -82,7 +129,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | if ./ci.sh gh-spartan-bench; then - echo "ENABLE_DEPLOY_BENCH=1" >> $GITHUB_ENV + echo "ENABLE_DEPLOY_BENCH=1" >> "$GITHUB_ENV" fi - name: Upload benchmarks @@ -102,49 +149,109 @@ jobs: fail-on-alert: false max-items-in-chart: 100 + cleanup-bench: + if: always() + needs: + - deploy-bench-network + - wait-bench-l2-block + - benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Cleanup network resources + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NO_SPOT: 1 + run: ./.github/ci3.sh network-teardown tps-scenario nightly-bench + + notify-bench-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-bench-network + - wait-bench-l2-block + - benchmark + - cleanup-bench + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + TAG="${{ needs.select-image.outputs.nightly_tag || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ "Nightly Spartan Benchmarks FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ "Nightly Spartan benchmarks failed (nightly tag ${TAG}). CI run: ${RUN_URL}. Investigate the benchmark failure and identify the root cause." \ --link "$RUN_URL" - proving-benchmark: + # --------------------------------------------------------------------------- + # Proving benchmark (env prove-n-tps-fake, namespace prove-n-tps-fake) + # --------------------------------------------------------------------------- + deploy-proving-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: prove-n-tps-fake + namespace: prove-n-tps-fake + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-proving-l2-block: + needs: deploy-proving-network runs-on: ubuntu-latest + timeout-minutes: 120 steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: ref: next - - name: Determine nightly tag - id: nightly-tag - run: | - if [[ -n "${{ inputs.nightly_tag }}" ]]; then - nightly_tag="${{ inputs.nightly_tag }}" - else - current_version=$(jq -r '."."' .release-please-manifest.json) - nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" - fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT - echo "Using nightly tag: $nightly_tag" + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} - - name: Check if Docker image exists + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NAMESPACE: prove-n-tps-fake run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - echo "Checking if Docker image exists: $DOCKER_IMAGE" - if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then - echo "Docker image exists: $DOCKER_IMAGE" - else - echo "Docker image does not exist: $DOCKER_IMAGE" - exit 1 - fi + cd spartan + ./bootstrap.sh wait_for_l2_block prove-n-tps-fake + + proving-benchmark: + needs: + - select-image + - wait-proving-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next - name: Run proving benchmarks timeout-minutes: 180 @@ -159,20 +266,9 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 180 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | - ./.github/ci3.sh network-proving-bench prove-n-tps-fake prove-n-tps-fake "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - - - name: Cleanup network resources - if: always() - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} - BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} - GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - NO_SPOT: 1 - run: ./.github/ci3.sh network-teardown prove-n-tps-fake prove-n-tps-fake + ./.github/ci3.sh network-proving-bench prove-n-tps-fake prove-n-tps-fake "${{ needs.select-image.outputs.docker_image }}" - name: Download benchmarks if: always() @@ -181,7 +277,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | if ./ci.sh gh-spartan-proving-bench; then - echo "ENABLE_DEPLOY_BENCH=1" >> $GITHUB_ENV + echo "ENABLE_DEPLOY_BENCH=1" >> "$GITHUB_ENV" fi - name: Upload benchmarks @@ -200,49 +296,109 @@ jobs: fail-on-alert: false max-items-in-chart: 100 + cleanup-proving: + if: always() + needs: + - deploy-proving-network + - wait-proving-l2-block + - proving-benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Cleanup network resources + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NO_SPOT: 1 + run: ./.github/ci3.sh network-teardown prove-n-tps-fake prove-n-tps-fake + + notify-proving-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-proving-network + - wait-proving-l2-block + - proving-benchmark + - cleanup-proving + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + TAG="${{ needs.select-image.outputs.nightly_tag || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ "Nightly Proving Benchmarks FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ "Nightly proving benchmarks failed (nightly tag ${TAG}). CI run: ${RUN_URL}. Investigate the benchmark failure and identify the root cause." \ --link "$RUN_URL" - block-capacity-benchmark: + # --------------------------------------------------------------------------- + # Block capacity benchmark (env block-capacity, namespace nightly-block-capacity) + # --------------------------------------------------------------------------- + deploy-block-capacity-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: block-capacity + namespace: nightly-block-capacity + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-block-capacity-l2-block: + needs: deploy-block-capacity-network runs-on: ubuntu-latest + timeout-minutes: 120 steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: - ref: merge-train/spartan + ref: next - - name: Determine nightly tag - id: nightly-tag - run: | - if [[ -n "${{ inputs.nightly_tag }}" ]]; then - nightly_tag="${{ inputs.nightly_tag }}" - else - current_version=$(jq -r '."."' .release-please-manifest.json) - nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" - fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT - echo "Using nightly tag: $nightly_tag" + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} - - name: Check if Docker image exists + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NAMESPACE: nightly-block-capacity run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - echo "Checking if Docker image exists: $DOCKER_IMAGE" - if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then - echo "Docker image exists: $DOCKER_IMAGE" - else - echo "Docker image does not exist: $DOCKER_IMAGE" - exit 1 - fi + cd spartan + ./bootstrap.sh wait_for_l2_block block-capacity + + block-capacity-benchmark: + needs: + - select-image + - wait-block-capacity-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next - name: Run block capacity benchmarks timeout-minutes: 240 @@ -257,20 +413,9 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 240 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | - ./.github/ci3.sh network-block-capacity-bench block-capacity nightly-block-capacity "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - - - name: Cleanup network resources - if: always() - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} - BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} - GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - NO_SPOT: 1 - run: ./.github/ci3.sh network-teardown block-capacity nightly-block-capacity + ./.github/ci3.sh network-block-capacity-bench block-capacity nightly-block-capacity "${{ needs.select-image.outputs.docker_image }}" - name: Download benchmarks if: always() @@ -279,7 +424,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | if ./ci.sh gh-spartan-block-capacity-bench; then - echo "ENABLE_DEPLOY_BENCH=1" >> $GITHUB_ENV + echo "ENABLE_DEPLOY_BENCH=1" >> "$GITHUB_ENV" fi - name: Upload benchmarks @@ -299,13 +444,51 @@ jobs: fail-on-alert: false max-items-in-chart: 100 + cleanup-block-capacity: + if: always() + needs: + - deploy-block-capacity-network + - wait-block-capacity-l2-block + - block-capacity-benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Cleanup network resources + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NO_SPOT: 1 + run: ./.github/ci3.sh network-teardown block-capacity nightly-block-capacity + + notify-block-capacity-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-block-capacity-network + - wait-block-capacity-l2-block + - block-capacity-benchmark + - cleanup-block-capacity + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + TAG="${{ needs.select-image.outputs.nightly_tag || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ "Nightly Block Capacity Benchmarks FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ diff --git a/.github/workflows/weekly-proving-bench.yml b/.github/workflows/weekly-proving-bench.yml index b8b383a23022..654a38c610a5 100644 --- a/.github/workflows/weekly-proving-bench.yml +++ b/.github/workflows/weekly-proving-bench.yml @@ -2,7 +2,7 @@ name: Weekly Real Proving Benchmark on: schedule: - - cron: "0 6 * * 1" # Every Monday at 6 AM UTC + - cron: "0 6 * * 1" # Every Monday at 6 AM UTC workflow_dispatch: inputs: nightly_tag: @@ -15,8 +15,11 @@ concurrency: cancel-in-progress: true jobs: - real-proving-benchmark: + select-image: runs-on: ubuntu-latest + outputs: + nightly_tag: ${{ steps.nightly-tag.outputs.nightly_tag }} + docker_image: ${{ steps.nightly-tag.outputs.docker_image }} steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd @@ -32,12 +35,15 @@ jobs: current_version=$(jq -r '."."' .release-please-manifest.json) nightly_tag="${current_version}-nightly.$(date -u +%Y%m%d)" fi - echo "nightly_tag=$nightly_tag" >> $GITHUB_OUTPUT + + docker_image="aztecprotocol/aztec:${nightly_tag}" + echo "nightly_tag=$nightly_tag" >> "$GITHUB_OUTPUT" + echo "docker_image=$docker_image" >> "$GITHUB_OUTPUT" echo "Using nightly tag: $nightly_tag" - name: Check if Docker image exists run: | - DOCKER_IMAGE="aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" + DOCKER_IMAGE="${{ steps.nightly-tag.outputs.docker_image }}" echo "Checking if Docker image exists: $DOCKER_IMAGE" if docker manifest inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then echo "Docker image exists: $DOCKER_IMAGE" @@ -46,6 +52,53 @@ jobs: exit 1 fi + deploy-real-proving-network: + needs: select-image + uses: ./.github/workflows/deploy-network.yml + with: + network: prove-n-tps-real + namespace: prove-n-tps-real + aztec_docker_image: ${{ needs.select-image.outputs.docker_image }} + ref: next + notify_on_failure: false + secrets: inherit + + wait-for-first-l2-block: + needs: deploy-real-proving-network + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} + + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a + with: + install_components: gke-gcloud-auth-plugin + + - name: Wait for first L2 block + env: + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + run: | + cd spartan + ./bootstrap.sh wait_for_l2_block prove-n-tps-real + + benchmark: + needs: wait-for-first-l2-block + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Run real proving benchmarks timeout-minutes: 180 env: @@ -59,20 +112,9 @@ jobs: RUN_ID: ${{ github.run_id }} AWS_SHUTDOWN_TIME: 180 NO_SPOT: 1 + SKIP_NETWORK_DEPLOY: "1" run: | - ./.github/ci3.sh network-proving-bench prove-n-tps-real prove-n-tps-real "aztecprotocol/aztec:${{ steps.nightly-tag.outputs.nightly_tag }}" - - - name: Cleanup network resources - if: always() - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} - BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} - GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - NO_SPOT: 1 - run: ./.github/ci3.sh network-teardown prove-n-tps-real prove-n-tps-real + ./.github/ci3.sh network-proving-bench prove-n-tps-real prove-n-tps-real - name: Download benchmarks if: always() @@ -81,7 +123,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | if ./ci.sh gh-spartan-proving-bench; then - echo "ENABLE_DEPLOY_BENCH=1" >> $GITHUB_ENV + echo "ENABLE_DEPLOY_BENCH=1" >> "$GITHUB_ENV" fi - name: Upload benchmarks @@ -100,13 +142,52 @@ jobs: fail-on-alert: false max-items-in-chart: 100 + cleanup: + if: always() + needs: + - select-image + - deploy-real-proving-network + - wait-for-first-l2-block + - benchmark + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + + - name: Cleanup network resources + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NO_SPOT: 1 + run: ./.github/ci3.sh network-teardown prove-n-tps-real prove-n-tps-real + + notify-failure: + if: ${{ always() && failure() && github.event_name != 'workflow_dispatch' }} + needs: + - select-image + - deploy-real-proving-network + - wait-for-first-l2-block + - benchmark + - cleanup + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: next + - name: Notify Slack and dispatch ClaudeBox on failure - if: failure() && github.event_name != 'workflow_dispatch' env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} run: | - TAG="${{ steps.nightly-tag.outputs.nightly_tag }}" + TAG="${{ needs.select-image.outputs.nightly_tag || 'unknown' }}" RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" ./ci3/slack_notify_with_claudebox_kickoff "#alerts-next-scenario" \ "Weekly Real Proving Benchmark FAILED (nightly tag ${TAG}): <${RUN_URL}|View Run> (🤖)" \ diff --git a/.test_patterns.yml b/.test_patterns.yml index aaa4e6dadca2..299706444e55 100644 --- a/.test_patterns.yml +++ b/.test_patterns.yml @@ -116,9 +116,7 @@ tests: error_regex: "✕ Repay" owners: - *lasse - # http://ci.aztec-labs.com/e85ff6c5da65a1e7 - - regex: "src/e2e_cross_chain_messaging/l1_to_l2.test.ts" - error_regex: "Failed to advance block" + - regex: "src/e2e_cross_chain_messaging/l1_to_l2" owners: - *palla - regex: "src/e2e_cross_chain_messaging/token_bridge_private" @@ -141,6 +139,10 @@ tests: error_regex: "Anvil failed to stop in time|Cannot read properties of undefined" owners: - *palla + - regex: "src/e2e_bot.test.ts" + error_regex: "Tx dropped" + owners: + - *palla # yarn-project tests # Attempt to catch all kv-store browser test failures (consider them quarantined for now) @@ -164,6 +166,10 @@ tests: error_regex: "Error: Timeout of 2000ms exceeded" owners: - *martin + - regex: "kv-store/.*store\\.test" + error_regex: "guards against too many cursors" + owners: + - *palla - regex: "ethereum/src/test/tx_delayer.test.ts" error_regex: "delays a transaction until a given L1 timestamp" owners: @@ -172,6 +178,18 @@ tests: error_regex: "ContractFunctionExecutionError: The contract function" owners: - *mitch + # Under proposer pipelining each validator votes in its own slot and the votes + # don't aggregate into the same round, so the slashing quorum (3) is never + # reached within the 414s budget; the test consistently times out at the docker + # outer 600s (exit 124). The publisher refactor lands all vote-offenses tx's + # on L1 successfully — voteCount on the slasher proposer simply stays at 1 + # per round. This is a slashing-payload aggregation issue independent of + # publisher work; skip until the slashing team addresses it separately. + - regex: "e2e_p2p/valid_epoch_pruned_slash.test.ts" + skip: true + owners: + - *mitch + - *palla - regex: "archiver/src/archiver/archiver.test.ts" error_regex: "Received number of calls: 1" owners: @@ -185,14 +203,6 @@ tests: - *phil - *palla - # http://ci.aztec-labs.com/64a972aafaa40dd0 - # ProvingBroker › Retries › does not retry if job is stale — kv-store closes - # before the broker's final reportProvingJobError write lands. - - regex: "prover-client/src/proving_broker/proving_broker.test.ts" - error_regex: "does not retry if job is stale|Store is closed" - owners: - - *alex - # Nightly GKE tests - regex: "spartan/bootstrap.sh" owners: @@ -347,11 +357,42 @@ tests: owners: - *esau + # http://ci.aztec-labs.com/6db6103599cb22e6 + # Under pipelining, the lazy validator's attestation can arrive after the + # p2p checkpoint-attestation-validator's acceptance window, getting rejected + # before the slasher's gossip callback fires. The slasher then never records + # ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL and the test times out. + - regex: "src/e2e_slashing/attested_invalid_proposal.test.ts" + error_regex: "Timeout awaiting honest validator slash offenses for invalid proposal attestation" + owners: + - *palla + + # HA full suite is unstable under HA pipelining: multiple distinct failure + # modes (governance vote coord, work distribution, afterAll teardown hook + # timeouts, peer races on checkpoint proposals — see #23344, #23541, + # ci.aztec-labs.com/136431da99834194). Flagging individual error_regex + # entries and even the whole-suite flake match still let it dequeue PRs + # because ci3 retries once and the suite fails both attempts. Skip + # outright on merge-train/spartan until HA pipelining stabilises. - regex: "yarn-project/end-to-end/scripts/run_test.sh ha src/composed/ha/e2e_ha_full.test.ts" - error_regex: "✕ should coordinate governance voting across HA nodes" + skip: true owners: - *spyros + # Multi-validator web3signer suite is unstable under proposer pipelining: + # two distinct failure modes have been seen in the same "should build blocks + # & attest with multiple validator keys" case — Promise.all index-0 + # waitForTx aborting with "Tx dropped by P2P node" + # (ci.aztec-labs.com/9a5fa90aa18f62e7), and the proposer missing the slot's + # 5-attestation deadline ("AttestationTimeoutError" / "Block .* not found .* + # reorg") on PR #23344 run 26370196367 (ci.aztec-labs.com/b91d3218b5e88ae4). + # Error-regex flake matches still let ci3 retry-and-fail both attempts. Skip + # outright on merge-train/spartan until proposer pipelining stabilises. + - regex: "yarn-project/end-to-end/scripts/run_test.sh web3signer src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts" + skip: true + owners: + - *palla + # http://ci.aztec-labs.com/98d59d04f85223f8 # Build-cache flake: module not found during Jest startup - regex: "src/e2e_sequencer/gov_proposal.parallel.test.ts" @@ -374,3 +415,11 @@ tests: error_regex: "✕ verifies transactions at 10 TPS" owners: - *phil + + # http://ci.aztec-labs.com/930ddc9ede87059f + # Pipelining race: slasher doesn't record the duplicate proposal offense before + # the test's wait timeout — same family as #23501. + - regex: "src/e2e_p2p/duplicate_proposal_slash.test.ts" + error_regex: "TimeoutError: Timeout awaiting duplicate proposal offense" + owners: + - *palla diff --git a/avm-transpiler/src/procedures/compiler.rs b/avm-transpiler/src/procedures/compiler.rs index c3789e48b221..8cd6091881d6 100644 --- a/avm-transpiler/src/procedures/compiler.rs +++ b/avm-transpiler/src/procedures/compiler.rs @@ -233,10 +233,8 @@ fn compile_opcode( Mnemonic::ECADD => { collector.memory_address_operand()?; // p1 x collector.memory_address_operand()?; // p1 y - collector.memory_address_operand()?; // p1 is_infinite collector.memory_address_operand()?; // p2 x collector.memory_address_operand()?; // p2 y - collector.memory_address_operand()?; // p2 is_infinite collector.memory_address_operand()?; // result let collection = collector.finish()?; result.add_instruction( diff --git a/avm-transpiler/src/procedures/msm.rs b/avm-transpiler/src/procedures/msm.rs index f00f3504bb46..f952ae0ddac3 100644 --- a/avm-transpiler/src/procedures/msm.rs +++ b/avm-transpiler/src/procedures/msm.rs @@ -1,15 +1,13 @@ pub(crate) const MSM_ASSEMBLY: &str = " ; We are passed three pointers and one usize. - ; d0 points to the points. Points are represented by (x: Field, y: Field, is_infinite: bool) + ; d0 points to the points. Points are represented by (x: Field, y: Field). ; d1 points to the scalars. Scalars are represented by (lo: Field, hi: Field) both range checked to 128 bits. ; d2 contains the number of points. ; d3 points to the result. The result is a point. ADD d3, /*the reserved register 'one_usize'*/ $2, d4; Compute the pointer to the result y. - ADD d4, $2, d5; Compute the pointer to the result is_infinite ; Initialize the msm result: point at infinity SET i3, 0 ff SET i4, 0 ff - SET i5, 1 u1 ; Loop globals SET d6, 0 u32; Initialize the outer loop variable, ranging from 0 to the number of points SET d8, 0 ff; Initialize a 0 FF @@ -18,13 +16,12 @@ pub(crate) const MSM_ASSEMBLY: &str = " SET d10, 128 u32; Initialize a constant 128 SET d11, 1 u1; Initialize a constant true SET d12, 0 u1; Initialize a constant false - SET d13, 2 u32; Initialize a constant 2 - SET d14, 3 u32; Initialize a constant 3 for computing pointers to the point components + SET d13, 2 u32; Initialize a constant 2 for computing pointers to point and scalar components ; Main loop: iterate over the points/scalars OUTER_HEAD: LT d6, d2, d15 ; Check if we are done with the outer loop JUMPI d15, OUTER_BODY JUMP OUTER_END -OUTER_BODY: MUL d6, d14, d16; Compute the pointer to the point +OUTER_BODY: MUL d6, d13, d16; Compute the pointer to the point ADD d16, d0, d16; MUL d6, d13, d17; Compute the pointer to the scalar lo ADD d17, d1, d17 @@ -51,16 +48,13 @@ FIND_MSB_BODY: JUMPI i19, FIND_MSB_END; Check if the current bit is one JUMP FIND_MSB_BODY ; Now we have the pointer of the MSB in d19 - ; Now store the result of the scalar multiplication in d22, d23, d24 + ; Now store the result of the scalar multiplication in d22, d23 FIND_MSB_END: MOV i16, d22; x ADD d16, $2, d25; pointer to y MOV i25, d23; y - ADD d25, $2, d25; pointer to is_infinite - MOV i25, d24; is_infinite - ; Also store the original point in d25, d26, d27 + ; Also store the original point in d25, d26 MOV d22, d25; x MOV d23, d26; y - MOV d24, d27; is_infinite ; Now we need to do the inner loop, that will do double then add ; We need to iterate from the pointer of the MSB + 1 to the end pointer (d21) @@ -68,18 +62,18 @@ FIND_MSB_END: MOV i16, d22; x INNER_HEAD: LT d19, d21, d28; Check if we are done with the loop JUMPI d28, INNER_BODY JUMP INNER_END -INNER_BODY: ECADD d22, d23, d24, d22, d23, d24, /*not indirect, so the result is stored in d22, d23, d24*/ d22; Double the current result. +INNER_BODY: ECADD d22, d23, d22, d23, /*not indirect, so the result is stored in d22, d23*/ d22; Double the current result. EQ i19, d12, d28; Check if the current bit is zero JUMPI d28, INNER_INC; If the current bit is zero, continue - ECADD d25, d26, d27, d22, d23, d24, /*not indirect, so the result is stored in d22, d23, d24*/ d22; Add the original point to the result + ECADD d25, d26, d22, d23, /*not indirect, so the result is stored in d22, d23*/ d22; Add the original point to the result INNER_INC: ADD d19, $2, d19; Increment the pointer JUMP INNER_HEAD ; After the inner loop we have computed the scalar multiplication. Add it to the msm result -INNER_END: ECADD i3, i4, i5, d22, d23, d24, i3; Add the result to the msm result +INNER_END: ECADD i3, i4, d22, d23, i3; Add the result to the msm result OUTER_INC: ADD d6, $2, d6; Increment the outer loop variable JUMP OUTER_HEAD - ; After the outer loop we have computed the msm. We can return since we wrote the result in i3, i4, i5 + ; After the outer loop we have computed the msm. We can return since we wrote the result in i3, i4 OUTER_END: INTERNALRETURN "; diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 40e3a6f0bb4f..2380c95ce34e 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -1280,32 +1280,26 @@ fn handle_black_box_function( BlackBoxOp::EmbeddedCurveAdd { input1_x: p1_x_offset, input1_y: p1_y_offset, - input1_infinite: p1_infinite_offset, input2_x: p2_x_offset, input2_y: p2_y_offset, - input2_infinite: p2_infinite_offset, result, } => avm_instrs.push(AvmInstruction { opcode: AvmOpcode::ECADD, - // The result (SIXTH operand) is indirect (addressing mode). + // The result (FOURTH operand) is indirect (addressing mode). addressing_mode: Some( AddressingModeBuilder::default() .direct_operand(p1_x_offset) .direct_operand(p1_y_offset) - .direct_operand(p1_infinite_offset) .direct_operand(p2_x_offset) .direct_operand(p2_y_offset) - .direct_operand(p2_infinite_offset) .indirect_operand(&result.pointer) .build(), ), operands: vec![ AvmOperand::U16 { value: p1_x_offset.to_u32() as u16 }, AvmOperand::U16 { value: p1_y_offset.to_u32() as u16 }, - AvmOperand::U16 { value: p1_infinite_offset.to_u32() as u16 }, AvmOperand::U16 { value: p2_x_offset.to_u32() as u16 }, AvmOperand::U16 { value: p2_y_offset.to_u32() as u16 }, - AvmOperand::U16 { value: p2_infinite_offset.to_u32() as u16 }, AvmOperand::U16 { value: result.pointer.to_u32() as u16 }, ], ..Default::default() @@ -1313,20 +1307,19 @@ fn handle_black_box_function( BlackBoxOp::MultiScalarMul { points, scalars, outputs } => { // The length of the scalars vector is 2x the length of the points vector due to limb - // decomposition - // Output array is fixed to 3 + // decomposition. Points are (x, y); the point at infinity is encoded as (0, 0). assert_eq!( outputs.size, - SemiFlattenedLength(3), - "Output array size must be equal to 3" + SemiFlattenedLength(2), + "Output array size must be equal to 2" ); - assert_eq!(points.size.0 % 3, 0, "Points array size must be divisible by 3"); + assert_eq!(points.size.0 % 2, 0, "Points array size must be divisible by 2"); avm_instrs.push(generate_mov_to_procedure(&points.pointer, 0)); avm_instrs.push(generate_mov_to_procedure(&scalars.pointer, 1)); avm_instrs.push(generate_set_to_procedure( AvmTypeTag::UINT32, - &FieldElement::from(points.size.0 / 3), + &FieldElement::from(points.size.0 / 2), 2, )); avm_instrs.push(generate_mov_to_procedure(&outputs.pointer, 3)); @@ -1634,6 +1627,7 @@ fn handle_get_contract_instance( DEPLOYER, CLASS_ID, INIT_HASH, + IMMUTABLES_HASH, } assert_eq!(inputs.len(), 1); @@ -1643,6 +1637,7 @@ fn handle_get_contract_instance( "aztec_avm_getContractInstanceDeployer" => ContractInstanceMember::DEPLOYER, "aztec_avm_getContractInstanceClassId" => ContractInstanceMember::CLASS_ID, "aztec_avm_getContractInstanceInitializationHash" => ContractInstanceMember::INIT_HASH, + "aztec_avm_getContractInstanceImmutablesHash" => ContractInstanceMember::IMMUTABLES_HASH, _ => panic!("Transpiler doesn't know how to process function {:?}", function), }; diff --git a/aztec-up/bootstrap.sh b/aztec-up/bootstrap.sh index dad8802868d8..4618253bca97 100755 --- a/aztec-up/bootstrap.sh +++ b/aztec-up/bootstrap.sh @@ -20,6 +20,9 @@ function build { echo # Create Verdaccio config. + # publish.allow_offline lets verdaccio accept publishes when the npmjs + # uplink is briefly unreachable, instead of returning 503. We never want + # the upstream existence check to gate these local fake-publishes. cat > /tmp/verdaccio-config.yaml < P == -Q (INVERSE_PRED == true): // R := O // If P == O: - // R := Q (r_x := q_x, r_y := q_y, r_is_inf = q_is_inf) + // R := Q (r_x := q_x, r_y := q_y) // Vice versa, if Q == O: - // R := P (r_x := p_x, r_y := p_y, r_is_inf = p_is_inf) + // R := P (r_x := p_x, r_y := p_y) // pol INVERSE_PRED = x_match * (1 - y_match); @@ -182,6 +191,4 @@ namespace ecc; sel * (r_x - (EITHER_INF * (p_is_inf * q_x + q_is_inf * p_x)) - result_infinity * INFINITY_X - use_computed_result * COMPUTED_R_X) = 0; #[OUTPUT_Y_COORD] sel * (r_y - (EITHER_INF * (p_is_inf * q_y + q_is_inf * p_y)) - result_infinity * INFINITY_Y - use_computed_result * COMPUTED_R_Y) = 0; - #[OUTPUT_INF_FLAG] - sel * (r_is_inf - result_infinity) = 0; diff --git a/barretenberg/cpp/pil/vm2/ecc_mem.pil b/barretenberg/cpp/pil/vm2/ecc_mem.pil index efd63ca6814c..e7d6d41e01e1 100644 --- a/barretenberg/cpp/pil/vm2/ecc_mem.pil +++ b/barretenberg/cpp/pil/vm2/ecc_mem.pil @@ -8,28 +8,29 @@ include "precomputed.pil"; * This handles the memory writes when the ECADD opcode is executed by user code. * Given two points, P & Q, this trace constrains that both exist on the Grumpkin curve * and the claimed result point, R = P + Q, is written to memory addresses within range. + * A point exists on the curve if it satisfies the curve equation (SW form: Y^2 = X^3 − 17) + * or is the point at infinity, represented by (X, Y) = (INFINITY_X, INFINITY_Y) = (0, 0). * The reads of P and Q are handled by the registers in the execution trace. The correctness * of point addition is handled by the ECC subtrace. * * This trace writes the resulting embedded curve point to the addresses {dst, - * dst + 1, and dst + 2 }. Embedded curve points consist of the tuple of types - * {x: FF, y: FF, is_inf: U1 }. + * dst + 1 }. Embedded curve points consist of the tuple of types {x: FF, y: FF }. * - * PRECONDITIONS: Input point coordinates have tag checked FF coordinates and U1 is_inf - * flag (see Memory I/O below for details). + * PRECONDITIONS: Input point coordinates have tag checked FF coordinates (see Memory I/O + * below for details). * * USAGE: Dispatching lookup defined in execution.pil: * #[DISPATCH_TO_ECC_ADD] * sel_exec_dispatch_ecc_add { * clk, context_id, - * register[0], register[1], register[2], // Point P - * register[3], register[4], register[5], // Point Q - * rop[6], // Dst address + * register[0], register[1], // Point P + * register[2], register[3], // Point Q + * rop[4], // Dst address * sel_opcode_error // Error * } is ecc_add_mem.sel { * ecc_add_mem.execution_clk, ecc_add_mem.space_id, - * ecc_add_mem.p_x, ecc_add_mem.p_y, ecc_add_mem.p_is_inf, // Point P - * ecc_add_mem.q_x, ecc_add_mem.q_y, ecc_add_mem.q_is_inf, // Point Q + * ecc_add_mem.p_x, ecc_add_mem.p_y, // Point P + * ecc_add_mem.q_x, ecc_add_mem.q_y, // Point Q * ecc_add_mem.dst_addr[0], // Dst address * ecc_add_mem.err // Error * }; @@ -37,38 +38,30 @@ include "precomputed.pil"; * Opcode operands (relevant in EXECUTION when interacting with this gadget): * - rop[0]: p_x_addr * - rop[1]: p_y_addr - * - rop[2]: p_is_inf_addr - * - rop[3]: q_x_addr - * - rop[4]: q_y_addr - * - rop[5]: q_is_inf_addr - * - rop[6]: dst_addr + * - rop[2]: q_x_addr + * - rop[3]: q_y_addr + * - rop[4]: dst_addr * * Memory I/O: * - register[0]: M[p_x_addr] aka p_x (x coordinate of point P - read from memory by EXECUTION) * - p_x is tagged-checked by execution/registers to be FF based on instruction spec. * - register[1]: M[p_y_addr] aka p_y (y coordinate of point P - read from memory by EXECUTION) * - p_y is tagged-checked by execution/registers to be FF based on instruction spec. - * - register[2]: M[p_is_inf_addr] aka p_is_inf (boolean flag if P is the point at infinity - read from memory by EXECUTION) - * - p_is_inf is tagged-checked by execution/registers to be U1 based on instruction spec. - * - register[3]: M[q_x_addr] aka q_x (x coordinate of point Q - read from memory by EXECUTION) + * - register[2]: M[q_x_addr] aka q_x (x coordinate of point Q - read from memory by EXECUTION) * - q_x is tagged-checked by execution/registers to be FF based on instruction spec. - * - register[4]: M[q_y_addr] aka q_y (y coordinate of point Q - read from memory by EXECUTION) + * - register[3]: M[q_y_addr] aka q_y (y coordinate of point Q - read from memory by EXECUTION) * - q_y is tagged-checked by execution/registers to be FF based on instruction spec. - * - register[5]: M[q_is_inf_addr] aka q_is_inf (boolean flag if Q is the point at infinity - read from memory by EXECUTION) - * - q_is_inf is tagged-checked by execution/registers to be U1 based on instruction spec. - * - M[rop[6]]: M[dst_addr] aka res_x (x coordinate of the resulting point RES - written by this gadget) + * - M[rop[4]]: M[dst_addr] aka res_x (x coordinate of the resulting point RES - written by this gadget) * - guaranteed by this gadget to be FF. - * - M[rop[6]+1]: M[dst_offset+1] aka res_y (y coordinate of the resulting point RES - written by this gadget) + * - M[rop[4]+1]: M[dst_offset+1] aka res_y (y coordinate of the resulting point RES - written by this gadget) * - guaranteed by this gadget to be FF. - * - M[rop[6]+2]: M[dst_offset+2] aka res_is_inf (boolean flag if RES is the point at infinity - written by this gadget) - * - guaranteed by this gadget to be U1. * * ERROR HANDLING: * Two errors need to be handled as part of this trace, * (1) DST_OUT_OF_BOUNDS_ACCESS: If the writes would access a memory address outside * of the max AVM memory address (AVM_HIGHEST_MEM_ADDRESS). * (2) POINT_NOT_ON_CURVE: If either of the inputs (embedded curve points) do not - * satisfy the Grumpkin curve equation (SW form: Y^2 = X^3 − 17) + * exist on the Grumpkin curve. * * TRACE SHAPE: This subtrace writes the values within 1 single row (i.e. 3 output columns) * @@ -78,19 +71,27 @@ include "precomputed.pil"; * --> gt.pil * This subtrace is looked up by: * - execution.pil: To constrain the dispatch permutation for the ECADD opcode (#[DISPATCH_TO_ECC_ADD]). Includes memory - * reads (register[0] to register[5]), the initial write address (rop[6]), and error flag (sel_opcode_error). + * reads (register[0] to register[3]), the initial write address (rop[4]), and error flag (sel_opcode_error). * * This subtrace looks up: - * - memory.pil: To write the output point values (res_x, res_y, res_is_inf) to memory with standard write permutations - * (#[WRITE_MEM_i] for i = 0, 1, 2). + * - memory.pil: To write the output point values (res_x, res_y) to memory with standard write permutations + * (#[WRITE_MEM_i] for i = 0, 1). * - ecc.pil: To retrieve the output point R as the result of adding the points P and Q read from memory * (#[INPUT_OUTPUT_ECC_ADD]). See below for details on infinity points. * - gt.pil: To constrain that the maximum written memory address is within range (#[CHECK_DST_ADDR_IN_RANGE]). * - * This subtrace is connected to the ECC subtrace via a lookup. ECC is used by - * other subtraces internally (e.g., address derivation). We re-map any input infinity points to (0, 0) - * so ECC correctly manages edge cases. Resulting infinity points are guaranteed to be (0, 0) by the - * ECC subtrace (see #[OUTPUT_X_COORD] and #[OUTPUT_Y_COORD]). + * This subtrace is connected to the ECC subtrace via a lookup. ECC is used by other subtraces internally + * (e.g. address derivation). Now that the is_inf flag has been removed from noir (noir-lang/noir/#11926/) we consider + * a point to be infinity iff its coordinates are (0, 0); the noir standard representation (see relations #[P/Q_INF_X/Y_CHECK]). + * + * Note that the point at infinity, O, does not have valid coordinates (a property of SW curves like Grumpkin). We represent it + * as (0, 0) but any (ecc.INFINITY_X, ecc.INFINITY_Y) not satisfying the curve equation will be correctly handled in this trace. + * + * The ECC subtrace requires a correctly constrained is_inf flag for each point. We derive it within this circuit by enforcing + * (0, 0) <==> is_inf for input points P and Q: + * - (0, 0) ==> is_inf by #[P/Q_ON_CURVE_CHECK] (zero coordinates will fail this relation unless is_inf is set correctly). + * - is_inf ==> (0, 0) by #[P/Q_INF_X/Y_CHECK]. + * Resulting infinity points are guaranteed to be (0, 0) by the ECC subtrace (see #[OUTPUT_X_COORD] and #[OUTPUT_Y_COORD]). */ namespace ecc_add_mem; @@ -103,16 +104,17 @@ namespace ecc_add_mem; pol commit execution_clk; pol commit space_id; - pol commit dst_addr[3]; + pol commit dst_addr[2]; // dst_addr[0] constrained by the permutation to execution #[WRITE_INCR_DST_ADDR] dst_addr[1] = sel * (dst_addr[0] + 1); - dst_addr[2] = sel * (dst_addr[0] + 2); - // p_is_inf, q_is_inf are constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD]) - pol commit p_x, p_y, p_is_inf; - pol commit q_x, q_y, q_is_inf; + pol commit p_x, p_y; + pol commit q_x, q_y; + + // Needs to be committed columns as they are used in the lookups + pol commit p_is_inf, q_is_inf; // constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD]) //////////////////////////////////////////////// // Error Handling - Out of Range Memory Access @@ -121,15 +123,15 @@ namespace ecc_add_mem; // Use the comparison gadget to check that the max addresses are within range // The comparison gadget provides the ability to test GreaterThan so we check - // dst_addr[2] > max_mem_addr + // dst_addr[1] > max_mem_addr pol commit max_mem_addr; // Column needed until we support constants in lookups sel * (max_mem_addr - constants.AVM_HIGHEST_MEM_ADDRESS) = 0; // Preconditions to `gt` gadget require both inputs to be bounded by 2^128. - // `dst_addr[2]` = dst_addr[0] + 2 where dst_addr[0] is an address (< 2^32), so dst_addr[2] < 2^33. + // `dst_addr[1]` = dst_addr[0] + 1 where dst_addr[0] is an address (< 2^32), so dst_addr[1] < 2^33. // `max_mem_addr` = AVM_HIGHEST_MEM_ADDRESS which is < 2^32. #[CHECK_DST_ADDR_IN_RANGE] - sel { dst_addr[2], max_mem_addr, sel_dst_out_of_range_err } + sel { dst_addr[1], max_mem_addr, sel_dst_out_of_range_err } in gt.sel_others { gt.input_a, gt.input_b, gt.res }; @@ -142,6 +144,8 @@ namespace ecc_add_mem; pol commit sel_q_not_on_curve_err; // @boolean sel_q_not_on_curve_err * (1 - sel_q_not_on_curve_err) = 0; + // Note: The below additionally constrains that (X, Y) == (INFINITY_X, INFINITY_Y) ==> is_inf. See above description. + // Y^2 = X^3 − 17, re-formulate to Y^2 - (X^3 - 17) = 0 pol commit p_is_on_curve_eqn; // Needs to be committed to reduce relation degrees pol P_X3 = p_x * p_x * p_x; @@ -170,32 +174,31 @@ namespace ecc_add_mem; /////////////////////////////////////////////////////////////////////// // Dispatch inputs to ecc add and retrieve outputs /////////////////////////////////////////////////////////////////////// - pol commit res_x, res_y, res_is_inf; // res_is_inf is constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD]) + pol commit res_x, res_y; pol commit sel_should_exec; // @boolean (by definition) sel_should_exec = sel * (1 - err); - // Needs to be committed columns as they are used in the lookups - pol commit p_x_n, p_y_n; - pol commit q_x_n, q_y_n; - - // We re-map input infinity points to (0, 0) for ecc.pil. Output infinities are already constrained to be (0, 0) in the subtrace. - // Note that we cannot use p_x, p_y, etc. because they are read from memory in execution's #[DISPATCH_TO_ECC_ADD]. - sel_should_exec * (p_x_n - (1 - p_is_inf) * p_x - p_is_inf * ecc.INFINITY_X) = 0; - sel_should_exec * (p_y_n - (1 - p_is_inf) * p_y - p_is_inf * ecc.INFINITY_Y) = 0; - sel_should_exec * (q_x_n - (1 - q_is_inf) * q_x - q_is_inf * ecc.INFINITY_X) = 0; - sel_should_exec * (q_y_n - (1 - q_is_inf) * q_y - q_is_inf * ecc.INFINITY_Y) = 0; + // Constrains that the infinity flags required for the ecc trace have been set correctly: + #[P_INF_X_CHECK] + sel * p_is_inf * (p_x - ecc.INFINITY_X) = 0; + #[P_INF_Y_CHECK] + sel * p_is_inf * (p_y - ecc.INFINITY_Y) = 0; + #[Q_INF_X_CHECK] + sel * q_is_inf * (q_x - ecc.INFINITY_X) = 0; + #[Q_INF_Y_CHECK] + sel * q_is_inf * (q_y - ecc.INFINITY_Y) = 0; #[INPUT_OUTPUT_ECC_ADD] sel_should_exec { - p_x_n, p_y_n, p_is_inf, - q_x_n, q_y_n, q_is_inf, - res_x, res_y, res_is_inf + p_x, p_y, p_is_inf, + q_x, q_y, q_is_inf, + res_x, res_y } in ecc.sel { ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.q_x, ecc.q_y, ecc.q_is_inf, - ecc.r_x, ecc.r_y, ecc.r_is_inf + ecc.r_x, ecc.r_y }; //////////////////////////////////////////////// @@ -216,12 +219,3 @@ namespace ecc_add_mem; memory.sel_ecc_write[1] { memory.clk, memory.space_id, memory.address, memory.value, memory.tag, memory.rw }; - - #[WRITE_MEM_2] - sel_should_exec { - execution_clk, space_id, dst_addr[2], res_is_inf, /*U1_mem_tag=1*/ sel_should_exec, /*rw=1*/ sel_should_exec - } is - memory.sel_ecc_write[2] { - memory.clk, memory.space_id, memory.address, memory.value, memory.tag, memory.rw - }; - diff --git a/barretenberg/cpp/pil/vm2/execution.pil b/barretenberg/cpp/pil/vm2/execution.pil index 98bffa729581..fd7f7a2e217f 100644 --- a/barretenberg/cpp/pil/vm2/execution.pil +++ b/barretenberg/cpp/pil/vm2/execution.pil @@ -1277,10 +1277,10 @@ sel_exec_dispatch_keccakf1600 { }; // ECADD DISPATCHING -// Each input point uses 3 registers: -// P = [x, y, is_inf] -> register[0..2], Q = [x, y, is_inf] -> register[3..5] +// Each input point uses 2 registers: +// P = [x, y] -> register[0..1], Q = [x, y] -> register[2..3] // The output point is written to memory internally inside the ecc_add_mem (ecc_mem.pil) trace, starting at: -// dst_addr[0] -> rop[6] +// dst_addr[0] -> rop[4] // Outputs (#[WRITE_MEM_x]) and memory write checks (#[CHECK_DST_ADDR_IN_RANGE]) are hence handled by the trace. #[DISPATCH_TO_ECC_ADD] @@ -1290,13 +1290,11 @@ sel_exec_dispatch_ecc_add { // Point P register[0], register[1], - register[2], // Point Q + register[2], register[3], - register[4], - register[5], // Dst address - rop[6], + rop[4], // Error sel_opcode_error } is ecc_add_mem.sel { @@ -1305,11 +1303,9 @@ sel_exec_dispatch_ecc_add { // Point P ecc_add_mem.p_x, ecc_add_mem.p_y, - ecc_add_mem.p_is_inf, // Point Q ecc_add_mem.q_x, ecc_add_mem.q_y, - ecc_add_mem.q_is_inf, // Dst address ecc_add_mem.dst_addr[0], // Error diff --git a/barretenberg/cpp/pil/vm2/memory.pil b/barretenberg/cpp/pil/vm2/memory.pil index ed27382c2dc5..be46a78734a9 100644 --- a/barretenberg/cpp/pil/vm2/memory.pil +++ b/barretenberg/cpp/pil/vm2/memory.pil @@ -175,10 +175,9 @@ sel_sha256_op[6] * (1 - sel_sha256_op[6]) = 0; sel_sha256_op[7] * (1 - sel_sha256_op[7]) = 0; // Permutation selectors (ecc_mem.pil). -pol commit sel_ecc_write[3]; // @boolean +pol commit sel_ecc_write[2]; // @boolean sel_ecc_write[0] * (1 - sel_ecc_write[0]) = 0; sel_ecc_write[1] * (1 - sel_ecc_write[1]) = 0; -sel_ecc_write[2] * (1 - sel_ecc_write[2]) = 0; // Permutation selectors (to_radix_mem.pil). pol commit sel_to_radix_write; // @boolean @@ -212,7 +211,7 @@ sel = // Addressing. + sel_sha256_op[0] + sel_sha256_op[1] + sel_sha256_op[2] + sel_sha256_op[3] + sel_sha256_op[4] + sel_sha256_op[5] + sel_sha256_op[6] + sel_sha256_op[7] // ECC. - + sel_ecc_write[0] + sel_ecc_write[1] + sel_ecc_write[2] + + sel_ecc_write[0] + sel_ecc_write[1] // To Radix. + sel_to_radix_write; diff --git a/barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil b/barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil index 0cea9409ff82..38bbbad882bb 100644 --- a/barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil +++ b/barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil @@ -11,16 +11,17 @@ include "../precomputed.pil"; * - Bounds-check dst_offset+1 via #[WRITE_OUT_OF_BOUNDS_CHECK]. If dst_offset is the * maximum valid address, dst_offset+1 would be out of bounds. * - Look up member_enum in the precomputed table (#[PRECOMPUTED_INFO]) to determine - * validity and which member is selected (deployer, class_id, or init_hash). + * validity and which member is selected (deployer, class_id, init_hash or immutables_hash). * The precomputed table covers the full 8-bit range: - * +-------+----------------------+-------------+-------------+--------------+ - * | idx | is_valid_member_enum | is_deployer | is_class_id | is_init_hash | - * +-------+----------------------+-------------+-------------+--------------+ - * | 0 | 1 | 1 | 0 | 0 | - * | 1 | 1 | 0 | 1 | 0 | - * | 2 | 1 | 0 | 0 | 1 | - * | 3+ | 0 | 0 | 0 | 0 | - * +-------+----------------------+-------------+-------------+--------------+ + * +-------+----------------------+-------------+-------------+--------------+--------------------+ + * | idx | is_valid_member_enum | is_deployer | is_class_id | is_init_hash | is_immutables_hash | + * +-------+----------------------+-------------+-------------+--------------+--------------------+ + * | 0 | 1 | 1 | 0 | 0 | 0 | + * | 1 | 1 | 0 | 1 | 0 | 0 | + * | 2 | 1 | 0 | 0 | 1 | 0 | + * | 3 | 1 | 0 | 0 | 0 | 1 | + * | 4+ | 0 | 0 | 0 | 0 | 0 | + * +-------+----------------------+-------------+-------------+--------------+--------------------+ * - Aggregate errors via #[ERROR_AGGREGATION]. sel_error is set when either * is_valid_writes_in_bounds or is_valid_member_enum is false. * - [no error only] Retrieve contract instance via the ContractInstanceRetrieval gadget @@ -72,7 +73,7 @@ include "../precomputed.pil"; * ERROR HANDLING: * Two error conditions, which are NOT mutually exclusive: * - Write out-of-bounds: dst_offset == AVM_HIGHEST_MEM_ADDRESS (dst_offset+1 overflows). - * - Invalid member enum: member_enum >= 3 (precomputed table returns is_valid_member_enum=0). + * - Invalid member enum: member_enum >= 4 (precomputed table returns is_valid_member_enum=0). * On error, the row has sel_error=1. The contract instance retrieval lookup and memory * write permutations are disabled (their selectors is_valid_member_enum / is_valid_writes_in_bounds * are 0), so no destination interactions fire for error rows. @@ -121,13 +122,14 @@ namespace get_contract_instance; // (from precomputed.pil's GETCONTRACTINSTANCE opcode precomputed columns) // These are constrained only via the #[PRECOMPUTED_INFO] lookup when is_valid_writes_in_bounds == 1. // When the lookup is disabled (writes out of bounds), is_valid_member_enum is forced to 0 by - // #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]. is_deployer/is_class_id/is_init_hash + // #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]. is_deployer/is_class_id/is_init_hash/is_immutables_hash // are free in that case, but safe: they are only consumed in #[SELECTED_MEMBER] and the memory // write permutations, all of which are gated on is_valid_member_enum (which is 0). pol commit is_valid_member_enum; // @boolean (by lookup when is_valid_writes_in_bounds == 1) pol commit is_deployer; // @boolean (by lookup when is_valid_writes_in_bounds == 1) pol commit is_class_id; // @boolean (by lookup when is_valid_writes_in_bounds == 1) pol commit is_init_hash; // @boolean (by lookup when is_valid_writes_in_bounds == 1) + pol commit is_immutables_hash; // @boolean (by lookup when is_valid_writes_in_bounds == 1) // Note: member_enum is guaranteed to be 8 bits by execution (as a U8 immediate operand), // and the precomputed table is populated for the entire 8-bit range (256 rows). #[PRECOMPUTED_INFO] @@ -138,7 +140,8 @@ namespace get_contract_instance; is_valid_member_enum, is_deployer, is_class_id, - is_init_hash + is_init_hash, + is_immutables_hash } in precomputed.sel_range_8 { // inputs precomputed.idx, @@ -146,7 +149,8 @@ namespace get_contract_instance; precomputed.is_valid_member_enum, precomputed.is_deployer, precomputed.is_class_id, - precomputed.is_init_hash + precomputed.is_init_hash, + precomputed.is_immutables_hash }; // Do not allow is_valid_member_enum to be 1 if the precomputed lookup is disabled. #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP] @@ -171,6 +175,7 @@ namespace get_contract_instance; pol commit retrieved_deployer_addr; pol commit retrieved_class_id; pol commit retrieved_init_hash; + pol commit retrieved_immutables_hash; #[CONTRACT_INSTANCE_RETRIEVAL] is_valid_member_enum { @@ -182,7 +187,8 @@ namespace get_contract_instance; instance_exists, retrieved_deployer_addr, retrieved_class_id, - retrieved_init_hash + retrieved_init_hash, + retrieved_immutables_hash } in contract_instance_retrieval.sel { // inputs contract_instance_retrieval.address, @@ -192,14 +198,15 @@ namespace get_contract_instance; contract_instance_retrieval.exists, contract_instance_retrieval.deployer_addr, contract_instance_retrieval.current_class_id, - contract_instance_retrieval.init_hash + contract_instance_retrieval.init_hash, + contract_instance_retrieval.immutables_hash }; // Select the member indicated by the enum for writing to memory // Note: is_* selectors are guaranteed to be mutually exclusive booleans by the precomputed table. pol commit selected_member; #[SELECTED_MEMBER] - selected_member = is_deployer * retrieved_deployer_addr + is_class_id * retrieved_class_id + is_init_hash * retrieved_init_hash; + selected_member = is_deployer * retrieved_deployer_addr + is_class_id * retrieved_class_id + is_init_hash * retrieved_init_hash + is_immutables_hash * retrieved_immutables_hash; // Compute memory offsets for writing to pol commit member_write_offset; diff --git a/barretenberg/cpp/pil/vm2/precomputed.pil b/barretenberg/cpp/pil/vm2/precomputed.pil index 734d6b761e46..0e03550ddc90 100644 --- a/barretenberg/cpp/pil/vm2/precomputed.pil +++ b/barretenberg/cpp/pil/vm2/precomputed.pil @@ -435,7 +435,7 @@ pol constant out_tag; // ===== Section 14: GETCONTRACTINSTANCE opcode columns ===== // Maps contract instance member enum values to selectors indicating which field -// (deployer, class_id, init_hash) is being accessed. +// (deployer, class_id, init_hash, immutables_hash) is being accessed. // Used by the GETCONTRACTINSTANCE opcode. // // see opcodes/get_contract_instance.pil for ascii table @@ -444,3 +444,4 @@ pol constant is_valid_member_enum; pol constant is_deployer; pol constant is_class_id; pol constant is_init_hash; +pol constant is_immutables_hash; diff --git a/barretenberg/cpp/pil/vm2/scalar_mul.pil b/barretenberg/cpp/pil/vm2/scalar_mul.pil index cac3cd20e2dd..f77e5d86ce94 100644 --- a/barretenberg/cpp/pil/vm2/scalar_mul.pil +++ b/barretenberg/cpp/pil/vm2/scalar_mul.pil @@ -17,12 +17,17 @@ include "precomputed.pil"; * * The correctness of point addition (res + temp and temp + temp above) is constrained by a lookup into ecc.pil. * - * PRECONDITIONS: Input P is a valid point on the Grumpkin curve, input s is FF (see below note). + * PRECONDITIONS: Input P is a valid point on the Grumpkin curve, either satisfying the curve equation or the point + * at infinity representation (such that is_inf <==> (X, Y) == (ecc.INFINITY_X, ecc.INFINITY_Y)), and input s is FF. * Note: Grumpkin forms a 2-cycle with BN254, i.e the base field of one is the scalar field of the other and vice-versa, * so the scalar is actually a Fq value. We treat it as a Fr (FF tagged) value in circuit. Since r < q, we cannot use an * invalid scalar here. * - * USAGE: This is a non-memory aware subtrace used to constrain scalar point multiplicationas defined above. Each point can + * Note that once TODO(#AVM-266) is complete, is_inf will no longer be part of our point representation and we must either: + * - continue to rely on the 'calling' trace to inject a constrained is_inf, or + * - derive is_inf (<==> (X, Y) == (ecc.INFINITY_X, ecc.INFINITY_Y)) within this trace. + * + * USAGE: This is a non-memory aware subtrace used to constrain scalar point multiplication as defined above. Each point can * be looked up by coordinates (lookup as defined in address_derivation.pil): * #[PREADDRESS_SCALAR_MUL] * sel { @@ -116,6 +121,7 @@ namespace scalar_mul; sel_not_end * (point_x - point_x') = 0; #[INPUT_CONSISTENCY_Y] sel_not_end * (point_y - point_y') = 0; + // TODO(MW): remove/rework below? only used at end #[INPUT_CONSISTENCY_INF] sel_not_end * (point_inf - point_inf') = 0; #[INPUT_CONSISTENCY_SCALAR] @@ -172,7 +178,7 @@ namespace scalar_mul; sel_not_end { temp_x, temp_y, temp_inf, temp_x', temp_y', temp_inf', sel_not_end /* = 1 */ } in ecc.sel - { ecc.r_x, ecc.r_y, ecc.r_is_inf, ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.double_op }; + { ecc.r_x, ecc.r_y, ecc.result_infinity, ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.double_op }; /////////////////////////////// // Result Computation @@ -200,7 +206,7 @@ namespace scalar_mul; should_add { res_x, res_y, res_inf, res_x', res_y', res_inf', temp_x, temp_y, temp_inf } in ecc.sel - { ecc.r_x, ecc.r_y, ecc.r_is_inf, ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.q_x, ecc.q_y, ecc.q_is_inf }; + { ecc.r_x, ecc.r_y, ecc.result_infinity, ecc.p_x, ecc.p_y, ecc.p_is_inf, ecc.q_x, ecc.q_y, ecc.q_is_inf }; diff --git a/barretenberg/cpp/scripts/chonk-inputs.hash b/barretenberg/cpp/scripts/chonk-inputs.hash index 36bfba515855..74d7f158b3e2 100644 --- a/barretenberg/cpp/scripts/chonk-inputs.hash +++ b/barretenberg/cpp/scripts/chonk-inputs.hash @@ -1 +1 @@ -5d17cc1cfa051b60 +209dde8e69a27c9f diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp index 3b1499cc35ce..d70fabc58e8f 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp @@ -136,10 +136,10 @@ ContractInstance FuzzerContractDB::from_logs(const PrivateLog& log) const FF contract_class_id = log.fields[offset++]; FF initialization_hash = log.fields[offset++]; PublicKeys public_keys = { - .nullifier_key = { log.fields[offset++], log.fields[offset++] }, + .nullifier_key_hash = log.fields[offset++], .incoming_viewing_key = { log.fields[offset++], log.fields[offset++] }, - .outgoing_viewing_key = { log.fields[offset++], log.fields[offset++] }, - .tagging_key = { log.fields[offset++], log.fields[offset++] }, + .outgoing_viewing_key_hash = log.fields[offset++], + .tagging_key_hash = log.fields[offset++], }; auto deployer = AztecAddress(log.fields[offset++]); return ContractInstance{ diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp index b69cccff3231..c31decf6f8a4 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp @@ -40,10 +40,10 @@ ContractInstance create_default_instance(const ContractClassId& class_id) .initialization_hash = 0, .public_keys = PublicKeys{ - .nullifier_key = affine_one, + .nullifier_key_hash = 0, .incoming_viewing_key = affine_one, - .outgoing_viewing_key = affine_one, - .tagging_key = affine_one, + .outgoing_viewing_key_hash = 0, + .tagging_key_hash = 0, }, }; } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp index fce2e07f1a28..35e70ed2ab05 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp @@ -573,12 +573,10 @@ struct SUCCESSCOPY_Instruction { struct ECADD_Instruction { ParamRef p1_x; ParamRef p1_y; - ParamRef p1_infinite; ParamRef p2_x; ParamRef p2_y; - ParamRef p2_infinite; AddressRef result; - SERIALIZATION_FIELDS(p1_x, p1_y, p1_infinite, p2_x, p2_y, p2_infinite, result); + SERIALIZATION_FIELDS(p1_x, p1_y, p2_x, p2_y, result); }; /// @brief POSEIDON2PERM: Perform Poseidon2 permutation on 4 FF values @@ -881,8 +879,8 @@ inline std::ostream& operator<<(std::ostream& os, const FuzzInstruction& instruc << arg.dst_address; }, [&](ECADD_Instruction arg) { - os << "ECADD_Instruction " << arg.p1_x << " " << arg.p1_y << " " << arg.p1_infinite << " " << arg.p2_x - << " " << arg.p2_y << " " << arg.p2_infinite << " " << arg.result; + os << "ECADD_Instruction " << arg.p1_x << " " << arg.p1_y << " " << arg.p2_x << " " << arg.p2_y << " " + << arg.result; }, [&](POSEIDON2PERM_Instruction arg) { os << "POSEIDON2PERM_Instruction " << arg.src_address << " " << arg.dst_address; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp index b719d65bca5d..7c98c29b05f3 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp @@ -1287,40 +1287,32 @@ void ProgramBlock::process_ecadd_instruction(ECADD_Instruction instruction) #endif auto p1_x = memory_manager.get_resolved_address_and_operand_16(instruction.p1_x); auto p1_y = memory_manager.get_resolved_address_and_operand_16(instruction.p1_y); - auto p1_inf = memory_manager.get_resolved_address_and_operand_16(instruction.p1_infinite); auto p2_x = memory_manager.get_resolved_address_and_operand_16(instruction.p2_x); auto p2_y = memory_manager.get_resolved_address_and_operand_16(instruction.p2_y); - auto p2_inf = memory_manager.get_resolved_address_and_operand_16(instruction.p2_infinite); auto result = memory_manager.get_resolved_address_and_operand_16(instruction.result); - if (!p1_x.has_value() || !p1_y.has_value() || !p1_inf.has_value() || !p2_x.has_value() || !p2_y.has_value() || - !p2_inf.has_value() || !result.has_value()) { + if (!p1_x.has_value() || !p1_y.has_value() || !p2_x.has_value() || !p2_y.has_value() || !result.has_value()) { return; } preprocess_memory_addresses(p1_x.value().first); preprocess_memory_addresses(p1_y.value().first); - preprocess_memory_addresses(p1_inf.value().first); preprocess_memory_addresses(p2_x.value().first); preprocess_memory_addresses(p2_y.value().first); - preprocess_memory_addresses(p2_inf.value().first); preprocess_memory_addresses(result.value().first); auto ecadd_instruction = bb::avm2::testing::InstructionBuilder(bb::avm2::WireOpCode::ECADD) .operand(p1_x.value().second) .operand(p1_y.value().second) - .operand(p1_inf.value().second) .operand(p2_x.value().second) .operand(p2_y.value().second) - .operand(p2_inf.value().second) .operand(result.value().second) .build(); instructions.push_back(ecadd_instruction); - // ECADD writes 3 consecutive memory locations: result_x (FF), result_y (FF), result_is_inf (U1) + // ECADD writes 2 consecutive memory locations: result_x (FF), result_y (FF) memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, result.value().first.absolute_address); memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, result.value().first.absolute_address + 1); - memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result.value().first.absolute_address + 2); } void ProgramBlock::process_poseidon2perm_instruction(POSEIDON2PERM_Instruction instruction) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp index ec53d8b7c769..b33fb95ba8e8 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp @@ -299,10 +299,10 @@ ContractArtifacts build_bytecode_and_artifacts(FuzzerData& fuzzer_data) .current_contract_class_id = class_id, // Initial and current are the same .original_contract_class_id = class_id, .public_keys = { - .nullifier_key = { 0, 0 }, + .nullifier_key_hash = 0, .incoming_viewing_key = grumpkin::g1::element::one(), - .outgoing_viewing_key = { 0, 0 }, - .tagging_key = { 0, 0 }, + .outgoing_viewing_key_hash = 0, + .tagging_key_hash = 0, }, }; return { bytecode, contract_class, contract_instance }; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/ecc.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/ecc.fuzzer.cpp index 19e79a8078ed..5237bc909014 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/ecc.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/ecc.fuzzer.cpp @@ -94,8 +94,8 @@ struct EccFuzzerInput { AffinePoint q = AffinePoint::one(); Fq scalar = Fq::zero(); // Addresses are organised as: - // p_x, p_y, p_inf, q_x, q_y, q_inf, output_addr - std::array addresses{}; + // p_x, p_y, q_x, q_y, output_addr + std::array addresses{}; EccFuzzerInput() = default; // Serialize to buffer @@ -109,7 +109,7 @@ struct EccFuzzerInput { Fq::serialize_to_buffer(scalar, buffer + offset); offset += sizeof(Fq); // Serialize memory addresses - std::memcpy(buffer + offset, &addresses[0], sizeof(MemoryAddress) * 7); + std::memcpy(buffer + offset, &addresses[0], sizeof(MemoryAddress) * 5); } static EccFuzzerInput from_buffer(const uint8_t* buffer) @@ -137,7 +137,7 @@ struct EccFuzzerInput { input.scalar = Fq::serialize_from_buffer(buffer + offset); offset += sizeof(Fq); // Deserialize memory addresses - std::memcpy(&input.addresses[0], buffer + offset, sizeof(MemoryAddress) * 7); + std::memcpy(&input.addresses[0], buffer + offset, sizeof(MemoryAddress) * 5); return input; } @@ -210,7 +210,7 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size, size_t max case 7: { // Mutate memory addresses // Select a random address to mutate - std::uniform_int_distribution addr_dist(0, 6); + std::uniform_int_distribution addr_dist(0, 4); size_t addr_index = addr_dist(rng); input.addresses[addr_index] = mutate_memory_address(input.addresses[addr_index], rng); break; @@ -268,15 +268,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) mem->set(/*p_x_addr*/ input.addresses[0], MemoryValue::from_tag(MemoryTag::FF, point_p.x())); mem->set(/*p_y_addr*/ input.addresses[1], MemoryValue::from_tag(MemoryTag::FF, point_p.y())); - mem->set(/*p_inf*/ input.addresses[2], MemoryValue::from_tag(MemoryTag::U1, point_p.is_infinity() ? FF(1) : FF(0))); - mem->set(/*q_x_addr*/ input.addresses[3], MemoryValue::from_tag(MemoryTag::FF, point_q.x())); - mem->set(/*q_y_addr*/ input.addresses[4], MemoryValue::from_tag(MemoryTag::FF, point_q.y())); - mem->set(/*q_inf*/ input.addresses[5], MemoryValue::from_tag(MemoryTag::U1, point_q.is_infinity() ? FF(1) : FF(0))); + mem->set(/*q_x_addr*/ input.addresses[2], MemoryValue::from_tag(MemoryTag::FF, point_q.x())); + mem->set(/*q_y_addr*/ input.addresses[3], MemoryValue::from_tag(MemoryTag::FF, point_q.y())); EmbeddedCurvePoint scalar_mul_result; try { - ecc.add(*mem, point_p, point_q, /* output_addr */ input.addresses[6]); + ecc.add(*mem, point_p, point_q, /* output_addr */ input.addresses[4]); scalar_mul_result = ecc.scalar_mul(input.p, FF(uint256_t(input.scalar))); } catch (std::exception& e) { // info("Caught exception during ECC add: {}", e.what()); @@ -286,15 +284,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) EmbeddedCurvePoint expected_result = point_p + point_q; // Verify output in memory - MemoryValue res_x = mem->get(input.addresses[6]); - MemoryValue res_y = mem->get(input.addresses[6] + 1); - MemoryValue res_inf = mem->get(input.addresses[6] + 2); + MemoryValue res_x = mem->get(input.addresses[4]); + MemoryValue res_y = mem->get(input.addresses[4] + 1); - EmbeddedCurvePoint result_point = EmbeddedCurvePoint(res_x.as_ff(), res_y.as_ff(), res_inf.as_ff() == FF(1)); + EmbeddedCurvePoint result_point = EmbeddedCurvePoint(res_x.as_ff(), res_y.as_ff()); BB_ASSERT(result_point.x() == expected_result.x(), "Result x-coordinate mismatch"); BB_ASSERT(result_point.y() == expected_result.y(), "Result y-coordinate mismatch"); - BB_ASSERT(result_point.is_infinity() == expected_result.is_infinity(), "Result infinity flag mismatch"); // Non mem-aware ecmul result: expected_result = point_p * input.scalar; @@ -309,15 +305,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) auto trace = TestTraceContainer({ { { Column::execution_context_id, 0 }, // Point P - { Column::execution_register_0_, point_p.x() }, // = px - { Column::execution_register_1_, point_p.y() }, // = py - { Column::execution_register_2_, point_p.is_infinity() ? FF(1) : FF(0) }, // = p_inf + { Column::execution_register_0_, point_p.x() }, // = px + { Column::execution_register_1_, point_p.y() }, // = py // Point Q - { Column::execution_register_3_, point_q.x() }, // = qx - { Column::execution_register_4_, point_q.y() }, // = qy - { Column::execution_register_5_, point_q.is_infinity() ? FF(1) : FF(0) }, // = q_inf + { Column::execution_register_2_, point_q.x() }, // = qx + { Column::execution_register_3_, point_q.y() }, // = qy // Dst address - { Column::execution_rop_6_, input.addresses[6] }, // = dst_addr + { Column::execution_rop_4_, input.addresses[4] }, // = dst_addr { Column::execution_sel_exec_dispatch_ecc_add, 1 }, // = sel { Column::execution_sel_opcode_error, error ? 1 : 0 }, // = sel_err } }); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp index a4dddc705162..45ef5d2e1975 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp @@ -206,7 +206,7 @@ void mutate_contract_instances(std::vector& contract_instances break; case 3: // Mutate nullifier key - mutate_point(instance.public_keys.nullifier_key, rng); + mutate_field(instance.public_keys.nullifier_key_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION); break; case 4: // Mutate incoming viewing key @@ -214,11 +214,11 @@ void mutate_contract_instances(std::vector& contract_instances break; case 5: // Mutate outgoing viewing key - mutate_point(instance.public_keys.outgoing_viewing_key, rng); + mutate_field(instance.public_keys.outgoing_viewing_key_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION); break; case 6: // Mutate tagging key - mutate_point(instance.public_keys.tagging_key, rng); + mutate_field(instance.public_keys.tagging_key_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION); break; default: break; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp index 02b2278f658d..6801ee5ff5d3 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp @@ -428,17 +428,15 @@ std::vector InstructionMutator::generate_ecadd_instruction(std: // Random mode: use existing memory values (may fail if not valid points on curve) return { ECADD_Instruction{ .p1_x = generate_variable_ref(rng), .p1_y = generate_variable_ref(rng), - .p1_infinite = generate_variable_ref(rng), .p2_x = generate_variable_ref(rng), .p2_y = generate_variable_ref(rng), - .p2_infinite = generate_variable_ref(rng), .result = generate_address_ref(rng, MAX_16BIT_OPERAND) } }; } // Backfill mode: generate valid points on the Grumpkin curve and SET them - // 6 SET instructions (2 points * 3 fields each) + 1 ECADD = 7 instructions + // 4 SET instructions (2 points * 4 fields each) + 1 ECADD = 5 instructions std::vector instructions; - instructions.reserve(7); + instructions.reserve(5); // Generate a valid point via scalar multiplication of the generator (always on curve) auto generate_point = [&rng]() { @@ -447,17 +445,12 @@ std::vector InstructionMutator::generate_ecadd_instruction(std: }; // Generate SET instructions to backfill a point at the given addresses - auto backfill_point = [&instructions](const bb::avm2::EmbeddedCurvePoint& point, - AddressRef x_addr, - AddressRef y_addr, - AddressRef inf_addr) { + auto backfill_point = [&instructions]( + const bb::avm2::EmbeddedCurvePoint& point, AddressRef x_addr, AddressRef y_addr) { instructions.push_back( SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, .result_address = x_addr, .value = point.x() }); instructions.push_back( SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, .result_address = y_addr, .value = point.y() }); - instructions.push_back(SET_8_Instruction{ .value_tag = bb::avm2::MemoryTag::U1, - .result_address = inf_addr, - .value = static_cast(point.is_infinity() ? 1 : 0) }); }; auto p1 = generate_point(); @@ -466,20 +459,16 @@ std::vector InstructionMutator::generate_ecadd_instruction(std: // Generate addresses (SET_FF uses 16-bit, SET_8 uses 8-bit operands) AddressRef p1_x_addr = generate_address_ref(rng, MAX_16BIT_OPERAND); AddressRef p1_y_addr = generate_address_ref(rng, MAX_16BIT_OPERAND); - AddressRef p1_inf_addr = generate_address_ref(rng, MAX_8BIT_OPERAND); AddressRef p2_x_addr = generate_address_ref(rng, MAX_16BIT_OPERAND); AddressRef p2_y_addr = generate_address_ref(rng, MAX_16BIT_OPERAND); - AddressRef p2_inf_addr = generate_address_ref(rng, MAX_8BIT_OPERAND); - backfill_point(p1, p1_x_addr, p1_y_addr, p1_inf_addr); - backfill_point(p2, p2_x_addr, p2_y_addr, p2_inf_addr); + backfill_point(p1, p1_x_addr, p1_y_addr); + backfill_point(p2, p2_x_addr, p2_y_addr); instructions.push_back(ECADD_Instruction{ .p1_x = p1_x_addr, .p1_y = p1_y_addr, - .p1_infinite = p1_inf_addr, .p2_x = p2_x_addr, .p2_y = p2_y_addr, - .p2_infinite = p2_inf_addr, .result = generate_address_ref(rng, MAX_16BIT_OPERAND) }); return instructions; @@ -1476,8 +1465,8 @@ void InstructionMutator::mutate_successcopy_instruction(SUCCESSCOPY_Instruction& void InstructionMutator::mutate_ecadd_instruction(ECADD_Instruction& instruction, std::mt19937_64& rng) { - // ECADD has 7 operands, select one to mutate - int choice = std::uniform_int_distribution(0, 6)(rng); + // ECADD has 5 operands, select one to mutate + int choice = std::uniform_int_distribution(0, 4)(rng); switch (choice) { case 0: mutate_param_ref(instruction.p1_x, rng, MemoryTag::FF, MAX_16BIT_OPERAND); @@ -1486,18 +1475,12 @@ void InstructionMutator::mutate_ecadd_instruction(ECADD_Instruction& instruction mutate_param_ref(instruction.p1_y, rng, MemoryTag::FF, MAX_16BIT_OPERAND); break; case 2: - mutate_param_ref(instruction.p1_infinite, rng, MemoryTag::U1, MAX_16BIT_OPERAND); - break; - case 3: mutate_param_ref(instruction.p2_x, rng, MemoryTag::FF, MAX_16BIT_OPERAND); break; - case 4: + case 3: mutate_param_ref(instruction.p2_y, rng, MemoryTag::FF, MAX_16BIT_OPERAND); break; - case 5: - mutate_param_ref(instruction.p2_infinite, rng, MemoryTag::U1, MAX_16BIT_OPERAND); - break; - case 6: + case 4: mutate_address_ref(instruction.result, rng, MAX_16BIT_OPERAND); break; } diff --git a/barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp index 070d5bbc80ef..e63b9d7e3615 100644 --- a/barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp @@ -233,7 +233,7 @@ #define AVM_POSEIDON2_BASE_L2_GAS 360 #define AVM_SHA256COMPRESSION_BASE_L2_GAS 12288 #define AVM_KECCAKF1600_BASE_L2_GAS 58176 -#define AVM_ECADD_BASE_L2_GAS 270 +#define AVM_ECADD_BASE_L2_GAS 180 #define AVM_TORADIXBE_BASE_L2_GAS 24 #define AVM_CALLDATACOPY_DYN_L2_GAS 3 #define AVM_RETURNDATACOPY_DYN_L2_GAS 3 @@ -272,7 +272,8 @@ #define DOM_SEP__CONTRACT_CLASS_ID 3923495515UL #define DOM_SEP__SALTED_INITIALIZATION_HASH 2763052992UL #define DOM_SEP__PUBLIC_KEYS_HASH 777457226UL +#define DOM_SEP__SINGLE_PUBLIC_KEY_HASH 3452068255UL #define DOM_SEP__PARTIAL_ADDRESS 2103633018UL -#define DOM_SEP__CONTRACT_ADDRESS_V1 1788365517UL +#define DOM_SEP__CONTRACT_ADDRESS_V2 4099338721UL #define DOM_SEP__BLOCK_HEADER_HASH 4195546849UL #define DOM_SEP__PUBLIC_CALLDATA 2760353947UL diff --git a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp index 7bcc3fc2edfc..571ca7804e27 100644 --- a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp +++ b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp @@ -11,7 +11,7 @@ GrumpkinMul::Response GrumpkinMul::execute(BBApiRequest& request) && if (!point.on_curve()) { BBAPI_ERROR(request, "Input point must be on the curve"); } - return { point * scalar }; + return { grumpkin::g1::element(point).mul_const_time(scalar).to_affine_const_time() }; } GrumpkinAdd::Response GrumpkinAdd::execute(BBApiRequest& request) && @@ -32,7 +32,11 @@ GrumpkinBatchMul::Response GrumpkinBatchMul::execute(BBApiRequest& request) && BBAPI_ERROR(request, "Input point must be on the curve"); } } - auto output = grumpkin::g1::element::batch_mul_with_endomorphism(points, scalar); + std::vector output; + output.reserve(points.size()); + for (const auto& p : points) { + output.emplace_back(grumpkin::g1::element(p).mul_const_time(scalar).to_affine_const_time()); + } return { std::move(output) }; } @@ -54,7 +58,7 @@ Secp256k1Mul::Response Secp256k1Mul::execute(BBApiRequest& request) && if (!point.on_curve()) { BBAPI_ERROR(request, "Input point must be on the curve"); } - return { point * scalar }; + return { secp256k1::g1::element(point).mul_const_time(scalar).to_affine_const_time() }; } Secp256k1GetRandomFr::Response Secp256k1GetRandomFr::execute(BB_UNUSED BBApiRequest& request) && @@ -87,7 +91,7 @@ Bn254G1Mul::Response Bn254G1Mul::execute(BBApiRequest& request) && if (!point.on_curve()) { BBAPI_ERROR(request, "Input point must be on the curve"); } - auto result = point * scalar; + auto result = bb::g1::element(point).mul_const_time(scalar).to_affine_const_time(); if (!result.on_curve()) { BBAPI_ERROR(request, "Output point must be on the curve"); } diff --git a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecdsa.cpp b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecdsa.cpp index c664e74d65a5..e2f351a302f1 100644 --- a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecdsa.cpp +++ b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecdsa.cpp @@ -10,12 +10,12 @@ namespace bb::bbapi { // Secp256k1 implementations EcdsaSecp256k1ComputePublicKey::Response EcdsaSecp256k1ComputePublicKey::execute(BB_UNUSED BBApiRequest& request) && { - return { secp256k1::g1::one * private_key }; + return { secp256k1::g1::element(secp256k1::g1::one).mul_const_time(private_key).to_affine_const_time() }; } EcdsaSecp256k1ConstructSignature::Response EcdsaSecp256k1ConstructSignature::execute(BB_UNUSED BBApiRequest& request) && { - auto pub_key = secp256k1::g1::one * private_key; + auto pub_key = secp256k1::g1::element(secp256k1::g1::one).mul_const_time(private_key).to_affine_const_time(); crypto::ecdsa_key_pair key_pair = { private_key, pub_key }; std::string message_str(reinterpret_cast(message.data()), message.size()); @@ -44,12 +44,12 @@ EcdsaSecp256k1VerifySignature::Response EcdsaSecp256k1VerifySignature::execute(B // Secp256r1 implementations EcdsaSecp256r1ComputePublicKey::Response EcdsaSecp256r1ComputePublicKey::execute(BB_UNUSED BBApiRequest& request) && { - return { secp256r1::g1::one * private_key }; + return { secp256r1::g1::element(secp256r1::g1::one).mul_const_time(private_key).to_affine_const_time() }; } EcdsaSecp256r1ConstructSignature::Response EcdsaSecp256r1ConstructSignature::execute(BB_UNUSED BBApiRequest& request) && { - auto pub_key = secp256r1::g1::one * private_key; + auto pub_key = secp256r1::g1::element(secp256r1::g1::one).mul_const_time(private_key).to_affine_const_time(); crypto::ecdsa_key_pair key_pair = { private_key, pub_key }; std::string message_str(reinterpret_cast(message.data()), message.size()); diff --git a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp index 68b51ea2cd8e..f5c365a23479 100644 --- a/barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp +++ b/barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp @@ -8,12 +8,13 @@ namespace bb::bbapi { SchnorrComputePublicKey::Response SchnorrComputePublicKey::execute(BB_UNUSED BBApiRequest& request) && { - return { grumpkin::g1::one * private_key }; + return { grumpkin::g1::element(grumpkin::g1::one).mul_const_time(private_key).to_affine_const_time() }; } SchnorrConstructSignature::Response SchnorrConstructSignature::execute(BB_UNUSED BBApiRequest& request) && { - grumpkin::g1::affine_element pub_key = grumpkin::g1::one * private_key; + grumpkin::g1::affine_element pub_key = + grumpkin::g1::element(grumpkin::g1::one).mul_const_time(private_key).to_affine_const_time(); crypto::schnorr_key_pair key_pair = { private_key, pub_key }; auto sig = crypto::schnorr_construct_signature(message_field, key_pair); diff --git a/barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp b/barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp index 8588ffae6876..a028e787fb9b 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp @@ -31,11 +31,11 @@ ecdsa_signature ecdsa_construct_signature(const std::string& message, const ecds // Compute R = k * G. k is the secret RFC6979 nonce, so use the constant-time multiplication // to defend against the Hamming-weight / bit-length timing leak in operator*. - typename G1::affine_element R(typename G1::element(G1::one).mul_const_time(k)); + typename G1::affine_element R(typename G1::element(G1::one).mul_const_time(k).to_affine_const_time()); // Compute the signature Fr r = Fr(R.x); - Fr s = (z + r * account.private_key) / k; + Fr s = (z + r * account.private_key) * k.invert_const_time(); secure_erase_bytes(&k, sizeof(k)); // Ensure that the value of s is "low", i.e. s := min{ s, (|Fr| - s) } diff --git a/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc b/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc index 847608a53244..16fe624c72dc 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc +++ b/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc @@ -86,7 +86,7 @@ schnorr_signature schnorr_construct_signature(const typename G1::Fq& message_fie // k is a secret nonce; use the constant-time multiplication to defend against the // Hamming-weight / bit-length timing leak in operator*. - typename G1::affine_element R(typename G1::element(G1::one).mul_const_time(k)); + typename G1::affine_element R(typename G1::element(G1::one).mul_const_time(k).to_affine_const_time()); using Fq = typename G1::Fq; Fq e = schnorr_generate_challenge(message_field, public_key, R); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp index a60ce0cedaf0..e00b57168858 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp @@ -252,9 +252,8 @@ void update_max_witness_index_from_opcode(Acir::Opcode const& opcode, AcirFormat } }, [&](const Acir::Opcode::MemoryOp& arg) { - update_max_witness_index_from_expression(arg.op.index, af); - update_max_witness_index_from_expression(arg.op.value, af); - update_max_witness_index_from_expression(arg.op.operation, af); + update_max_witness_index_from_witness(arg.op.index); + update_max_witness_index_from_witness(arg.op.value); }, [&](const Acir::Opcode::BrilligCall& arg) { for (const auto& input : arg.inputs) { @@ -703,7 +702,6 @@ void add_blackbox_func_call_to_acir_format(Acir::Opcode::BlackBoxFuncCall const& .predicate = parse_input(arg.predicate), .out_point_x = to_witness((*arg.outputs)[0]), .out_point_y = to_witness((*arg.outputs)[1]), - .out_point_is_infinite = to_witness((*arg.outputs)[2]), }); af.original_opcode_indices.multi_scalar_mul_constraints.push_back(opcode_index); }, @@ -711,14 +709,11 @@ void add_blackbox_func_call_to_acir_format(Acir::Opcode::BlackBoxFuncCall const& af.ec_add_constraints.push_back(EcAdd{ .input1_x = parse_input((*arg.input1)[0]), .input1_y = parse_input((*arg.input1)[1]), - .input1_infinite = parse_input((*arg.input1)[2]), .input2_x = parse_input((*arg.input2)[0]), .input2_y = parse_input((*arg.input2)[1]), - .input2_infinite = parse_input((*arg.input2)[2]), .predicate = parse_input(arg.predicate), .result_x = to_witness((*arg.outputs)[0]), .result_y = to_witness((*arg.outputs)[1]), - .result_infinite = to_witness((*arg.outputs)[2]), }); af.original_opcode_indices.ec_add_constraints.push_back(opcode_index); }, @@ -817,36 +812,8 @@ BlockConstraint memory_init_to_block_constraint(Acir::Opcode::MemoryInit const& void add_memory_op_to_block_constraint(Acir::Opcode::MemoryOp const& mem_op, BlockConstraint& block) { - // Lambda to convert an Acir::Expression to a witness index. Noir always emits a single unscaled witness term for - // memory op indices and values, so anything else is a malformed input. - auto acir_expression_to_witness = [](const Acir::Expression& expr) -> uint32_t { - BB_ASSERT(expr.mul_terms.empty(), "MemoryOp should not have multiplication terms"); - BB_ASSERT_EQ(expr.linear_combinations.size(), 1U, "MemoryOp expression must be a single witness"); - - const fr a_scaling = from_buffer_with_bound_checks(std::get<0>(expr.linear_combinations[0])); - const fr constant_term = from_buffer_with_bound_checks(expr.q_c); - - BB_ASSERT(a_scaling == fr::one() && constant_term == fr::zero(), - "MemoryOp expression must be a single unscaled witness with no constant term"); - - return std::get<1>(expr.linear_combinations[0]).value; - }; - - // Lambda to determine whether a memory operation is a read or write operation - auto is_read_operation = [](const Acir::Expression& expr) { - BB_ASSERT(expr.mul_terms.empty(), "MemoryOp expression should not have multiplication terms"); - BB_ASSERT(expr.linear_combinations.empty(), "MemoryOp expression should not have linear terms"); - - const fr const_term = from_buffer_with_bound_checks(expr.q_c); - - BB_ASSERT((const_term == fr::one()) || (const_term == fr::zero()), - "MemoryOp expression should be either zero or one"); - - // A read operation is given by a zero Expression - return const_term == fr::zero(); - }; - - AccessType access_type = is_read_operation(mem_op.op.operation) ? AccessType::Read : AccessType::Write; + // Acir::MemOp::read is the serialized MemOpKind bool: false = Read, true = Write. + AccessType access_type = mem_op.op.read ? AccessType::Write : AccessType::Read; if (access_type == AccessType::Write) { // We are not allowed to write on the databus BB_ASSERT((block.type != BlockType::CallData) && (block.type != BlockType::ReturnData)); @@ -856,8 +823,8 @@ void add_memory_op_to_block_constraint(Acir::Opcode::MemoryOp const& mem_op, Blo MemOp acir_mem_op = MemOp{ .access_type = access_type, - .index = acir_expression_to_witness(mem_op.op.index), - .value = acir_expression_to_witness(mem_op.op.value), + .index = mem_op.op.index.value, + .value = mem_op.op.value.value, }; block.trace.push_back(acir_mem_op); } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 12b15b737f0e..7b619640e656 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -20,6 +20,45 @@ namespace { auto& engine = numeric::get_debug_randomness(); } // namespace +TEST(BlockConstraintMemOpEncoding, ReadFlagFalseDecodesAsRead) +{ + Acir::Opcode::MemoryInit mem_init{ + .block_id = Acir::BlockId{ .value = 0 }, + .init = { Acir::Witness{ .value = 0 } }, + .block_type = Acir::BlockType{ .value = Acir::BlockType::CallData{ .value = 0 } }, + }; + BlockConstraint block = memory_init_to_block_constraint(mem_init); + + Acir::Opcode::MemoryOp mem_op{ + .block_id = Acir::BlockId{ .value = 0 }, + .op = Acir::MemOp{ .read = false, .index = Acir::Witness{ .value = 1 }, .value = Acir::Witness{ .value = 2 } }, + }; + + EXPECT_NO_THROW(add_memory_op_to_block_constraint(mem_op, block)); + + ASSERT_EQ(block.trace.size(), 1); + EXPECT_EQ(block.trace[0].access_type, AccessType::Read); + EXPECT_EQ(block.trace[0].index, 1); + EXPECT_EQ(block.trace[0].value, 2); +} + +TEST(BlockConstraintMemOpEncoding, AccessTypeEncodesToReadFlag) +{ + const MemOp read_op{ + .access_type = AccessType::Read, + .index = 1, + .value = 2, + }; + const MemOp write_op{ + .access_type = AccessType::Write, + .index = 3, + .value = 4, + }; + + EXPECT_FALSE(mem_op_to_acir_mem_op(read_op).read); + EXPECT_TRUE(mem_op_to_acir_mem_op(write_op).read); +} + template struct ROMTestParams { using Builder = Builder_; static constexpr size_t table_size = TableSize_; @@ -304,12 +343,10 @@ using RAMTestConfigs = testing::Types, RAMTestParams, RAMTestParams, - RAMTestParams, RAMTestParams, RAMTestParams, RAMTestParams, - RAMTestParams, - RAMTestParams>; + RAMTestParams>; TYPED_TEST_SUITE(RAMTest, RAMTestConfigs); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp index 66d4b8b382c2..8ad5b8595e4d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.cpp @@ -46,38 +46,25 @@ template void create_ec_add_constraint(Builder& builder, cons field_ct input_result_x = field_ct::from_witness_index(&builder, input.result_x); field_ct input_result_y = field_ct::from_witness_index(&builder, input.result_y); - bool_ct input_result_infinite = bool_ct(field_ct::from_witness_index(&builder, input.result_infinite)); if (builder.is_write_vk_mode()) { builder.set_variable(input_result_x.get_witness_index(), bb::grumpkin::g1::affine_one.x); builder.set_variable(input_result_y.get_witness_index(), bb::grumpkin::g1::affine_one.y); - builder.set_variable(input_result_infinite.get_witness_index(), bb::fr(0)); // generator is finite } - cycle_group_ct input1_point = - to_grumpkin_point(input.input1_x, input.input1_y, input.input1_infinite, predicate, builder); - cycle_group_ct input2_point = - to_grumpkin_point(input.input2_x, input.input2_y, input.input2_infinite, predicate, builder); + cycle_group_ct input1_point = to_grumpkin_point(input.input1_x, input.input1_y, predicate, builder); + cycle_group_ct input2_point = to_grumpkin_point(input.input2_x, input.input2_y, predicate, builder); // Use public constructor which auto-detects infinity from (0,0) coordinates. // Note that input_result is computed by Noir and passed to bb via ACIR. Hence, it is always a valid point on // Grumpkin, so we don't need to assert on curve. cycle_group_ct input_result(input_result_x, input_result_y, /*assert_on_curve=*/false); - // Constrain the result_infinite witness against the auto-detected infinity from coordinates. - // Use conditional_assign so the constraint is inactive when predicate is false. - bool_ct expected_infinite = - bool_ct::conditional_assign(predicate, input_result.is_point_at_infinity(), input_result_infinite); - input_result_infinite.assert_equal(expected_infinite); - // Step 2. cycle_group_ct result = input1_point + input2_point; // The assert_equal method standardizes both points before comparing, so if either of them is the point at - // infinity, the coordinates will be assigned to be (0,0). This is OK as long as Noir developers do not use the - // coordinates of a point at infinity (otherwise input_result might be the point at infinity different from (0, - // 0, true), and the fact that assert_equal passes doesn't imply anything for the original coordinates of - // input_result). + // infinity, the coordinates will be assigned to be (0,0). cycle_group_ct to_be_asserted_equal = cycle_group_ct::conditional_assign(predicate, input_result, result); result.assert_equal(to_be_asserted_equal); } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.hpp index b1c9bee4dfff..e7969be3fcf5 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.hpp @@ -13,35 +13,30 @@ namespace acir_format { /** * @brief Constraints for addition of two points on the Grumpkin curve. * - * @details EcAdd constraints have 10 components: + * @details EcAdd constraints have 7 components: * - input1_x: x-coordinate of the first input point * - input1_y: y-coordinate of the first input point - * - input1_infinite: flag indicating if the first input point is the point at infinity * - input2_x: x-coordinate of the second input point * - input2_y: y-coordinate of the second input point - * - input2_infinite: flag indicating if the second input point is the point at infinity * - predicate: flag indicating whether the constraint is active * - result_x: witness index for the x-coordinate of the resulting point * - result_y: witness index for the y-coordinate of the resulting point - * - result_infinite: witness index for the flag indicating if the result is the point at infinity * - * The data related to input1 and input2 can either be given by witnesses or constants. However, x and y coordinates - * pertaining to the same input must be either all witnesses or all constants. + * The point at infinity is represented by the coordinates (0, 0). The data related to input1 and input2 can either be + * given by witnesses or constants. However, x and y coordinates pertaining to the same input must be either all + * witnesses or all constants. */ struct EcAdd { WitnessOrConstant input1_x; WitnessOrConstant input1_y; - WitnessOrConstant input1_infinite; WitnessOrConstant input2_x; WitnessOrConstant input2_y; - WitnessOrConstant input2_infinite; // Predicate indicating whether the constraint should be disabled: // - true: the constraint is valid // - false: the constraint is disabled, i.e it must not fail and can return whatever. WitnessOrConstant predicate; uint32_t result_x; uint32_t result_y; - uint32_t result_infinite; friend bool operator==(EcAdd const& lhs, EcAdd const& rhs) = default; }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp index 27f80a89566c..848b5a80c5d9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp @@ -60,15 +60,12 @@ template class EcOperationsTesting auto construct_point = [&](const GrumpkinPoint& point, bool as_constant) -> std::vector> { if (as_constant) { // Point is constant - return { WitnessOrConstant::from_constant(point.x), - WitnessOrConstant::from_constant(point.y), - WitnessOrConstant::from_constant(point.is_point_at_infinity() ? FF(1) : FF(0)) }; + return { WitnessOrConstant::from_constant(point.x), WitnessOrConstant::from_constant(point.y) }; } // Point is witness std::vector point_indices = add_to_witness_and_track_indices(witness_values, point); return { WitnessOrConstant::from_index(point_indices[0]), - WitnessOrConstant::from_index(point_indices[1]), - WitnessOrConstant::from_index(point_indices[2]) }; + WitnessOrConstant::from_index(point_indices[1]) }; }; // Determine which inputs are constants based on the Constancy template parameter @@ -87,14 +84,11 @@ template class EcOperationsTesting ec_add_constraint = EcAdd{ .input1_x = input1_fields[0], .input1_y = input1_fields[1], - .input1_infinite = input1_fields[2], .input2_x = input2_fields[0], .input2_y = input2_fields[1], - .input2_infinite = input2_fields[2], .predicate = WitnessOrConstant::from_index(predicate_index), .result_x = result_indices[0], .result_y = result_indices[1], - .result_infinite = result_indices[2], }; } @@ -124,7 +118,6 @@ template class EcOperationsTesting // Tamper with the result (always a witness) by setting it to the generator point witness_values[constraint.result_x] = GrumpkinPoint::one().x; witness_values[constraint.result_y] = GrumpkinPoint::one().y; - witness_values[constraint.result_infinite] = FF::zero(); break; } case InvalidWitness::Target::None: @@ -296,34 +289,29 @@ TYPED_TEST(EcOperationsTestsBothConstant, InvalidWitnesses) } // ============================================================ -// Infinity flag tests +// Infinity tests: the point at infinity is encoded as (0, 0). // ============================================================ using GrumpkinPoint = bb::grumpkin::g1::affine_element; using FF = bb::fr; struct AcirPoint { - FF x, y, inf; - static AcirPoint from_native(const GrumpkinPoint& p) - { - return { p.x, p.y, p.is_point_at_infinity() ? FF(1) : FF(0) }; - } - static AcirPoint infinity() { return { FF(0), FF(0), FF(1) }; } + FF x, y; + static AcirPoint from_native(const GrumpkinPoint& p) { return { p.x, p.y }; } + static AcirPoint infinity() { return { FF(0), FF(0) }; } }; template class EcOperationsInfinityTests : public ::testing::Test { protected: static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } - // Push an AcirPoint to the witness vector and return the [x, y, inf] indices. - static std::array push_point(WitnessVector& witness, const AcirPoint& pt) + // Push an AcirPoint to the witness vector and return the [x, y] indices. + static std::array push_point(WitnessVector& witness, const AcirPoint& pt) { uint32_t xi = static_cast(witness.size()); witness.emplace_back(pt.x); uint32_t yi = static_cast(witness.size()); witness.emplace_back(pt.y); - uint32_t ii = static_cast(witness.size()); - witness.emplace_back(pt.inf); - return { xi, yi, ii }; + return { xi, yi }; } // Build an EcAdd constraint (predicate=1) from three ACIR points. @@ -340,14 +328,11 @@ template class EcOperationsInfinityTests : public ::testing:: EcAdd c{ .input1_x = WitnessOrConstant::from_index(i1[0]), .input1_y = WitnessOrConstant::from_index(i1[1]), - .input1_infinite = WitnessOrConstant::from_index(i1[2]), .input2_x = WitnessOrConstant::from_index(i2[0]), .input2_y = WitnessOrConstant::from_index(i2[1]), - .input2_infinite = WitnessOrConstant::from_index(i2[2]), .predicate = WitnessOrConstant::from_index(pred_idx), .result_x = r[0], .result_y = r[1], - .result_infinite = r[2], }; return { c, witness }; } @@ -365,7 +350,7 @@ template class EcOperationsInfinityTests : public ::testing:: TYPED_TEST_SUITE(EcOperationsInfinityTests, BuilderTypes); -// P + (-P) = point_at_infinity: valid proof with result_infinite=1, result_x=0, result_y=0. +// P + (-P) = (0, 0): valid circuit. TYPED_TEST(EcOperationsInfinityTests, ResultIsInfinity) { BB_DISABLE_ASSERTS(); @@ -376,37 +361,7 @@ TYPED_TEST(EcOperationsInfinityTests, ResultIsInfinity) EXPECT_TRUE(ok) << "P + (-P) = infinity should produce a valid circuit"; } -// A finite result with result_infinite=1 (forged) must fail. -TYPED_TEST(EcOperationsInfinityTests, ForgedInfinityFlagOnFiniteResultFails) -{ - BB_DISABLE_ASSERTS(); - GrumpkinPoint p = GrumpkinPoint::random_element(); - GrumpkinPoint q = GrumpkinPoint::random_element(); - ASSERT_FALSE((p + q).is_point_at_infinity()); - auto [constraint, witness] = - TestFixture::make_ec_add(AcirPoint::from_native(p), AcirPoint::from_native(q), AcirPoint::from_native(p + q)); - witness[constraint.result_infinite] = FF(1); // forge: finite result claimed as infinite - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) - << "Forged infinity flag on finite result should fail"; -} - -// An infinity result with result_infinite=0 (forged) must fail. -TYPED_TEST(EcOperationsInfinityTests, ForgedFiniteFlagOnInfinityResultFails) -{ - BB_DISABLE_ASSERTS(); - GrumpkinPoint p = GrumpkinPoint::random_element(); - // Forge result: (0,0) coordinates but is_infinite=0 (should be 1) - auto [constraint, witness] = TestFixture::make_ec_add( - AcirPoint::from_native(p), AcirPoint::from_native(-p), AcirPoint{ FF(0), FF(0), FF(0) }); - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) - << "Forged finite flag on infinity result should fail"; -} - -// Input point at infinity (∞ + P = P): should produce a valid circuit. +// Input point at infinity (∞ + P = P): valid circuit. TYPED_TEST(EcOperationsInfinityTests, Input1IsInfinity) { BB_DISABLE_ASSERTS(); @@ -417,17 +372,3 @@ TYPED_TEST(EcOperationsInfinityTests, Input1IsInfinity) auto [ok, err] = TestFixture::run_circuit(constraint, witness); EXPECT_TRUE(ok) << "infinity + P = P should produce a valid circuit"; } - -// Input point with forged input_infinite=1 (non-zero coordinates) must fail. -TYPED_TEST(EcOperationsInfinityTests, ForgedInputInfinityFlagFails) -{ - BB_DISABLE_ASSERTS(); - GrumpkinPoint p = GrumpkinPoint::random_element(); - GrumpkinPoint q = GrumpkinPoint::random_element(); - auto [constraint, witness] = - TestFixture::make_ec_add(AcirPoint::from_native(p), AcirPoint::from_native(q), AcirPoint::from_native(p + q)); - witness[constraint.input1_infinite.index] = FF(1); // forge: finite input1 claimed as infinite - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) << "Forged input infinity flag should fail"; -} diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp index e4f6adb5cc71..8f9febf543bc 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp @@ -43,8 +43,8 @@ template inline constexpr size_t BLAKE3 = 2158 + ZERO_GATE + template inline constexpr size_t KECCAK_PERMUTATION = 17387 + ZERO_GATE + MEGA_OFFSET; template inline constexpr size_t POSEIDON2_PERMUTATION = (IsMegaBuilder ? 27 : 73) + ZERO_GATE + MEGA_OFFSET; -template inline constexpr size_t MULTI_SCALAR_MUL = 3563 + ZERO_GATE; -template inline constexpr size_t EC_ADD = 84 + ZERO_GATE + MEGA_OFFSET; +template inline constexpr size_t MULTI_SCALAR_MUL = 3557 + ZERO_GATE; +template inline constexpr size_t EC_ADD = 76 + ZERO_GATE + MEGA_OFFSET; template inline constexpr size_t BLOCK_ROM_READ = 9 + ZERO_GATE + MEGA_OFFSET; template inline constexpr size_t BLOCK_RAM_READ = 9 + ZERO_GATE + MEGA_OFFSET; template inline constexpr size_t BLOCK_RAM_WRITE = 18 + ZERO_GATE + MEGA_OFFSET; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp index 6be1896928f5..dca9f880c246 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.cpp @@ -83,13 +83,11 @@ static MsmInputs reconstruct_msm_inputs(Builder& builder, const MultiSc // Reconstruct expected result field_ct input_result_x = field_ct::from_witness_index(&builder, input.out_point_x); field_ct input_result_y = field_ct::from_witness_index(&builder, input.out_point_y); - bool_ct input_result_infinite = bool_ct(field_ct::from_witness_index(&builder, input.out_point_is_infinite)); // If no valid witness assignments, set result to generator point to avoid errors during circuit construction if (builder.is_write_vk_mode()) { builder.set_variable(input_result_x.get_witness_index(), bb::grumpkin::g1::affine_one.x); builder.set_variable(input_result_y.get_witness_index(), bb::grumpkin::g1::affine_one.y); - builder.set_variable(input_result_infinite.get_witness_index(), bb::fr(0)); // generator is finite } // Use public constructor which auto-detects infinity from (0,0) coordinates. @@ -97,25 +95,17 @@ static MsmInputs reconstruct_msm_inputs(Builder& builder, const MultiSc // Grumpkin, so we don't need to assert on curve. cycle_group_ct input_result(input_result_x, input_result_y, /*assert_on_curve=*/false); - // Constrain the out_point_is_infinite witness against the auto-detected infinity from coordinates. - // Use conditional_assign so the constraint is inactive when predicate is false. - bool_ct expected_infinite = - bool_ct::conditional_assign(predicate, input_result.is_point_at_infinity(), input_result_infinite); - input_result_infinite.assert_equal(expected_infinite); - // Reconstruct points and scalars std::vector points; std::vector scalars; - // Ensure that the number of points and scalars are consistent (3 field elements per point, 2 per scalar) - BB_ASSERT(input.points.size() * 2 == input.scalars.size() * 3, "MultiScalarMul input size mismatch"); + // Ensure that the number of points and scalars are consistent (2 field elements per point, 2 per scalar) + BB_ASSERT_EQ(input.points.size(), input.scalars.size(), "MultiScalarMul input size mismatch"); - for (size_t i = 0; i < input.points.size(); i += 3) { - cycle_group_ct input_point = - to_grumpkin_point(input.points[i], input.points[i + 1], input.points[i + 2], predicate, builder); + for (size_t i = 0; i < input.points.size(); i += 2) { + cycle_group_ct input_point = to_grumpkin_point(input.points[i], input.points[i + 1], predicate, builder); - cycle_scalar_ct scalar = - to_grumpkin_scalar(input.scalars[2 * (i / 3)], input.scalars[2 * (i / 3) + 1], predicate, builder); + cycle_scalar_ct scalar = to_grumpkin_scalar(input.scalars[i], input.scalars[i + 1], predicate, builder); points.push_back(input_point); scalars.push_back(scalar); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.hpp index 8c9d051e4dd9..fbb3a12f47c8 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.hpp @@ -23,7 +23,6 @@ struct MultiScalarMul { uint32_t out_point_x; uint32_t out_point_y; - uint32_t out_point_is_infinite; friend bool operator==(MultiScalarMul const& lhs, MultiScalarMul const& rhs) = default; }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp index a1e15b726336..408112454fe5 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp @@ -65,19 +65,15 @@ template class MultiScalarMulTesti constexpr bool scalars_are_constant = (Constancy == InputConstancy::Scalars || Constancy == InputConstancy::Both); - // Helper to add points: either as witnesses or constants based on Constancy + // Helper to add points: either as witnesses or constants based on Constancy. + // Points are encoded as (x, y); the point at infinity is encoded as (0, 0). auto construct_points = [&]() -> std::vector> { if constexpr (points_are_constant) { - // Points are constants - return { WitnessOrConstant::from_constant(point.x), - WitnessOrConstant::from_constant(point.y), - WitnessOrConstant::from_constant(point.is_point_at_infinity() ? FF(1) : FF(0)) }; + return { WitnessOrConstant::from_constant(point.x), WitnessOrConstant::from_constant(point.y) }; } - // Points are witnesses std::vector point_indices = add_to_witness_and_track_indices(witness_values, point); return { WitnessOrConstant::from_index(point_indices[0]), - WitnessOrConstant::from_index(point_indices[1]), - WitnessOrConstant::from_index(point_indices[2]) }; + WitnessOrConstant::from_index(point_indices[1]) }; }; // Helper to add scalars: either as witnesses or constants based on Constancy @@ -112,7 +108,6 @@ template class MultiScalarMulTesti .predicate = WitnessOrConstant::from_index(predicate_index), .out_point_x = result_indices[0], .out_point_y = result_indices[1], - .out_point_is_infinite = result_indices[2], }; } @@ -142,7 +137,6 @@ template class MultiScalarMulTesti // Tamper with the result by setting it to the generator point witness_values[constraint.out_point_x] = GrumpkinPoint::one().x; witness_values[constraint.out_point_y] = GrumpkinPoint::one().y; - witness_values[constraint.out_point_is_infinite] = FF::zero(); break; } case InvalidWitness::Target::None: @@ -314,20 +308,16 @@ TYPED_TEST(MultiScalarMulTestsBothConstant, InvalidWitnesses) } // ============================================================ -// Infinity flag tests +// Infinity tests: the point at infinity is encoded as (0, 0). // ============================================================ -// ACIR convention for encoding a curve point: (x, y, is_infinite) as field values. using MsmGrumpkinPoint = bb::grumpkin::g1::affine_element; using MsmFF = bb::fr; struct MsmAcirPoint { - MsmFF x, y, inf; - static MsmAcirPoint from_native(const MsmGrumpkinPoint& p) - { - return { p.x, p.y, p.is_point_at_infinity() ? MsmFF(1) : MsmFF(0) }; - } - static MsmAcirPoint infinity() { return { MsmFF(0), MsmFF(0), MsmFF(1) }; } + MsmFF x, y; + static MsmAcirPoint from_native(const MsmGrumpkinPoint& p) { return { p.x, p.y }; } + static MsmAcirPoint infinity() { return { MsmFF(0), MsmFF(0) }; } }; // Grumpkin scalar split into low 128-bit and high 128-bit field limbs. @@ -347,16 +337,14 @@ template class MsmSingleTermFixture : public ::testing::Test protected: static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } - // Push an MsmAcirPoint to witness; return [x, y, inf] indices. - static std::array push_point(WitnessVector& witness, const MsmAcirPoint& pt) + // Push an MsmAcirPoint to witness; return [x, y] indices. + static std::array push_point(WitnessVector& witness, const MsmAcirPoint& pt) { uint32_t xi = static_cast(witness.size()); witness.emplace_back(pt.x); uint32_t yi = static_cast(witness.size()); witness.emplace_back(pt.y); - uint32_t ii = static_cast(witness.size()); - witness.emplace_back(pt.inf); - return { xi, yi, ii }; + return { xi, yi }; } // Push a scalar (lo, hi) to witness; return [lo_idx, hi_idx]. @@ -381,14 +369,11 @@ template class MsmSingleTermFixture : public ::testing::Test witness.emplace_back(MsmFF(1)); MultiScalarMul c{ - .points = { WitnessOrConstant::from_index(p[0]), - WitnessOrConstant::from_index(p[1]), - WitnessOrConstant::from_index(p[2]) }, + .points = { WitnessOrConstant::from_index(p[0]), WitnessOrConstant::from_index(p[1]) }, .scalars = { WitnessOrConstant::from_index(s[0]), WitnessOrConstant::from_index(s[1]) }, .predicate = WitnessOrConstant::from_index(pred_idx), .out_point_x = r[0], .out_point_y = r[1], - .out_point_is_infinite = r[2], }; return { c, witness }; } @@ -408,7 +393,7 @@ template class MultiScalarMulInfinityTests : public MsmSingle TYPED_TEST_SUITE(MultiScalarMulInfinityTests, BuilderTypes); -// scalar=0 → result = ∞: valid proof with out_point_is_infinite=1. +// scalar=0 → result = (0, 0): valid circuit. TYPED_TEST(MultiScalarMulInfinityTests, ResultIsInfinity) { BB_DISABLE_ASSERTS(); @@ -420,40 +405,6 @@ TYPED_TEST(MultiScalarMulInfinityTests, ResultIsInfinity) EXPECT_TRUE(ok) << "0 * P = infinity should produce a valid circuit"; } -// A finite result with out_point_is_infinite=1 (forged) must fail. -TYPED_TEST(MultiScalarMulInfinityTests, ForgedInfinityFlagOnFiniteResultFails) -{ - BB_DISABLE_ASSERTS(); - MsmGrumpkinPoint point = MsmGrumpkinPoint::random_element(); - bb::fq scalar_native = bb::fq::random_element(); - while (scalar_native.is_zero()) { - scalar_native = bb::fq::random_element(); - } - MsmGrumpkinPoint result = point * scalar_native; - ASSERT_FALSE(result.is_point_at_infinity()); - auto [constraint, witness] = TestFixture::make_msm( - MsmAcirPoint::from_native(point), MsmScalar::from_native(scalar_native), MsmAcirPoint::from_native(result)); - witness[constraint.out_point_is_infinite] = MsmFF(1); // forge: finite result claimed as infinite - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) - << "Forged infinity flag on finite result should fail"; -} - -// An infinity result with out_point_is_infinite=0 (forged) must fail. -TYPED_TEST(MultiScalarMulInfinityTests, ForgedFiniteFlagOnInfinityResultFails) -{ - BB_DISABLE_ASSERTS(); - MsmGrumpkinPoint point = MsmGrumpkinPoint::random_element(); - // Forge result: (0,0) coordinates but is_infinite=0 (should be 1) - auto [constraint, witness] = TestFixture::make_msm( - MsmAcirPoint::from_native(point), MsmScalar::zero(), MsmAcirPoint{ MsmFF(0), MsmFF(0), MsmFF(0) }); - - auto [ok, err] = TestFixture::run_circuit(constraint, witness); - EXPECT_TRUE(!ok || err.find("assert_eq") != std::string::npos) - << "Forged finite flag on infinity result should fail"; -} - // ============================================================ // Scalar field-bounds tests // ============================================================ diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/opcode_gate_count.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/opcode_gate_count.test.cpp index 73c722bd6c1a..43876202a8cb 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/opcode_gate_count.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/opcode_gate_count.test.cpp @@ -391,25 +391,21 @@ TYPED_TEST(OpcodeGateCountTests, MultiScalarMul) // Create a minimal MSM with one point and one scalar msm_constraint.points.push_back(WitnessOrConstant::from_index(0)); // x msm_constraint.points.push_back(WitnessOrConstant::from_index(1)); // y - msm_constraint.points.push_back(WitnessOrConstant::from_index(2)); // is_infinite - msm_constraint.scalars.push_back(WitnessOrConstant::from_index(3)); // scalar_lo - msm_constraint.scalars.push_back(WitnessOrConstant::from_index(4)); // scalar_hi + msm_constraint.scalars.push_back(WitnessOrConstant::from_index(2)); // scalar_lo + msm_constraint.scalars.push_back(WitnessOrConstant::from_index(3)); // scalar_hi - msm_constraint.predicate = WitnessOrConstant::from_index(5); + msm_constraint.predicate = WitnessOrConstant::from_index(4); - msm_constraint.out_point_x = 6; - msm_constraint.out_point_y = 7; - msm_constraint.out_point_is_infinite = 8; + msm_constraint.out_point_x = 5; + msm_constraint.out_point_y = 6; - WitnessVector witness(9, fr(0)); + WitnessVector witness(7, fr(0)); // Set valid point coordinates witness[0] = point.x; witness[1] = point.y; - witness[2] = fr(0); - witness[6] = point.x; - witness[7] = point.y; - witness[8] = fr(0); + witness[5] = point.x; + witness[6] = point.y; AcirFormat constraint_system = constraint_to_acir_format(msm_constraint); @@ -431,29 +427,23 @@ TYPED_TEST(OpcodeGateCountTests, EcAdd) EcAdd ec_add_constraint{ .input1_x = WitnessOrConstant::from_index(0), .input1_y = WitnessOrConstant::from_index(1), - .input1_infinite = WitnessOrConstant::from_index(2), - .input2_x = WitnessOrConstant::from_index(3), - .input2_y = WitnessOrConstant::from_index(4), - .input2_infinite = WitnessOrConstant::from_index(5), - .predicate = WitnessOrConstant::from_index(6), - .result_x = 7, - .result_y = 8, - .result_infinite = 9, + .input2_x = WitnessOrConstant::from_index(2), + .input2_y = WitnessOrConstant::from_index(3), + .predicate = WitnessOrConstant::from_index(4), + .result_x = 5, + .result_y = 6, }; - WitnessVector witness(10, fr(0)); + WitnessVector witness(7, fr(0)); // Set valid point1 coordinates witness[0] = point1.x; witness[1] = point1.y; - witness[2] = fr(0); // Set valid point2 coordinates - witness[3] = point2.x; - witness[4] = point2.y; - witness[5] = fr(0); + witness[2] = point2.x; + witness[3] = point2.y; // Set valid result coordinates - witness[7] = point1.x; - witness[8] = point1.y; - witness[9] = fr(0); + witness[5] = point1.x; + witness[6] = point1.y; AcirFormat constraint_system = constraint_to_acir_format(ec_add_constraint); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index cb20bb49b70b..d27238411e6f 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -1125,23 +1125,19 @@ struct BlackBoxOp { struct EmbeddedCurveAdd { Acir::MemoryAddress input1_x; Acir::MemoryAddress input1_y; - Acir::MemoryAddress input1_infinite; Acir::MemoryAddress input2_x; Acir::MemoryAddress input2_y; - Acir::MemoryAddress input2_infinite; Acir::HeapArray result; friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); void msgpack_pack(auto& packer) const { - packer.pack_array(7); + packer.pack_array(5); packer.pack(input1_x); packer.pack(input1_y); - packer.pack(input1_infinite); packer.pack(input2_x); packer.pack(input2_y); - packer.pack(input2_infinite); packer.pack(result); } @@ -1152,20 +1148,16 @@ struct BlackBoxOp { auto kvmap = Helpers::make_kvmap(o, name); Helpers::conv_fld_from_kvmap(kvmap, name, "input1_x", input1_x, false); Helpers::conv_fld_from_kvmap(kvmap, name, "input1_y", input1_y, false); - Helpers::conv_fld_from_kvmap(kvmap, name, "input1_infinite", input1_infinite, false); Helpers::conv_fld_from_kvmap(kvmap, name, "input2_x", input2_x, false); Helpers::conv_fld_from_kvmap(kvmap, name, "input2_y", input2_y, false); - Helpers::conv_fld_from_kvmap(kvmap, name, "input2_infinite", input2_infinite, false); Helpers::conv_fld_from_kvmap(kvmap, name, "result", result, false); } else if (o.type == msgpack::type::ARRAY) { auto array = o.via.array; Helpers::conv_fld_from_array(array, name, "input1_x", input1_x, 0); Helpers::conv_fld_from_array(array, name, "input1_y", input1_y, 1); - Helpers::conv_fld_from_array(array, name, "input1_infinite", input1_infinite, 2); - Helpers::conv_fld_from_array(array, name, "input2_x", input2_x, 3); - Helpers::conv_fld_from_array(array, name, "input2_y", input2_y, 4); - Helpers::conv_fld_from_array(array, name, "input2_infinite", input2_infinite, 5); - Helpers::conv_fld_from_array(array, name, "result", result, 6); + Helpers::conv_fld_from_array(array, name, "input2_x", input2_x, 2); + Helpers::conv_fld_from_array(array, name, "input2_y", input2_y, 3); + Helpers::conv_fld_from_array(array, name, "result", result, 4); } else { throw_or_abort("expected MAP or ARRAY for " + name); } @@ -3224,7 +3216,7 @@ struct BlackBoxFuncCall { std::vector points; std::vector scalars; Acir::FunctionInput predicate; - std::shared_ptr> outputs; + std::shared_ptr> outputs; friend bool operator==(const MultiScalarMul&, const MultiScalarMul&); @@ -3259,10 +3251,10 @@ struct BlackBoxFuncCall { }; struct EmbeddedCurveAdd { - std::shared_ptr> input1; - std::shared_ptr> input2; + std::shared_ptr> input1; + std::shared_ptr> input2; Acir::FunctionInput predicate; - std::shared_ptr> outputs; + std::shared_ptr> outputs; friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); @@ -4141,16 +4133,16 @@ struct BrilligOutputs { }; struct MemOp { - Acir::Expression operation; - Acir::Expression index; - Acir::Expression value; + bool read; + Acir::Witness index; + Acir::Witness value; friend bool operator==(const MemOp&, const MemOp&); void msgpack_pack(auto& packer) const { packer.pack_array(3); - packer.pack(operation); + packer.pack(read); packer.pack(index); packer.pack(value); } @@ -4160,12 +4152,12 @@ struct MemOp { std::string name = "MemOp"; if (o.type == msgpack::type::MAP) { auto kvmap = Helpers::make_kvmap(o, name); - Helpers::conv_fld_from_kvmap(kvmap, name, "operation", operation, false); + Helpers::conv_fld_from_kvmap(kvmap, name, "read", read, false); Helpers::conv_fld_from_kvmap(kvmap, name, "index", index, false); Helpers::conv_fld_from_kvmap(kvmap, name, "value", value, false); } else if (o.type == msgpack::type::ARRAY) { auto array = o.via.array; - Helpers::conv_fld_from_array(array, name, "operation", operation, 0); + Helpers::conv_fld_from_array(array, name, "read", read, 0); Helpers::conv_fld_from_array(array, name, "index", index, 1); Helpers::conv_fld_from_array(array, name, "value", value, 2); } else { @@ -4792,7 +4784,6 @@ struct PublicInputs { struct Circuit { std::string function_name; - uint32_t current_witness_index; std::vector opcodes; std::vector private_parameters; Acir::PublicInputs public_parameters; @@ -4803,9 +4794,8 @@ struct Circuit { void msgpack_pack(auto& packer) const { - packer.pack_array(7); + packer.pack_array(6); packer.pack(function_name); - packer.pack(current_witness_index); packer.pack(opcodes); packer.pack(private_parameters); packer.pack(public_parameters); @@ -4819,7 +4809,6 @@ struct Circuit { if (o.type == msgpack::type::MAP) { auto kvmap = Helpers::make_kvmap(o, name); Helpers::conv_fld_from_kvmap(kvmap, name, "function_name", function_name, false); - Helpers::conv_fld_from_kvmap(kvmap, name, "current_witness_index", current_witness_index, false); Helpers::conv_fld_from_kvmap(kvmap, name, "opcodes", opcodes, false); Helpers::conv_fld_from_kvmap(kvmap, name, "private_parameters", private_parameters, false); Helpers::conv_fld_from_kvmap(kvmap, name, "public_parameters", public_parameters, false); @@ -4828,12 +4817,11 @@ struct Circuit { } else if (o.type == msgpack::type::ARRAY) { auto array = o.via.array; Helpers::conv_fld_from_array(array, name, "function_name", function_name, 0); - Helpers::conv_fld_from_array(array, name, "current_witness_index", current_witness_index, 1); - Helpers::conv_fld_from_array(array, name, "opcodes", opcodes, 2); - Helpers::conv_fld_from_array(array, name, "private_parameters", private_parameters, 3); - Helpers::conv_fld_from_array(array, name, "public_parameters", public_parameters, 4); - Helpers::conv_fld_from_array(array, name, "return_values", return_values, 5); - Helpers::conv_fld_from_array(array, name, "assert_messages", assert_messages, 6); + Helpers::conv_fld_from_array(array, name, "opcodes", opcodes, 1); + Helpers::conv_fld_from_array(array, name, "private_parameters", private_parameters, 2); + Helpers::conv_fld_from_array(array, name, "public_parameters", public_parameters, 3); + Helpers::conv_fld_from_array(array, name, "return_values", return_values, 4); + Helpers::conv_fld_from_array(array, name, "assert_messages", assert_messages, 5); } else { throw_or_abort("expected MAP or ARRAY for " + name); } @@ -6535,18 +6523,12 @@ inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd& lhs, const BlackBoxOp if (!(lhs.input1_y == rhs.input1_y)) { return false; } - if (!(lhs.input1_infinite == rhs.input1_infinite)) { - return false; - } if (!(lhs.input2_x == rhs.input2_x)) { return false; } if (!(lhs.input2_y == rhs.input2_y)) { return false; } - if (!(lhs.input2_infinite == rhs.input2_infinite)) { - return false; - } if (!(lhs.result == rhs.result)) { return false; } @@ -6562,10 +6544,8 @@ void serde::Serializable::serialize(const Ac { serde::Serializable::serialize(obj.input1_x, serializer); serde::Serializable::serialize(obj.input1_y, serializer); - serde::Serializable::serialize(obj.input1_infinite, serializer); serde::Serializable::serialize(obj.input2_x, serializer); serde::Serializable::serialize(obj.input2_y, serializer); - serde::Serializable::serialize(obj.input2_infinite, serializer); serde::Serializable::serialize(obj.result, serializer); } @@ -6577,10 +6557,8 @@ Acir::BlackBoxOp::EmbeddedCurveAdd serde::Deserializable::deserialize(deserializer); obj.input1_y = serde::Deserializable::deserialize(deserializer); - obj.input1_infinite = serde::Deserializable::deserialize(deserializer); obj.input2_x = serde::Deserializable::deserialize(deserializer); obj.input2_y = serde::Deserializable::deserialize(deserializer); - obj.input2_infinite = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } @@ -7827,9 +7805,6 @@ inline bool operator==(const Circuit& lhs, const Circuit& rhs) if (!(lhs.function_name == rhs.function_name)) { return false; } - if (!(lhs.current_witness_index == rhs.current_witness_index)) { - return false; - } if (!(lhs.opcodes == rhs.opcodes)) { return false; } @@ -7856,7 +7831,6 @@ void serde::Serializable::serialize(const Acir::Circuit& obj, Ser { serializer.increase_container_depth(); serde::Serializable::serialize(obj.function_name, serializer); - serde::Serializable::serialize(obj.current_witness_index, serializer); serde::Serializable::serialize(obj.opcodes, serializer); serde::Serializable::serialize(obj.private_parameters, serializer); serde::Serializable::serialize(obj.public_parameters, serializer); @@ -7872,7 +7846,6 @@ Acir::Circuit serde::Deserializable::deserialize(Deserializer& de deserializer.increase_container_depth(); Acir::Circuit obj; obj.function_name = serde::Deserializable::deserialize(deserializer); - obj.current_witness_index = serde::Deserializable::deserialize(deserializer); obj.opcodes = serde::Deserializable::deserialize(deserializer); obj.private_parameters = serde::Deserializable::deserialize(deserializer); obj.public_parameters = serde::Deserializable::deserialize(deserializer); @@ -8481,7 +8454,7 @@ namespace Acir { inline bool operator==(const MemOp& lhs, const MemOp& rhs) { - if (!(lhs.operation == rhs.operation)) { + if (!(lhs.read == rhs.read)) { return false; } if (!(lhs.index == rhs.index)) { @@ -8500,7 +8473,7 @@ template void serde::Serializable::serialize(const Acir::MemOp& obj, Serializer& serializer) { serializer.increase_container_depth(); - serde::Serializable::serialize(obj.operation, serializer); + serde::Serializable::serialize(obj.read, serializer); serde::Serializable::serialize(obj.index, serializer); serde::Serializable::serialize(obj.value, serializer); serializer.decrease_container_depth(); @@ -8512,7 +8485,7 @@ Acir::MemOp serde::Deserializable::deserialize(Deserializer& deseri { deserializer.increase_container_depth(); Acir::MemOp obj; - obj.operation = serde::Deserializable::deserialize(deserializer); + obj.read = serde::Deserializable::deserialize(deserializer); obj.index = serde::Deserializable::deserialize(deserializer); obj.value = serde::Deserializable::deserialize(deserializer); deserializer.decrease_container_depth(); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/test_class.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/test_class.hpp index 46e28314aee8..8f3a1d1470e9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/test_class.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/test_class.hpp @@ -1,5 +1,6 @@ #pragma once +#include "barretenberg/common/assert.hpp" #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp" #include "barretenberg/dsl/acir_format/serde/index.hpp" @@ -66,43 +67,16 @@ inline Acir::Expression witness_or_constant_to_expression(const WitnessOrConstan return expr; } -/** - * @brief Convert an AccessType to an Acir::Expression representing the operation type. - * - * @details Read operations are represented by Expression with constant 0, - * Write operations are represented by Expression with constant 1. - */ -inline Acir::Expression access_type_to_expression(AccessType access_type) -{ - bb::fr value = (access_type == AccessType::Write) ? bb::fr::one() : bb::fr::zero(); - return Acir::Expression{ - .mul_terms = {}, - .linear_combinations = {}, - .q_c = value.to_buffer(), - }; -} - -/** - * @brief Convert a witness index to an Acir::Expression representing a single unscaled witness term. - */ -inline Acir::Expression witness_to_expression(uint32_t witness_index) -{ - return Acir::Expression{ - .mul_terms = {}, - .linear_combinations = { std::make_tuple(bb::fr::one().to_buffer(), Acir::Witness{ .value = witness_index }) }, - .q_c = bb::fr::zero().to_buffer(), - }; -} - /** * @brief Convert an acir_format::MemOp to an Acir::MemOp. */ inline Acir::MemOp mem_op_to_acir_mem_op(const MemOp& mem_op) { return Acir::MemOp{ - .operation = access_type_to_expression(mem_op.access_type), - .index = witness_to_expression(mem_op.index), - .value = witness_to_expression(mem_op.value), + // Acir::MemOp::read is the serialized MemOpKind bool: false = Read, true = Write. + .read = (mem_op.access_type == AccessType::Write), + .index = Acir::Witness{ .value = mem_op.index }, + .value = Acir::Witness{ .value = mem_op.value }, }; } @@ -391,10 +365,9 @@ template std::vector constraint_to_acir_ for (const auto& sc : constraint.scalars) { scalars.push_back(witness_or_constant_to_function_input(sc)); } - auto outputs = std::make_shared>(); + auto outputs = std::make_shared>(); (*outputs)[0] = Acir::Witness{ .value = constraint.out_point_x }; (*outputs)[1] = Acir::Witness{ .value = constraint.out_point_y }; - (*outputs)[2] = Acir::Witness{ .value = constraint.out_point_is_infinite }; return { Acir::Opcode{ .value = Acir::Opcode::BlackBoxFuncCall{ .value = Acir::BlackBoxFuncCall{ .value = Acir::BlackBoxFuncCall::MultiScalarMul{ @@ -404,18 +377,15 @@ template std::vector constraint_to_acir_ .outputs = outputs, } } } } }; } else if constexpr (std::is_same_v) { - auto input1 = std::make_shared>(); + auto input1 = std::make_shared>(); (*input1)[0] = witness_or_constant_to_function_input(constraint.input1_x); (*input1)[1] = witness_or_constant_to_function_input(constraint.input1_y); - (*input1)[2] = witness_or_constant_to_function_input(constraint.input1_infinite); - auto input2 = std::make_shared>(); + auto input2 = std::make_shared>(); (*input2)[0] = witness_or_constant_to_function_input(constraint.input2_x); (*input2)[1] = witness_or_constant_to_function_input(constraint.input2_y); - (*input2)[2] = witness_or_constant_to_function_input(constraint.input2_infinite); - auto outputs = std::make_shared>(); + auto outputs = std::make_shared>(); (*outputs)[0] = Acir::Witness{ .value = constraint.result_x }; (*outputs)[1] = Acir::Witness{ .value = constraint.result_y }; - (*outputs)[2] = Acir::Witness{ .value = constraint.result_infinite }; return { Acir::Opcode{ .value = Acir::Opcode::BlackBoxFuncCall{ .value = Acir::BlackBoxFuncCall{ .value = Acir::BlackBoxFuncCall::EmbeddedCurveAdd{ diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/utils.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/utils.hpp index 505f4de368e9..904be8dbe27c 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/utils.hpp @@ -96,8 +96,6 @@ std::vector add_to_witness_and_track_indices(std::vector& witn witness.emplace_back(input.x); indices.emplace_back(witness.size()); witness.emplace_back(input.y); - indices.emplace_back(witness.size()); - witness.emplace_back(input.is_point_at_infinity() ? bb::fr(1) : bb::fr(0)); } else if constexpr (requires { input.data(); input.size(); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp index 3d94d525db72..8f4360f9e192 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.cpp @@ -14,9 +14,8 @@ using namespace bb::stdlib; /** * @brief Convert inputs representing a Grumpkin point into a cycle_group element. - * @details Inputs x, y, and is_infinite are provided from the ACIR opcode. The cycle_group constructor - * auto-detects infinity from (0,0) coordinates; the is_infinite flag is constrained to agree with this - * auto-detected value, ensuring the external flag cannot be forged. + * @details Inputs x and y are provided from the ACIR opcode. The cycle_group constructor auto-detects + * infinity from (0,0) coordinates. * * We handle two special cases: * 1. write_vk scenario: we set the point to be the generator of Grumpkin to avoid circuit construction failures. @@ -26,70 +25,52 @@ using namespace bb::stdlib; * @tparam Builder * @param input_x x-coordinate of the point * @param input_y y-coordinate of the point - * @param input_infinite boolean from ACIR; constrained to agree with the infinity flag in cycle_group * @param predicate A relevant predicate used to conditionally assign the point to a valid value * @param builder * @return bb::stdlib::cycle_group - * - * TODO: remove input_infinite parameter once the ACIR format is updated to drop the is_infinite field for Grumpkin - * points. This requires a noir-side change. */ template bb::stdlib::cycle_group to_grumpkin_point(const WitnessOrConstant& input_x, const WitnessOrConstant& input_y, - const WitnessOrConstant& input_infinite, const bb::stdlib::bool_t& predicate, Builder& builder) { - using bool_ct = bb::stdlib::bool_t; using field_ct = bb::stdlib::field_t; bool constant_coordinates = input_x.is_constant && input_y.is_constant; auto point_x = to_field_ct(input_x, builder); auto point_y = to_field_ct(input_y, builder); - auto infinite = bool_ct(to_field_ct(input_infinite, builder)); // If a witness is not provided (we are in a write_vk scenario) we ensure the coordinates correspond to a valid // point to avoid erroneous failures during circuit construction. We set coordinates to the generator (a finite - // point) and the infinity flag to false for consistency. + // point). if (builder.is_write_vk_mode() && !constant_coordinates) { builder.set_variable(input_x.index, bb::grumpkin::g1::affine_one.x); builder.set_variable(input_y.index, bb::grumpkin::g1::affine_one.y); - if (!input_infinite.is_constant) { - builder.set_variable(input_infinite.index, bb::fr(0)); - } } // If the predicate is a non-constant witness, conditionally replace coordinates with a valid point. if (!predicate.is_constant()) { point_x = field_ct::conditional_assign(predicate, point_x, field_ct(bb::grumpkin::g1::affine_one.x)); point_y = field_ct::conditional_assign(predicate, point_y, field_ct(bb::grumpkin::g1::affine_one.y)); - infinite = bool_ct::conditional_assign(predicate, infinite, bool_ct(false)); } else { BB_ASSERT(predicate.get_value(), "Creating Grumpkin point with a constant predicate equal to false."); } // Use public constructor which auto-detects infinity from (0,0) coordinates. - cycle_group input_point(point_x, point_y, /*assert_on_curve=*/true); - - // The external infinity flag must agree with the auto-detected infinity from coordinates. - infinite.assert_equal(input_point.is_point_at_infinity()); - - return input_point; + return cycle_group(point_x, point_y, /*assert_on_curve=*/true); } template bb::stdlib::cycle_group to_grumpkin_point( const WitnessOrConstant& input_x, const WitnessOrConstant& input_y, - const WitnessOrConstant& input_infinite, const bb::stdlib::bool_t& predicate, UltraCircuitBuilder& builder); template bb::stdlib::cycle_group to_grumpkin_point( const WitnessOrConstant& input_x, const WitnessOrConstant& input_y, - const WitnessOrConstant& input_infinite, const bb::stdlib::bool_t& predicate, MegaCircuitBuilder& builder); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp index 32c033506634..eb9e78a48b6b 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/witness_constant.hpp @@ -48,7 +48,6 @@ bb::stdlib::field_t to_field_ct(const WitnessOrConstant bb::stdlib::cycle_group to_grumpkin_point(const WitnessOrConstant& input_x, const WitnessOrConstant& input_y, - const WitnessOrConstant& input_infinite, const bb::stdlib::bool_t& predicate, Builder& builder); diff --git a/barretenberg/cpp/src/barretenberg/ecc/curves/invert_differential.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/invert_differential.fuzzer.cpp new file mode 100644 index 000000000000..6ef8c48599fb --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/curves/invert_differential.fuzzer.cpp @@ -0,0 +1,240 @@ +/** + * @file invert_differential.fuzzer.cpp + * @brief Differential fuzzer for Bernstein-Yang modular inverse vs Fermat (modexp). + * + * Reuses the FieldVM driver from `multi_field.fuzzer.cpp` to generate diverse + * field elements via sequences of arithmetic operations. After each VM phase + * it takes the last element produced (the highest-indexed non-zero slot in the + * VM's internal state, with a fallback to slot 0) and computes its inverse + * three different ways: + * + * - A: `pow(modulus_minus_two)` — Fermat's little theorem (modexp). + * - B: `invert_vartime` — safegcd, 5×64-bit limb kernel + * (selected on native targets, BATCH=62). + * - C: `invert_vartime` — safegcd, 9×29-bit limb kernel + * (selected on WASM targets, BATCH=58). + * + * All three are compared in canonical (non-Montgomery) form. Any discrepancy + * triggers an abort with full diagnostic output (field type, input, all three + * outputs, plus Montgomery checks `a * X ?= 1` for each). Cross-checking the + * WASM kernel here gives it libFuzzer coverage even though libFuzzer itself + * doesn't run under WASM — both kernels are plain C++ classes. + * + * Only 254-bit primes are tested (BN254 Fr/Fq, Grumpkin shares the BN254 + * curves), since the 5-limb signed BY state requires p < 2^255 and the + * production `field::invert()` dispatch also gates on this. 256-bit primes + * (secp256k1/r1) don't use BY and are skipped. + */ + +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/ecc/fields/bernstein_yang_inverse.hpp" +#include "barretenberg/ecc/fields/field.fuzzer.hpp" +#include +#include +#include +#include +#include +#include + +using namespace bb; +using numeric::uint256_t; + +// --------------------------------------------------------------- +// Phase header — same 2-byte layout as multi_field.fuzzer.cpp but restricted +// to the two 254-bit fields that actually use BY. +// --------------------------------------------------------------- +enum class FieldType : uint8_t { + BN254_FQ = 0, + BN254_FR = 1, +}; + +static constexpr size_t NUM_FIELD_TYPES = 2; +static constexpr size_t MAX_STEPS = 64; +static constexpr size_t PHASE_HEADER_SIZE = 2; + +struct VMPhaseHeader { + uint8_t field_type; + uint8_t steps; +}; +static_assert(sizeof(VMPhaseHeader) == 2, "VMPhaseHeader must be 2 bytes"); + +template static uint256_t reduce_to_modulus(const uint256_t& value) +{ + return (value < Field::modulus) ? value : (value % Field::modulus); +} + +template +static void import_state_with_reduction(FieldVM& vm, const std::vector& state) +{ + for (size_t i = 0; i < INTERNAL_STATE_SIZE && i < state.size(); i++) { + vm.uint_internal_state[i] = reduce_to_modulus(state[i]); + vm.field_internal_state[i] = Field(vm.uint_internal_state[i]); + } +} + +// --------------------------------------------------------------- +// Differential oracle. +// +// Fetches `a_raw` (the non-Montgomery integer) from the VM's uint state and +// computes a^{-1} two ways; aborts on mismatch. +// --------------------------------------------------------------- +template static Field raw_to_montgomery(const uint256_t& raw) +{ + Field f{ raw.data[0], raw.data[1], raw.data[2], raw.data[3] }; + f.self_to_montgomery_form(); + return f; +} + +static void print_limbs(const char* label, const uint256_t& v) +{ + std::fprintf(stderr, + " %s = 0x%016lx%016lx%016lx%016lx\n", + label, + (unsigned long)v.data[3], + (unsigned long)v.data[2], + (unsigned long)v.data[1], + (unsigned long)v.data[0]); +} + +template static void differential_check_inverse(const Field& a_mont, const uint256_t& a_raw) +{ + if (a_raw == 0) { + return; // 0 has no inverse — skip. + } + + // A: Fermat via pow. We bypass field::invert() (which now dispatches into + // BY) by calling pow(modulus_minus_two) directly, so the paths are + // genuinely independent implementations. + Field fermat_inv = a_mont.pow(Field::modulus_minus_two); + + // B, C: Bernstein-Yang safegcd, called with the raw (non-Montgomery) value + // on both the Native5x64 (BATCH=62) and Wasm9x29 (BATCH=58) kernels. + // Each kernel needs its own p_inv_mod_2^BATCH constant. + constexpr uint256_t p_uint = Field::modulus; + constexpr uint64_t p_inv_native = + bernstein_yang::Native5x64::p_inv_mod_2k_from_montgomery_r_inv(Field::Params::r_inv); + constexpr uint64_t p_inv_wasm = bernstein_yang::Wasm9x29::p_inv_mod_2k_from_montgomery_r_inv(Field::Params::r_inv); + + uint256_t native_inv_raw = bernstein_yang::invert_vartime(a_raw, p_uint, p_inv_native); + uint256_t wasm_inv_raw = bernstein_yang::invert_vartime(a_raw, p_uint, p_inv_wasm); + + Field native_inv = raw_to_montgomery(native_inv_raw); + Field wasm_inv = raw_to_montgomery(wasm_inv_raw); + + const bool native_ok = (fermat_inv == native_inv); + const bool wasm_ok = (fermat_inv == wasm_inv); + if (native_ok && wasm_ok) { + return; + } + + std::fprintf(stderr, "\n[invert_differential.fuzzer] MISMATCH\n"); + std::fprintf(stderr, " field: %s\n", typeid(Field).name()); + std::fprintf(stderr, " native_ok: %s\n", native_ok ? "yes" : "NO"); + std::fprintf(stderr, " wasm_ok: %s\n", wasm_ok ? "yes" : "NO"); + print_limbs("a_raw ", a_raw); + print_limbs("fermat ", static_cast(fermat_inv)); + print_limbs("BY native ", static_cast(native_inv)); + print_limbs("BY wasm ", static_cast(wasm_inv)); + print_limbs("a*fermat ", static_cast(a_mont * fermat_inv)); + print_limbs("a*native ", static_cast(a_mont * native_inv)); + print_limbs("a*wasm ", static_cast(a_mont * wasm_inv)); + std::fflush(stderr); + std::abort(); +} + +// Pick the last element produced: highest-indexed non-zero slot of the VM's +// uint state, with a fallback to slot 0 if all slots are zero. +static size_t last_element_index(const std::vector& state) +{ + for (size_t i = state.size(); i > 0; --i) { + if (state[i - 1] != uint256_t(0)) { + return i - 1; + } + } + return 0; +} + +template +static int run_phase_and_diff(const VMPhaseHeader& header, + const unsigned char* data, + size_t size, + size_t& data_offset, + std::vector& current_state) +{ + FieldVM vm(false, header.steps); + if (!current_state.empty()) { + import_state_with_reduction(vm, current_state); + } + vm.set_max_steps(header.steps); + size_t bytes_consumed = vm.run(data + data_offset, size - data_offset, true); + if (bytes_consumed == 0) { + return 0; + } + + if (!vm.check_internal_state()) { + // Internal VM invariant violation — not the inverse bug we're looking + // for, but still a failure of the driver. Report and stop. + std::fprintf(stderr, "[invert_differential.fuzzer] VM internal state check failed\n"); + return -1; + } + + // Differential inverse check on the last element produced this phase, + // plus every non-zero slot in the final state for extra coverage. + auto uint_state = vm.export_uint_state(); + size_t last_idx = last_element_index(uint_state); + differential_check_inverse(vm.field_internal_state[last_idx], uint_state[last_idx]); + + // Extra coverage: also diff every other non-zero slot. Same check on + // many more values per phase, virtually free CPU-wise. + for (size_t i = 0; i < uint_state.size(); ++i) { + if (i != last_idx && uint_state[i] != uint256_t(0)) { + differential_check_inverse(vm.field_internal_state[i], uint_state[i]); + } + } + + current_state = uint_state; + data_offset += bytes_consumed; + return 1; +} + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) +{ + if (size < PHASE_HEADER_SIZE) { + return 0; + } + + std::vector current_state; + size_t data_offset = 0; + + while (data_offset + PHASE_HEADER_SIZE <= size) { + const VMPhaseHeader* header_ptr = reinterpret_cast(data + data_offset); + VMPhaseHeader header = *header_ptr; + + FieldType selected_field_type = static_cast(header.field_type % NUM_FIELD_TYPES); + uint8_t selected_steps = header.steps % MAX_STEPS; + if (selected_steps == 0) { + selected_steps = 1; + } + header.field_type = static_cast(selected_field_type); + header.steps = selected_steps; + + int r = 0; + switch (selected_field_type) { + case FieldType::BN254_FQ: + r = run_phase_and_diff(header, data, size, data_offset, current_state); + break; + case FieldType::BN254_FR: + r = run_phase_and_diff(header, data, size, data_offset, current_state); + break; + } + + if (r < 0) { + return 1; + } + if (r == 0) { + break; + } + } + return 0; +} diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.hpp new file mode 100644 index 000000000000..4e4190d1bdf9 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.hpp @@ -0,0 +1,369 @@ +// Bernstein-Yang safegcd modular inverse. +// +// We want a⁻¹ mod p, where p is an odd prime. Run an extended binary GCD on +// the pair (f, g) starting at (p, a), with Bezout coefficients (d, e) +// satisfying invariants d·a ≡ f (mod p) and e·a ≡ g (mod p) at all times. +// When g reaches 0, gcd(p, a) = ±f = ±1 (since p is prime, a ≠ 0), so +// a⁻¹ = ±d. +// +// The cheap operation in a binary GCD is "if g is odd swap-and-subtract to +// make it even, then divide g by 2"; one such step is a "divstep" and +// shrinks |g| by ~1 bit. Doing each divstep on the full 256-bit state would +// be slow, so we use Pornin's trick: do BATCH divsteps purely on the low 64 +// bits of (f, g), accumulating the resulting linear transform as a 2×2 +// integer matrix M, then apply M to the full-precision (f, g, d, e) in one +// go (with an exact /2^BATCH at the end). The (d, e) side needs a 2-adic +// correction k·p added before dividing so the result stays integer-valued +// — k is determined by the low BATCH bits of M·(d, e) and p⁻¹ mod 2^BATCH. +// +// Native5x64 and Wasm9x29 wrap the platform-specific limb representation +// behind the same static interface so `invert_vartime` below is a +// single algorithm for both targets. + +#pragma once + +#include "barretenberg/numeric/uint256/uint256.hpp" +#include + +namespace bb::bernstein_yang { + +using numeric::uint256_t; +using u64 = uint64_t; +using i64 = int64_t; + +// The transition matrix produced by BATCH divsteps. With the implicit +// "/ 2^BATCH" at the end of apply_divstep_matrix, it represents the linear +// map (f, g) ↦ (M·(f, g) / 2^BATCH). Each divstep doubles one matrix entry, +// so after BATCH steps |u|, |v|, |q|, |r| ≤ 2^BATCH; they are signed (the +// swap-and-subtract case introduces negatives). +struct DivstepMatrix { + i64 u, v, q, r; +}; + +// 5 × 64-bit limbs, top limb two's-complement signed. Products via __int128. +class Native5x64 { + public: + // Number of divsteps folded into one matrix application. Bigger BATCH + // means fewer matrix applications per inversion but bigger matrix + // entries. Cap is set by the matrix-times-state product staying inside + // an __int128 accumulator: a single (i63 entry) × (u64 limb) is 127 bits, + // so BATCH ≤ 63; we use 62 to keep one bit of slack for the running sum. + static constexpr int BATCH = 62; + + // Worst-case number of matrix applications needed before g must have + // reached 0. The 735-divstep bound for 254-bit inputs is from the BY + // paper's convergence proof (rate ≈ 1 / 1.7 bits of g consumed per + // divstep). We pick the smallest NUM_ITERATIONS so NUM_ITERATIONS * + // BATCH ≥ 735; ⌈735 / 62⌉ = 12. The actual loop usually exits much + // earlier via the early break on g == 0. + static constexpr int NUM_ITERATIONS = 12; + + // The Bezout coefficients (d, e) live mod p but during the iteration we + // hold them as signed integers in the state. Each matrix application grows + // |d|, |e| by roughly a factor of 2 (matrix entry × value) plus an + // additive p (from the 2-adic correction k·p), so without bringing them + // back to [0, p) they would eventually overflow the state. + // reduce_to_canonical does that subtract-or-add-p reduction. Calling it + // every iter is wasteful — the 5×64-bit signed state has enough room to + // let |d|, |e| reach ~2^K · p before they no longer fit, so we only + // reduce every REDUCE_INTERVAL = 4 iters (|d|, |e| stay ≤ ~32p between + // reductions, plenty of headroom). + static constexpr int REDUCE_INTERVAL = 4; + + // Worst-case iteration cap inside reduce_to_canonical. After + // REDUCE_INTERVAL iters between reductions, |d|, |e| ≤ (2^(REDUCE_INTERVAL+1) - 1)·p, + // so reducing requires that many subtractions plus one break iter. + static constexpr int REDUCE_TO_CANONICAL_MAX_ITERS = 36; + static_assert((1U << (REDUCE_INTERVAL + 1)) <= REDUCE_TO_CANONICAL_MAX_ITERS, + "REDUCE_INTERVAL too large for reduce_to_canonical iteration bound"); + + Native5x64() noexcept + : l{} + {} + explicit Native5x64(const uint256_t& x) noexcept + : l{ x.data[0], x.data[1], x.data[2], x.data[3], 0 } + {} + static Native5x64 one() noexcept + { + Native5x64 r; + r.l[0] = 1; + return r; + } + + uint256_t to_uint256() const noexcept { return { l[0], l[1], l[2], l[3] }; } + u64 low_64() const noexcept { return l[0]; } + bool is_zero() const noexcept { return (l[0] | l[1] | l[2] | l[3] | l[4]) == 0; } + bool is_negative() const noexcept { return (i64)l[4] < 0; } + void neg() noexcept + { + u64 c = 1; + for (int i = 0; i < N; ++i) { + u64 v = (~l[i]) + c; + c = (c && v == 0) ? 1 : 0; + l[i] = v; + } + } + // Iter cap chosen by the REDUCE_TO_CANONICAL_MAX_ITERS / REDUCE_INTERVAL + // static_assert above; see those constants for the magnitude argument. + void reduce_to_canonical(const Native5x64& p) noexcept + { + for (int it = 0; it < REDUCE_TO_CANONICAL_MAX_ITERS; ++it) { + if (is_negative()) { + add_inplace(p); + } else if (ge(p)) { + sub_inplace(p); + } else { + break; + } + } + } + + // BATCH branchy divsteps on the low 64 bits of (f, g); returns the + // transition matrix M and updates δ. Variable-time over the inner + // branches — non-secret inputs only. + static DivstepMatrix compute_divstep_matrix(i64& delta, u64 f_lo, u64 g_lo) noexcept; + // (f, g) ← M·(f, g) / 2^BATCH and (d, e) ← (M·(d, e) + k·p) / 2^BATCH, + // where k_i = -((M·(d, e))_i · p⁻¹) mod 2^BATCH (the 2-adic correction + // that makes (M·(d, e))_i + k_i·p divisible by 2^BATCH). + static void apply_divstep_matrix(const DivstepMatrix& m, + Native5x64& f, + Native5x64& g, + Native5x64& d, + Native5x64& e, + const Native5x64& p, + u64 p_inv_mod_2k) noexcept; + // r_inv = -p⁻¹ mod 2^64 (barretenberg's Montgomery constant), so p⁻¹ mod + // 2^BATCH is the low BATCH bits of -r_inv. + static constexpr u64 p_inv_mod_2k_from_montgomery_r_inv(u64 r_inv) noexcept + { + // r_inv = -p^{-1} mod 2^64, so 0 - r_inv = p^{-1} mod 2^64. + return (0ULL - r_inv) & ((1ULL << BATCH) - 1); + } + + private: + static constexpr int N = 5; + u64 l[N]; + + void add_inplace(const Native5x64& b) noexcept + { + u64 c = 0; + for (int i = 0; i < N; ++i) { + __uint128_t s = (__uint128_t)l[i] + b.l[i] + c; + l[i] = (u64)s; + c = (u64)(s >> 64); + } + } + void sub_inplace(const Native5x64& b) noexcept + { + u64 borrow = 0; + for (int i = 0; i < N; ++i) { + __uint128_t s = (__uint128_t)l[i] - (__uint128_t)b.l[i] - borrow; + l[i] = (u64)s; + borrow = ((i64)(s >> 64) < 0) ? 1 : 0; + } + } + bool ge(const Native5x64& b) const noexcept + { + i64 a_top = (i64)l[N - 1], b_top = (i64)b.l[N - 1]; + if (a_top != b_top) { + return a_top > b_top; + } + for (int i = N - 2; i >= 0; --i) { + if (l[i] != b.l[i]) { + return l[i] > b.l[i]; + } + } + return true; + } + + friend struct NativeMatrix; +}; + +// 6-limb signed product helpers used by Native5x64::apply_divstep_matrix. +struct NativeMatrix { + static void signed_linear_combination(i64 a, const Native5x64& x, i64 b, const Native5x64& y, u64 out[6]) noexcept + { + __int128 c = 0; + for (int i = 0; i < 4; ++i) { + c += (__int128)a * (__int128)(u64)x.l[i] + (__int128)b * (__int128)(u64)y.l[i]; + out[i] = (u64)c; + c >>= 64; + } + c += (__int128)a * (__int128)(i64)x.l[4] + (__int128)b * (__int128)(i64)y.l[4]; + out[4] = (u64)c; + out[5] = (u64)(c >> 64); + } + // Sign-preserving exact /2^BATCH on the 6-limb signed `t`. Sign of the + // result lives in bit 63 of r.l[4], which is bit 61 of t[5]. This is the + // sign of t iff t[5] is just sign-extension of the actual magnitude — i.e., + // iff |t| < 2^319. BY guarantees this: |M·(x,y) + k·p| ≤ 2^324 in the + // (d,e) row and ≤ 2^319 in the (f,g) row, both with |result/2^62| < 2^263 < 2^319. + // A future change widening the matrix entries or state without re-running + // this analysis will silently corrupt the sign bit. + static Native5x64 arithmetic_shift_by_batch(const u64 t[6]) noexcept + { + Native5x64 r; + for (int i = 0; i < 4; ++i) { + r.l[i] = (t[i] >> 62) | (t[i + 1] << 2); + } + r.l[4] = (t[4] >> 62) | (t[5] << 2); + return r; + } +}; + +// Each inner step shrinks |g| by ~1 bit using a binary-GCD-style move. +// Three cases, depending on g's parity and the "δ" tracker (which decides +// whether |f| or |g| is currently smaller): +// g even : g ← g/2. +// g odd, δ ≤ 0 : g ← (g + f)/2 (adding f to make g+f even before /2). +// g odd, δ > 0 : swap roles — (f, g) ← (g, (g - f)/2). +// The matrix (u, v, q, r) tracks the same linear transform applied +// symbolically; doubling u, v (or q, r) corresponds to the implicit /2 each +// inner step performs. After BATCH steps the low BATCH bits of the +// transformed state are guaranteed zero, so apply_divstep_matrix's implicit +// "/ 2^BATCH" is an exact integer division. +inline DivstepMatrix Native5x64::compute_divstep_matrix(i64& delta, u64 f_lo, u64 g_lo) noexcept +{ + i64 u = 1, v = 0, q = 0, r = 1; + for (int i = 0; i < BATCH; ++i) { + if (g_lo & 1) { + if (delta > 0) { + u64 nf = g_lo, ng = (g_lo - f_lo) >> 1; + i64 nu = q << 1, nv = r << 1, nq = q - u, nr = r - v; + f_lo = nf; + g_lo = ng; + u = nu; + v = nv; + q = nq; + r = nr; + delta = 1 - delta; + } else { + g_lo = (g_lo + f_lo) >> 1; + q = q + u; + r = r + v; + u <<= 1; + v <<= 1; + delta = delta + 1; + } + } else { + g_lo >>= 1; + u <<= 1; + v <<= 1; + delta = delta + 1; + } + } + return { u, v, q, r }; +} + +inline void Native5x64::apply_divstep_matrix(const DivstepMatrix& m, + Native5x64& f, + Native5x64& g, + Native5x64& d, + Native5x64& e, + const Native5x64& p, + u64 p_inv_mod_2k) noexcept +{ + constexpr u64 MASK_BATCH = (1ULL << BATCH) - 1; + + u64 nf[6], ng[6]; + NativeMatrix::signed_linear_combination(m.u, f, m.v, g, nf); + NativeMatrix::signed_linear_combination(m.q, f, m.r, g, ng); + f = NativeMatrix::arithmetic_shift_by_batch(nf); + g = NativeMatrix::arithmetic_shift_by_batch(ng); + + // k = -t · p_inv_mod_2k mod 2^BATCH makes t + k·p divisible by 2^BATCH. + auto apply_corrected_row = [&](i64 a, const Native5x64& da, i64 b, const Native5x64& eb, Native5x64& out) { + u64 t[6]; + NativeMatrix::signed_linear_combination(a, da, b, eb, t); + u64 k = ((0ULL - t[0]) * p_inv_mod_2k) & MASK_BATCH; + u64 kp[6] = {}; + u64 carry = 0; + for (int i = 0; i < 5; ++i) { + __uint128_t prod = (__uint128_t)k * (u64)p.l[i] + carry; + kp[i] = (u64)prod; + carry = (u64)(prod >> 64); + } + kp[5] = carry; + u64 c = 0; + for (int i = 0; i < 6; ++i) { + __uint128_t s = (__uint128_t)t[i] + kp[i] + c; + t[i] = (u64)s; + c = (u64)(s >> 64); + } + out = NativeMatrix::arithmetic_shift_by_batch(t); + }; + Native5x64 nd, ne; + apply_corrected_row(m.u, d, m.v, e, nd); + apply_corrected_row(m.q, d, m.r, e, ne); + d = nd; + e = ne; +} + +} // namespace bb::bernstein_yang + +#include "./bernstein_yang_inverse_wasm.hpp" + +namespace bb::bernstein_yang { + +#if defined(__wasm__) +using State = Wasm9x29; +#else +using State = Native5x64; +#endif + +/** + * @brief Variable-time safegcd inverse (Bernstein-Yang TCHES 2019, Pornin 2020 §4). + * + * Iterates (f, g) starting at (p, a); each outer iter batches BATCH divsteps + * into a 2×2 matrix M and applies M to (f, g) / (d, e). When g reaches 0, + * gcd(p, a) = ±f and a⁻¹ = ±d mod p. Returns 0 for a == 0. + * + * @param p_inv_mod_2k p⁻¹ mod 2^BATCH (used by apply_divstep_matrix's 2-adic correction). + * @pre p odd prime, p < 2^255, 0 ≤ a < p. + */ +template +inline uint256_t invert_vartime(const uint256_t& a, const uint256_t& p, u64 p_inv_mod_2k) noexcept +{ + if (a == uint256_t(0)) { + return uint256_t(0); + } + S P(p), f = P, g(a), d, e = S::one(); + // δ is Pornin's auxiliary used by the divstep rule to decide swap-vs-add cases. + i64 delta = 1; + for (int i = 0; i < S::NUM_ITERATIONS; ++i) { + DivstepMatrix m = S::compute_divstep_matrix(delta, f.low_64(), g.low_64()); + S::apply_divstep_matrix(m, f, g, d, e, P, p_inv_mod_2k); + if (g.is_zero()) { + break; + } + if ((i + 1) % S::REDUCE_INTERVAL == 0) { + d.reduce_to_canonical(P); + e.reduce_to_canonical(P); + } + } + d.reduce_to_canonical(P); + if (f.is_negative()) { + d.neg(); + d.reduce_to_canonical(P); + } + return d.to_uint256(); +} + +inline constexpr u64 p_inv_mod_2k_from_montgomery_r_inv(u64 r_inv) noexcept +{ + return State::p_inv_mod_2k_from_montgomery_r_inv(r_inv); +} + +// True iff `invert_vartime` is usable for field params T: the active +// kernel must be compilable on this toolchain (Native5x64 needs __int128, the +// WASM kernel is unconditional) and T's modulus must fit BY's < 2^255 +// precondition. Used to gate the dispatch in `field::invert()`. +template +inline constexpr bool supported_v = +#if defined(__SIZEOF_INT128__) || defined(__wasm__) + T::modulus_3 < (1ULL << 63); +#else + false; +#endif + +} // namespace bb::bernstein_yang diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.md b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.md new file mode 100644 index 000000000000..c03ca5c5bd0e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.md @@ -0,0 +1,392 @@ +# Bernstein–Yang modular inverse: the algorithm + +A description of the modular inverse algorithm implemented in `bernstein_yang_inverse.hpp`. + +Throughout, $p$ is an **odd prime**, $0 < a < p$, and we want +$$a^{-1} \bmod p.$$ + +All quantities are integers; reductions modulo $p$ are made explicit when used. + +--- + +## 1. Setup + +We track a $2 \times 2$ integer matrix + +$$ +\Phi \;=\; \begin{pmatrix} f & d \\ g & e \end{pmatrix} +$$ + +initialised at + +$$ +\Phi_0 \;=\; \begin{pmatrix} p & 0 \\ a & 1 \end{pmatrix}, \qquad \det \Phi_0 \;=\; p. +$$ + +### The kernel invariant + +The whole algorithm preserves a single congruence: + +$$ +\boxed{\quad \Phi \begin{pmatrix} 1 \\ -a \end{pmatrix} \;\equiv\; \begin{pmatrix} 0 \\ 0 \end{pmatrix} \pmod p. \quad} +$$ + +Equivalently, the column vector $(1, -a)^T \in \mathbb{F}_p^2$ is in the kernel +of $\Phi \bmod p$. Unpacking entry by entry, this is just two Bezout congruences: + +$$ +f \;\equiv\; d \cdot a \pmod p, \qquad g \;\equiv\; e \cdot a \pmod p. +$$ + +The initial state satisfies them ($p \equiv 0 \cdot a$, $a \equiv 1 \cdot a$). + +### The reduction goal + +We reduce $\Phi$ to upper triangular form: + +$$ +\Phi_N \;=\; \begin{pmatrix} \pm 1 & a^{-1} \bmod p \\ 0 & \star \end{pmatrix}. +$$ + +When $g = 0$, the kernel invariant gives $e a \equiv 0 \pmod p$, +hence (since $\gcd(a, p) = 1$) $p \mid e$, putting the bottom-right at a +multiple of $p$. Independently, $f$ at termination equals $\pm \gcd(p, a) = \pm 1$, +and the invariant collapses to $d a \equiv \pm 1 \pmod p$, giving +$a^{-1} \equiv \pm d \pmod p$. The sign is read off the top-left entry. + +So **the BY algorithm is a reduction of $\Phi_0$ to upper triangular form, with +the inverse appearing as the top-right entry.** + +--- + +## 2. The generators $L_a, L_b, L_c$ + +The algorithm proceeds by repeated left multiplication: $\Phi \to L_n \Phi$, +choosing $L_n$ from a fixed set of three matrices: + +$$ +L_a \;=\; \begin{pmatrix} 1 & 0 \\ 0 & \tfrac{1}{2} \end{pmatrix}, \qquad +L_b \;=\; \begin{pmatrix} 1 & 0 \\ \tfrac{1}{2} & \tfrac{1}{2} \end{pmatrix}, \qquad +L_c \;=\; \begin{pmatrix} 0 & 1 \\ -\tfrac{1}{2} & \tfrac{1}{2} \end{pmatrix}. +$$ + +Each has $\det L_n = \tfrac{1}{2}$, so $L_n \in \mathrm{GL}_2(\mathbb{Z}[\tfrac{1}{2}])$ +but not in $\mathrm{SL}_2$. They act on the rows of $\Phi$: equivalently, on +$(f, g)$ and on $(d, e)$ in lockstep. + +### Divstep + +A small auxiliary integer $\delta$ is carried alongside $\Phi$, initialised at +$\delta_0 = 1$. At every step, the parity of $g$ together with the sign of +$\delta$ dictates which generator to apply: + +| Condition | Generator | $\delta$ update | +| --- | --- | --- | +| $g$ even | $L_a$ | $\delta \leftarrow \delta + 1$ | +| $g$ odd, $\delta \le 0$ | $L_b$ | $\delta \leftarrow \delta + 1$ | +| $g$ odd, $\delta > 0$ | $L_c$ | $\delta \leftarrow 1 - \delta$ | + +The convention $f$ odd is maintained throughout: $p$ is odd, the $L_n$ preserve +$f \bmod 2$, so $f$ stays odd until termination. + +One application of this rule is one **divstep**. Each divstep multiplies $\det \Phi$ +by $\tfrac{1}{2}$ (so after $N$ divsteps $\det \Phi_N = p / 2^N$) and shrinks +the magnitude of the lower-left entry $g$ on average. + +### Why the case split makes sense + +Unpacking $L_a, L_b, L_c$ as row operations on $(f, g)$: + +- $L_a$: $g \leftarrow g/2$. Valid only when $g$ is even, otherwise the result is non-integer. +- $L_b$: $g \leftarrow (g + f)/2$. Used when $g$ is odd but $|g| \le |f|$ in spirit (tracked by $\delta \le 0$): adding $f$ first makes the sum even. +- $L_c$: $(f, g) \leftarrow (g, (g - f)/2)$. Swap-and-subtract; used when $g$ is odd and $|g| > |f|$ in spirit ($\delta > 0$). + +The "in spirit" caveats are because BY tracks $|f|$ vs. $|g|$ comparisons via the +integer $\delta$ rather than by an actual size comparison — $\delta$ effectively +measures the running deficit "extra divisions of $g$ over extra divisions of $f$." + +### Right-column $p$-shift + +Left multiplication by $L_n$ alone would leave $\Phi$ with non-integer entries +in the right column (because $L_n$ has $\tfrac{1}{2}$ entries acting on +$(d, e)$). To keep the state integer-valued we add a multiple of $p$ to the +right column before halving — a *2-adic correction* that vanishes modulo $p$ +and hence doesn't disturb the kernel invariant. The mechanics live in §6. + +So one full divstep is: +$$ +\Phi \;\longmapsto\; L_n \,\Phi \;+\; p \cdot \big(\text{adjustment in right column}\big), \qquad L_n \in \{L_a, L_b, L_c\}. +$$ + +The left column ($f, g$) updates via clean left multiplication; the right +column ($d, e$) updates via left multiplication plus a $p$-shift. + +--- + +## 3. Convergence + +The Bernstein--Yang/Pornin convergence proof guarantees $g = 0$ within 735 divsteps for 254-bit inputs; native runs $12 \cdot 62 = 744$ divsteps and wasm runs $13 \cdot 58 = 754$, so both cover the bound. + +--- + +## 4. Batching: products of $L_n$ as a $2 \times 2$ matrix + +A single divstep touches only the lowest bit of $g$ (to read parity) and is a +linear combination of $(f, g)$. So the next $\mathrm{BATCH}$ divsteps depend +only on the low $\mathrm{BATCH}$ bits of $(f, g)$ — the high bits do not +influence the choice between $L_a, L_b, L_c$ within those steps. + +Let $\mathrm{BATCH} = 62$ (the implementation choice on native; $58$ on wasm). +Run $\mathrm{BATCH}$ divsteps purely on the low $64$ bits of $(f, g)$, +accumulating the result as a single $2 \times 2$ rational matrix + +$$ +M \;=\; L_{n_{\mathrm{BATCH}-1}} \cdots L_{n_1} L_{n_0} \;=\; \begin{pmatrix} u & v \\ q & r \end{pmatrix} \cdot 2^{-\mathrm{BATCH}}. +$$ + +After clearing the implicit denominator, the *integer* part $\begin{pmatrix} u & v \\ q & r \end{pmatrix} = 2^{\mathrm{BATCH}} M$ has all four entries bounded by $|u|, |v|, |q|, |r| \le 2^{\mathrm{BATCH}}$ (each individual $L_n$ at most doubles one entry of the running product). With $\mathrm{BATCH} = 62$, the four entries fit in `int64_t`. + +--- + +## 5. Applying $M$ to the left column $(f, g)$ + +The new $(f', g')^T = M \cdot (f, g)^T$ is computed as + +1. The two integer linear combinations + $$t_f = u \cdot f + v \cdot g, \qquad t_g = q \cdot f + r \cdot g$$ + in full precision. With $|u|, \ldots, |r| \le 2^{62}$ and $|f|, |g|$ + fitting in $256$ bits (see §7), each product fits in $318$ bits and the + sum in $319$ bits. +2. Arithmetic-right-shift by $\mathrm{BATCH}$ bits: + $$f' \;=\; t_f \gg \mathrm{BATCH}, \qquad g' \;=\; t_g \gg \mathrm{BATCH}.$$ + +The shift is exact: the low $\mathrm{BATCH}$ bits of $t_f$ and $t_g$ are zero +by construction. Each divstep makes one bit of $g$ cancel, and after +$\mathrm{BATCH}$ divsteps the bottom $\mathrm{BATCH}$ bits of the linear +combinations are guaranteed zero — this is the "exact integer division" +property of the divstep cascade. + +In the implementation this lives in `NativeMatrix::signed_linear_combination` (the +products) and `NativeMatrix::arithmetic_shift_by_batch` (the right shift). + +--- + +## 6. Applying $M$ to the right column $(d, e)$: the 2-adic correction + +Applying $M$ to $(d, e)$ presents the same divisibility question, but now the +state lives modulo $p$. The integer linear combination $t = u \cdot d + v \cdot e$ +is **not** generally divisible by $2^{\mathrm{BATCH}}$. We need an integer +correction $k$ such that $t + k \cdot p$ is divisible by $2^{\mathrm{BATCH}}$, +then take the quotient. + +This is a 2-adic problem: + +$$ +t + k\cdot p \;\equiv\; 0 \pmod{2^{\mathrm{BATCH}}} +\;\Longleftrightarrow\; +k \;\equiv\; -\, t \cdot p^{-1} \pmod{2^{\mathrm{BATCH}}}. +$$ + +$p$ is odd, so $p^{-1} \bmod 2^{\mathrm{BATCH}}$ exists. The implementation +precomputes it once: $p^{-1} \bmod 2^{\mathrm{BATCH}}$ is the low +$\mathrm{BATCH}$ bits of $-r_{\mathrm{inv}}$, where $r_{\mathrm{inv}}$ is +barretenberg's Montgomery constant $-p^{-1} \bmod 2^{64}$. + +The correction step: + +$$ +\begin{aligned} +t &\;=\; u \cdot d + v \cdot e, \\ +k &\;\equiv\; -\, t \cdot p^{-1} \pmod{2^{\mathrm{BATCH}}}, \\ +d' &\;=\; (t + k \cdot p) \gg \mathrm{BATCH}. +\end{aligned} +$$ + +After the shift, $d'$ is an integer (because $t + k \cdot p$ is divisible by +$2^{\mathrm{BATCH}}$). The added $k \cdot p$ contributes only a multiple of $p$ +to the right column, so the kernel invariant $\Phi \binom{1}{-a} \equiv 0 \pmod p$ +is preserved. + +The same construction applied with $(q, r)$ and the second row of $M$ gives +the new $e'$. This is `apply_corrected_row` in the implementation. + +--- + +## 7. State bounds: why 5 limbs + +`Native5x64` stores each state value in five signed 64-bit limbs. Four limbs +would be enough for canonical field elements, but the BY state is not always +canonical while a batched matrix is being applied. + +For the left column, $f$ and $g$ are roughly 256-bit values between matrix +applications. During §5, however, the products $u f$, $v g$, $q f$, and $r g$ +can be as large as $2^{62} \cdot 2^{256}$, and their sums need about 319 bits. +Those sums are held in the temporary six-limb arrays inside +`NativeMatrix::signed_linear_combination`; after the exact right shift by +`BATCH`, $f$ and $g$ return to the normal state size. + +For the right column, $d$ and $e$ need extra resting headroom too. The 2-adic +correction adds $k \cdot p$ before the shift, and repeated matrix applications +can move 00,p)1 The implementation therefore reduces them +to canonical form every `REDUCE_INTERVAL = 4` iterations rather than after every +matrix application. + +Between reductions, $|d|$ and $|e|$ are bounded by roughly $32p$. Five signed +64-bit limbs provide about 319 bits of magnitude, enough room for that growth. +`Native5x64::reduce_to_canonical(p)` then repeatedly adds or subtracts $p$, +with a loop bound of 36 to cover the same worst-case headroom. + +--- + +## 8. Final answer extraction + +After the iteration loop: + +- $g = 0$. +- $f = \pm \gcd(p, a) = \pm 1$. +- Kernel invariant: $d \cdot a \equiv f \pmod{p}$, so $d \equiv \pm a^{-1} \pmod p$. + +Reduce $d$ to canonical form $[0, p)$. Then + +$$ +a^{-1} \bmod p \;=\; +\begin{cases} +d & \text{if } f > 0, \\ +{-d} \bmod p & \text{if } f < 0. +\end{cases} +$$ + +In code, this is the +`if (f.is_negative()) { d.neg(); d.reduce_to_canonical(P); }` at the end of +`invert_vartime`. + +--- + +## 9. Math-to-code map + +The implementation keeps the same mathematical state but hides the limb details +behind `Native5x64` and `Wasm9x29`. + +| Math description | Code | +| --- | --- | +| $\Phi = \begin{pmatrix} f & d \\ g & e \end{pmatrix}$ | `S P(p), f = P, g(a), d, e = S::one()` in `invert_vartime` | +| Auxiliary divstep counter $\delta$ | local `i64 delta` | +| Product of one batch of divsteps | `S::compute_divstep_matrix(delta, f.low_64(), g.low_64())` | +| $M = \begin{pmatrix} u & v \\ q & r \end{pmatrix} 2^{-B}$ | `DivstepMatrix { u, v, q, r }`; the denominator is the implicit `2^BATCH` | +| $M(f,g)/2^B$ | `apply_divstep_matrix`, using `NativeMatrix::signed_linear_combination` and `arithmetic_shift_by_batch` on native | +| $k \equiv -t p^{-1} \pmod {2^B}$ | `apply_corrected_row` on native; streamed as `k_d`, `k_e` on wasm | +| $p^{-1} \bmod 2^B$ from Montgomery metadata | `p_inv_mod_2k_from_montgomery_r_inv` | +| Periodic reduction of $d,e$ modulo $p$ | `reduce_to_canonical(P)` every `REDUCE_INTERVAL` iterations | +| Final sign correction $a^{-1} = \pm d$ | final `if (f.is_negative()) { d.neg(); ... }` | +| Platform-specific limb representation | `using State = Native5x64` or `Wasm9x29` | + +--- + +## 10. Example + +This example uses the same batched mechanics as the implementation, but with a toy $B = 3$ instead of native $B = 62$. + +Let + +$$ +p = 17, \qquad a = 3, \qquad +\Phi_0 = \begin{pmatrix} f & d \\ g & e \end{pmatrix} + = \begin{pmatrix} 17 & 0 \\ 3 & 1 \end{pmatrix}, \qquad +\delta_0 = 1. +$$ + +Since $17 \equiv 1 \pmod 8$, we have $p^{-1} \equiv 1 \pmod 8$. For each row +of the right column, the correction is + +$$ +k \equiv -t \cdot p^{-1} \pmod 8, +\qquad +x^\prime = (t + k p) / 8. +$$ + +### Batch 0 + +The first three divsteps are $L_c, L_b, L_a$. Their product is + +$$ +M_0 = \begin{pmatrix} 0 & 8 \\ -1 & 3 \end{pmatrix} \cdot 2^{-3}. +$$ + +Apply it to the left column: + +$$ +f^\prime = \frac{0 \cdot 17 + 8 \cdot 3}{8} = 3, +\qquad +g^\prime = \frac{-1 \cdot 17 + 3 \cdot 3}{8} = -1. +$$ + +Apply it to the right column. For $d^\prime$, $t = 0 \cdot 0 + 8 \cdot 1 = 8$, +so $k = 0$ and $d^\prime = 1$. For $e^\prime$, $t = -1 \cdot 0 + 3 \cdot 1 = 3$, +so $k \equiv -3 \equiv 5 \pmod 8$ and + +$$ +e^\prime = \frac{3 + 5 \cdot 17}{8} = 11. +$$ + +After batch 0, + +$$ +(f,g,d,e;\delta) = (3,-1,1,11;2). +$$ + +### Batch 1 + +The next three divsteps are $L_c, L_a, L_b$, giving + +$$ +M_1 = \begin{pmatrix} 0 & 8 \\ -1 & 5 \end{pmatrix} \cdot 2^{-3}. +$$ + +For the left column, + +$$ +f^\prime = \frac{0 \cdot 3 + 8 \cdot (-1)}{8} = -1, +\qquad +g^\prime = \frac{-1 \cdot 3 + 5 \cdot (-1)}{8} = -1. +$$ + +For the right column, the first row gives $t = 88$ and $k = 0$, hence +$d^\prime = 11$. The second row gives $t = -1 \cdot 1 + 5 \cdot 11 = 54$, +so $k \equiv -54 \equiv 2 \pmod 8$ and + +$$ +e^\prime = \frac{54 + 2 \cdot 17}{8} = 11. +$$ + +After batch 1, + +$$ +(f,g,d,e;\delta) = (-1,-1,11,11;1). +$$ + +### Batch 2 + +The next batch starts with the terminating divstep $L_c$; the remaining two +low-bit divsteps keep $g = 0$. The accumulated matrix is + +$$ +M_2 = \begin{pmatrix} 0 & 8 \\ -1 & 1 \end{pmatrix} \cdot 2^{-3}. +$$ + +Applying it gives + +$$ +f^\prime = \frac{0 \cdot (-1) + 8 \cdot (-1)}{8} = -1, +\qquad +g^\prime = \frac{-1 \cdot (-1) + 1 \cdot (-1)}{8} = 0, +$$ + +and for the right column, $d^\prime = 11$ and $e^\prime = 0$. + +Now $g=0$. Since $f=-1$, the inverse is $-d \bmod p$: + +$$ +a^{-1} \equiv -11 \equiv 6 \pmod {17}, +\qquad +3 \cdot 6 \equiv 1 \pmod {17}. +$$ diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.test.cpp new file mode 100644 index 000000000000..35f65e5c56fe --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse.test.cpp @@ -0,0 +1,150 @@ +#include "barretenberg/ecc/fields/bernstein_yang_inverse.hpp" +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp" +#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp" +#include "barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" +#include + +namespace { + +using bb::numeric::uint256_t; +using Native = bb::bernstein_yang::Native5x64; +using Wasm = bb::bernstein_yang::Wasm9x29; + +template uint256_t to_raw(const F& a) +{ + F nonmont = a.from_montgomery_form_reduced(); + return { nonmont.data[0], nonmont.data[1], nonmont.data[2], nonmont.data[3] }; +} + +template F from_raw(const uint256_t& a) +{ + F r{ a.data[0], a.data[1], a.data[2], a.data[3] }; + r.self_to_montgomery_form(); + return r; +} + +template uint256_t by_invert(const F& a) +{ + constexpr uint256_t p = F::modulus; + constexpr uint64_t p_inv_mod_2k = S::p_inv_mod_2k_from_montgomery_r_inv(F::Params::r_inv); + return bb::bernstein_yang::invert_vartime(to_raw(a), p, p_inv_mod_2k); +} + +// Random a, BY result roundtripped through Montgomery must invert a. +template void check_inverse_matches_modexp(size_t n) +{ + for (size_t i = 0; i < n; ++i) { + F a = F::random_element(); + if (a == F::zero()) { + continue; + } + F got = from_raw(by_invert(a)); + EXPECT_EQ(got * a, F::one()) << "iteration " << i; + } +} + +// Same input through both kernels must produce identical canonical output. +template void check_native_matches_wasm(size_t n) +{ + for (size_t i = 0; i < n; ++i) { + F a = F::random_element(); + if (a == F::zero()) { + continue; + } + EXPECT_EQ(by_invert(a), by_invert(a)) << "iteration " << i; + } +} + +template void check_edge_cases() +{ + // invert(1) == 1 + EXPECT_EQ(from_raw(by_invert(F::one())), F::one()); + + // invert(-1) == -1 + F neg_one = -F::one(); + EXPECT_EQ(from_raw(by_invert(neg_one)), neg_one); + + // a * invert(a) == 1 for small / boundary / sparse inputs + F two = F::one() + F::one(); + F neg_two = -two; + F top_limb_only{ 0, 0, 0, 1 }; // raw value 2^192, well below modulus for 254-bit fields + top_limb_only.self_to_montgomery_form(); + for (const F& a : { two, neg_two, top_limb_only }) { + F inv = from_raw(by_invert(a)); + EXPECT_EQ(inv * a, F::one()); + } + + // Involution: invert(invert(a)) == a, on random samples. + for (int i = 0; i < 64; ++i) { + F a = F::random_element(); + if (a == F::zero()) { + continue; + } + F inv = from_raw(by_invert(a)); + F inv_inv = from_raw(by_invert(inv)); + EXPECT_EQ(inv_inv, a); + } +} + +} // namespace + +TEST(Wasm9x29, MatchesModexp_BN254_Fr) +{ + check_inverse_matches_modexp(500); +} +TEST(Wasm9x29, MatchesModexp_BN254_Fq) +{ + check_inverse_matches_modexp(500); +} + +TEST(Native5x64, MatchesModexp_BN254_Fr) +{ + check_inverse_matches_modexp(500); +} +TEST(Native5x64, MatchesModexp_BN254_Fq) +{ + check_inverse_matches_modexp(500); +} + +TEST(Wasm9x29, EdgeCases_BN254_Fr) +{ + check_edge_cases(); +} +TEST(Wasm9x29, EdgeCases_BN254_Fq) +{ + check_edge_cases(); +} +TEST(Native5x64, EdgeCases_BN254_Fr) +{ + check_edge_cases(); +} +TEST(Native5x64, EdgeCases_BN254_Fq) +{ + check_edge_cases(); +} + +TEST(BernsteinYang, NativeMatchesWasm_BN254_Fr) +{ + check_native_matches_wasm(500); +} +TEST(BernsteinYang, NativeMatchesWasm_BN254_Fq) +{ + check_native_matches_wasm(500); +} + +// 256-bit moduli must keep working through field::invert() via the Fermat +// fallback (the BY dispatch is gated by `modulus_3 < 2^63`, which excludes +// secp256k1/r1). Pin that behavior so a future change to the gate gets caught. +TEST(BernsteinYang, FermatFallback_Secp256k1_Fr) +{ + auto a = bb::secp256k1::fr::random_element(); + EXPECT_EQ(a * a.invert(), bb::secp256k1::fr::one()); +} +TEST(BernsteinYang, FermatFallback_Secp256r1_Fr) +{ + auto a = bb::secp256r1::fr::random_element(); + EXPECT_EQ(a * a.invert(), bb::secp256r1::fr::one()); +} diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp new file mode 100644 index 000000000000..4d728e3de73b --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/bernstein_yang_inverse_wasm.hpp @@ -0,0 +1,280 @@ +// 9 × 29-bit-limb state. Included from bernstein_yang_inverse.hpp; uses the +// u64 / i64 / DivstepMatrix names declared there. +// +// Why a different limb size from Native5x64: on wasm32 there is no native +// 64×64→128 multiply, so i64 × u64 → __int128 lowers to a compiler-rt +// __multi3 dispatch. Pack the 254-bit state into 9 limbs of 29 bits each +// instead: every limb-level product is then i29 × i29 = i58, fitting in a +// single WASM i64.mul. Choosing the per-iter BATCH as exactly 2 × LIMB_BITS +// makes the "/ 2^BATCH" at the end of apply_divstep_matrix equivalent to dropping +// the bottom two 29-bit limbs (no sub-limb shift on the intermediate). + +#pragma once + +#include "barretenberg/numeric/uint256/uint256.hpp" +#include + +namespace bb::bernstein_yang { + +class Wasm9x29 { + public: + // Divsteps per matrix application; smaller than Native5x64::BATCH so + // the resulting "/ 2^BATCH" is limb-aligned (= drop the bottom two + // 29-bit limbs) and no sub-limb shift is needed on the intermediate. + static constexpr int BATCH = 58; + + // ⌈735 / 58⌉ = 13. Same convergence-bound logic as Native5x64; one + // iter more because BATCH is smaller. + static constexpr int NUM_ITERATIONS = 13; + + // |d|, |e| can grow by ~2× + p per matrix application; after 4 iters + // they reach ~31p ≈ 2^259, which still fits in the 9 × 29-bit signed + // state (capacity ~2^260). Reducing once every 4 iters instead of + // every iter saves ~3× reduce_to_canonical calls per inversion. + static constexpr int REDUCE_INTERVAL = 4; + + // Worst-case iteration cap inside reduce_to_canonical. After + // REDUCE_INTERVAL iters between reductions, |d|, |e| ≤ (2^(REDUCE_INTERVAL+1) - 1)·p, + // so reducing requires that many subtractions plus one break iter. + static constexpr int REDUCE_TO_CANONICAL_MAX_ITERS = 36; + static_assert((1U << (REDUCE_INTERVAL + 1)) <= REDUCE_TO_CANONICAL_MAX_ITERS, + "REDUCE_INTERVAL too large for reduce_to_canonical iteration bound"); + + Wasm9x29() noexcept + : l{} + {} + explicit Wasm9x29(const uint256_t& x) noexcept + { + const u64* d = x.data; + l[0] = (i64)(d[0] & LIMB_MASK); + l[1] = (i64)((d[0] >> 29) & LIMB_MASK); + l[2] = (i64)(((d[0] >> 58) & 0x3FULL) | ((d[1] & 0x7FFFFFULL) << 6)); + l[3] = (i64)((d[1] >> 23) & LIMB_MASK); + l[4] = (i64)(((d[1] >> 52) & 0xFFFULL) | ((d[2] & 0x1FFFFULL) << 12)); + l[5] = (i64)((d[2] >> 17) & LIMB_MASK); + l[6] = (i64)(((d[2] >> 46) & 0x3FFFFULL) | ((d[3] & 0x7FFULL) << 18)); + l[7] = (i64)((d[3] >> 11) & LIMB_MASK); + l[8] = (i64)((d[3] >> 40) & 0xFFFFFFULL); + } + static Wasm9x29 one() noexcept + { + Wasm9x29 r; + r.l[0] = 1; + return r; + } + + uint256_t to_uint256() const noexcept + { + return { (u64)l[0] | ((u64)l[1] << 29) | ((u64)l[2] << 58), + ((u64)l[2] >> 6) | ((u64)l[3] << 23) | ((u64)l[4] << 52), + ((u64)l[4] >> 12) | ((u64)l[5] << 17) | ((u64)l[6] << 46), + ((u64)l[6] >> 18) | ((u64)l[7] << 11) | ((u64)l[8] << 40) }; + } + u64 low_64() const noexcept { return (u64)l[0] | ((u64)l[1] << 29) | (((u64)l[2] & 0x3F) << 58); } + bool is_zero() const noexcept + { + i64 a = 0; + for (int i = 0; i < N; ++i) { + a |= l[i]; + } + return a == 0; + } + bool is_negative() const noexcept { return l[N - 1] < 0; } + void neg() noexcept + { + for (int i = 0; i < N; ++i) { + l[i] = -l[i]; + } + normalise(); + } + void reduce_to_canonical(const Wasm9x29& p) noexcept; + + // See Native5x64 for the batched divstep matrix, matrix application, + // and p_inv_mod_2k_from_montgomery_r_inv contracts; the bodies differ only + // in limb representation. + static DivstepMatrix compute_divstep_matrix(i64& delta, u64 f_lo, u64 g_lo) noexcept; + static void apply_divstep_matrix(const DivstepMatrix& m, + Wasm9x29& f, + Wasm9x29& g, + Wasm9x29& d, + Wasm9x29& e, + const Wasm9x29& p, + u64 p_inv_mod_2k) noexcept; + static constexpr u64 p_inv_mod_2k_from_montgomery_r_inv(u64 r_inv) noexcept + { + // r_inv = -p^{-1} mod 2^64, so 0 - r_inv = p^{-1} mod 2^64. + return (0ULL - r_inv) & ((1ULL << BATCH) - 1); + } + + private: + static constexpr int N = 9; + static constexpr int LIMB_BITS = 29; + static constexpr u64 LIMB_MASK = (1ULL << LIMB_BITS) - 1; + i64 l[N]; // top limb carries sign; lower limbs in [0, 2^29) post-normalise + + void normalise() noexcept + { + i64 c = 0; + for (int i = 0; i < N - 1; ++i) { + i64 v = l[i] + c; + l[i] = v & (i64)LIMB_MASK; + c = v >> LIMB_BITS; + } + l[N - 1] += c; + } + void add_inplace(const Wasm9x29& b) noexcept + { + for (int i = 0; i < N; ++i) { + l[i] += b.l[i]; + } + normalise(); + } + void sub_inplace(const Wasm9x29& b) noexcept + { + for (int i = 0; i < N; ++i) { + l[i] -= b.l[i]; + } + normalise(); + } +}; + +// Iter cap chosen by the REDUCE_TO_CANONICAL_MAX_ITERS / REDUCE_INTERVAL +// static_assert above; see those constants for the magnitude argument. +inline void Wasm9x29::reduce_to_canonical(const Wasm9x29& p) noexcept +{ + normalise(); + for (int it = 0; it < REDUCE_TO_CANONICAL_MAX_ITERS; ++it) { + if (is_negative()) { + add_inplace(p); + continue; + } + int cmp = 0; + for (int i = N - 1; i >= 0; --i) { + if (l[i] != p.l[i]) { + cmp = l[i] > p.l[i] ? 1 : -1; + break; + } + } + if (cmp < 0) { + break; + } + sub_inplace(p); + } +} + +inline DivstepMatrix Wasm9x29::compute_divstep_matrix(i64& delta, u64 f_lo, u64 g_lo) noexcept +{ + i64 u = 1, v = 0, q = 0, r = 1; + for (int i = 0; i < BATCH; ++i) { + if (g_lo & 1) { + if (delta > 0) { + u64 nf = g_lo, ng = (g_lo - f_lo) >> 1; + i64 nu = q << 1, nv = r << 1, nq = q - u, nr = r - v; + f_lo = nf; + g_lo = ng; + u = nu; + v = nv; + q = nq; + r = nr; + delta = 1 - delta; + } else { + g_lo = (g_lo + f_lo) >> 1; + q = q + u; + r = r + v; + u <<= 1; + v <<= 1; + delta = delta + 1; + } + } else { + g_lo >>= 1; + u <<= 1; + v <<= 1; + delta = delta + 1; + } + } + return { u, v, q, r }; +} + +// Streamed schoolbook: for each limb position i compute +// nf_i = u_lo·f_i + v_lo·g_i + u_hi·f_{i-1} + v_hi·g_{i-1} + carry_in +// (similarly ng, nd, ne), then carry_out = nf_i >> LIMB_BITS, masked low +// 29 bits land at output position i - 2 (= exact >> BATCH). The de row +// derives k_d, k_e from the low two limbs up front and folds k·p into the +// per-limb formula from position 2 onward. No 11-limb intermediate is +// materialised — the JIT keeps the four running carries in registers. +inline void Wasm9x29::apply_divstep_matrix(const DivstepMatrix& m, + Wasm9x29& f, + Wasm9x29& g, + Wasm9x29& d, + Wasm9x29& e, + const Wasm9x29& p, + u64 p_inv_mod_2k) noexcept +{ + constexpr u64 MASK_BATCH = (1ULL << BATCH) - 1; + const i64 u_lo = m.u & (i64)LIMB_MASK, u_hi = m.u >> LIMB_BITS; + const i64 v_lo = m.v & (i64)LIMB_MASK, v_hi = m.v >> LIMB_BITS; + const i64 q_lo = m.q & (i64)LIMB_MASK, q_hi = m.q >> LIMB_BITS; + const i64 r_lo = m.r & (i64)LIMB_MASK, r_hi = m.r >> LIMB_BITS; + + { + i64 cf = 0, cg = 0, fp = 0, gp = 0; + for (int i = 0; i < N; ++i) { + const i64 fi = f.l[i], gi = g.l[i]; + const i64 nf = u_lo * fi + v_lo * gi + u_hi * fp + v_hi * gp + cf; + const i64 ng = q_lo * fi + r_lo * gi + q_hi * fp + r_hi * gp + cg; + cf = nf >> LIMB_BITS; + cg = ng >> LIMB_BITS; + if (i >= 2) { + f.l[i - 2] = nf & (i64)LIMB_MASK; + g.l[i - 2] = ng & (i64)LIMB_MASK; + } + fp = fi; + gp = gi; + } + const i64 nf9 = u_hi * fp + v_hi * gp + cf; + const i64 ng9 = q_hi * fp + r_hi * gp + cg; + f.l[N - 2] = nf9 & (i64)LIMB_MASK; + g.l[N - 2] = ng9 & (i64)LIMB_MASK; + f.l[N - 1] = nf9 >> LIMB_BITS; + g.l[N - 1] = ng9 >> LIMB_BITS; + } + + // k_d, k_e (mod 2^BATCH) clear the low BATCH bits of nd, ne; fold k·p + // into the streaming pass from position 2 onward. + { + const i64 d0 = d.l[0], e0 = e.l[0], d1 = d.l[1], e1 = e.l[1]; + const i64 nd0 = u_lo * d0 + v_lo * e0; + const i64 ne0 = q_lo * d0 + r_lo * e0; + const i64 nd1 = u_lo * d1 + v_lo * e1 + u_hi * d0 + v_hi * e0; + const i64 ne1 = q_lo * d1 + r_lo * e1 + q_hi * d0 + r_hi * e0; + const u64 t_d = ((u64)nd0 & LIMB_MASK) | (((u64)(nd1 + (nd0 >> LIMB_BITS)) & LIMB_MASK) << LIMB_BITS); + const u64 t_e = ((u64)ne0 & LIMB_MASK) | (((u64)(ne1 + (ne0 >> LIMB_BITS)) & LIMB_MASK) << LIMB_BITS); + const u64 k_d = ((0ULL - t_d) * p_inv_mod_2k) & MASK_BATCH; + const u64 k_e = ((0ULL - t_e) * p_inv_mod_2k) & MASK_BATCH; + const i64 kd_lo = (i64)(k_d & LIMB_MASK), kd_hi = (i64)(k_d >> LIMB_BITS); + const i64 ke_lo = (i64)(k_e & LIMB_MASK), ke_hi = (i64)(k_e >> LIMB_BITS); + i64 cd = (nd1 + kd_lo * p.l[1] + kd_hi * p.l[0] + ((nd0 + kd_lo * p.l[0]) >> LIMB_BITS)) >> LIMB_BITS; + i64 ce = (ne1 + ke_lo * p.l[1] + ke_hi * p.l[0] + ((ne0 + ke_lo * p.l[0]) >> LIMB_BITS)) >> LIMB_BITS; + + i64 dp = d1, ep = e1; + for (int i = 2; i < N; ++i) { + const i64 di = d.l[i], ei = e.l[i]; + const i64 nd = u_lo * di + v_lo * ei + u_hi * dp + v_hi * ep + kd_lo * p.l[i] + kd_hi * p.l[i - 1] + cd; + const i64 ne = q_lo * di + r_lo * ei + q_hi * dp + r_hi * ep + ke_lo * p.l[i] + ke_hi * p.l[i - 1] + ce; + cd = nd >> LIMB_BITS; + ce = ne >> LIMB_BITS; + d.l[i - 2] = nd & (i64)LIMB_MASK; + e.l[i - 2] = ne & (i64)LIMB_MASK; + dp = di; + ep = ei; + } + const i64 nd9 = u_hi * dp + v_hi * ep + kd_hi * p.l[N - 1] + cd; + const i64 ne9 = q_hi * dp + r_hi * ep + ke_hi * p.l[N - 1] + ce; + d.l[N - 2] = nd9 & (i64)LIMB_MASK; + e.l[N - 2] = ne9 & (i64)LIMB_MASK; + d.l[N - 1] = nd9 >> LIMB_BITS; + e.l[N - 1] = ne9 >> LIMB_BITS; + } +} + +} // namespace bb::bernstein_yang diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp index fdbb7508dfa8..6362ac70e04c 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp @@ -340,6 +340,7 @@ template struct alignas(32) field { static constexpr uint256_t modulus_minus_two = uint256_t(Params::modulus_0 - 2ULL, Params::modulus_1, Params::modulus_2, Params::modulus_3); constexpr field invert() const noexcept; + constexpr field invert_const_time() const noexcept; template // has size() and operator[]. requires requires(C& c) { diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp index f97695d9be19..c9283b3847c6 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp @@ -15,6 +15,8 @@ #include #include +#include "./bernstein_yang_inverse.hpp" +#include "./bernstein_yang_inverse_wasm.hpp" #include "./field_declarations.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" @@ -384,6 +386,29 @@ template constexpr field field::pow(const uint64_t exponent) con } template constexpr field field::invert() const noexcept +{ + if (*this == zero()) { + bb::assert_failure("Trying to invert zero in the field"); + } + // BY uses __int128 and is not constexpr-evaluable; compile-time inversions keep Fermat. + if (std::is_constant_evaluated()) { + return pow(modulus_minus_two); + } + if constexpr (bernstein_yang::supported_v) { + constexpr uint256_t p_uint = modulus; + constexpr uint64_t p_inv_mod_2k = bernstein_yang::p_inv_mod_2k_from_montgomery_r_inv(T::r_inv); + field non_mont = from_montgomery_form_reduced(); + uint256_t a{ non_mont.data[0], non_mont.data[1], non_mont.data[2], non_mont.data[3] }; + uint256_t inv = bernstein_yang::invert_vartime(a, p_uint, p_inv_mod_2k); + field result{ inv.data[0], inv.data[1], inv.data[2], inv.data[3] }; + result.self_to_montgomery_form(); + return result; + } else { + return pow(modulus_minus_two); + } +} + +template constexpr field field::invert_const_time() const noexcept { if (*this == zero()) { bb::assert_failure("Trying to invert zero in the field"); diff --git a/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp index 03c24a5acb91..7c6fbb8d1c5b 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp @@ -113,6 +113,8 @@ template class alignas(32) element { // constexpr Fr operator/(const element& other) noexcept {} constexpr element normalize() const noexcept; + constexpr element normalize_const_time() const noexcept; + constexpr affine_element to_affine_const_time() const noexcept; static element infinity(); BB_INLINE constexpr element set_infinity() const noexcept; BB_INLINE constexpr void self_set_infinity() noexcept; diff --git a/barretenberg/cpp/src/barretenberg/ecc/groups/element_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/element_impl.hpp index bf3687445ad6..7c7f299f5fda 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/element_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/groups/element_impl.hpp @@ -63,6 +63,10 @@ constexpr element& element::operator=(element&& other) noe return *this; } +// Warning: variable-time — calls `z.invert()` (Bernstein-Yang safegcd). Do not +// use on points derived from secret material (signing nonces, private keys, DH +// shared secrets). For those, call `to_affine_const_time()` explicitly; the +// implicit conversion does NOT pick up the const-time path. template constexpr element::operator affine_element() const noexcept { if (is_point_at_infinity()) { @@ -79,6 +83,23 @@ template constexpr element::operator af return result; } +template +constexpr affine_element element::to_affine_const_time() const noexcept +{ + if (is_point_at_infinity()) { + affine_element result; + result.x = Fq(0); + result.y = Fq(0); + result.self_set_infinity(); + return result; + } + Fq z_inv = z.invert_const_time(); + Fq zz_inv = z_inv.sqr(); + Fq zzz_inv = zz_inv * z_inv; + affine_element result(x * zz_inv, y * zzz_inv); + return result; +} + template constexpr void element::self_dbl() noexcept { if constexpr (Fq::modulus.data[3] >= MODULUS_TOP_LIMB_LARGE_THRESHOLD) { @@ -461,12 +482,20 @@ element element::mul_const_time(const Fr& scalar, numeric: return R0; } +// Warning: variable-time via the implicit affine conversion above. For +// secret-input points use `normalize_const_time()`. template constexpr element element::normalize() const noexcept { const affine_element converted = *this; return element(converted); } +template +constexpr element element::normalize_const_time() const noexcept +{ + return element(to_affine_const_time()); +} + template element element::infinity() { element e{}; diff --git a/barretenberg/cpp/src/barretenberg/nodejs_module/util/async_op.hpp b/barretenberg/cpp/src/barretenberg/nodejs_module/util/async_op.hpp index ad62bc2bf4ae..e91306c7a62c 100644 --- a/barretenberg/cpp/src/barretenberg/nodejs_module/util/async_op.hpp +++ b/barretenberg/cpp/src/barretenberg/nodejs_module/util/async_op.hpp @@ -1,11 +1,16 @@ #pragma once #include "barretenberg/serialize/msgpack_impl.hpp" +#include #include #include #include #include +#ifndef _WIN32 +#include +#endif + namespace bb::nodejs { using async_fn = std::function; @@ -109,10 +114,17 @@ class ThreadedAsyncOperation : public std::enable_shared_from_this_fn(self->_result); self->_success = true; @@ -138,7 +150,43 @@ class ThreadedAsyncOperation : public std::enable_shared_from_this_completion_tsfn.Release(); }); - }).detach(); + }); + } + + // Launch `work` on a detached OS thread with an explicitly large stack (see WORKER_STACK_SIZE). + // std::thread cannot set a stack size, so use pthreads where available and fall back to a + // default-stack std::thread only if pthread creation is unavailable or fails. + static void launch_detached_with_large_stack(std::function work) + { +#ifndef _WIN32 + pthread_attr_t attr; + if (pthread_attr_init(&attr) == 0) { + pthread_attr_setstacksize(&attr, WORKER_STACK_SIZE); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + auto* heap_work = new std::function(std::move(work)); + pthread_t tid; + int rc = pthread_create( + &tid, + &attr, + [](void* arg) -> void* { + std::unique_ptr> fn(static_cast*>(arg)); + (*fn)(); + return nullptr; + }, + heap_work); + pthread_attr_destroy(&attr); + + if (rc == 0) { + return; + } + + // pthread_create failed; reclaim the work and fall back to a default std::thread. + std::unique_ptr> reclaimed(heap_work); + work = std::move(*reclaimed); + } +#endif + std::thread(std::move(work)).detach(); } async_fn _fn; diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/avm_io.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/avm_io.hpp index b503c573f12c..4378671f2521 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/avm_io.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/avm_io.hpp @@ -113,18 +113,16 @@ struct PublicInputs { //////////////////////////////////////////////////////////////////////////// // Hints (contracts) //////////////////////////////////////////////////////////////////////////// +// Only ivpk_m is sent as a point; the others are field-element hashes. struct PublicKeysHint { - AffinePoint master_nullifier_public_key; - AffinePoint master_incoming_viewing_public_key; - AffinePoint master_outgoing_viewing_public_key; - AffinePoint master_tagging_public_key; + FF npk_m_hash; + AffinePoint ivpk_m; + FF ovpk_m_hash; + FF tpk_m_hash; bool operator==(const PublicKeysHint& other) const = default; - MSGPACK_CAMEL_CASE_FIELDS(master_nullifier_public_key, - master_incoming_viewing_public_key, - master_outgoing_viewing_public_key, - master_tagging_public_key); + MSGPACK_CAMEL_CASE_FIELDS(npk_m_hash, ivpk_m, ovpk_m_hash, tpk_m_hash); }; struct ContractInstanceHint { @@ -135,6 +133,7 @@ struct ContractInstanceHint { ContractClassId current_contract_class_id; ContractClassId original_contract_class_id; FF initialization_hash; + FF immutables_hash; PublicKeysHint public_keys; bool operator==(const ContractInstanceHint& other) const = default; @@ -146,6 +145,7 @@ struct ContractInstanceHint { current_contract_class_id, original_contract_class_id, initialization_hash, + immutables_hash, public_keys); }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp index 4f8ec3dc8a11..f7e7ef9ed09c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp @@ -77,23 +77,29 @@ enum class ContractInstanceMember : uint8_t { DEPLOYER = 0, CLASS_ID = 1, INIT_HASH = 2, - MAX = INIT_HASH, + IMMUTABLES_HASH = 3, + MAX = IMMUTABLES_HASH, }; //////////////////////////////////////////////////////////////////////////// // Keys, Instances, Classes //////////////////////////////////////////////////////////////////////////// +// Only `incoming_viewing_key` is exposed as a point (since address derivation +// needs the curve point in-circuit); the other three keys are exposed as their hashes. struct PublicKeys { - AffinePoint nullifier_key; + FF nullifier_key_hash; AffinePoint incoming_viewing_key; - AffinePoint outgoing_viewing_key; - AffinePoint tagging_key; + FF outgoing_viewing_key_hash; + FF tagging_key_hash; std::vector to_fields() const { - return { nullifier_key.x, nullifier_key.y, incoming_viewing_key.x, incoming_viewing_key.y, - outgoing_viewing_key.x, outgoing_viewing_key.y, tagging_key.x, tagging_key.y }; + return { nullifier_key_hash, + incoming_viewing_key.x, + incoming_viewing_key.y, + outgoing_viewing_key_hash, + tagging_key_hash }; } bool operator==(const PublicKeys& other) const = default; @@ -102,14 +108,14 @@ struct PublicKeys { // TODO(fcarreiro): solve with macro void msgpack(auto pack_fn) { - pack_fn("masterNullifierPublicKey", - nullifier_key, - "masterIncomingViewingPublicKey", + pack_fn("npkMHash", + nullifier_key_hash, + "ivpkM", incoming_viewing_key, - "masterOutgoingViewingPublicKey", - outgoing_viewing_key, - "masterTaggingPublicKey", - tagging_key); + "ovpkMHash", + outgoing_viewing_key_hash, + "tpkMHash", + tagging_key_hash); } }; @@ -119,7 +125,8 @@ struct ContractInstance { ContractClassId current_contract_class_id = 0; ContractClassId original_contract_class_id = 0; FF initialization_hash = 0; - PublicKeys public_keys; + FF immutables_hash = 0; + PublicKeys public_keys{}; bool operator==(const ContractInstance& other) const = default; @@ -136,6 +143,8 @@ struct ContractInstance { original_contract_class_id, "initializationHash", initialization_hash, + "immutablesHash", + immutables_hash, "publicKeys", public_keys); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp index 112997b74b0d..3e6c7b6bb243 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp @@ -99,7 +99,7 @@ const std::unordered_map>& { WireOpCode::POSEIDON2PERM, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { WireOpCode::SHA256COMPRESSION, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { WireOpCode::KECCAKF1600, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { WireOpCode::ECADD, { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { WireOpCode::ECADD, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // Conversions { WireOpCode::TORADIXBE, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, }; @@ -420,7 +420,7 @@ const std::unordered_map& get_wire_instruction_ .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::KECCAKF1600) } }, { WireOpCode::ECADD, { .exec_opcode = ExecutionOpCode::ECADD, - .size_in_bytes = 17, + .size_in_bytes = 13, .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::ECADD) } }, // Conversions { WireOpCode::TORADIXBE, @@ -737,14 +737,12 @@ const std::unordered_map& get_exec_instruc { .num_addresses = 2, .gas_cost = { .opcode_gas = AVM_KECCAKF1600_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } }, { ExecutionOpCode::ECADD, - { .num_addresses = 7, + { .num_addresses = 5, .gas_cost = { .opcode_gas = AVM_ECADD_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 }, .register_info = RegisterInfo().add_inputs({ /*p_x=*/ValueTag::FF, /*p_y=*/ValueTag::FF, - /*p_inf*/ ValueTag::U1, /*q_x*/ ValueTag::FF, - /*q_y*/ ValueTag::FF, - /*q_inf*/ ValueTag::U1 }) } }, + /*q_y*/ ValueTag::FF }) } }, { ExecutionOpCode::TORADIXBE, { .num_addresses = 5, .gas_cost = { .opcode_gas = AVM_TORADIXBE_BASE_L2_GAS, diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.hpp index bbf2e6dbd9fb..1f0b271724fd 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.hpp @@ -6,16 +6,15 @@ namespace bb::avm2 { /** - * AVM bytecode expects the representation of points to be triplets, the two coordinates and an is_infinity boolean. - * Furthermore, its representation of infinity is inherited from noir's and is expected to be 0,0,true. - * BB, however, uses only the two coordinates to represent points. Infinity in barretenberg is represented as (P+1)/2,0. - * This class is a wrapper of the BB representation, needed to operate with points, that allows to extract the standard - * representation that AVM bytecode expects. - * NOTE: When constructing infinity from BB's two element representation, is_infinity() will be true but the coordinates - * will remain (P+1)/2,0. - * NOTE: When constructing infinity via BaseFields, input coordinates are maintained and can be any values, so may - * mismatch the underlying AffinePoint. Always check is_infinity() before ECC operations on coordinates. See test - * InfinityPreservesRawCoordinates for an example. + * The AVM's representation of infinity is inherited from noir's and is expected to be 0,0. + * BB, however, uses only the two coordinates to represent points. Infinity in barretenberg is represented as + * (P+1)/2,0,true. This class is a wrapper of the BB representation, needed to operate with points, that allows us to + * extract the standard representation that AVM bytecode expects. + * + * NOTE: When constructing infinity from BB's two element representation, we keep the original AffinePoint so operations + * can use it in the background, but set extractable coordinates to be our represention of (0,0). + * NOTE: When constructing infinity via BaseFields (equiv. inputting (0, 0), the underlying AffinePoint is set to BB's + * representation so operations can use it in the background. */ template class StandardAffinePoint { public: @@ -26,12 +25,12 @@ template class StandardAffinePoint { constexpr StandardAffinePoint(AffinePoint val) noexcept : point(val) - , x_coord(val.x) - , y_coord(val.y) + , x_coord(val.is_point_at_infinity() ? zero : val.x) + , y_coord(val.is_point_at_infinity() ? zero : val.y) {} - constexpr StandardAffinePoint(BaseField x, BaseField y, bool is_infinity) noexcept - : point(is_infinity ? AffinePoint::infinity() : AffinePoint(x, y)) + constexpr StandardAffinePoint(BaseField x, BaseField y) noexcept + : point((x.is_zero() && y.is_zero()) ? AffinePoint::infinity() : AffinePoint(x, y)) , x_coord(x) , y_coord(y) {} @@ -74,15 +73,15 @@ template class StandardAffinePoint { [[nodiscard]] constexpr bool on_curve() const noexcept { return point.on_curve(); } - // Always returns the raw coordinates, when an operation results in infinity these will be (0,0). - // If a point at infinity is constructed with non-zero coordinates, we likely want to preserve those. + // Always returns Noir standard coordinates. For the point at infinity this is always (0, 0). If that point was + // constructed via AffinePoint with a different representation, those non-zero coordinates are preserved in .point. constexpr const BaseField& x() const noexcept { return x_coord; } constexpr const BaseField& y() const noexcept { return y_coord; } static const StandardAffinePoint& infinity() { - static auto infinity = StandardAffinePoint(zero, zero, true); + static auto infinity = StandardAffinePoint(zero, zero); return infinity; } @@ -94,7 +93,7 @@ template class StandardAffinePoint { private: // The affine point for operations, this will always match the raw coordinates unless the point is infinity. - // In that case, the point will be set to barretenberg's infinity representation - which is not (0,0). + // In that case, the point will be set to AffinePoint's infinity representation - which may not be (0,0). AffinePoint point; // These are the raw x and y coordinates, that are set when constructing the point. When an operation results // in infinity, these will be set to (0,0) to match noir's expected representation. diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.test.cpp index 6a9386842417..b8e79e2a1f50 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/standard_affine_point.test.cpp @@ -10,18 +10,17 @@ using EmbeddedCurvePoint = StandardAffinePoint; using Fr = grumpkin::fr; using Fq = grumpkin::fq; -TEST(StandardAffinePointTest, InfinityPreservesRawCoordinates) +TEST(StandardAffinePointTest, ConstructingInfinityNormalized) { - // When constructing an infinity point with non-zero coordinates, - // x() and y() should return the raw coordinates - Fq raw_x = 1; - Fq raw_y = 2; - - EmbeddedCurvePoint point(raw_x, raw_y, /*is_infinity=*/true); - - EXPECT_TRUE(point.is_infinity()); - EXPECT_EQ(point.x(), raw_x); - EXPECT_EQ(point.y(), raw_y); + // Constructing a point with (0,0) coordinates should result in infinity + EmbeddedCurvePoint inf(0, 0); + EXPECT_TRUE(inf.is_infinity()); + // Constructing a point with BB's inf should result in infinity with (0,0) coordinates + EmbeddedCurvePoint inf_bb(grumpkin::g1::affine_element::infinity()); + EXPECT_TRUE(inf_bb.is_infinity()); + EXPECT_TRUE(inf_bb.x().is_zero()); + EXPECT_TRUE(inf_bb.y().is_zero()); + EXPECT_EQ(inf, inf_bb); } TEST(StandardAffinePointTest, NormalPointCoordinates) @@ -72,7 +71,7 @@ TEST(StandardAffinePointTest, ScalarMultiplicationResultingInInfinityNormalized) TEST(StandardAffinePointTest, StaticInfinityHasZeroCoordinates) { - // The static infinity() method should return (0,0,true) + // The static infinity() method should return (0,0) auto& inf = EmbeddedCurvePoint::infinity(); EXPECT_TRUE(inf.is_infinity()); @@ -80,18 +79,14 @@ TEST(StandardAffinePointTest, StaticInfinityHasZeroCoordinates) EXPECT_TRUE(inf.y().is_zero()); } -TEST(StandardAffinePointTest, NegatingInfinityPreservesRawCoordinates) +TEST(StandardAffinePointTest, NegatingInfinity) { - // Negating an infinity point should preserve its raw coordinates - Fq raw_x = 1; - Fq raw_y = 2; - EmbeddedCurvePoint inf(raw_x, raw_y, /*is_infinity=*/true); - - auto neg_inf = -inf; + // Negating an infinity point should return (0,0) + auto neg_inf = -EmbeddedCurvePoint::infinity(); EXPECT_TRUE(neg_inf.is_infinity()); - EXPECT_EQ(neg_inf.x(), raw_x); - EXPECT_EQ(neg_inf.y(), raw_y); + EXPECT_TRUE(neg_inf.x().is_zero()); + EXPECT_TRUE(neg_inf.y().is_zero()); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp index c060244f6965..a3d2d285a8b3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp @@ -17,7 +17,7 @@ class AvmHardCodedVKAndHash { using FF = bb::curve::BN254::ScalarField; // Precomputed VK hash (hash of all commitments below). - static FF vk_hash() { return FF(uint256_t("0x23a03c6f87c465dbecc386b091e8123a8936597b5b0749f276d042a8964bd390")); } + static FF vk_hash() { return FF(uint256_t("0x07c6aee864d89db19813358d6b6ea4e41643f8e60ce88ab8974314313a0470e1")); } static constexpr std::array get_all() { @@ -71,9 +71,9 @@ class AvmHardCodedVKAndHash { uint256_t( "0x090dda25e7d64ab5cabe09fd80fbb731af2a98de7a608157dc10394b4fc022a4")), // precomputed_exec_opcode_dynamic_l2_gas Commitment( - uint256_t("0x26086b5fb31a24f236f0441d5b922b94ca141e861b9cc640184681c518cd68d3"), + uint256_t("0x1fbccee2ff656d845414c1a520adde56aa3625e29b6fff377044986493023e6d"), uint256_t( - "0x0bab134bb4e25ff33584c1094847e762ce6573054bae27715d0e4eb2b7278d80")), // precomputed_exec_opcode_opcode_gas + "0x05c88802d3174f1c7b3c9aa1abf4754ebdaf6409d1aaf1dfa3f551da1c10fa93")), // precomputed_exec_opcode_opcode_gas Commitment( uint256_t("0x296def9415d1c96b4d8ab91df5f59ad8522a726f98461b1ab5c4d4c5b22471a4"), uint256_t( @@ -83,18 +83,15 @@ class AvmHardCodedVKAndHash { uint256_t( "0x06ea9cd6f2a50e2156f80beebc721d11d24821fd4b723932da48d8750300fbaa")), // precomputed_expected_tag_reg_1_ Commitment( - uint256_t("0x1cb1c6d46ddf9f7bd7a87a5e7dca5ef92c8a44669ab0cbc557a0fcb8331d0d8d"), + uint256_t("0x034e06277dc6d6e4f2ddea6d71635693db1a2869d33b918f0f70efa0530ecaa6"), uint256_t( - "0x281a3e4b96e4f595db502ba69acda314bc335957ae605af17423b0ff3d0528c3")), // precomputed_expected_tag_reg_2_ + "0x2d3e564f6e8885163d356daec0387132097e73dbf8e04475675b715151ce3cb9")), // precomputed_expected_tag_reg_2_ Commitment( uint256_t("0x1a3c36c4933c956751e6ca5631077a9418cd0ba4ec29e965508eaf8bc1a7ffd4"), uint256_t( "0x1203bdd1aab5bfc5f3ed6abbefc30ab303770b847d022c1c9c0f8de202a76560")), // precomputed_expected_tag_reg_3_ Commitment::infinity(), // precomputed_expected_tag_reg_4_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_expected_tag_reg_5_ + Commitment::infinity(), // precomputed_expected_tag_reg_5_ Commitment( uint256_t("0x0000000000000000000000000000000000000000000000000000000000000001"), uint256_t( @@ -103,9 +100,9 @@ class AvmHardCodedVKAndHash { uint256_t("0x14567e2c3e84fc1e3e69d81f6ce5808ca9a0451964a7bbabbd9e369db7556253"), uint256_t("0x0378926f150c30c760965df469ae6ed609c59feecf899f2b95aff519bbf3fb3c")), // precomputed_idx Commitment( - uint256_t("0x1e497723c3f95466c480f1ac1addb1e0dc68bb123cae27ee70d00e6d6fcc6896"), + uint256_t("0x2bef1e5de8c449d3cfa4cf9ab94e8b846755023b02e94dbbba1ffb3c73da0d1d"), uint256_t( - "0x24c9a31064fb5f18c18ac3ea4be1a10809765a43b06bcea177fbb171dd547ced")), // precomputed_instr_size + "0x06905ac3e0ae01f14b1bc598f9ba30af7eced70893019ca78b0e55668c38f3e0")), // precomputed_instr_size Commitment( uint256_t("0x11b710f896157a9557278a1f776cd6c7e1e7e256a572bd080797daaf1d6307d1"), uint256_t( @@ -134,6 +131,10 @@ class AvmHardCodedVKAndHash { uint256_t("0x0000000000000000000000000000000000000000000000000000000000000001"), uint256_t( "0x0000000000000000000000000000000000000000000000000000000000000002")), // precomputed_is_deployer + Commitment( + uint256_t("0x210bedcbb97a2e72905c082dd087be36c29c67e85b47de07b639e28a7dd78c76"), + uint256_t( + "0x18d1e431b83aa3ab2f6904bbbc452fee3472c01c0ceaf6d2fe6e37c4ff79e265")), // precomputed_is_immutables_hash Commitment( uint256_t("0x020ad6e43ccd48a6a39e43897cc85187bd364919be8a3b82d4809715cfe489db"), uint256_t( @@ -171,9 +172,9 @@ class AvmHardCodedVKAndHash { uint256_t( "0x23268ad7678b97fba97cc3e75da6cff9a3659c3b8a49046cce4062820e5c1116")), // precomputed_is_tree_padding Commitment( - uint256_t("0x210cdba7d0dae8d84cdd77a912060188657a0628905c0531fa63138ec3cbc9ea"), + uint256_t("0x00c43726f75b6fda0de22ce0e0dfab6bcc7a05ff95a96b289424c5f733670d96"), uint256_t( - "0x264f0d3eab260e5a20bdc5324e1ddcb3a0c0d811bb4a23b983417fd8c280486a")), // precomputed_is_valid_member_enum + "0x2f9b6e0b4e2c01968de5c32482aa7d1d0a09d7178ec93bad7858f96e64f0b48d")), // precomputed_is_valid_member_enum Commitment( uint256_t("0x057e5478fbad129bb84bfb618f6e7a747812510b4f6f70bd84d4688f760ecb62"), uint256_t( @@ -280,14 +281,8 @@ class AvmHardCodedVKAndHash { uint256_t("0x1530ccb47d1198320c163380a82ca8cbaf87b2d40ede856d21c60535e2251262"), uint256_t( "0x29dd7ccea05e6d47a7373ea950a7988caed0d20880612e046af575217a21652a")), // precomputed_sel_mem_op_reg_3_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_mem_op_reg_4_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_mem_op_reg_5_ + Commitment::infinity(), // precomputed_sel_mem_op_reg_4_ + Commitment::infinity(), // precomputed_sel_mem_op_reg_5_ Commitment( uint256_t("0x089cdab4e8e8381977b093cb267a1b7c8c60f4466c39a99af1247e37fe56ebfe"), uint256_t( @@ -296,10 +291,7 @@ class AvmHardCodedVKAndHash { uint256_t("0x0bf1970c2e92fee577ba15d063fa78fdd17752cafd19261ff0f176a1d3348769"), uint256_t( "0x21f1906edf2fe01e804774aa539abe8411cfda1731be99853f90253ed2652868")), // precomputed_sel_op_dc_0 - Commitment( - uint256_t("0x2ad6f77a7f7c14780d95de8bd1f5b2146fe71fb1b7e6d55016734664f10d653b"), - uint256_t( - "0x131ac1fc680fbc2584b74e5aece1f0d50afe030adf4289613e54935339829496")), // precomputed_sel_op_dc_1 + Commitment::infinity(), // precomputed_sel_op_dc_1 Commitment( uint256_t("0x225d208d9012b15a17b7dac26e737c0d2f9c8bf80de627bd13e1a9c042ede642"), uint256_t( @@ -380,14 +372,8 @@ class AvmHardCodedVKAndHash { uint256_t("0x1530ccb47d1198320c163380a82ca8cbaf87b2d40ede856d21c60535e2251262"), uint256_t( "0x29dd7ccea05e6d47a7373ea950a7988caed0d20880612e046af575217a21652a")), // precomputed_sel_op_is_address_4_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_op_is_address_5_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_op_is_address_6_ + Commitment::infinity(), // precomputed_sel_op_is_address_5_ + Commitment::infinity(), // precomputed_sel_op_is_address_6_ Commitment( uint256_t("0x1525ae740393f8dec3a1ea8f39f456861afece20561b5870db4291410d2f3429"), uint256_t( @@ -424,14 +410,8 @@ class AvmHardCodedVKAndHash { uint256_t("0x1530ccb47d1198320c163380a82ca8cbaf87b2d40ede856d21c60535e2251262"), uint256_t( "0x29dd7ccea05e6d47a7373ea950a7988caed0d20880612e046af575217a21652a")), // precomputed_sel_tag_check_reg_3_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_tag_check_reg_4_ - Commitment( - uint256_t("0x11b316123744c8602e394b9a558ed664a70d8a7e8f5a3138c9971302c193dd84"), - uint256_t( - "0x08a817c8ab332c7f8b478ec9bddb41a8ca1593c3b8fb85d6236d3eecc2df3b37")), // precomputed_sel_tag_check_reg_5_ + Commitment::infinity(), // precomputed_sel_tag_check_reg_4_ + Commitment::infinity(), // precomputed_sel_tag_check_reg_5_ Commitment( uint256_t("0x2b770f46bb0db9c1447e6010b3ca12f1dc2b2a237ff6d2390d9ddf5a056d09ad"), uint256_t( diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp index 8720e12efd4e..252c8793a4a2 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp @@ -72,14 +72,17 @@ TEST(AddressDerivationConstrainingTest, Basic) auto instance = testing::random_contract_instance(); - FF salted_initialization_hash = poseidon2::hash( - { DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer }); + FF salted_initialization_hash = poseidon2::hash({ DOM_SEP__SALTED_INITIALIZATION_HASH, + instance.salt, + instance.initialization_hash, + instance.deployer, + instance.immutables_hash }); FF partial_address = poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash }); FF public_keys_hash = hash_public_keys(instance.public_keys); - FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }); + FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }); EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one(); EmbeddedCurvePoint preaddress_public_key = g1 * Fq(preaddress); @@ -215,6 +218,62 @@ TEST(AddressDerivationConstrainingTest, NegativeWithInteractions) "Failed.*PREADDRESS_SCALAR_MUL. Could not find tuple in destination."); } +TEST(AddressDerivationConstrainingTest, NegativeMutateImmutablesHash) +{ + EventEmitter ecadd_event_emitter; + EventEmitter scalar_mul_event_emitter; + NoopEventEmitter ecc_add_memory_event_emitter; + EventEmitter hash_event_emitter; + NoopEventEmitter perm_event_emitter; + NoopEventEmitter perm_mem_event_emitter; + EventEmitter address_derivation_event_emitter; + + StrictMock mock_exec_id_manager; + EXPECT_CALL(mock_exec_id_manager, get_execution_id).WillRepeatedly(Return(0)); + StrictMock mock_gt; + Poseidon2 poseidon2_simulator( + mock_exec_id_manager, mock_gt, hash_event_emitter, perm_event_emitter, perm_mem_event_emitter); + + PureToRadix to_radix_simulator; + Ecc ecc_simulator(mock_exec_id_manager, + mock_gt, + to_radix_simulator, + ecadd_event_emitter, + scalar_mul_event_emitter, + ecc_add_memory_event_emitter); + + AddressDerivation address_derivation(poseidon2_simulator, ecc_simulator, address_derivation_event_emitter); + + TestTraceContainer trace({ + { { C::precomputed_first_row, 1 } }, + }); + + AddressDerivationTraceBuilder builder; + Poseidon2TraceBuilder poseidon2_builder; + EccTraceBuilder ecc_builder; + + ContractInstance instance = testing::random_contract_instance(); + AztecAddress address = compute_contract_address(instance); + address_derivation.assert_derivation(address, instance); + + builder.process(address_derivation_event_emitter.dump_events(), trace); + poseidon2_builder.process_hash(hash_event_emitter.dump_events(), trace); + ecc_builder.process_add(ecadd_event_emitter.dump_events(), trace); + ecc_builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace); + + check_all_interactions(trace); + check_relation(trace); + + // Mutate immutables_hash (the second input of the second poseidon2 round). The salted-init-hash + // round-2 lookup into poseidon2 should now fail because (deployer, mutated_immutables_hash, 0, + // salted_init_hash) no longer exists in the poseidon2 trace. + trace.set(C::address_derivation_immutables_hash, 0, instance.immutables_hash + 1); + EXPECT_THROW_WITH_MESSAGE( + (check_interaction(trace)), + "Failed.*SALTED_INITIALIZATION_HASH_POSEIDON2_1. Could not find tuple in destination."); +} + TEST(AddressDerivationConstrainingTest, NegativeIVKNotOnCurve) { TestTraceContainer trace; @@ -232,7 +291,7 @@ TEST(AddressDerivationConstrainingTest, NegativeIVKNotOnCurve) poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash }); FF public_keys_hash = hash_public_keys(instance.public_keys); - FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }); + FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }); EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one(); EmbeddedCurvePoint preaddress_public_key = g1 * Fq(preaddress); diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp index 793b2edc1488..10251ffaccc7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp @@ -45,12 +45,13 @@ ContractInstance create_test_contract_instance(uint32_t salt_value = 123) .current_contract_class_id = FF(0xdeadbeefULL), .original_contract_class_id = FF(0xcafebabeULL), .initialization_hash = FF(0x11111111ULL), + .immutables_hash = FF(0x22222222ULL), .public_keys = PublicKeys{ - .nullifier_key = { FF(0x100), FF(0x101) }, + .nullifier_key_hash = FF(0x100), .incoming_viewing_key = { FF(0x200), FF(0x201) }, - .outgoing_viewing_key = { FF(0x300), FF(0x301) }, - .tagging_key = { FF(0x400), FF(0x401) }, + .outgoing_viewing_key_hash = FF(0x300), + .tagging_key_hash = FF(0x400), }, }; } @@ -72,14 +73,12 @@ TEST(ContractInstanceRetrievalConstrainingTest, CompleteValidTrace) const auto current_class_id = FF(0xdeadbeefULL); const auto original_class_id = FF(0xcafebabeULL); const auto init_hash = FF(0x11111111ULL); - const auto nullifier_key_x = FF(0x100); - const auto nullifier_key_y = FF(0x101); + const auto immutables_hash = FF(0x22222222ULL); + const auto nullifier_key_hash = FF(0x100); const auto incoming_viewing_key_x = FF(0x200); const auto incoming_viewing_key_y = FF(0x201); - const auto outgoing_viewing_key_x = FF(0x300); - const auto outgoing_viewing_key_y = FF(0x301); - const auto tagging_key_x = FF(0x400); - const auto tagging_key_y = FF(0x401); + const auto outgoing_viewing_key_hash = FF(0x300); + const auto tagging_key_hash = FF(0x400); // Test complete valid trace with all constraints TestTraceContainer trace({ @@ -92,19 +91,17 @@ TEST(ContractInstanceRetrievalConstrainingTest, CompleteValidTrace) { C::contract_instance_retrieval_current_class_id, current_class_id }, { C::contract_instance_retrieval_original_class_id, original_class_id }, { C::contract_instance_retrieval_init_hash, init_hash }, + { C::contract_instance_retrieval_immutables_hash, immutables_hash }, { C::contract_instance_retrieval_public_data_tree_root, public_data_tree_root }, { C::contract_instance_retrieval_nullifier_tree_root, nullifier_tree_root }, { C::contract_instance_retrieval_nullifier_tree_height, NULLIFIER_TREE_HEIGHT }, { C::contract_instance_retrieval_nullifier_merkle_separator, DOM_SEP__NULLIFIER_MERKLE }, { C::contract_instance_retrieval_siloing_separator, DOM_SEP__SILOED_NULLIFIER }, - { C::contract_instance_retrieval_nullifier_key_x, nullifier_key_x }, - { C::contract_instance_retrieval_nullifier_key_y, nullifier_key_y }, + { C::contract_instance_retrieval_nullifier_key_hash, nullifier_key_hash }, { C::contract_instance_retrieval_incoming_viewing_key_x, incoming_viewing_key_x }, { C::contract_instance_retrieval_incoming_viewing_key_y, incoming_viewing_key_y }, - { C::contract_instance_retrieval_outgoing_viewing_key_x, outgoing_viewing_key_x }, - { C::contract_instance_retrieval_outgoing_viewing_key_y, outgoing_viewing_key_y }, - { C::contract_instance_retrieval_tagging_key_x, tagging_key_x }, - { C::contract_instance_retrieval_tagging_key_y, tagging_key_y }, + { C::contract_instance_retrieval_outgoing_viewing_key_hash, outgoing_viewing_key_hash }, + { C::contract_instance_retrieval_tagging_key_hash, tagging_key_hash }, { C::contract_instance_retrieval_deployer_protocol_contract_address, CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS }, // Protocol Contract conditionals @@ -147,23 +144,20 @@ TEST(ContractInstanceRetrievalConstrainingTest, MultipleInstancesTrace) { C::contract_instance_retrieval_current_class_id, contract_instance.current_contract_class_id }, { C::contract_instance_retrieval_original_class_id, contract_instance.original_contract_class_id }, { C::contract_instance_retrieval_init_hash, contract_instance.initialization_hash }, + { C::contract_instance_retrieval_immutables_hash, contract_instance.immutables_hash }, { C::contract_instance_retrieval_public_data_tree_root, FF(base_public_data_tree_root + i) }, { C::contract_instance_retrieval_nullifier_tree_root, FF(base_nullifier_tree_root + i) }, { C::contract_instance_retrieval_nullifier_tree_height, NULLIFIER_TREE_HEIGHT }, { C::contract_instance_retrieval_nullifier_merkle_separator, DOM_SEP__NULLIFIER_MERKLE }, { C::contract_instance_retrieval_siloing_separator, DOM_SEP__SILOED_NULLIFIER }, - { C::contract_instance_retrieval_nullifier_key_x, contract_instance.public_keys.nullifier_key.x }, - { C::contract_instance_retrieval_nullifier_key_y, contract_instance.public_keys.nullifier_key.y }, + { C::contract_instance_retrieval_nullifier_key_hash, contract_instance.public_keys.nullifier_key_hash }, { C::contract_instance_retrieval_incoming_viewing_key_x, contract_instance.public_keys.incoming_viewing_key.x }, { C::contract_instance_retrieval_incoming_viewing_key_y, contract_instance.public_keys.incoming_viewing_key.y }, - { C::contract_instance_retrieval_outgoing_viewing_key_x, - contract_instance.public_keys.outgoing_viewing_key.x }, - { C::contract_instance_retrieval_outgoing_viewing_key_y, - contract_instance.public_keys.outgoing_viewing_key.y }, - { C::contract_instance_retrieval_tagging_key_x, contract_instance.public_keys.tagging_key.x }, - { C::contract_instance_retrieval_tagging_key_y, contract_instance.public_keys.tagging_key.y }, + { C::contract_instance_retrieval_outgoing_viewing_key_hash, + contract_instance.public_keys.outgoing_viewing_key_hash }, + { C::contract_instance_retrieval_tagging_key_hash, contract_instance.public_keys.tagging_key_hash }, { C::contract_instance_retrieval_deployer_protocol_contract_address, CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS }, // Protocol Contract conditionals @@ -199,6 +193,7 @@ TEST(ContractInstanceRetrievalConstrainingTest, NonExistentInstanceTrace) { C::contract_instance_retrieval_current_class_id, 0 }, { C::contract_instance_retrieval_original_class_id, 0 }, { C::contract_instance_retrieval_init_hash, 0 }, + { C::contract_instance_retrieval_immutables_hash, 0 }, { C::contract_instance_retrieval_public_data_tree_root, public_data_tree_root }, { C::contract_instance_retrieval_nullifier_tree_root, nullifier_tree_root }, { C::contract_instance_retrieval_nullifier_tree_height, NULLIFIER_TREE_HEIGHT }, @@ -242,6 +237,12 @@ TEST(ContractInstanceRetrievalConstrainingTest, NonExistentInstanceTrace) "INSTANCE_MEMBER_INIT_HASH_IS_ZERO_IF_DNE"); // reset trace.set(C::contract_instance_retrieval_init_hash, 1, 0); + // mutate immutables_hash + trace.set(C::contract_instance_retrieval_immutables_hash, 1, 1); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace), + "INSTANCE_MEMBER_IMMUTABLES_HASH_IS_ZERO_IF_DNE"); + // reset + trace.set(C::contract_instance_retrieval_immutables_hash, 1, 0); } TEST(ContractInstanceRetrievalConstrainingTest, MaximumFieldValuesTrace) @@ -260,19 +261,17 @@ TEST(ContractInstanceRetrievalConstrainingTest, MaximumFieldValuesTrace) { C::contract_instance_retrieval_current_class_id, max_field }, { C::contract_instance_retrieval_original_class_id, max_field }, { C::contract_instance_retrieval_init_hash, max_field }, + { C::contract_instance_retrieval_immutables_hash, max_field }, { C::contract_instance_retrieval_public_data_tree_root, max_field }, { C::contract_instance_retrieval_nullifier_tree_root, max_field }, { C::contract_instance_retrieval_nullifier_tree_height, NULLIFIER_TREE_HEIGHT }, { C::contract_instance_retrieval_nullifier_merkle_separator, DOM_SEP__NULLIFIER_MERKLE }, { C::contract_instance_retrieval_siloing_separator, DOM_SEP__SILOED_NULLIFIER }, - { C::contract_instance_retrieval_nullifier_key_x, max_field }, - { C::contract_instance_retrieval_nullifier_key_y, max_field }, + { C::contract_instance_retrieval_nullifier_key_hash, max_field }, { C::contract_instance_retrieval_incoming_viewing_key_x, max_field }, { C::contract_instance_retrieval_incoming_viewing_key_y, max_field }, - { C::contract_instance_retrieval_outgoing_viewing_key_x, max_field }, - { C::contract_instance_retrieval_outgoing_viewing_key_y, max_field }, - { C::contract_instance_retrieval_tagging_key_x, max_field }, - { C::contract_instance_retrieval_tagging_key_y, max_field }, + { C::contract_instance_retrieval_outgoing_viewing_key_hash, max_field }, + { C::contract_instance_retrieval_tagging_key_hash, max_field }, { C::contract_instance_retrieval_deployer_protocol_contract_address, CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS }, // Protocol Contract conditionals @@ -460,14 +459,13 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenValidInstance { C::address_derivation_deployer_addr, contract_instance_data.deployer }, { C::address_derivation_class_id, contract_instance_data.original_contract_class_id }, { C::address_derivation_init_hash, contract_instance_data.initialization_hash }, - { C::address_derivation_nullifier_key_x, contract_instance_data.public_keys.nullifier_key.x }, - { C::address_derivation_nullifier_key_y, contract_instance_data.public_keys.nullifier_key.y }, + { C::address_derivation_immutables_hash, contract_instance_data.immutables_hash }, + { C::address_derivation_nullifier_key_hash, contract_instance_data.public_keys.nullifier_key_hash }, { C::address_derivation_incoming_viewing_key_x, contract_instance_data.public_keys.incoming_viewing_key.x }, { C::address_derivation_incoming_viewing_key_y, contract_instance_data.public_keys.incoming_viewing_key.y }, - { C::address_derivation_outgoing_viewing_key_x, contract_instance_data.public_keys.outgoing_viewing_key.x }, - { C::address_derivation_outgoing_viewing_key_y, contract_instance_data.public_keys.outgoing_viewing_key.y }, - { C::address_derivation_tagging_key_x, contract_instance_data.public_keys.tagging_key.x }, - { C::address_derivation_tagging_key_y, contract_instance_data.public_keys.tagging_key.y }, + { C::address_derivation_outgoing_viewing_key_hash, + contract_instance_data.public_keys.outgoing_viewing_key_hash }, + { C::address_derivation_tagging_key_hash, contract_instance_data.public_keys.tagging_key_hash }, // For update check lookup { C::update_check_sel, 1 }, { C::update_check_address, contract_address }, @@ -535,18 +533,16 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenNonExistentIn // For address derivation lookup { C::address_derivation_sel, 0 }, // Not selected since nullifier doesn't exist { C::address_derivation_address, contract_address }, - { C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_nullifier_key_x, 0 }, - { C::address_derivation_nullifier_key_y, 0 }, + { C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_immutables_hash, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_nullifier_key_hash, 0 }, { C::address_derivation_incoming_viewing_key_x, 0 }, { C::address_derivation_incoming_viewing_key_y, 0 }, - { C::address_derivation_outgoing_viewing_key_x, 0 }, - { C::address_derivation_outgoing_viewing_key_y, 0 }, - { C::address_derivation_tagging_key_x, 0 }, - { C::address_derivation_tagging_key_y, 0 }, + { C::address_derivation_outgoing_viewing_key_hash, 0 }, + { C::address_derivation_tagging_key_hash, 0 }, // For update check lookup (only populated when nullifier exists) { C::update_check_sel, 0 }, // Not selected since nullifier doesn't exist { C::update_check_address, contract_address }, @@ -616,18 +612,16 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenAddressZero) // For address derivation lookup { C::address_derivation_sel, 0 }, // Not selected since nullifier doesn't exist { C::address_derivation_address, contract_address }, - { C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist - { C::address_derivation_nullifier_key_x, 0 }, - { C::address_derivation_nullifier_key_y, 0 }, + { C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_immutables_hash, 0 }, // zero since nullifier doesn't exist + { C::address_derivation_nullifier_key_hash, 0 }, { C::address_derivation_incoming_viewing_key_x, 0 }, { C::address_derivation_incoming_viewing_key_y, 0 }, - { C::address_derivation_outgoing_viewing_key_x, 0 }, - { C::address_derivation_outgoing_viewing_key_y, 0 }, - { C::address_derivation_tagging_key_x, 0 }, - { C::address_derivation_tagging_key_y, 0 }, + { C::address_derivation_outgoing_viewing_key_hash, 0 }, + { C::address_derivation_tagging_key_hash, 0 }, // For update check lookup (only populated when nullifier exists) { C::update_check_sel, 0 }, // Not selected since nullifier doesn't exist { C::update_check_address, contract_address }, @@ -710,18 +704,15 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenMultipleInsta { C::address_derivation_deployer_addr, contract_instance_data.deployer }, { C::address_derivation_class_id, contract_instance_data.original_contract_class_id }, { C::address_derivation_init_hash, contract_instance_data.initialization_hash }, - { C::address_derivation_nullifier_key_x, contract_instance_data.public_keys.nullifier_key.x }, - { C::address_derivation_nullifier_key_y, contract_instance_data.public_keys.nullifier_key.y }, + { C::address_derivation_immutables_hash, contract_instance_data.immutables_hash }, + { C::address_derivation_nullifier_key_hash, contract_instance_data.public_keys.nullifier_key_hash }, { C::address_derivation_incoming_viewing_key_x, contract_instance_data.public_keys.incoming_viewing_key.x }, { C::address_derivation_incoming_viewing_key_y, contract_instance_data.public_keys.incoming_viewing_key.y }, - { C::address_derivation_outgoing_viewing_key_x, - contract_instance_data.public_keys.outgoing_viewing_key.x }, - { C::address_derivation_outgoing_viewing_key_y, - contract_instance_data.public_keys.outgoing_viewing_key.y }, - { C::address_derivation_tagging_key_x, contract_instance_data.public_keys.tagging_key.x }, - { C::address_derivation_tagging_key_y, contract_instance_data.public_keys.tagging_key.y }, + { C::address_derivation_outgoing_viewing_key_hash, + contract_instance_data.public_keys.outgoing_viewing_key_hash }, + { C::address_derivation_tagging_key_hash, contract_instance_data.public_keys.tagging_key_hash }, // For update check lookup (only when nullifier exists) { C::update_check_sel, 1 }, { C::update_check_address, FF(base_address + i) }, diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp index 50bb15ba3321..cfe37e518bda 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -63,11 +64,11 @@ using simulation::ToRadixMemoryEvent; // Known good points for P and Q FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); -EmbeddedCurvePoint p(p_x, p_y, false); +EmbeddedCurvePoint p(p_x, p_y); FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); -EmbeddedCurvePoint q(q_x, q_y, false); +EmbeddedCurvePoint q(q_x, q_y); TEST(EccAddConstrainingTest, EccEmptyRow) { @@ -79,7 +80,7 @@ TEST(EccAddConstrainingTest, EccAdd) // R = P + Q; FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); auto trace = TestTraceContainer({ { { C::ecc_add_op, 1 }, @@ -102,7 +103,6 @@ TEST(EccAddConstrainingTest, EccAdd) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -123,7 +123,7 @@ TEST(EccAddConstrainingTest, EccDouble) // R = P + P; FF r_x("0x088b996194bb5e6e8e5e49733bb671c3e660cf77254f743f366cc8e33534ee3b"); FF r_y("0x2807ffa01c0f522d0be1e1acfb6914ac8eabf1acf420c0629d37beee992e9a0e"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); auto trace = TestTraceContainer({ { { C::ecc_add_op, 0 }, @@ -146,7 +146,6 @@ TEST(EccAddConstrainingTest, EccDouble) { C::ecc_q_y, p.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -173,13 +172,13 @@ TEST(EccAddConstrainingTest, EccAddSameYDifferentX) // Point P - known valid point on Grumpkin FF local_p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF local_p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint local_p(local_p_x, local_p_y, false); + EmbeddedCurvePoint local_p(local_p_x, local_p_y); // Point Q - p_x * omega (cube root of unity), same y-coordinate! // omega = 0x0000000000000000b3c4d79d41a917585bfc41088d8daaa78b17ea66b99c90dd FF local_q_x("0x14dd39aa19e1c8b29e0c530a28106a7d64d2213486baba3c86dce51bdddf75bb"); FF local_q_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint local_q(local_q_x, local_q_y, false); + EmbeddedCurvePoint local_q(local_q_x, local_q_y); // Verify preconditions: same y, different x ASSERT_NE(local_p.x(), local_q.x()); @@ -188,7 +187,7 @@ TEST(EccAddConstrainingTest, EccAddSameYDifferentX) // Expected result R = P + Q (lambda = 0 since y's are equal) FF local_r_x("0x16bdb7ada0799a3088b9dd3faade12c3f79dbfe9cb1234783a1a7add546398dc"); FF local_r_y("0x2d08e098faf58cb97223d13f2a1b87dd6614173f3cefe87ca6a74e3034c244a1"); - EmbeddedCurvePoint local_r(local_r_x, local_r_y, false); + EmbeddedCurvePoint local_r(local_r_x, local_r_y); // Use simulation to generate events EventEmitter ecc_add_event_emitter; @@ -221,8 +220,8 @@ TEST(EccAddConstrainingTest, EccAddSameYDifferentX) TEST(EccAddConstrainingTest, EccAddResultingInInfinity) { // R = P + (-P) = O; , where O is the point at infinity - EmbeddedCurvePoint q(p.x(), -p.y(), false); - EmbeddedCurvePoint r(0, 0, true); + EmbeddedCurvePoint q(p.x(), -p.y()); + EmbeddedCurvePoint r(0, 0); auto trace = TestTraceContainer({ { { C::ecc_add_op, 0 }, @@ -245,7 +244,6 @@ TEST(EccAddConstrainingTest, EccAddResultingInInfinity) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -261,11 +259,11 @@ TEST(EccAddConstrainingTest, EccAddResultingInInfinity) TEST(EccAddConstrainingTest, EccAddingToInfinity) { - EmbeddedCurvePoint p(0, 0, true); + EmbeddedCurvePoint p(0, 0); // R = O + Q = Q; , where O is the point at infinity - EmbeddedCurvePoint r(q.x(), q.y(), false); + EmbeddedCurvePoint r(q.x(), q.y()); auto trace = TestTraceContainer({ { { C::ecc_add_op, 1 }, @@ -288,7 +286,6 @@ TEST(EccAddConstrainingTest, EccAddingToInfinity) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -304,10 +301,10 @@ TEST(EccAddConstrainingTest, EccAddingToInfinity) TEST(EccAddConstrainingTest, EccAddingInfinity) { - EmbeddedCurvePoint q(0, 0, true); + EmbeddedCurvePoint q(0, 0); // R = P + O = P; , where O is the point at infinity - EmbeddedCurvePoint r(p.x(), p.y(), false); + EmbeddedCurvePoint r(p.x(), p.y()); auto trace = TestTraceContainer({ { { C::ecc_add_op, 1 }, @@ -330,7 +327,6 @@ TEST(EccAddConstrainingTest, EccAddingInfinity) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -347,10 +343,10 @@ TEST(EccAddConstrainingTest, EccAddingInfinity) TEST(EccAddConstrainingTest, EccDoublingInf) { - EmbeddedCurvePoint p(0, 0, true); + EmbeddedCurvePoint p(0, 0); // r = O + O = O; , where O is the point at infinity - EmbeddedCurvePoint r(0, 0, true); + EmbeddedCurvePoint r(0, 0); auto trace = TestTraceContainer({ { { C::ecc_add_op, 0 }, @@ -373,7 +369,6 @@ TEST(EccAddConstrainingTest, EccDoublingInf) { C::ecc_q_y, p.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -414,7 +409,6 @@ TEST(EccAddConstrainingTest, EccTwoOps) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r1.is_infinity()) }, { C::ecc_r_x, r1.x() }, { C::ecc_r_y, r1.y() }, @@ -447,7 +441,6 @@ TEST(EccAddConstrainingTest, EccTwoOps) { C::ecc_q_y, r1.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r2.is_infinity()) }, { C::ecc_r_x, r2.x() }, { C::ecc_r_y, r2.y() }, @@ -469,7 +462,7 @@ TEST(EccAddConstrainingTest, EccNegativeBadAdd) FF r_x("0x20f096ae3de9aea007e0b94a0274b2443d6682d1901f6909f284ec967bc169be"); FF r_y("0x27948713833bb314e828f2b6f45f408da6564a3ac03b9e430a9c6634bb849ef2"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); auto trace = TestTraceContainer({ { { C::ecc_add_op, 1 }, @@ -492,7 +485,6 @@ TEST(EccAddConstrainingTest, EccNegativeBadAdd) { C::ecc_q_y, q.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -513,7 +505,7 @@ TEST(EccAddConstrainingTest, EccNegativeBadDouble) FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); auto trace = TestTraceContainer({ { { C::ecc_add_op, 0 }, @@ -536,7 +528,6 @@ TEST(EccAddConstrainingTest, EccNegativeBadDouble) { C::ecc_q_y, p.y() }, // Resulting Point - { C::ecc_r_is_inf, static_cast(r.is_infinity()) }, { C::ecc_r_x, r.x() }, { C::ecc_r_y, r.y() }, @@ -771,40 +762,6 @@ TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinity) EventEmitter scalar_mul_event_emitter; NoopEventEmitter ecc_add_memory_event_emitter; - StrictMock execution_id_manager; - StrictMock gt; - PureToRadix to_radix_simulator = PureToRadix(); - EccSimulator ecc_simulator(execution_id_manager, - gt, - to_radix_simulator, - ecc_add_event_emitter, - scalar_mul_event_emitter, - ecc_add_memory_event_emitter); - - EmbeddedCurvePoint result = ecc_simulator.scalar_mul(EmbeddedCurvePoint::infinity(), FF(10)); - ASSERT_TRUE(result.is_infinity()); - - TestTraceContainer trace({ - { { C::precomputed_first_row, 1 } }, - }); - - builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace); - builder.process_add(ecc_add_event_emitter.dump_events(), trace); - - check_interaction(trace); - - check_relation(trace); - check_relation(trace); -} - -TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinityRep) -{ - EccTraceBuilder builder; - - EventEmitter ecc_add_event_emitter; - EventEmitter scalar_mul_event_emitter; - NoopEventEmitter ecc_add_memory_event_emitter; - StrictMock execution_id_manager; StrictMock gt; PureToRadix to_radix_simulator = PureToRadix(); @@ -816,14 +773,13 @@ TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinityRep) ecc_add_memory_event_emitter); EmbeddedCurvePoint inf = EmbeddedCurvePoint::infinity(); - // EmbeddedCurvePoint preserves raw coordinates (see StandardAffinePointTest) + EmbeddedCurvePoint inf_bb = EmbeddedCurvePoint(avm2::AffinePoint::infinity()); - EmbeddedCurvePoint inf_alt = EmbeddedCurvePoint(1, 2, true); EmbeddedCurvePoint result = ecc_simulator.scalar_mul(inf_bb, FF(10)); ASSERT_TRUE(result.is_infinity()); - result = ecc_simulator.scalar_mul(inf_alt, FF(10)); - ASSERT_TRUE(result.is_infinity()); + EXPECT_EQ(result.x(), inf.x()); + EXPECT_EQ(result.y(), inf.y()); TestTraceContainer trace({ { { C::precomputed_first_row, 1 } }, @@ -1178,16 +1134,14 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInteractions) // Execution { C::execution_sel, 1 }, { C::execution_sel_exec_dispatch_ecc_add, 1 }, - { C::execution_rop_6_, dst_address }, + { C::execution_rop_4_, dst_address }, { C::execution_register_0_, p.x() }, { C::execution_register_1_, p.y() }, - { C::execution_register_2_, p.is_infinity() ? 1 : 0 }, - { C::execution_register_3_, q.x() }, - { C::execution_register_4_, q.y() }, - { C::execution_register_5_, q.is_infinity() ? 1 : 0 }, + { C::execution_register_2_, q.x() }, + { C::execution_register_3_, q.y() }, // GT - dst out of range check { C::gt_sel, 1 }, - { C::gt_input_a, dst_address + 2 }, // highest write address is dst_address + 2 + { C::gt_input_a, dst_address + 1 }, // highest write address is dst_address + 1 { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, { C::gt_res, 0 }, // Memory Writes @@ -1205,14 +1159,6 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInteractions) { C::memory_rw, 1 }, // write { C::memory_tag, static_cast(MemoryTag::FF) }, }, - { - // Memory Writes - { C::memory_address, dst_address + 2 }, - { C::memory_value, result.is_infinity() }, - { C::memory_sel, 1 }, - { C::memory_rw, 1 }, // write - { C::memory_tag, static_cast(MemoryTag::U1) }, - }, }); ecc_simulator.add(memory, p, q, dst_address); @@ -1237,7 +1183,7 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInvalidDstRange) StrictMock execution_id_manager; EXPECT_CALL(execution_id_manager, get_execution_id) - .WillRepeatedly(Return(0)); // Use a fixed execution IDfor the test + .WillRepeatedly(Return(0)); // Use a fixed execution ID for the test PureGreaterThan gt; PureToRadix to_radix_simulator = PureToRadix(); @@ -1248,7 +1194,7 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInvalidDstRange) scalar_mul_event_emitter, ecc_add_memory_event_emitter); - uint32_t dst_address = AVM_HIGHEST_MEM_ADDRESS - 1; // Invalid address, will result in out of range error + uint32_t dst_address = AVM_HIGHEST_MEM_ADDRESS; // Invalid address, will result in out of range error // Set the execution and gt traces TestTraceContainer trace = TestTraceContainer({ // Row 0 @@ -1256,17 +1202,15 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryInvalidDstRange) // Execution { C::execution_sel, 1 }, { C::execution_sel_exec_dispatch_ecc_add, 1 }, - { C::execution_rop_6_, dst_address }, + { C::execution_rop_4_, dst_address }, { C::execution_register_0_, p.x() }, { C::execution_register_1_, p.y() }, - { C::execution_register_2_, p.is_infinity() ? 1 : 0 }, - { C::execution_register_3_, q.x() }, - { C::execution_register_4_, q.y() }, - { C::execution_register_5_, q.is_infinity() ? 1 : 0 }, + { C::execution_register_2_, q.x() }, + { C::execution_register_3_, q.y() }, { C::execution_sel_opcode_error, 1 }, // GT - dst out of range check { C::gt_sel, 1 }, - { C::gt_input_a, static_cast(dst_address) + 2 }, + { C::gt_input_a, static_cast(dst_address) + 1 }, { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, { C::gt_res, 1 }, }, @@ -1306,7 +1250,7 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryPointError) // Point P is not on the curve FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); uint32_t dst_address = 0x1000; @@ -1318,17 +1262,15 @@ TEST(EccAddMemoryConstrainingTest, EccAddMemoryPointError) // Execution { C::execution_sel, 1 }, { C::execution_sel_exec_dispatch_ecc_add, 1 }, - { C::execution_rop_6_, dst_address }, + { C::execution_rop_4_, dst_address }, { C::execution_register_0_, p.x() }, { C::execution_register_1_, p.y() }, - { C::execution_register_2_, p.is_infinity() ? 1 : 0 }, - { C::execution_register_3_, q.x() }, - { C::execution_register_4_, q.y() }, - { C::execution_register_5_, q.is_infinity() ? 1 : 0 }, + { C::execution_register_2_, q.x() }, + { C::execution_register_3_, q.y() }, { C::execution_sel_opcode_error, 1 }, // Indicate an error in the operation // GT - dst out of range check { C::gt_sel, 1 }, - { C::gt_input_a, dst_address + 2 }, // highest write address is dst_address + 2 + { C::gt_input_a, dst_address + 1 }, // highest write address is dst_address + 1 { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, { C::gt_res, 0 }, }, @@ -1368,42 +1310,23 @@ TEST(EccAddMemoryConstrainingTest, InfinityRepresentations) // Point P is infinity EmbeddedCurvePoint inf = EmbeddedCurvePoint::infinity(); - // EmbeddedCurvePoint preserves raw coordinates (see StandardAffinePointTest) + // EmbeddedCurvePoint always sets extractable coordinates as (0,0) and the underlying point as + // AffinePoint::infinity() for input infinity points. EmbeddedCurvePoint inf_bb = EmbeddedCurvePoint(avm2::AffinePoint::infinity()); - EmbeddedCurvePoint inf_alt = EmbeddedCurvePoint(1, 2, true); + EXPECT_EQ(inf_bb, inf); TestTraceContainer trace; - // Internal add() expects normalized points: - EXPECT_THROW_WITH_MESSAGE(ecc_simulator.add(inf, inf_alt), "normalized"); - - // Coordinates are normalized in tracegen, so even though inf_bb and inf_alt have different coordinates, the circuit - // correctly assigns double_op = true when doubling inf: - ecc_simulator.add(memory, inf, inf_alt, dst_address); - // As above for the noir (0, 0) and bb (x, 0) inf reps: - ecc_simulator.add(memory, inf, inf_bb, dst_address + 3); + // The circuit correctly assigns double_op = true when doubling inf: + ecc_simulator.add(memory, inf, inf_bb, dst_address); builder.process_add(ecc_add_event_emitter.dump_events(), trace); check_relation(trace); EXPECT_EQ(trace.get(C::ecc_double_op, 0), 1); + ecc_simulator.add(memory, inf, inf_bb, dst_address); + // Set memory reads: trace.set(0, - { { // Execution - { C::execution_sel, 1 }, - { C::execution_sel_exec_dispatch_ecc_add, 1 }, - { C::execution_rop_6_, dst_address }, - { C::execution_register_0_, inf.x() }, - { C::execution_register_1_, inf.y() }, - { C::execution_register_2_, inf.is_infinity() ? 1 : 0 }, - { C::execution_register_3_, inf_alt.x() }, - { C::execution_register_4_, inf_alt.y() }, - { C::execution_register_5_, inf_alt.is_infinity() ? 1 : 0 }, - // GT - dst out of range check - { C::gt_sel, 1 }, - { C::gt_input_a, dst_address + 2 }, // highest write address is dst_address + 2 - { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, - { C::gt_res, 0 } } }); - trace.set(1, { { // Execution { C::execution_sel, 1 }, { C::execution_sel_exec_dispatch_ecc_add, 1 }, @@ -1416,22 +1339,21 @@ TEST(EccAddMemoryConstrainingTest, InfinityRepresentations) { C::execution_register_5_, inf_bb.is_infinity() ? 1 : 0 }, // GT - dst out of range check { C::gt_sel, 1 }, - { C::gt_input_a, dst_address + 5 }, + { C::gt_input_a, dst_address + 2 }, { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS }, { C::gt_res, 0 } } }); builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace); - // The original coordinates are stored in memory for the read... - EXPECT_EQ(trace.get(C::ecc_add_mem_q_x, 1), inf_bb.x()); - EXPECT_EQ(trace.get(C::ecc_add_mem_q_y, 1), inf_bb.y()); - // ...but normalised coordinates are sent to the ecc subtrace: - EXPECT_EQ(trace.get(C::ecc_add_mem_q_x_n, 1), 0); - EXPECT_EQ(trace.get(C::ecc_add_mem_q_y_n, 1), 0); - check_relation(trace); - check_relation(trace); - check_all_interactions(trace); - check_interaction(trace); + // The derived is_inf column must be true if the coordinates are (0, 0): + trace.set(C::ecc_add_mem_p_is_inf, 0, 0); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, mem_aware_ecc::SR_P_CURVE_EQN), "P_CURVE_EQN"); + + // If is_inf is set, the coordinates must be (0, 0): + trace.set(C::ecc_add_mem_q_x, 0, 1); + trace.set(C::ecc_add_mem_q_y, 0, 2); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, mem_aware_ecc::SR_Q_INF_X_CHECK), "Q_INF_X_CHECK"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, mem_aware_ecc::SR_Q_INF_Y_CHECK), "Q_INF_Y_CHECK"); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp index 30337347c8de..3ac442fe3116 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp @@ -141,6 +141,7 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint) const FF deployer_addr = 0x1234; const FF class_id = 0x5678; const FF init_hash = 0x9ABC; + const FF immutables_hash = 0xCAFE; const FF wrong_value = 0x1111; // Test selected member subrelation @@ -152,9 +153,11 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint) { C::get_contract_instance_is_deployer, 1 }, { C::get_contract_instance_is_class_id, 0 }, { C::get_contract_instance_is_init_hash, 0 }, + { C::get_contract_instance_is_immutables_hash, 0 }, { C::get_contract_instance_retrieved_deployer_addr, deployer_addr }, { C::get_contract_instance_retrieved_class_id, class_id }, - { C::get_contract_instance_retrieved_init_hash, init_hash } }, + { C::get_contract_instance_retrieved_init_hash, init_hash }, + { C::get_contract_instance_retrieved_immutables_hash, immutables_hash } }, }); check_relation(trace, get_contract_instance::SR_SELECTED_MEMBER); @@ -171,6 +174,12 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint) trace.set(C::get_contract_instance_is_init_hash, 1, 1); check_relation(trace, get_contract_instance::SR_SELECTED_MEMBER); + // Test IMMUTABLES_HASH selection + trace.set(C::get_contract_instance_selected_member, 1, immutables_hash); + trace.set(C::get_contract_instance_is_init_hash, 1, 0); + trace.set(C::get_contract_instance_is_immutables_hash, 1, 1); + check_relation(trace, get_contract_instance::SR_SELECTED_MEMBER); + // Negative test: wrong selected member trace.set(C::get_contract_instance_selected_member, 1, wrong_value); // Wrong value EXPECT_THROW_WITH_MESSAGE(check_relation(trace, get_contract_instance::SR_SELECTED_MEMBER), diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp index 3ab83cac013e..16b5e1b14b22 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp @@ -96,9 +96,7 @@ TEST(InstrFetchingConstrainingTest, EcaddWithTraceGen) Operand::from(0x127a), Operand::from(0x127b), Operand::from(0x127c), - Operand::from(0x127d), - Operand::from(0x127e), - Operand::from(0x127f) }, + Operand::from(0x127d), }, }; std::vector bytecode = ecadd_instruction.serialize(); diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp index 3d1bfac00e40..55bf30c6aac7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp @@ -7,9 +7,9 @@ namespace bb::avm2 { // clang-format off -#define AVM2_PRECOMPUTED_ENTITIES_E(e) e precomputed_addressing_gas, e precomputed_bitwise_input_a, e precomputed_bitwise_input_b, e precomputed_bitwise_output_and, e precomputed_bitwise_output_or, e precomputed_bitwise_output_xor, e precomputed_dyn_gas_id, e precomputed_envvar_pi_row_idx, e precomputed_exec_opcode, e precomputed_exec_opcode_base_da_gas, e precomputed_exec_opcode_dynamic_da_gas, e precomputed_exec_opcode_dynamic_l2_gas, e precomputed_exec_opcode_opcode_gas, e precomputed_expected_tag_reg_0_, e precomputed_expected_tag_reg_1_, e precomputed_expected_tag_reg_2_, e precomputed_expected_tag_reg_3_, e precomputed_expected_tag_reg_4_, e precomputed_expected_tag_reg_5_, e precomputed_first_row, e precomputed_idx, e precomputed_instr_size, e precomputed_invalid_envvar_enum, e precomputed_is_address, e precomputed_is_class_id, e precomputed_is_cleanup, e precomputed_is_collect_fee, e precomputed_is_dagasleft, e precomputed_is_deployer, e precomputed_is_init_hash, e precomputed_is_isstaticcall, e precomputed_is_l2gasleft, e precomputed_is_public_call_request, e precomputed_is_revertible, e precomputed_is_sender, e precomputed_is_teardown, e precomputed_is_transactionfee, e precomputed_is_tree_padding, e precomputed_is_valid_member_enum, e precomputed_keccak_round_constant, e precomputed_next_phase_on_revert, e precomputed_opcode_out_of_range, e precomputed_out_tag, e precomputed_p_decomposition_limb, e precomputed_p_decomposition_limb_index, e precomputed_p_decomposition_radix, e precomputed_power_of_2, e precomputed_read_pi_length_offset, e precomputed_read_pi_start_offset, e precomputed_rw_reg_0_, e precomputed_rw_reg_1_, e precomputed_rw_reg_2_, e precomputed_rw_reg_3_, e precomputed_rw_reg_4_, e precomputed_rw_reg_5_, e precomputed_sel_addressing_gas, e precomputed_sel_append_l2_l1_msg, e precomputed_sel_append_note_hash, e precomputed_sel_append_nullifier, e precomputed_sel_envvar_pi_lookup_col0, e precomputed_sel_envvar_pi_lookup_col1, e precomputed_sel_exec_spec, e precomputed_sel_has_tag, e precomputed_sel_keccak, e precomputed_sel_mem_op_reg_0_, e precomputed_sel_mem_op_reg_1_, e precomputed_sel_mem_op_reg_2_, e precomputed_sel_mem_op_reg_3_, e precomputed_sel_mem_op_reg_4_, e precomputed_sel_mem_op_reg_5_, e precomputed_sel_mem_tag_out_of_range, e precomputed_sel_op_dc_0, e precomputed_sel_op_dc_1, e precomputed_sel_op_dc_10, e precomputed_sel_op_dc_11, e precomputed_sel_op_dc_12, e precomputed_sel_op_dc_13, e precomputed_sel_op_dc_14, e precomputed_sel_op_dc_15, e precomputed_sel_op_dc_16, e precomputed_sel_op_dc_2, e precomputed_sel_op_dc_3, e precomputed_sel_op_dc_4, e precomputed_sel_op_dc_5, e precomputed_sel_op_dc_6, e precomputed_sel_op_dc_7, e precomputed_sel_op_dc_8, e precomputed_sel_op_dc_9, e precomputed_sel_op_is_address_0_, e precomputed_sel_op_is_address_1_, e precomputed_sel_op_is_address_2_, e precomputed_sel_op_is_address_3_, e precomputed_sel_op_is_address_4_, e precomputed_sel_op_is_address_5_, e precomputed_sel_op_is_address_6_, e precomputed_sel_p_decomposition, e precomputed_sel_phase, e precomputed_sel_range_16, e precomputed_sel_range_8, e precomputed_sel_sha256_compression, e precomputed_sel_tag_check_reg_0_, e precomputed_sel_tag_check_reg_1_, e precomputed_sel_tag_check_reg_2_, e precomputed_sel_tag_check_reg_3_, e precomputed_sel_tag_check_reg_4_, e precomputed_sel_tag_check_reg_5_, e precomputed_sel_tag_is_op2, e precomputed_sel_tag_parameters, e precomputed_sel_to_radix_p_limb_counts, e precomputed_sha256_compression_round_constant, e precomputed_subtrace_id, e precomputed_subtrace_operation_id, e precomputed_tag_byte_length, e precomputed_tag_max_bits, e precomputed_tag_max_value, e precomputed_to_radix_num_limbs_for_p, e precomputed_to_radix_safe_limbs, e precomputed_zero, e public_inputs_sel -#define AVM2_WIRE_ENTITIES_E(e) e public_inputs_cols_0_, e public_inputs_cols_1_, e public_inputs_cols_2_, e public_inputs_cols_3_, e address_derivation_address, e address_derivation_address_y, e address_derivation_class_id, e address_derivation_const_four, e address_derivation_const_thirteen, e address_derivation_const_three, e address_derivation_const_two, e address_derivation_deployer_addr, e address_derivation_g1_x, e address_derivation_g1_y, e address_derivation_incoming_viewing_key_x, e address_derivation_incoming_viewing_key_y, e address_derivation_init_hash, e address_derivation_nullifier_key_x, e address_derivation_nullifier_key_y, e address_derivation_outgoing_viewing_key_x, e address_derivation_outgoing_viewing_key_y, e address_derivation_partial_address, e address_derivation_partial_address_domain_separator, e address_derivation_preaddress, e address_derivation_preaddress_domain_separator, e address_derivation_preaddress_public_key_x, e address_derivation_preaddress_public_key_y, e address_derivation_public_keys_hash, e address_derivation_public_keys_hash_domain_separator, e address_derivation_salt, e address_derivation_salted_init_hash, e address_derivation_salted_init_hash_domain_separator, e address_derivation_sel, e address_derivation_tagging_key_x, e address_derivation_tagging_key_y, e alu_a_hi, e alu_a_hi_bits, e alu_a_lo, e alu_a_lo_bits, e alu_ab_diff_inv, e alu_ab_tags_diff_inv, e alu_b_hi, e alu_b_inv, e alu_b_lo, e alu_c_hi, e alu_cf, e alu_constant_64, e alu_gt_input_a, e alu_gt_input_b, e alu_gt_result_c, e alu_helper1, e alu_ia, e alu_ia_tag, e alu_ib, e alu_ib_tag, e alu_ic, e alu_ic_tag, e alu_max_bits, e alu_max_value, e alu_mid, e alu_mid_bits, e alu_op_id, e alu_sel, e alu_sel_ab_tag_mismatch, e alu_sel_decompose_a, e alu_sel_div_0_err, e alu_sel_div_no_err, e alu_sel_err, e alu_sel_ff_gt, e alu_sel_int_gt, e alu_sel_is_ff, e alu_sel_is_u128, e alu_sel_mul_div_u128, e alu_sel_mul_no_err_non_ff, e alu_sel_op_add, e alu_sel_op_div, e alu_sel_op_eq, e alu_sel_op_fdiv, e alu_sel_op_lt, e alu_sel_op_lte, e alu_sel_op_mul, e alu_sel_op_not, e alu_sel_op_shl, e alu_sel_op_shr, e alu_sel_op_sub, e alu_sel_op_truncate, e alu_sel_shift_ops_no_overflow, e alu_sel_tag_err, e alu_sel_trunc_gte_128, e alu_sel_trunc_lt_128, e alu_sel_trunc_non_trivial, e alu_sel_trunc_trivial, e alu_shift_lo_bits, e alu_tag_ff_diff_inv, e alu_tag_u128_diff_inv, e alu_two_pow_shift_lo_bits, e bc_decomposition_bytes_pc_plus_36, e bc_decomposition_bytes_rem_inv, e bc_decomposition_bytes_rem_min_one_inv, e bc_decomposition_bytes_to_read, e bc_decomposition_last_of_contract, e bc_decomposition_next_packed_pc_min_pc_inv, e bc_decomposition_packed_field, e bc_decomposition_sel_packed, e bc_decomposition_sel_packed_read_0_, e bc_decomposition_sel_packed_read_1_, e bc_decomposition_sel_packed_read_2_, e bc_decomposition_sel_windows_eq_remaining, e bc_decomposition_windows_min_remaining_inv, e bc_hashing_end, e bc_hashing_input_len, e bc_hashing_packed_fields_0, e bc_hashing_packed_fields_1, e bc_hashing_packed_fields_2, e bc_hashing_pc_index, e bc_hashing_pc_index_2, e bc_hashing_sel_not_padding_1, e bc_hashing_sel_not_padding_2, e bc_hashing_size_in_bytes, e bc_retrieval_address, e bc_retrieval_artifact_hash, e bc_retrieval_bytecode_id, e bc_retrieval_current_class_id, e bc_retrieval_error, e bc_retrieval_instance_exists, e bc_retrieval_is_new_class, e bc_retrieval_next_retrieved_bytecodes_tree_root, e bc_retrieval_next_retrieved_bytecodes_tree_size, e bc_retrieval_no_remaining_bytecodes, e bc_retrieval_nullifier_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_size, e bc_retrieval_private_functions_root, e bc_retrieval_public_data_tree_root, e bc_retrieval_remaining_bytecodes_inv, e bc_retrieval_retrieved_bytecodes_merkle_separator, e bc_retrieval_retrieved_bytecodes_tree_height, e bc_retrieval_sel, e bc_retrieval_should_retrieve, e bitwise_ctr_min_one_inv, e bitwise_end, e bitwise_err, e bitwise_ia_byte, e bitwise_ib_byte, e bitwise_ic_byte, e bitwise_output_and, e bitwise_output_or, e bitwise_output_xor, e bitwise_sel_and, e bitwise_sel_compute, e bitwise_sel_get_ctr, e bitwise_sel_or, e bitwise_sel_tag_ff_err, e bitwise_sel_tag_mismatch_err, e bitwise_sel_xor, e bitwise_start_keccak, e bitwise_start_sha256, e bitwise_tag_a, e bitwise_tag_a_inv, e bitwise_tag_ab_diff_inv, e bitwise_tag_b, e bitwise_tag_c, e calldata_end, e calldata_hashing_end, e calldata_hashing_index_1_, e calldata_hashing_index_2_, e calldata_hashing_input_0_, e calldata_hashing_input_1_, e calldata_hashing_input_2_, e calldata_hashing_input_len, e calldata_hashing_sel_end_not_empty, e calldata_hashing_sel_not_padding_1, e calldata_hashing_sel_not_padding_2, e calldata_hashing_sel_not_start, e calldata_value, e class_id_derivation_artifact_hash, e class_id_derivation_class_id, e class_id_derivation_const_four, e class_id_derivation_gen_index_contract_class_id, e class_id_derivation_private_functions_root, e class_id_derivation_public_bytecode_commitment, e class_id_derivation_sel, e context_stack_bytecode_id, e context_stack_context_id, e context_stack_contract_address, e context_stack_entered_context_id, e context_stack_internal_call_id, e context_stack_internal_call_return_id, e context_stack_is_static, e context_stack_msg_sender, e context_stack_next_internal_call_id, e context_stack_next_pc, e context_stack_note_hash_tree_root, e context_stack_note_hash_tree_size, e context_stack_nullifier_tree_root, e context_stack_nullifier_tree_size, e context_stack_num_l2_to_l1_messages, e context_stack_num_note_hashes_emitted, e context_stack_num_nullifiers_emitted, e context_stack_num_public_log_fields, e context_stack_parent_calldata_addr, e context_stack_parent_calldata_size, e context_stack_parent_da_gas_limit, e context_stack_parent_da_gas_used, e context_stack_parent_id, e context_stack_parent_l2_gas_limit, e context_stack_parent_l2_gas_used, e context_stack_public_data_tree_root, e context_stack_public_data_tree_size, e context_stack_sel, e context_stack_written_public_data_slots_tree_root, e context_stack_written_public_data_slots_tree_size, e contract_instance_retrieval_address, e contract_instance_retrieval_address_sub_one, e contract_instance_retrieval_current_class_id, e contract_instance_retrieval_deployer_addr, e contract_instance_retrieval_deployer_protocol_contract_address, e contract_instance_retrieval_derived_address, e contract_instance_retrieval_derived_address_pi_index, e contract_instance_retrieval_exists, e contract_instance_retrieval_incoming_viewing_key_x, e contract_instance_retrieval_incoming_viewing_key_y, e contract_instance_retrieval_init_hash, e contract_instance_retrieval_is_protocol_contract, e contract_instance_retrieval_max_protocol_contracts, e contract_instance_retrieval_nullifier_key_x, e contract_instance_retrieval_nullifier_key_y, e contract_instance_retrieval_nullifier_merkle_separator, e contract_instance_retrieval_nullifier_tree_height, e contract_instance_retrieval_nullifier_tree_root, e contract_instance_retrieval_original_class_id, e contract_instance_retrieval_outgoing_viewing_key_x, e contract_instance_retrieval_outgoing_viewing_key_y, e contract_instance_retrieval_protocol_contract_derived_address_inv, e contract_instance_retrieval_public_data_tree_root, e contract_instance_retrieval_salt, e contract_instance_retrieval_sel, e contract_instance_retrieval_should_check_for_update, e contract_instance_retrieval_should_check_nullifier, e contract_instance_retrieval_siloing_separator, e contract_instance_retrieval_tagging_key_x, e contract_instance_retrieval_tagging_key_y, e data_copy_cd_copy_col_read, e data_copy_clamped_read_index_upper_bound, e data_copy_dst_out_of_range_err, e data_copy_end, e data_copy_is_top_level, e data_copy_mem_size, e data_copy_offset, e data_copy_offset_plus_size, e data_copy_offset_plus_size_is_gt, e data_copy_parent_id_inv, e data_copy_read_addr_plus_one, e data_copy_read_addr_upper_bound, e data_copy_reads_left_inv, e data_copy_sel_cd_copy_start, e data_copy_sel_has_reads, e data_copy_sel_mem_read, e data_copy_sel_mem_write, e data_copy_sel_rd_copy_start, e data_copy_sel_write_count_is_zero, e data_copy_src_addr, e data_copy_src_data_size, e data_copy_src_reads_exceed_mem, e data_copy_start_no_err, e data_copy_tag, e data_copy_value, e data_copy_write_addr_upper_bound, e data_copy_write_count_minus_one_inv, e data_copy_write_count_zero_inv, e ecc_add_mem_dst_addr_0_, e ecc_add_mem_dst_addr_1_, e ecc_add_mem_dst_addr_2_, e ecc_add_mem_err, e ecc_add_mem_execution_clk, e ecc_add_mem_max_mem_addr, e ecc_add_mem_p_is_inf, e ecc_add_mem_p_is_on_curve_eqn, e ecc_add_mem_p_is_on_curve_eqn_inv, e ecc_add_mem_p_x, e ecc_add_mem_p_x_n, e ecc_add_mem_p_y, e ecc_add_mem_p_y_n, e ecc_add_mem_q_is_inf, e ecc_add_mem_q_is_on_curve_eqn, e ecc_add_mem_q_is_on_curve_eqn_inv, e ecc_add_mem_q_x, e ecc_add_mem_q_x_n, e ecc_add_mem_q_y, e ecc_add_mem_q_y_n, e ecc_add_mem_res_is_inf, e ecc_add_mem_res_x, e ecc_add_mem_res_y, e ecc_add_mem_sel, e ecc_add_mem_sel_dst_out_of_range_err, e ecc_add_mem_sel_p_not_on_curve_err, e ecc_add_mem_sel_q_not_on_curve_err, e ecc_add_mem_sel_should_exec, e ecc_add_mem_space_id, e ecc_add_op, e ecc_double_op, e ecc_inv_2_p_y, e ecc_inv_x_diff, e ecc_inv_y_diff, e ecc_lambda, e ecc_p_is_inf, e ecc_p_x, e ecc_p_y, e ecc_q_is_inf, e ecc_q_x, e ecc_q_y, e ecc_r_is_inf, e ecc_r_x, e ecc_r_y, e ecc_result_infinity, e ecc_sel, e ecc_use_computed_result, e ecc_x_match, e ecc_y_match, e emit_public_log_discard, e emit_public_log_end, e emit_public_log_end_log_address_upper_bound, e emit_public_log_error, e emit_public_log_error_too_many_log_fields, e emit_public_log_expected_next_log_fields, e emit_public_log_is_static, e emit_public_log_log_size, e emit_public_log_max_mem_size, e emit_public_log_max_public_logs_payload_length, e emit_public_log_next_num_public_log_fields, e emit_public_log_prev_num_public_log_fields, e emit_public_log_public_inputs_value, e emit_public_log_remaining_rows_inv, e emit_public_log_sel_read_memory, e emit_public_log_tag, e emit_public_log_tag_inv, e emit_public_log_value, e execution_addressing_error_collection_inv, e execution_addressing_gas, e execution_addressing_mode, e execution_base_address_tag, e execution_base_address_tag_diff_inv, e execution_base_address_val, e execution_base_da_gas, e execution_batched_tags_diff_inv, e execution_batched_tags_diff_inv_reg, e execution_da_gas_left, e execution_da_gas_used, e execution_dying_context_diff_inv, e execution_dying_context_id_inv, e execution_dyn_gas_id, e execution_dynamic_da_gas, e execution_dynamic_da_gas_factor, e execution_dynamic_l2_gas, e execution_dynamic_l2_gas_factor, e execution_enqueued_call_end, e execution_envvar_pi_row_idx, e execution_exec_opcode, e execution_expected_tag_reg_0_, e execution_expected_tag_reg_1_, e execution_expected_tag_reg_2_, e execution_expected_tag_reg_3_, e execution_expected_tag_reg_4_, e execution_expected_tag_reg_5_, e execution_has_parent_ctx, e execution_highest_address, e execution_instr_size, e execution_internal_call_return_id_inv, e execution_is_address, e execution_is_da_gas_left_gt_allocated, e execution_is_dagasleft, e execution_is_dying_context, e execution_is_isstaticcall, e execution_is_l2_gas_left_gt_allocated, e execution_is_l2gasleft, e execution_is_parent_id_inv, e execution_is_sender, e execution_is_transactionfee, e execution_l1_to_l2_msg_leaf_in_range, e execution_l1_to_l2_msg_tree_leaf_count, e execution_l2_gas_left, e execution_l2_gas_used, e execution_max_data_writes_reached, e execution_max_eth_address_value, e execution_mem_tag_reg_0_, e execution_mem_tag_reg_1_, e execution_mem_tag_reg_2_, e execution_mem_tag_reg_3_, e execution_mem_tag_reg_4_, e execution_mem_tag_reg_5_, e execution_nested_failure, e execution_nested_return, e execution_next_pc, e execution_note_hash_leaf_in_range, e execution_note_hash_tree_leaf_count, e execution_note_hash_tree_root, e execution_note_hash_tree_size, e execution_nullifier_merkle_separator, e execution_nullifier_pi_offset, e execution_nullifier_siloing_separator, e execution_nullifier_tree_height, e execution_nullifier_tree_root, e execution_nullifier_tree_size, e execution_num_l2_to_l1_messages, e execution_num_note_hashes_emitted, e execution_num_nullifiers_emitted, e execution_num_p_limbs, e execution_num_public_log_fields, e execution_num_relative_operands_inv, e execution_op_0_, e execution_op_1_, e execution_op_2_, e execution_op_3_, e execution_op_4_, e execution_op_5_, e execution_op_6_, e execution_op_after_relative_0_, e execution_op_after_relative_1_, e execution_op_after_relative_2_, e execution_op_after_relative_3_, e execution_op_after_relative_4_, e execution_op_after_relative_5_, e execution_op_after_relative_6_, e execution_opcode_gas, e execution_out_of_gas_da, e execution_out_of_gas_l2, e execution_public_data_tree_root, e execution_public_data_tree_size, e execution_public_inputs_index, e execution_register_0_, e execution_register_1_, e execution_register_2_, e execution_register_3_, e execution_register_4_, e execution_register_5_, e execution_remaining_data_writes_inv, e execution_remaining_l2_to_l1_msgs_inv, e execution_remaining_note_hashes_inv, e execution_remaining_nullifiers_inv, e execution_retrieved_bytecodes_tree_root, e execution_retrieved_bytecodes_tree_size, e execution_rop_0_, e execution_rop_1_, e execution_rop_2_, e execution_rop_3_, e execution_rop_4_, e execution_rop_5_, e execution_rop_6_, e execution_rop_tag_0_, e execution_rop_tag_1_, e execution_rop_tag_2_, e execution_rop_tag_3_, e execution_rop_tag_4_, e execution_rop_tag_5_, e execution_rop_tag_6_, e execution_rw_reg_0_, e execution_rw_reg_1_, e execution_rw_reg_2_, e execution_rw_reg_3_, e execution_rw_reg_4_, e execution_rw_reg_5_, e execution_sel_addressing_error, e execution_sel_apply_indirection_0_, e execution_sel_apply_indirection_1_, e execution_sel_apply_indirection_2_, e execution_sel_apply_indirection_3_, e execution_sel_apply_indirection_4_, e execution_sel_apply_indirection_5_, e execution_sel_apply_indirection_6_, e execution_sel_base_address_failure, e execution_sel_bytecode_retrieval_failure, e execution_sel_bytecode_retrieval_success, e execution_sel_check_gas, e execution_sel_do_base_check, e execution_sel_enter_call, e execution_sel_envvar_pi_lookup_col0, e execution_sel_envvar_pi_lookup_col1, e execution_sel_error, e execution_sel_exec_dispatch_alu, e execution_sel_exec_dispatch_bitwise, e execution_sel_exec_dispatch_calldata_copy, e execution_sel_exec_dispatch_cast, e execution_sel_exec_dispatch_ecc_add, e execution_sel_exec_dispatch_emit_public_log, e execution_sel_exec_dispatch_execution, e execution_sel_exec_dispatch_get_contract_instance, e execution_sel_exec_dispatch_keccakf1600, e execution_sel_exec_dispatch_poseidon2_perm, e execution_sel_exec_dispatch_returndata_copy, e execution_sel_exec_dispatch_set, e execution_sel_exec_dispatch_sha256_compression, e execution_sel_exec_dispatch_to_radix, e execution_sel_execute_call, e execution_sel_execute_debug_log, e execution_sel_execute_emit_notehash, e execution_sel_execute_emit_nullifier, e execution_sel_execute_get_env_var, e execution_sel_execute_internal_call, e execution_sel_execute_internal_return, e execution_sel_execute_jump, e execution_sel_execute_jumpi, e execution_sel_execute_l1_to_l2_message_exists, e execution_sel_execute_mov, e execution_sel_execute_notehash_exists, e execution_sel_execute_nullifier_exists, e execution_sel_execute_opcode, e execution_sel_execute_return, e execution_sel_execute_returndata_size, e execution_sel_execute_revert, e execution_sel_execute_send_l2_to_l1_msg, e execution_sel_execute_sload, e execution_sel_execute_sstore, e execution_sel_execute_static_call, e execution_sel_execute_success_copy, e execution_sel_exit_call, e execution_sel_failure, e execution_sel_gas_bitwise, e execution_sel_gas_calldata_copy, e execution_sel_gas_emit_public_log, e execution_sel_gas_returndata_copy, e execution_sel_gas_sstore, e execution_sel_gas_to_radix, e execution_sel_instruction_fetching_failure, e execution_sel_instruction_fetching_success, e execution_sel_l2_to_l1_msg_limit_error, e execution_sel_lookup_num_p_limbs, e execution_sel_mem_op_reg_0_, e execution_sel_mem_op_reg_1_, e execution_sel_mem_op_reg_2_, e execution_sel_mem_op_reg_3_, e execution_sel_mem_op_reg_4_, e execution_sel_mem_op_reg_5_, e execution_sel_op_do_overflow_check_0_, e execution_sel_op_do_overflow_check_1_, e execution_sel_op_do_overflow_check_2_, e execution_sel_op_do_overflow_check_3_, e execution_sel_op_do_overflow_check_4_, e execution_sel_op_do_overflow_check_5_, e execution_sel_op_do_overflow_check_6_, e execution_sel_op_is_address_0_, e execution_sel_op_is_address_1_, e execution_sel_op_is_address_2_, e execution_sel_op_is_address_3_, e execution_sel_op_is_address_4_, e execution_sel_op_is_address_5_, e execution_sel_op_is_address_6_, e execution_sel_op_is_indirect_wire_0_, e execution_sel_op_is_indirect_wire_1_, e execution_sel_op_is_indirect_wire_2_, e execution_sel_op_is_indirect_wire_3_, e execution_sel_op_is_indirect_wire_4_, e execution_sel_op_is_indirect_wire_5_, e execution_sel_op_is_indirect_wire_6_, e execution_sel_op_is_indirect_wire_7_, e execution_sel_op_is_relative_wire_0_, e execution_sel_op_is_relative_wire_1_, e execution_sel_op_is_relative_wire_2_, e execution_sel_op_is_relative_wire_3_, e execution_sel_op_is_relative_wire_4_, e execution_sel_op_is_relative_wire_5_, e execution_sel_op_is_relative_wire_6_, e execution_sel_op_is_relative_wire_7_, e execution_sel_op_reg_effective_0_, e execution_sel_op_reg_effective_1_, e execution_sel_op_reg_effective_2_, e execution_sel_op_reg_effective_3_, e execution_sel_op_reg_effective_4_, e execution_sel_op_reg_effective_5_, e execution_sel_opcode_error, e execution_sel_out_of_gas, e execution_sel_radix_gt_256, e execution_sel_reached_max_note_hashes, e execution_sel_reached_max_nullifiers, e execution_sel_read_registers, e execution_sel_read_unwind_call_stack, e execution_sel_register_read_error, e execution_sel_relative_overflow_0_, e execution_sel_relative_overflow_1_, e execution_sel_relative_overflow_2_, e execution_sel_relative_overflow_3_, e execution_sel_relative_overflow_4_, e execution_sel_relative_overflow_5_, e execution_sel_relative_overflow_6_, e execution_sel_some_final_check_failed, e execution_sel_tag_check_reg_0_, e execution_sel_tag_check_reg_1_, e execution_sel_tag_check_reg_2_, e execution_sel_tag_check_reg_3_, e execution_sel_tag_check_reg_4_, e execution_sel_tag_check_reg_5_, e execution_sel_too_large_recipient_error, e execution_sel_use_num_limbs, e execution_sel_write_l2_to_l1_msg, e execution_sel_write_note_hash, e execution_sel_write_nullifier, e execution_sel_write_public_data, e execution_sel_write_registers, e execution_subtrace_id, e execution_subtrace_operation_id, e execution_total_gas_da, e execution_total_gas_l2, e execution_two_five_six, e execution_value_from_pi, e execution_written_public_data_slots_tree_root, e execution_written_public_data_slots_tree_size, e execution_written_slots_merkle_separator, e execution_written_slots_tree_height, e execution_written_slots_tree_siloing_separator, e ff_gt_a, e ff_gt_b, e ff_gt_borrow, e ff_gt_constant_128, e ff_gt_end, e ff_gt_p_a_borrow, e ff_gt_p_b_borrow, e ff_gt_res_hi, e ff_gt_res_lo, e ff_gt_result, e get_contract_instance_clk, e get_contract_instance_contract_address, e get_contract_instance_dst_offset, e get_contract_instance_dst_offset_diff_max_inv, e get_contract_instance_exists_tag, e get_contract_instance_instance_exists, e get_contract_instance_is_class_id, e get_contract_instance_is_deployer, e get_contract_instance_is_init_hash, e get_contract_instance_is_valid_member_enum, e get_contract_instance_is_valid_writes_in_bounds, e get_contract_instance_member_enum, e get_contract_instance_member_tag, e get_contract_instance_member_write_offset, e get_contract_instance_nullifier_tree_root, e get_contract_instance_public_data_tree_root, e get_contract_instance_retrieved_class_id, e get_contract_instance_retrieved_deployer_addr, e get_contract_instance_retrieved_init_hash, e get_contract_instance_sel, e get_contract_instance_sel_error, e get_contract_instance_selected_member, e get_contract_instance_space_id, e gt_abs_diff, e gt_input_a, e gt_input_b, e gt_num_bits, e gt_res, e gt_sel, e gt_sel_addressing, e gt_sel_alu, e gt_sel_gas, e gt_sel_others, e gt_sel_sha256, e indexed_tree_check_address, e indexed_tree_check_const_three, e indexed_tree_check_discard, e indexed_tree_check_exists, e indexed_tree_check_intermediate_root, e indexed_tree_check_low_leaf_hash, e indexed_tree_check_low_leaf_index, e indexed_tree_check_low_leaf_next_index, e indexed_tree_check_low_leaf_next_value, e indexed_tree_check_low_leaf_value, e indexed_tree_check_merkle_hash_separator, e indexed_tree_check_new_leaf_hash, e indexed_tree_check_next_value_inv, e indexed_tree_check_next_value_is_nonzero, e indexed_tree_check_not_exists, e indexed_tree_check_public_inputs_index, e indexed_tree_check_root, e indexed_tree_check_sel, e indexed_tree_check_sel_insert, e indexed_tree_check_sel_silo, e indexed_tree_check_sel_write_to_public_inputs, e indexed_tree_check_siloed_value, e indexed_tree_check_siloing_separator, e indexed_tree_check_tree_height, e indexed_tree_check_tree_size_after_write, e indexed_tree_check_tree_size_before_write, e indexed_tree_check_updated_low_leaf_hash, e indexed_tree_check_updated_low_leaf_next_index, e indexed_tree_check_updated_low_leaf_next_value, e indexed_tree_check_value, e indexed_tree_check_value_low_leaf_value_diff_inv, e indexed_tree_check_write, e indexed_tree_check_write_root, e instr_fetching_addressing_mode, e instr_fetching_bd0, e instr_fetching_bd1, e instr_fetching_bd10, e instr_fetching_bd11, e instr_fetching_bd12, e instr_fetching_bd13, e instr_fetching_bd14, e instr_fetching_bd15, e instr_fetching_bd16, e instr_fetching_bd17, e instr_fetching_bd18, e instr_fetching_bd19, e instr_fetching_bd2, e instr_fetching_bd20, e instr_fetching_bd21, e instr_fetching_bd22, e instr_fetching_bd23, e instr_fetching_bd24, e instr_fetching_bd25, e instr_fetching_bd26, e instr_fetching_bd27, e instr_fetching_bd28, e instr_fetching_bd29, e instr_fetching_bd3, e instr_fetching_bd30, e instr_fetching_bd31, e instr_fetching_bd32, e instr_fetching_bd33, e instr_fetching_bd34, e instr_fetching_bd35, e instr_fetching_bd36, e instr_fetching_bd4, e instr_fetching_bd5, e instr_fetching_bd6, e instr_fetching_bd7, e instr_fetching_bd8, e instr_fetching_bd9, e instr_fetching_bytecode_id, e instr_fetching_bytecode_size, e instr_fetching_bytes_to_read, e instr_fetching_exec_opcode, e instr_fetching_instr_abs_diff, e instr_fetching_instr_out_of_range, e instr_fetching_instr_size, e instr_fetching_op1, e instr_fetching_op2, e instr_fetching_op3, e instr_fetching_op4, e instr_fetching_op5, e instr_fetching_op6, e instr_fetching_op7, e instr_fetching_opcode_out_of_range, e instr_fetching_pc, e instr_fetching_pc_abs_diff, e instr_fetching_pc_out_of_range, e instr_fetching_pc_size_in_bits, e instr_fetching_sel, e instr_fetching_sel_has_tag, e instr_fetching_sel_op_dc_0, e instr_fetching_sel_op_dc_1, e instr_fetching_sel_op_dc_10, e instr_fetching_sel_op_dc_11, e instr_fetching_sel_op_dc_12, e instr_fetching_sel_op_dc_13, e instr_fetching_sel_op_dc_14, e instr_fetching_sel_op_dc_15, e instr_fetching_sel_op_dc_16, e instr_fetching_sel_op_dc_2, e instr_fetching_sel_op_dc_3, e instr_fetching_sel_op_dc_4, e instr_fetching_sel_op_dc_5, e instr_fetching_sel_op_dc_6, e instr_fetching_sel_op_dc_7, e instr_fetching_sel_op_dc_8, e instr_fetching_sel_op_dc_9, e instr_fetching_sel_parsing_err, e instr_fetching_sel_pc_in_range, e instr_fetching_sel_tag_is_op2, e instr_fetching_tag_out_of_range, e instr_fetching_tag_value, e internal_call_stack_call_id, e internal_call_stack_context_id, e internal_call_stack_entered_call_id, e internal_call_stack_return_call_id, e internal_call_stack_return_pc, e internal_call_stack_sel, e keccak_memory_ctr_end, e keccak_memory_end, e keccak_memory_single_tag_error, e keccak_memory_state_size_min_ctr_inv, e keccak_memory_tag, e keccak_memory_tag_min_u64_inv, e keccak_memory_val_24_, e keccakf1600_bitwise_and_op_id, e keccakf1600_bitwise_xor_op_id, e keccakf1600_dst_out_of_range_error, e keccakf1600_end, e keccakf1600_error, e keccakf1600_highest_slice_address, e keccakf1600_rot_64_min_len_01, e keccakf1600_rot_64_min_len_03, e keccakf1600_rot_64_min_len_11, e keccakf1600_rot_64_min_len_13, e keccakf1600_rot_64_min_len_20, e keccakf1600_rot_64_min_len_22, e keccakf1600_rot_64_min_len_24, e keccakf1600_rot_64_min_len_31, e keccakf1600_rot_64_min_len_34, e keccakf1600_rot_64_min_len_42, e keccakf1600_rot_len_02, e keccakf1600_rot_len_04, e keccakf1600_rot_len_10, e keccakf1600_rot_len_12, e keccakf1600_rot_len_14, e keccakf1600_rot_len_21, e keccakf1600_rot_len_23, e keccakf1600_rot_len_30, e keccakf1600_rot_len_32, e keccakf1600_rot_len_33, e keccakf1600_rot_len_40, e keccakf1600_rot_len_41, e keccakf1600_rot_len_43, e keccakf1600_rot_len_44, e keccakf1600_round_cst, e keccakf1600_sel_slice_read, e keccakf1600_sel_slice_write, e keccakf1600_src_addr, e keccakf1600_src_out_of_range_error, e keccakf1600_state_chi_00, e keccakf1600_state_chi_01, e keccakf1600_state_chi_02, e keccakf1600_state_chi_03, e keccakf1600_state_chi_04, e keccakf1600_state_chi_10, e keccakf1600_state_chi_11, e keccakf1600_state_chi_12, e keccakf1600_state_chi_13, e keccakf1600_state_chi_14, e keccakf1600_state_chi_20, e keccakf1600_state_chi_21, e keccakf1600_state_chi_22, e keccakf1600_state_chi_23, e keccakf1600_state_chi_24, e keccakf1600_state_chi_30, e keccakf1600_state_chi_31, e keccakf1600_state_chi_32, e keccakf1600_state_chi_33, e keccakf1600_state_chi_34, e keccakf1600_state_chi_40, e keccakf1600_state_chi_41, e keccakf1600_state_chi_42, e keccakf1600_state_chi_43, e keccakf1600_state_chi_44, e keccakf1600_state_iota_00, e keccakf1600_state_pi_and_00, e keccakf1600_state_pi_and_01, e keccakf1600_state_pi_and_02, e keccakf1600_state_pi_and_03, e keccakf1600_state_pi_and_04, e keccakf1600_state_pi_and_10, e keccakf1600_state_pi_and_11, e keccakf1600_state_pi_and_12, e keccakf1600_state_pi_and_13, e keccakf1600_state_pi_and_14, e keccakf1600_state_pi_and_20, e keccakf1600_state_pi_and_21, e keccakf1600_state_pi_and_22, e keccakf1600_state_pi_and_23, e keccakf1600_state_pi_and_24, e keccakf1600_state_pi_and_30, e keccakf1600_state_pi_and_31, e keccakf1600_state_pi_and_32, e keccakf1600_state_pi_and_33, e keccakf1600_state_pi_and_34, e keccakf1600_state_pi_and_40, e keccakf1600_state_pi_and_41, e keccakf1600_state_pi_and_42, e keccakf1600_state_pi_and_43, e keccakf1600_state_pi_and_44, e keccakf1600_state_pi_not_00, e keccakf1600_state_pi_not_01, e keccakf1600_state_pi_not_02, e keccakf1600_state_pi_not_03, e keccakf1600_state_pi_not_04, e keccakf1600_state_pi_not_10, e keccakf1600_state_pi_not_11, e keccakf1600_state_pi_not_12, e keccakf1600_state_pi_not_13, e keccakf1600_state_pi_not_14, e keccakf1600_state_pi_not_20, e keccakf1600_state_pi_not_21, e keccakf1600_state_pi_not_22, e keccakf1600_state_pi_not_23, e keccakf1600_state_pi_not_24, e keccakf1600_state_pi_not_30, e keccakf1600_state_pi_not_31, e keccakf1600_state_pi_not_32, e keccakf1600_state_pi_not_33, e keccakf1600_state_pi_not_34, e keccakf1600_state_pi_not_40, e keccakf1600_state_pi_not_41, e keccakf1600_state_pi_not_42, e keccakf1600_state_pi_not_43, e keccakf1600_state_pi_not_44, e keccakf1600_state_rho_01, e keccakf1600_state_rho_02, e keccakf1600_state_rho_03, e keccakf1600_state_rho_04, e keccakf1600_state_rho_10, e keccakf1600_state_rho_11, e keccakf1600_state_rho_12, e keccakf1600_state_rho_13, e keccakf1600_state_rho_14, e keccakf1600_state_rho_20, e keccakf1600_state_rho_21, e keccakf1600_state_rho_22, e keccakf1600_state_rho_23, e keccakf1600_state_rho_24, e keccakf1600_state_rho_30, e keccakf1600_state_rho_31, e keccakf1600_state_rho_32, e keccakf1600_state_rho_33, e keccakf1600_state_rho_34, e keccakf1600_state_rho_40, e keccakf1600_state_rho_41, e keccakf1600_state_rho_42, e keccakf1600_state_rho_43, e keccakf1600_state_rho_44, e keccakf1600_state_theta_00, e keccakf1600_state_theta_01, e keccakf1600_state_theta_02, e keccakf1600_state_theta_03, e keccakf1600_state_theta_04, e keccakf1600_state_theta_10, e keccakf1600_state_theta_11, e keccakf1600_state_theta_12, e keccakf1600_state_theta_13, e keccakf1600_state_theta_14, e keccakf1600_state_theta_20, e keccakf1600_state_theta_21, e keccakf1600_state_theta_22, e keccakf1600_state_theta_23, e keccakf1600_state_theta_24, e keccakf1600_state_theta_30, e keccakf1600_state_theta_31, e keccakf1600_state_theta_32, e keccakf1600_state_theta_33, e keccakf1600_state_theta_34, e keccakf1600_state_theta_40, e keccakf1600_state_theta_41, e keccakf1600_state_theta_42, e keccakf1600_state_theta_43, e keccakf1600_state_theta_44, e keccakf1600_state_theta_hi_02, e keccakf1600_state_theta_hi_04, e keccakf1600_state_theta_hi_10, e keccakf1600_state_theta_hi_12, e keccakf1600_state_theta_hi_14, e keccakf1600_state_theta_hi_21, e keccakf1600_state_theta_hi_23, e keccakf1600_state_theta_hi_30, e keccakf1600_state_theta_hi_32, e keccakf1600_state_theta_hi_33, e keccakf1600_state_theta_hi_40, e keccakf1600_state_theta_hi_41, e keccakf1600_state_theta_hi_43, e keccakf1600_state_theta_hi_44, e keccakf1600_state_theta_low_01, e keccakf1600_state_theta_low_03, e keccakf1600_state_theta_low_11, e keccakf1600_state_theta_low_13, e keccakf1600_state_theta_low_20, e keccakf1600_state_theta_low_22, e keccakf1600_state_theta_low_24, e keccakf1600_state_theta_low_31, e keccakf1600_state_theta_low_34, e keccakf1600_state_theta_low_42, e keccakf1600_tag_error, e keccakf1600_tag_u64, e keccakf1600_theta_combined_xor_0, e keccakf1600_theta_combined_xor_1, e keccakf1600_theta_combined_xor_2, e keccakf1600_theta_combined_xor_3, e keccakf1600_theta_combined_xor_4, e keccakf1600_theta_xor_01, e keccakf1600_theta_xor_02, e keccakf1600_theta_xor_03, e keccakf1600_theta_xor_11, e keccakf1600_theta_xor_12, e keccakf1600_theta_xor_13, e keccakf1600_theta_xor_21, e keccakf1600_theta_xor_22, e keccakf1600_theta_xor_23, e keccakf1600_theta_xor_31, e keccakf1600_theta_xor_32, e keccakf1600_theta_xor_33, e keccakf1600_theta_xor_41, e keccakf1600_theta_xor_42, e keccakf1600_theta_xor_43, e keccakf1600_theta_xor_row_0, e keccakf1600_theta_xor_row_1, e keccakf1600_theta_xor_row_2, e keccakf1600_theta_xor_row_3, e keccakf1600_theta_xor_row_4, e keccakf1600_theta_xor_row_msb_0, e keccakf1600_theta_xor_row_msb_1, e keccakf1600_theta_xor_row_msb_2, e keccakf1600_theta_xor_row_msb_3, e keccakf1600_theta_xor_row_msb_4, e keccakf1600_theta_xor_row_rotl1_0, e keccakf1600_theta_xor_row_rotl1_1, e keccakf1600_theta_xor_row_rotl1_2, e keccakf1600_theta_xor_row_rotl1_3, e keccakf1600_theta_xor_row_rotl1_4, e l1_to_l2_message_tree_check_exists, e l1_to_l2_message_tree_check_l1_to_l2_message_tree_height, e l1_to_l2_message_tree_check_leaf_index, e l1_to_l2_message_tree_check_leaf_value, e l1_to_l2_message_tree_check_leaf_value_msg_hash_diff_inv, e l1_to_l2_message_tree_check_merkle_hash_separator, e l1_to_l2_message_tree_check_msg_hash, e l1_to_l2_message_tree_check_root, e l1_to_l2_message_tree_check_sel, e memory_diff, e memory_glob_addr_diff_inv, e memory_last_access, e memory_limb_0_, e memory_limb_1_, e memory_limb_2_, e memory_max_bits, e memory_sel_addressing_base, e memory_sel_addressing_indirect_0_, e memory_sel_addressing_indirect_1_, e memory_sel_addressing_indirect_2_, e memory_sel_addressing_indirect_3_, e memory_sel_addressing_indirect_4_, e memory_sel_addressing_indirect_5_, e memory_sel_addressing_indirect_6_, e memory_sel_data_copy_read, e memory_sel_data_copy_write, e memory_sel_ecc_write_0_, e memory_sel_ecc_write_1_, e memory_sel_ecc_write_2_, e memory_sel_get_contract_instance_exists_write, e memory_sel_get_contract_instance_member_write, e memory_sel_keccak, e memory_sel_poseidon2_read_0_, e memory_sel_poseidon2_read_1_, e memory_sel_poseidon2_read_2_, e memory_sel_poseidon2_read_3_, e memory_sel_poseidon2_write_0_, e memory_sel_poseidon2_write_1_, e memory_sel_poseidon2_write_2_, e memory_sel_poseidon2_write_3_, e memory_sel_public_log_read, e memory_sel_register_op_0_, e memory_sel_register_op_1_, e memory_sel_register_op_2_, e memory_sel_register_op_3_, e memory_sel_register_op_4_, e memory_sel_register_op_5_, e memory_sel_rng_chk, e memory_sel_rng_write, e memory_sel_sha256_op_0_, e memory_sel_sha256_op_1_, e memory_sel_sha256_op_2_, e memory_sel_sha256_op_3_, e memory_sel_sha256_op_4_, e memory_sel_sha256_op_5_, e memory_sel_sha256_op_6_, e memory_sel_sha256_op_7_, e memory_sel_sha256_read, e memory_sel_tag_is_ff, e memory_sel_to_radix_write, e memory_tag_ff_diff_inv, e merkle_check_const_three, e merkle_check_end, e merkle_check_index_is_even, e merkle_check_path_len_min_one_inv, e merkle_check_read_left_node, e merkle_check_read_output_hash, e merkle_check_read_right_node, e merkle_check_sibling, e merkle_check_write_left_node, e merkle_check_write_output_hash, e merkle_check_write_right_node, e note_hash_tree_check_address, e note_hash_tree_check_const_three, e note_hash_tree_check_discard, e note_hash_tree_check_exists, e note_hash_tree_check_first_nullifier, e note_hash_tree_check_first_nullifier_pi_index, e note_hash_tree_check_leaf_index, e note_hash_tree_check_merkle_hash_separator, e note_hash_tree_check_next_leaf_value, e note_hash_tree_check_next_root, e note_hash_tree_check_nonce, e note_hash_tree_check_nonce_separator, e note_hash_tree_check_note_hash, e note_hash_tree_check_note_hash_index, e note_hash_tree_check_note_hash_tree_height, e note_hash_tree_check_prev_leaf_value, e note_hash_tree_check_prev_leaf_value_unique_note_hash_diff_inv, e note_hash_tree_check_prev_root, e note_hash_tree_check_public_inputs_index, e note_hash_tree_check_sel, e note_hash_tree_check_sel_silo, e note_hash_tree_check_sel_unique, e note_hash_tree_check_sel_write_to_public_inputs, e note_hash_tree_check_siloed_note_hash, e note_hash_tree_check_siloing_separator, e note_hash_tree_check_unique_note_hash, e note_hash_tree_check_unique_note_hash_separator, e note_hash_tree_check_write, e poseidon2_hash_b_0, e poseidon2_hash_b_1, e poseidon2_hash_b_2, e poseidon2_hash_b_3, e poseidon2_hash_end, e poseidon2_hash_input_len, e poseidon2_hash_num_perm_rounds_rem_min_one_inv, e poseidon2_hash_padding, e poseidon2_perm_B_10_0, e poseidon2_perm_B_10_1, e poseidon2_perm_B_10_2, e poseidon2_perm_B_10_3, e poseidon2_perm_B_11_0, e poseidon2_perm_B_11_1, e poseidon2_perm_B_11_2, e poseidon2_perm_B_11_3, e poseidon2_perm_B_12_0, e poseidon2_perm_B_12_1, e poseidon2_perm_B_12_2, e poseidon2_perm_B_12_3, e poseidon2_perm_B_13_0, e poseidon2_perm_B_13_1, e poseidon2_perm_B_13_2, e poseidon2_perm_B_13_3, e poseidon2_perm_B_14_0, e poseidon2_perm_B_14_1, e poseidon2_perm_B_14_2, e poseidon2_perm_B_14_3, e poseidon2_perm_B_15_0, e poseidon2_perm_B_15_1, e poseidon2_perm_B_15_2, e poseidon2_perm_B_15_3, e poseidon2_perm_B_16_0, e poseidon2_perm_B_16_1, e poseidon2_perm_B_16_2, e poseidon2_perm_B_16_3, e poseidon2_perm_B_17_0, e poseidon2_perm_B_17_1, e poseidon2_perm_B_17_2, e poseidon2_perm_B_17_3, e poseidon2_perm_B_18_0, e poseidon2_perm_B_18_1, e poseidon2_perm_B_18_2, e poseidon2_perm_B_18_3, e poseidon2_perm_B_19_0, e poseidon2_perm_B_19_1, e poseidon2_perm_B_19_2, e poseidon2_perm_B_19_3, e poseidon2_perm_B_20_0, e poseidon2_perm_B_20_1, e poseidon2_perm_B_20_2, e poseidon2_perm_B_20_3, e poseidon2_perm_B_21_0, e poseidon2_perm_B_21_1, e poseidon2_perm_B_21_2, e poseidon2_perm_B_21_3, e poseidon2_perm_B_22_0, e poseidon2_perm_B_22_1, e poseidon2_perm_B_22_2, e poseidon2_perm_B_22_3, e poseidon2_perm_B_23_0, e poseidon2_perm_B_23_1, e poseidon2_perm_B_23_2, e poseidon2_perm_B_23_3, e poseidon2_perm_B_24_0, e poseidon2_perm_B_24_1, e poseidon2_perm_B_24_2, e poseidon2_perm_B_24_3, e poseidon2_perm_B_25_0, e poseidon2_perm_B_25_1, e poseidon2_perm_B_25_2, e poseidon2_perm_B_25_3, e poseidon2_perm_B_26_0, e poseidon2_perm_B_26_1, e poseidon2_perm_B_26_2, e poseidon2_perm_B_26_3, e poseidon2_perm_B_27_0, e poseidon2_perm_B_27_1, e poseidon2_perm_B_27_2, e poseidon2_perm_B_27_3, e poseidon2_perm_B_28_0, e poseidon2_perm_B_28_1, e poseidon2_perm_B_28_2, e poseidon2_perm_B_28_3, e poseidon2_perm_B_29_0, e poseidon2_perm_B_29_1, e poseidon2_perm_B_29_2, e poseidon2_perm_B_29_3, e poseidon2_perm_B_30_0, e poseidon2_perm_B_30_1, e poseidon2_perm_B_30_2, e poseidon2_perm_B_30_3, e poseidon2_perm_B_31_0, e poseidon2_perm_B_31_1, e poseidon2_perm_B_31_2, e poseidon2_perm_B_31_3, e poseidon2_perm_B_32_0, e poseidon2_perm_B_32_1, e poseidon2_perm_B_32_2, e poseidon2_perm_B_32_3, e poseidon2_perm_B_33_0, e poseidon2_perm_B_33_1, e poseidon2_perm_B_33_2, e poseidon2_perm_B_33_3, e poseidon2_perm_B_34_0, e poseidon2_perm_B_34_1, e poseidon2_perm_B_34_2, e poseidon2_perm_B_34_3, e poseidon2_perm_B_35_0, e poseidon2_perm_B_35_1, e poseidon2_perm_B_35_2, e poseidon2_perm_B_35_3, e poseidon2_perm_B_36_0, e poseidon2_perm_B_36_1, e poseidon2_perm_B_36_2, e poseidon2_perm_B_36_3, e poseidon2_perm_B_37_0, e poseidon2_perm_B_37_1, e poseidon2_perm_B_37_2, e poseidon2_perm_B_37_3, e poseidon2_perm_B_38_0, e poseidon2_perm_B_38_1, e poseidon2_perm_B_38_2, e poseidon2_perm_B_38_3, e poseidon2_perm_B_39_0, e poseidon2_perm_B_39_1, e poseidon2_perm_B_39_2, e poseidon2_perm_B_39_3, e poseidon2_perm_B_40_0, e poseidon2_perm_B_40_1, e poseidon2_perm_B_40_2, e poseidon2_perm_B_40_3, e poseidon2_perm_B_41_0, e poseidon2_perm_B_41_1, e poseidon2_perm_B_41_2, e poseidon2_perm_B_41_3, e poseidon2_perm_B_42_0, e poseidon2_perm_B_42_1, e poseidon2_perm_B_42_2, e poseidon2_perm_B_42_3, e poseidon2_perm_B_43_0, e poseidon2_perm_B_43_1, e poseidon2_perm_B_43_2, e poseidon2_perm_B_43_3, e poseidon2_perm_B_44_0, e poseidon2_perm_B_44_1, e poseidon2_perm_B_44_2, e poseidon2_perm_B_44_3, e poseidon2_perm_B_45_0, e poseidon2_perm_B_45_1, e poseidon2_perm_B_45_2, e poseidon2_perm_B_45_3, e poseidon2_perm_B_46_0, e poseidon2_perm_B_46_1, e poseidon2_perm_B_46_2, e poseidon2_perm_B_46_3, e poseidon2_perm_B_47_0, e poseidon2_perm_B_47_1, e poseidon2_perm_B_47_2, e poseidon2_perm_B_47_3, e poseidon2_perm_B_48_0, e poseidon2_perm_B_48_1, e poseidon2_perm_B_48_2, e poseidon2_perm_B_48_3, e poseidon2_perm_B_49_0, e poseidon2_perm_B_49_1, e poseidon2_perm_B_49_2, e poseidon2_perm_B_49_3, e poseidon2_perm_B_4_0, e poseidon2_perm_B_4_1, e poseidon2_perm_B_4_2, e poseidon2_perm_B_4_3, e poseidon2_perm_B_50_0, e poseidon2_perm_B_50_1, e poseidon2_perm_B_50_2, e poseidon2_perm_B_50_3, e poseidon2_perm_B_51_0, e poseidon2_perm_B_51_1, e poseidon2_perm_B_51_2, e poseidon2_perm_B_51_3, e poseidon2_perm_B_52_0, e poseidon2_perm_B_52_1, e poseidon2_perm_B_52_2, e poseidon2_perm_B_52_3, e poseidon2_perm_B_53_0, e poseidon2_perm_B_53_1, e poseidon2_perm_B_53_2, e poseidon2_perm_B_53_3, e poseidon2_perm_B_54_0, e poseidon2_perm_B_54_1, e poseidon2_perm_B_54_2, e poseidon2_perm_B_54_3, e poseidon2_perm_B_55_0, e poseidon2_perm_B_55_1, e poseidon2_perm_B_55_2, e poseidon2_perm_B_55_3, e poseidon2_perm_B_56_0, e poseidon2_perm_B_56_1, e poseidon2_perm_B_56_2, e poseidon2_perm_B_56_3, e poseidon2_perm_B_57_0, e poseidon2_perm_B_57_1, e poseidon2_perm_B_57_2, e poseidon2_perm_B_57_3, e poseidon2_perm_B_58_0, e poseidon2_perm_B_58_1, e poseidon2_perm_B_58_2, e poseidon2_perm_B_58_3, e poseidon2_perm_B_59_0, e poseidon2_perm_B_59_1, e poseidon2_perm_B_59_2, e poseidon2_perm_B_59_3, e poseidon2_perm_B_5_0, e poseidon2_perm_B_5_1, e poseidon2_perm_B_5_2, e poseidon2_perm_B_5_3, e poseidon2_perm_B_6_0, e poseidon2_perm_B_6_1, e poseidon2_perm_B_6_2, e poseidon2_perm_B_6_3, e poseidon2_perm_B_7_0, e poseidon2_perm_B_7_1, e poseidon2_perm_B_7_2, e poseidon2_perm_B_7_3, e poseidon2_perm_B_8_0, e poseidon2_perm_B_8_1, e poseidon2_perm_B_8_2, e poseidon2_perm_B_8_3, e poseidon2_perm_B_9_0, e poseidon2_perm_B_9_1, e poseidon2_perm_B_9_2, e poseidon2_perm_B_9_3, e poseidon2_perm_EXT_LAYER_4, e poseidon2_perm_EXT_LAYER_5, e poseidon2_perm_EXT_LAYER_6, e poseidon2_perm_EXT_LAYER_7, e poseidon2_perm_T_0_4, e poseidon2_perm_T_0_5, e poseidon2_perm_T_0_6, e poseidon2_perm_T_0_7, e poseidon2_perm_T_1_4, e poseidon2_perm_T_1_5, e poseidon2_perm_T_1_6, e poseidon2_perm_T_1_7, e poseidon2_perm_T_2_4, e poseidon2_perm_T_2_5, e poseidon2_perm_T_2_6, e poseidon2_perm_T_2_7, e poseidon2_perm_T_3_4, e poseidon2_perm_T_3_5, e poseidon2_perm_T_3_6, e poseidon2_perm_T_3_7, e poseidon2_perm_T_60_4, e poseidon2_perm_T_60_5, e poseidon2_perm_T_60_6, e poseidon2_perm_T_60_7, e poseidon2_perm_T_61_4, e poseidon2_perm_T_61_5, e poseidon2_perm_T_61_6, e poseidon2_perm_T_61_7, e poseidon2_perm_T_62_4, e poseidon2_perm_T_62_5, e poseidon2_perm_T_62_6, e poseidon2_perm_T_62_7, e poseidon2_perm_T_63_4, e poseidon2_perm_T_63_5, e poseidon2_perm_T_63_6, e poseidon2_perm_T_63_7, e poseidon2_perm_a_0, e poseidon2_perm_a_1, e poseidon2_perm_a_2, e poseidon2_perm_a_3, e poseidon2_perm_b_0, e poseidon2_perm_b_1, e poseidon2_perm_b_2, e poseidon2_perm_b_3, e poseidon2_perm_mem_batch_tag_inv, e poseidon2_perm_mem_err, e poseidon2_perm_mem_execution_clk, e poseidon2_perm_mem_input_0_, e poseidon2_perm_mem_input_1_, e poseidon2_perm_mem_input_2_, e poseidon2_perm_mem_input_3_, e poseidon2_perm_mem_input_tag_0_, e poseidon2_perm_mem_input_tag_1_, e poseidon2_perm_mem_input_tag_2_, e poseidon2_perm_mem_input_tag_3_, e poseidon2_perm_mem_max_mem_addr, e poseidon2_perm_mem_output_0_, e poseidon2_perm_mem_output_1_, e poseidon2_perm_mem_output_2_, e poseidon2_perm_mem_output_3_, e poseidon2_perm_mem_read_address_0_, e poseidon2_perm_mem_read_address_1_, e poseidon2_perm_mem_read_address_2_, e poseidon2_perm_mem_read_address_3_, e poseidon2_perm_mem_sel, e poseidon2_perm_mem_sel_dst_out_of_range_err, e poseidon2_perm_mem_sel_invalid_tag_err, e poseidon2_perm_mem_sel_should_exec, e poseidon2_perm_mem_sel_should_read_mem, e poseidon2_perm_mem_sel_src_out_of_range_err, e poseidon2_perm_mem_space_id, e poseidon2_perm_mem_write_address_0_, e poseidon2_perm_mem_write_address_1_, e poseidon2_perm_mem_write_address_2_, e poseidon2_perm_mem_write_address_3_, e poseidon2_perm_sel, e public_data_check_address, e public_data_check_clk_diff_hi, e public_data_check_clk_diff_lo, e public_data_check_const_four, e public_data_check_const_three, e public_data_check_discard, e public_data_check_end, e public_data_check_final_value, e public_data_check_intermediate_root, e public_data_check_leaf_not_exists, e public_data_check_leaf_slot, e public_data_check_leaf_slot_low_leaf_slot_diff_inv, e public_data_check_length_pi_idx, e public_data_check_low_leaf_hash, e public_data_check_low_leaf_index, e public_data_check_low_leaf_next_index, e public_data_check_low_leaf_next_slot, e public_data_check_low_leaf_slot, e public_data_check_low_leaf_value, e public_data_check_merkle_hash_separator, e public_data_check_new_leaf_hash, e public_data_check_next_slot_inv, e public_data_check_next_slot_is_nonzero, e public_data_check_non_discarded_write, e public_data_check_non_protocol_write, e public_data_check_not_end, e public_data_check_protocol_write, e public_data_check_public_data_writes_length, e public_data_check_root, e public_data_check_sel_write_to_public_inputs, e public_data_check_should_insert, e public_data_check_siloing_separator, e public_data_check_slot, e public_data_check_tree_height, e public_data_check_tree_size_after_write, e public_data_check_tree_size_before_write, e public_data_check_updated_low_leaf_hash, e public_data_check_updated_low_leaf_next_index, e public_data_check_updated_low_leaf_next_slot, e public_data_check_updated_low_leaf_value, e public_data_check_value, e public_data_check_write, e public_data_check_write_root, e public_data_squash_check_clock, e public_data_squash_clk_diff_hi, e public_data_squash_clk_diff_lo, e public_data_squash_leaf_slot_increase, e public_data_squash_value, e range_check_dyn_diff, e range_check_dyn_rng_chk_bits, e range_check_dyn_rng_chk_pow_2, e range_check_is_lte_u112, e range_check_is_lte_u128, e range_check_is_lte_u16, e range_check_is_lte_u32, e range_check_is_lte_u48, e range_check_is_lte_u64, e range_check_is_lte_u80, e range_check_is_lte_u96, e range_check_rng_chk_bits, e range_check_sel, e range_check_sel_alu, e range_check_sel_gt, e range_check_sel_keccak, e range_check_sel_memory, e range_check_sel_r0_16_bit_rng_lookup, e range_check_sel_r1_16_bit_rng_lookup, e range_check_sel_r2_16_bit_rng_lookup, e range_check_sel_r3_16_bit_rng_lookup, e range_check_sel_r4_16_bit_rng_lookup, e range_check_sel_r5_16_bit_rng_lookup, e range_check_sel_r6_16_bit_rng_lookup, e range_check_u16_r0, e range_check_u16_r1, e range_check_u16_r2, e range_check_u16_r3, e range_check_u16_r4, e range_check_u16_r5, e range_check_u16_r6, e range_check_u16_r7, e range_check_value, e scalar_mul_bit, e scalar_mul_const_two, e scalar_mul_end, e scalar_mul_sel_not_end, e scalar_mul_should_add, e sha256_a_and_b, e sha256_a_and_b_xor_a_and_c, e sha256_a_and_c, e sha256_a_rotr_13, e sha256_a_rotr_2, e sha256_a_rotr_22, e sha256_a_rotr_2_xor_a_rotr_13, e sha256_and_op_id, e sha256_b_and_c, e sha256_batch_tag_inv, e sha256_ch, e sha256_computed_w_lhs, e sha256_computed_w_rhs, e sha256_e_and_f, e sha256_e_rotr_11, e sha256_e_rotr_25, e sha256_e_rotr_6, e sha256_e_rotr_6_xor_e_rotr_11, e sha256_end, e sha256_err, e sha256_input, e sha256_input_rounds_rem_inv, e sha256_input_tag, e sha256_input_tag_diff_inv, e sha256_last, e sha256_lhs_w_10, e sha256_lhs_w_3, e sha256_maj, e sha256_max_input_addr, e sha256_max_mem_addr, e sha256_max_output_addr, e sha256_max_state_addr, e sha256_mem_out_of_range_err, e sha256_memory_address_0_, e sha256_memory_address_1_, e sha256_memory_address_2_, e sha256_memory_address_3_, e sha256_memory_address_4_, e sha256_memory_address_5_, e sha256_memory_address_6_, e sha256_memory_address_7_, e sha256_memory_register_0_, e sha256_memory_register_1_, e sha256_memory_register_2_, e sha256_memory_register_3_, e sha256_memory_register_4_, e sha256_memory_register_5_, e sha256_memory_register_6_, e sha256_memory_register_7_, e sha256_memory_tag_0_, e sha256_memory_tag_1_, e sha256_memory_tag_2_, e sha256_memory_tag_3_, e sha256_memory_tag_4_, e sha256_memory_tag_5_, e sha256_memory_tag_6_, e sha256_memory_tag_7_, e sha256_next_a_lhs, e sha256_next_a_rhs, e sha256_next_e_lhs, e sha256_next_e_rhs, e sha256_not_e, e sha256_not_e_and_g, e sha256_output_a_lhs, e sha256_output_a_rhs, e sha256_output_b_lhs, e sha256_output_b_rhs, e sha256_output_c_lhs, e sha256_output_c_rhs, e sha256_output_d_lhs, e sha256_output_d_rhs, e sha256_output_e_lhs, e sha256_output_e_rhs, e sha256_output_f_lhs, e sha256_output_f_rhs, e sha256_output_g_lhs, e sha256_output_g_rhs, e sha256_output_h_lhs, e sha256_output_h_rhs, e sha256_perform_round, e sha256_rhs_a_13, e sha256_rhs_a_2, e sha256_rhs_a_22, e sha256_rhs_e_11, e sha256_rhs_e_25, e sha256_rhs_e_6, e sha256_rhs_w_10, e sha256_rhs_w_17, e sha256_rhs_w_18, e sha256_rhs_w_19, e sha256_rhs_w_3, e sha256_rhs_w_7, e sha256_round_constant, e sha256_round_count, e sha256_rounds_remaining_inv, e sha256_rw, e sha256_s_0, e sha256_s_1, e sha256_sel_compute_w, e sha256_sel_input_out_of_range_err, e sha256_sel_invalid_input_row_tag_err, e sha256_sel_invalid_state_tag_err, e sha256_sel_is_input_round, e sha256_sel_mem_state_or_output, e sha256_sel_output_out_of_range_err, e sha256_sel_read_input_from_memory, e sha256_sel_state_out_of_range_err, e sha256_state_addr, e sha256_two_pow_10, e sha256_two_pow_11, e sha256_two_pow_13, e sha256_two_pow_17, e sha256_two_pow_18, e sha256_two_pow_19, e sha256_two_pow_2, e sha256_two_pow_22, e sha256_two_pow_25, e sha256_two_pow_3, e sha256_two_pow_32, e sha256_two_pow_6, e sha256_two_pow_7, e sha256_u32_tag, e sha256_w, e sha256_w_15_rotr_18, e sha256_w_15_rotr_7, e sha256_w_15_rotr_7_xor_w_15_rotr_18, e sha256_w_2_rotr_17, e sha256_w_2_rotr_17_xor_w_2_rotr_19, e sha256_w_2_rotr_19, e sha256_w_s_0, e sha256_w_s_1, e sha256_xor_op_id, e to_radix_end, e to_radix_found, e to_radix_is_unsafe_limb, e to_radix_limb_p_diff, e to_radix_limb_radix_diff, e to_radix_mem_err, e to_radix_mem_input_validation_error, e to_radix_mem_last, e to_radix_mem_limb_index_to_lookup, e to_radix_mem_limb_value, e to_radix_mem_max_mem_size, e to_radix_mem_num_limbs_inv, e to_radix_mem_num_limbs_minus_one_inv, e to_radix_mem_output_tag, e to_radix_mem_radix_min_two_inv, e to_radix_mem_sel_dst_out_of_range_err, e to_radix_mem_sel_invalid_bitwise_radix, e to_radix_mem_sel_num_limbs_is_zero, e to_radix_mem_sel_radix_eq_2, e to_radix_mem_sel_radix_gt_256_err, e to_radix_mem_sel_radix_lt_2_err, e to_radix_mem_sel_value_is_zero, e to_radix_mem_two, e to_radix_mem_two_five_six, e to_radix_mem_value_found, e to_radix_mem_value_inv, e to_radix_mem_write_addr_upper_bound, e to_radix_p_limb, e to_radix_rem_inverse, e to_radix_safety_diff_inverse, e tx_array_length_l2_to_l1_messages_pi_offset, e tx_array_length_note_hashes_pi_offset, e tx_array_length_nullifiers_pi_offset, e tx_calldata_hash, e tx_calldata_size, e tx_const_three, e tx_contract_addr, e tx_dom_sep_public_storage_map_slot, e tx_effective_fee_per_da_gas, e tx_effective_fee_per_l2_gas, e tx_end_phase, e tx_fee_juice_balance_slot, e tx_fee_juice_balances_slot_constant, e tx_fee_juice_contract_address, e tx_fee_payer, e tx_fee_payer_balance, e tx_fee_payer_new_balance, e tx_fee_payer_pi_offset, e tx_fields_length_public_logs_pi_offset, e tx_gas_limit_pi_offset, e tx_gas_used_pi_offset, e tx_is_cleanup, e tx_is_collect_fee, e tx_is_padded, e tx_is_public_call_request, e tx_is_static, e tx_is_tree_insert_phase, e tx_is_tree_padding, e tx_l1_l2_pi_offset, e tx_l2_l1_msg_content, e tx_l2_l1_msg_contract_address, e tx_l2_l1_msg_recipient, e tx_leaf_value, e tx_msg_sender, e tx_next_da_gas_used, e tx_next_da_gas_used_sent_to_enqueued_call, e tx_next_l2_gas_used, e tx_next_l2_gas_used_sent_to_enqueued_call, e tx_next_note_hash_tree_root, e tx_next_note_hash_tree_size, e tx_next_nullifier_tree_root, e tx_next_nullifier_tree_size, e tx_next_num_l2_to_l1_messages, e tx_next_num_note_hashes_emitted, e tx_next_num_nullifiers_emitted, e tx_next_num_public_log_fields, e tx_next_phase_on_revert, e tx_next_public_data_tree_root, e tx_next_public_data_tree_size, e tx_next_retrieved_bytecodes_tree_root, e tx_next_retrieved_bytecodes_tree_size, e tx_next_written_public_data_slots_tree_root, e tx_next_written_public_data_slots_tree_size, e tx_note_hash_pi_offset, e tx_nullifier_limit_error, e tx_nullifier_merkle_separator, e tx_nullifier_pi_offset, e tx_nullifier_tree_height, e tx_prev_da_gas_used_sent_to_enqueued_call, e tx_prev_l2_gas_used_sent_to_enqueued_call, e tx_public_data_pi_offset, e tx_read_pi_length_offset, e tx_read_pi_start_offset, e tx_remaining_phase_inv, e tx_remaining_phase_minus_one_inv, e tx_remaining_side_effects_inv, e tx_reverted_pi_offset, e tx_sel_append_l2_l1_msg, e tx_sel_append_note_hash, e tx_sel_append_nullifier, e tx_sel_l2_l1_msg_append, e tx_sel_note_hash_append, e tx_sel_nullifier_append, e tx_sel_process_call_request, e tx_sel_read_phase_length, e tx_sel_read_trees_and_gas_used, e tx_sel_try_l2_l1_msg_append, e tx_sel_try_note_hash_append, e tx_sel_try_nullifier_append, e tx_setup_phase_value, e tx_should_read_gas_limit, e tx_uint32_max, e tx_write_nullifier_pi_offset, e tx_write_pi_offset, e update_check_address, e update_check_const_three, e update_check_contract_instance_registry_address, e update_check_current_class_id, e update_check_delayed_public_mutable_hash_slot, e update_check_delayed_public_mutable_slot, e update_check_dom_sep_public_storage_map_slot, e update_check_hash_not_zero, e update_check_original_class_id, e update_check_public_data_tree_root, e update_check_sel, e update_check_timestamp, e update_check_timestamp_is_lt_timestamp_of_change, e update_check_timestamp_of_change, e update_check_timestamp_of_change_bit_size, e update_check_timestamp_pi_offset, e update_check_update_hash, e update_check_update_hash_inv, e update_check_update_hi_metadata, e update_check_update_hi_metadata_bit_size, e update_check_update_post_class_id_is_zero, e update_check_update_post_class_inv, e update_check_update_pre_class_id_is_zero, e update_check_update_pre_class_inv, e update_check_update_preimage_metadata, e update_check_update_preimage_post_class_id, e update_check_update_preimage_pre_class_id, e update_check_updated_class_ids_slot, e lookup_range_check_dyn_rng_chk_pow_2_counts, e lookup_range_check_dyn_diff_is_u16_counts, e lookup_range_check_r0_is_u16_counts, e lookup_range_check_r1_is_u16_counts, e lookup_range_check_r2_is_u16_counts, e lookup_range_check_r3_is_u16_counts, e lookup_range_check_r4_is_u16_counts, e lookup_range_check_r5_is_u16_counts, e lookup_range_check_r6_is_u16_counts, e lookup_range_check_r7_is_u16_counts, e lookup_ff_gt_a_lo_range_counts, e lookup_ff_gt_a_hi_range_counts, e lookup_gt_gt_range_counts, e lookup_alu_tag_max_bits_value_counts, e lookup_alu_range_check_decomposition_a_lo_counts, e lookup_alu_range_check_decomposition_a_hi_counts, e lookup_alu_range_check_decomposition_b_lo_counts, e lookup_alu_range_check_decomposition_b_hi_counts, e lookup_alu_range_check_mul_c_hi_counts, e lookup_alu_range_check_div_remainder_counts, e lookup_alu_ff_gt_counts, e lookup_alu_int_gt_counts, e lookup_alu_shifts_two_pow_counts, e lookup_alu_large_trunc_canonical_dec_counts, e lookup_alu_range_check_trunc_mid_counts, e lookup_bitwise_integral_tag_length_counts, e lookup_bitwise_byte_operations_counts, e lookup_memory_range_check_limb_0_counts, e lookup_memory_range_check_limb_1_counts, e lookup_memory_range_check_limb_2_counts, e lookup_memory_tag_max_bits_counts, e lookup_memory_range_check_write_tagged_value_counts, e lookup_data_copy_offset_plus_size_is_gt_data_size_counts, e lookup_data_copy_check_src_addr_in_range_counts, e lookup_data_copy_check_dst_addr_in_range_counts, e lookup_data_copy_sel_has_reads_counts, e lookup_data_copy_col_read_counts, e lookup_ecc_mem_check_dst_addr_in_range_counts, e lookup_ecc_mem_input_output_ecc_add_counts, e lookup_keccakf1600_theta_xor_01_counts, e lookup_keccakf1600_theta_xor_02_counts, e lookup_keccakf1600_theta_xor_03_counts, e lookup_keccakf1600_theta_xor_row_0_counts, e lookup_keccakf1600_theta_xor_11_counts, e lookup_keccakf1600_theta_xor_12_counts, e lookup_keccakf1600_theta_xor_13_counts, e lookup_keccakf1600_theta_xor_row_1_counts, e lookup_keccakf1600_theta_xor_21_counts, e lookup_keccakf1600_theta_xor_22_counts, e lookup_keccakf1600_theta_xor_23_counts, e lookup_keccakf1600_theta_xor_row_2_counts, e lookup_keccakf1600_theta_xor_31_counts, e lookup_keccakf1600_theta_xor_32_counts, e lookup_keccakf1600_theta_xor_33_counts, e lookup_keccakf1600_theta_xor_row_3_counts, e lookup_keccakf1600_theta_xor_41_counts, e lookup_keccakf1600_theta_xor_42_counts, e lookup_keccakf1600_theta_xor_43_counts, e lookup_keccakf1600_theta_xor_row_4_counts, e lookup_keccakf1600_theta_combined_xor_0_counts, e lookup_keccakf1600_theta_combined_xor_1_counts, e lookup_keccakf1600_theta_combined_xor_2_counts, e lookup_keccakf1600_theta_combined_xor_3_counts, e lookup_keccakf1600_theta_combined_xor_4_counts, e lookup_keccakf1600_state_theta_00_counts, e lookup_keccakf1600_state_theta_01_counts, e lookup_keccakf1600_state_theta_02_counts, e lookup_keccakf1600_state_theta_03_counts, e lookup_keccakf1600_state_theta_04_counts, e lookup_keccakf1600_state_theta_10_counts, e lookup_keccakf1600_state_theta_11_counts, e lookup_keccakf1600_state_theta_12_counts, e lookup_keccakf1600_state_theta_13_counts, e lookup_keccakf1600_state_theta_14_counts, e lookup_keccakf1600_state_theta_20_counts, e lookup_keccakf1600_state_theta_21_counts, e lookup_keccakf1600_state_theta_22_counts, e lookup_keccakf1600_state_theta_23_counts, e lookup_keccakf1600_state_theta_24_counts, e lookup_keccakf1600_state_theta_30_counts, e lookup_keccakf1600_state_theta_31_counts, e lookup_keccakf1600_state_theta_32_counts, e lookup_keccakf1600_state_theta_33_counts, e lookup_keccakf1600_state_theta_34_counts, e lookup_keccakf1600_state_theta_40_counts, e lookup_keccakf1600_state_theta_41_counts, e lookup_keccakf1600_state_theta_42_counts, e lookup_keccakf1600_state_theta_43_counts, e lookup_keccakf1600_state_theta_44_counts, e lookup_keccakf1600_theta_limb_02_range_counts, e lookup_keccakf1600_theta_limb_04_range_counts, e lookup_keccakf1600_theta_limb_10_range_counts, e lookup_keccakf1600_theta_limb_12_range_counts, e lookup_keccakf1600_theta_limb_14_range_counts, e lookup_keccakf1600_theta_limb_21_range_counts, e lookup_keccakf1600_theta_limb_23_range_counts, e lookup_keccakf1600_theta_limb_30_range_counts, e lookup_keccakf1600_theta_limb_32_range_counts, e lookup_keccakf1600_theta_limb_33_range_counts, e lookup_keccakf1600_theta_limb_40_range_counts, e lookup_keccakf1600_theta_limb_41_range_counts, e lookup_keccakf1600_theta_limb_43_range_counts, e lookup_keccakf1600_theta_limb_44_range_counts, e lookup_keccakf1600_theta_limb_01_range_counts, e lookup_keccakf1600_theta_limb_03_range_counts, e lookup_keccakf1600_theta_limb_11_range_counts, e lookup_keccakf1600_theta_limb_13_range_counts, e lookup_keccakf1600_theta_limb_20_range_counts, e lookup_keccakf1600_theta_limb_22_range_counts, e lookup_keccakf1600_theta_limb_24_range_counts, e lookup_keccakf1600_theta_limb_31_range_counts, e lookup_keccakf1600_theta_limb_34_range_counts, e lookup_keccakf1600_theta_limb_42_range_counts, e lookup_keccakf1600_state_pi_and_00_counts, e lookup_keccakf1600_state_pi_and_01_counts, e lookup_keccakf1600_state_pi_and_02_counts, e lookup_keccakf1600_state_pi_and_03_counts, e lookup_keccakf1600_state_pi_and_04_counts, e lookup_keccakf1600_state_pi_and_10_counts, e lookup_keccakf1600_state_pi_and_11_counts, e lookup_keccakf1600_state_pi_and_12_counts, e lookup_keccakf1600_state_pi_and_13_counts, e lookup_keccakf1600_state_pi_and_14_counts, e lookup_keccakf1600_state_pi_and_20_counts, e lookup_keccakf1600_state_pi_and_21_counts, e lookup_keccakf1600_state_pi_and_22_counts, e lookup_keccakf1600_state_pi_and_23_counts, e lookup_keccakf1600_state_pi_and_24_counts, e lookup_keccakf1600_state_pi_and_30_counts, e lookup_keccakf1600_state_pi_and_31_counts, e lookup_keccakf1600_state_pi_and_32_counts, e lookup_keccakf1600_state_pi_and_33_counts, e lookup_keccakf1600_state_pi_and_34_counts, e lookup_keccakf1600_state_pi_and_40_counts, e lookup_keccakf1600_state_pi_and_41_counts, e lookup_keccakf1600_state_pi_and_42_counts, e lookup_keccakf1600_state_pi_and_43_counts, e lookup_keccakf1600_state_pi_and_44_counts, e lookup_keccakf1600_state_chi_00_counts, e lookup_keccakf1600_state_chi_01_counts, e lookup_keccakf1600_state_chi_02_counts, e lookup_keccakf1600_state_chi_03_counts, e lookup_keccakf1600_state_chi_04_counts, e lookup_keccakf1600_state_chi_10_counts, e lookup_keccakf1600_state_chi_11_counts, e lookup_keccakf1600_state_chi_12_counts, e lookup_keccakf1600_state_chi_13_counts, e lookup_keccakf1600_state_chi_14_counts, e lookup_keccakf1600_state_chi_20_counts, e lookup_keccakf1600_state_chi_21_counts, e lookup_keccakf1600_state_chi_22_counts, e lookup_keccakf1600_state_chi_23_counts, e lookup_keccakf1600_state_chi_24_counts, e lookup_keccakf1600_state_chi_30_counts, e lookup_keccakf1600_state_chi_31_counts, e lookup_keccakf1600_state_chi_32_counts, e lookup_keccakf1600_state_chi_33_counts, e lookup_keccakf1600_state_chi_34_counts, e lookup_keccakf1600_state_chi_40_counts, e lookup_keccakf1600_state_chi_41_counts, e lookup_keccakf1600_state_chi_42_counts, e lookup_keccakf1600_state_chi_43_counts, e lookup_keccakf1600_state_chi_44_counts, e lookup_keccakf1600_round_cst_counts, e lookup_keccakf1600_state_iota_00_counts, e lookup_keccakf1600_src_out_of_range_toggle_counts, e lookup_keccakf1600_dst_out_of_range_toggle_counts, e lookup_poseidon2_mem_check_src_addr_in_range_counts, e lookup_poseidon2_mem_check_dst_addr_in_range_counts, e lookup_poseidon2_mem_input_output_poseidon2_perm_counts, e lookup_to_radix_limb_range_counts, e lookup_to_radix_limb_less_than_radix_range_counts, e lookup_to_radix_fetch_safe_limbs_counts, e lookup_to_radix_fetch_p_limb_counts, e lookup_to_radix_limb_p_diff_range_counts, e lookup_scalar_mul_to_radix_counts, e lookup_scalar_mul_double_counts, e lookup_scalar_mul_add_counts, e lookup_sha256_range_comp_w_lhs_counts, e lookup_sha256_range_comp_w_rhs_counts, e lookup_sha256_range_rhs_w_7_counts, e lookup_sha256_range_rhs_w_18_counts, e lookup_sha256_range_rhs_w_3_counts, e lookup_sha256_w_s_0_xor_0_counts, e lookup_sha256_w_s_0_xor_1_counts, e lookup_sha256_range_rhs_w_17_counts, e lookup_sha256_range_rhs_w_19_counts, e lookup_sha256_range_rhs_w_10_counts, e lookup_sha256_w_s_1_xor_0_counts, e lookup_sha256_w_s_1_xor_1_counts, e lookup_sha256_range_rhs_e_6_counts, e lookup_sha256_range_rhs_e_11_counts, e lookup_sha256_range_rhs_e_25_counts, e lookup_sha256_s_1_xor_0_counts, e lookup_sha256_s_1_xor_1_counts, e lookup_sha256_ch_and_0_counts, e lookup_sha256_ch_and_1_counts, e lookup_sha256_ch_xor_counts, e lookup_sha256_round_constant_counts, e lookup_sha256_range_rhs_a_2_counts, e lookup_sha256_range_rhs_a_13_counts, e lookup_sha256_range_rhs_a_22_counts, e lookup_sha256_s_0_xor_0_counts, e lookup_sha256_s_0_xor_1_counts, e lookup_sha256_maj_and_0_counts, e lookup_sha256_maj_and_1_counts, e lookup_sha256_maj_and_2_counts, e lookup_sha256_maj_xor_0_counts, e lookup_sha256_maj_xor_1_counts, e lookup_sha256_range_comp_next_a_lhs_counts, e lookup_sha256_range_comp_next_a_rhs_counts, e lookup_sha256_range_comp_next_e_lhs_counts, e lookup_sha256_range_comp_next_e_rhs_counts, e lookup_sha256_range_comp_a_rhs_counts, e lookup_sha256_range_comp_b_rhs_counts, e lookup_sha256_range_comp_c_rhs_counts, e lookup_sha256_range_comp_d_rhs_counts, e lookup_sha256_range_comp_e_rhs_counts, e lookup_sha256_range_comp_f_rhs_counts, e lookup_sha256_range_comp_g_rhs_counts, e lookup_sha256_range_comp_h_rhs_counts, e lookup_sha256_mem_check_state_addr_in_range_counts, e lookup_sha256_mem_check_input_addr_in_range_counts, e lookup_sha256_mem_check_output_addr_in_range_counts, e lookup_to_radix_mem_check_dst_addr_in_range_counts, e lookup_to_radix_mem_check_radix_lt_2_counts, e lookup_to_radix_mem_check_radix_gt_256_counts, e lookup_to_radix_mem_input_output_to_radix_counts, e lookup_poseidon2_hash_poseidon2_perm_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_counts, e lookup_address_derivation_partial_address_poseidon2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_0_counts, e lookup_address_derivation_public_keys_hash_poseidon2_1_counts, e lookup_address_derivation_public_keys_hash_poseidon2_2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_3_counts, e lookup_address_derivation_public_keys_hash_poseidon2_4_counts, e lookup_address_derivation_preaddress_poseidon2_counts, e lookup_address_derivation_preaddress_scalar_mul_counts, e lookup_address_derivation_address_ecadd_counts, e lookup_bc_decomposition_bytes_are_bytes_counts, e lookup_bc_hashing_poseidon2_hash_counts, e lookup_merkle_check_merkle_poseidon2_read_counts, e lookup_merkle_check_merkle_poseidon2_write_counts, e lookup_indexed_tree_check_silo_poseidon2_counts, e lookup_indexed_tree_check_low_leaf_value_validation_counts, e lookup_indexed_tree_check_low_leaf_next_value_validation_counts, e lookup_indexed_tree_check_low_leaf_poseidon2_counts, e lookup_indexed_tree_check_updated_low_leaf_poseidon2_counts, e lookup_indexed_tree_check_low_leaf_merkle_check_counts, e lookup_indexed_tree_check_new_leaf_poseidon2_counts, e lookup_indexed_tree_check_new_leaf_merkle_check_counts, e lookup_indexed_tree_check_write_value_to_public_inputs_counts, e lookup_public_data_squash_leaf_slot_increase_ff_gt_counts, e lookup_public_data_squash_clk_diff_range_lo_counts, e lookup_public_data_squash_clk_diff_range_hi_counts, e lookup_public_data_check_clk_diff_range_lo_counts, e lookup_public_data_check_clk_diff_range_hi_counts, e lookup_public_data_check_silo_poseidon2_counts, e lookup_public_data_check_low_leaf_slot_validation_counts, e lookup_public_data_check_low_leaf_next_slot_validation_counts, e lookup_public_data_check_low_leaf_poseidon2_0_counts, e lookup_public_data_check_low_leaf_poseidon2_1_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_0_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_1_counts, e lookup_public_data_check_low_leaf_merkle_check_counts, e lookup_public_data_check_new_leaf_poseidon2_0_counts, e lookup_public_data_check_new_leaf_poseidon2_1_counts, e lookup_public_data_check_new_leaf_merkle_check_counts, e lookup_public_data_check_write_public_data_to_public_inputs_counts, e lookup_public_data_check_write_writes_length_to_public_inputs_counts, e lookup_update_check_timestamp_from_public_inputs_counts, e lookup_update_check_delayed_public_mutable_slot_poseidon2_counts, e lookup_update_check_update_hash_public_data_read_counts, e lookup_update_check_update_hash_poseidon2_counts, e lookup_update_check_update_hi_metadata_range_counts, e lookup_update_check_update_lo_metadata_range_counts, e lookup_update_check_timestamp_is_lt_timestamp_of_change_counts, e lookup_contract_instance_retrieval_check_protocol_address_range_counts, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_counts, e lookup_contract_instance_retrieval_deployment_nullifier_read_counts, e lookup_contract_instance_retrieval_address_derivation_counts, e lookup_contract_instance_retrieval_update_check_counts, e lookup_class_id_derivation_class_id_poseidon2_0_counts, e lookup_class_id_derivation_class_id_poseidon2_1_counts, e lookup_bc_retrieval_contract_instance_retrieval_counts, e lookup_bc_retrieval_class_id_derivation_counts, e lookup_bc_retrieval_is_new_class_check_counts, e lookup_bc_retrieval_retrieved_bytecodes_insertion_counts, e lookup_instr_fetching_pc_abs_diff_positive_counts, e lookup_instr_fetching_instr_abs_diff_positive_counts, e lookup_instr_fetching_tag_value_validation_counts, e lookup_instr_fetching_bytecode_size_from_bc_dec_counts, e lookup_instr_fetching_bytes_from_bc_dec_counts, e lookup_instr_fetching_wire_instruction_info_counts, e lookup_emit_public_log_check_memory_out_of_bounds_counts, e lookup_emit_public_log_check_log_fields_count_counts, e lookup_emit_public_log_write_data_to_public_inputs_counts, e lookup_get_contract_instance_precomputed_info_counts, e lookup_get_contract_instance_contract_instance_retrieval_counts, e lookup_l1_to_l2_message_tree_check_merkle_check_counts, e lookup_internal_call_unwind_call_stack_counts, e lookup_context_ctx_stack_rollback_counts, e lookup_context_ctx_stack_return_counts, e lookup_addressing_relative_overflow_result_0_counts, e lookup_addressing_relative_overflow_result_1_counts, e lookup_addressing_relative_overflow_result_2_counts, e lookup_addressing_relative_overflow_result_3_counts, e lookup_addressing_relative_overflow_result_4_counts, e lookup_addressing_relative_overflow_result_5_counts, e lookup_addressing_relative_overflow_result_6_counts, e lookup_gas_addressing_gas_read_counts, e lookup_gas_is_out_of_gas_l2_counts, e lookup_gas_is_out_of_gas_da_counts, e lookup_note_hash_tree_check_silo_poseidon2_counts, e lookup_note_hash_tree_check_read_first_nullifier_counts, e lookup_note_hash_tree_check_nonce_computation_poseidon2_counts, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_counts, e lookup_note_hash_tree_check_merkle_check_counts, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_counts, e lookup_emit_notehash_notehash_tree_write_counts, e lookup_emit_nullifier_write_nullifier_counts, e lookup_external_call_is_l2_gas_left_gt_allocated_counts, e lookup_external_call_is_da_gas_left_gt_allocated_counts, e lookup_get_env_var_precomputed_info_counts, e lookup_get_env_var_read_from_public_inputs_col0_counts, e lookup_get_env_var_read_from_public_inputs_col1_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_counts, e lookup_notehash_exists_note_hash_leaf_index_in_range_counts, e lookup_notehash_exists_note_hash_read_counts, e lookup_nullifier_exists_nullifier_exists_check_counts, e lookup_send_l2_to_l1_msg_recipient_check_counts, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_counts, e lookup_sload_storage_read_counts, e lookup_sstore_record_written_storage_slot_counts, e lookup_execution_bytecode_retrieval_result_counts, e lookup_execution_instruction_fetching_result_counts, e lookup_execution_instruction_fetching_body_counts, e lookup_execution_exec_spec_read_counts, e lookup_execution_dyn_l2_factor_bitwise_counts, e lookup_execution_check_radix_gt_256_counts, e lookup_execution_get_p_limbs_counts, e lookup_execution_get_max_limbs_counts, e lookup_execution_check_written_storage_slot_counts, e lookup_execution_dispatch_to_alu_counts, e lookup_execution_dispatch_to_bitwise_counts, e lookup_execution_dispatch_to_cast_counts, e lookup_execution_dispatch_to_set_counts, e lookup_calldata_hashing_get_calldata_field_0_counts, e lookup_calldata_hashing_get_calldata_field_1_counts, e lookup_calldata_hashing_get_calldata_field_2_counts, e lookup_calldata_hashing_poseidon2_hash_counts, e lookup_tx_context_public_inputs_note_hash_tree_counts, e lookup_tx_context_public_inputs_nullifier_tree_counts, e lookup_tx_context_public_inputs_public_data_tree_counts, e lookup_tx_context_public_inputs_l1_l2_tree_counts, e lookup_tx_context_public_inputs_gas_used_counts, e lookup_tx_context_public_inputs_read_gas_limit_counts, e lookup_tx_context_public_inputs_read_reverted_counts, e lookup_tx_context_restore_state_on_revert_counts, e lookup_tx_context_public_inputs_write_note_hash_count_counts, e lookup_tx_context_public_inputs_write_nullifier_count_counts, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_counts, e lookup_tx_context_public_inputs_write_public_log_count_counts, e lookup_tx_read_phase_spec_counts, e lookup_tx_read_phase_length_counts, e lookup_tx_read_public_call_request_phase_counts, e lookup_tx_read_tree_insert_value_counts, e lookup_tx_note_hash_append_counts, e lookup_tx_nullifier_append_counts, e lookup_tx_read_l2_l1_msg_counts, e lookup_tx_write_l2_l1_msg_counts, e lookup_tx_read_effective_fee_public_inputs_counts, e lookup_tx_read_fee_payer_public_inputs_counts, e lookup_tx_balance_slot_poseidon2_counts, e lookup_tx_balance_read_counts, e lookup_tx_balance_validation_counts, e lookup_tx_write_fee_public_inputs_counts, e bc_decomposition_bytes, e bc_decomposition_bytes_pc_plus_1, e bc_decomposition_bytes_pc_plus_10, e bc_decomposition_bytes_pc_plus_11, e bc_decomposition_bytes_pc_plus_12, e bc_decomposition_bytes_pc_plus_13, e bc_decomposition_bytes_pc_plus_14, e bc_decomposition_bytes_pc_plus_15, e bc_decomposition_bytes_pc_plus_16, e bc_decomposition_bytes_pc_plus_17, e bc_decomposition_bytes_pc_plus_18, e bc_decomposition_bytes_pc_plus_19, e bc_decomposition_bytes_pc_plus_2, e bc_decomposition_bytes_pc_plus_20, e bc_decomposition_bytes_pc_plus_21, e bc_decomposition_bytes_pc_plus_22, e bc_decomposition_bytes_pc_plus_23, e bc_decomposition_bytes_pc_plus_24, e bc_decomposition_bytes_pc_plus_25, e bc_decomposition_bytes_pc_plus_26, e bc_decomposition_bytes_pc_plus_27, e bc_decomposition_bytes_pc_plus_28, e bc_decomposition_bytes_pc_plus_29, e bc_decomposition_bytes_pc_plus_3, e bc_decomposition_bytes_pc_plus_30, e bc_decomposition_bytes_pc_plus_31, e bc_decomposition_bytes_pc_plus_32, e bc_decomposition_bytes_pc_plus_33, e bc_decomposition_bytes_pc_plus_34, e bc_decomposition_bytes_pc_plus_35, e bc_decomposition_bytes_pc_plus_4, e bc_decomposition_bytes_pc_plus_5, e bc_decomposition_bytes_pc_plus_6, e bc_decomposition_bytes_pc_plus_7, e bc_decomposition_bytes_pc_plus_8, e bc_decomposition_bytes_pc_plus_9, e bc_decomposition_bytes_remaining, e bc_decomposition_id, e bc_decomposition_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_windows_gt_remaining, e bc_decomposition_start, e bc_hashing_bytecode_id, e bc_hashing_padding, e bc_hashing_pc_index_1, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_sel_not_start, e bc_hashing_start, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e bitwise_sel, e bitwise_start, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_src_context_id, e data_copy_start, e emit_public_log_contract_address, e emit_public_log_correct_tag, e emit_public_log_error_out_of_bounds, e emit_public_log_error_tag_mismatch, e emit_public_log_execution_clk, e emit_public_log_is_write_contract_address, e emit_public_log_is_write_memory_value, e emit_public_log_log_address, e emit_public_log_public_inputs_index, e emit_public_log_remaining_rows, e emit_public_log_seen_wrong_tag, e emit_public_log_sel, e emit_public_log_sel_write_to_public_inputs, e emit_public_log_space_id, e emit_public_log_start, e execution_bytecode_id, e execution_clk, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_public_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_sel, e keccak_memory_space_id, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_start, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_address, e memory_clk, e memory_rw, e memory_sel, e memory_space_id, e memory_tag, e memory_value, e merkle_check_index, e merkle_check_merkle_hash_separator, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_start, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, e poseidon2_hash_a_0, e poseidon2_hash_a_1, e poseidon2_hash_a_2, e poseidon2_hash_a_3, e poseidon2_hash_input_0, e poseidon2_hash_input_1, e poseidon2_hash_input_2, e poseidon2_hash_num_perm_rounds_rem, e poseidon2_hash_output, e poseidon2_hash_sel, e poseidon2_hash_start, e public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, e scalar_mul_bit_idx, e scalar_mul_point_inf, e scalar_mul_point_x, e scalar_mul_point_y, e scalar_mul_res_inf, e scalar_mul_res_x, e scalar_mul_res_y, e scalar_mul_scalar, e scalar_mul_sel, e scalar_mul_start, e scalar_mul_temp_inf, e scalar_mul_temp_x, e scalar_mul_temp_y, e sha256_a, e sha256_b, e sha256_c, e sha256_d, e sha256_e, e sha256_execution_clk, e sha256_f, e sha256_g, e sha256_h, e sha256_helper_w0, e sha256_helper_w1, e sha256_helper_w10, e sha256_helper_w11, e sha256_helper_w12, e sha256_helper_w13, e sha256_helper_w14, e sha256_helper_w15, e sha256_helper_w2, e sha256_helper_w3, e sha256_helper_w4, e sha256_helper_w5, e sha256_helper_w6, e sha256_helper_w7, e sha256_helper_w8, e sha256_helper_w9, e sha256_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_power, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_public_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted -#define AVM2_DERIVED_WITNESS_ENTITIES_E(e) e perm_data_copy_mem_write_inv, e perm_data_copy_mem_read_inv, e perm_ecc_mem_write_mem_0_inv, e perm_ecc_mem_write_mem_1_inv, e perm_ecc_mem_write_mem_2_inv, e perm_keccak_memory_slice_to_mem_inv, e perm_keccakf1600_read_to_slice_inv, e perm_keccakf1600_write_to_slice_inv, e perm_poseidon2_mem_pos_read_mem_0_inv, e perm_poseidon2_mem_pos_read_mem_1_inv, e perm_poseidon2_mem_pos_read_mem_2_inv, e perm_poseidon2_mem_pos_read_mem_3_inv, e perm_poseidon2_mem_pos_write_mem_0_inv, e perm_poseidon2_mem_pos_write_mem_1_inv, e perm_poseidon2_mem_pos_write_mem_2_inv, e perm_poseidon2_mem_pos_write_mem_3_inv, e perm_sha256_mem_mem_op_0_inv, e perm_sha256_mem_mem_op_1_inv, e perm_sha256_mem_mem_op_2_inv, e perm_sha256_mem_mem_op_3_inv, e perm_sha256_mem_mem_op_4_inv, e perm_sha256_mem_mem_op_5_inv, e perm_sha256_mem_mem_op_6_inv, e perm_sha256_mem_mem_op_7_inv, e perm_sha256_mem_mem_input_read_inv, e perm_to_radix_mem_write_mem_inv, e perm_bc_hashing_bytecode_length_bytes_inv, e perm_bc_hashing_get_packed_field_0_inv, e perm_bc_hashing_get_packed_field_1_inv, e perm_bc_hashing_get_packed_field_2_inv, e perm_public_data_check_squashing_inv, e perm_emit_public_log_read_mem_inv, e perm_get_contract_instance_mem_write_contract_instance_exists_inv, e perm_get_contract_instance_mem_write_contract_instance_member_inv, e perm_internal_call_push_call_stack_inv, e perm_context_ctx_stack_call_inv, e perm_addressing_base_address_from_memory_inv, e perm_addressing_indirect_from_memory_0_inv, e perm_addressing_indirect_from_memory_1_inv, e perm_addressing_indirect_from_memory_2_inv, e perm_addressing_indirect_from_memory_3_inv, e perm_addressing_indirect_from_memory_4_inv, e perm_addressing_indirect_from_memory_5_inv, e perm_addressing_indirect_from_memory_6_inv, e perm_registers_mem_op_0_inv, e perm_registers_mem_op_1_inv, e perm_registers_mem_op_2_inv, e perm_registers_mem_op_3_inv, e perm_registers_mem_op_4_inv, e perm_registers_mem_op_5_inv, e perm_sstore_storage_write_inv, e perm_execution_dispatch_to_cd_copy_inv, e perm_execution_dispatch_to_rd_copy_inv, e perm_execution_dispatch_to_get_contract_instance_inv, e perm_execution_dispatch_to_emit_public_log_inv, e perm_execution_dispatch_to_poseidon2_perm_inv, e perm_execution_dispatch_to_sha256_compression_inv, e perm_execution_dispatch_to_keccakf1600_inv, e perm_execution_dispatch_to_ecc_add_inv, e perm_execution_dispatch_to_to_radix_inv, e perm_calldata_hashing_check_final_size_inv, e perm_tx_read_calldata_hash_inv, e perm_tx_dispatch_exec_start_inv, e perm_tx_dispatch_exec_end_inv, e perm_tx_balance_update_inv, e lookup_range_check_dyn_rng_chk_pow_2_inv, e lookup_range_check_dyn_diff_is_u16_inv, e lookup_range_check_r0_is_u16_inv, e lookup_range_check_r1_is_u16_inv, e lookup_range_check_r2_is_u16_inv, e lookup_range_check_r3_is_u16_inv, e lookup_range_check_r4_is_u16_inv, e lookup_range_check_r5_is_u16_inv, e lookup_range_check_r6_is_u16_inv, e lookup_range_check_r7_is_u16_inv, e lookup_ff_gt_a_lo_range_inv, e lookup_ff_gt_a_hi_range_inv, e lookup_gt_gt_range_inv, e lookup_alu_tag_max_bits_value_inv, e lookup_alu_range_check_decomposition_a_lo_inv, e lookup_alu_range_check_decomposition_a_hi_inv, e lookup_alu_range_check_decomposition_b_lo_inv, e lookup_alu_range_check_decomposition_b_hi_inv, e lookup_alu_range_check_mul_c_hi_inv, e lookup_alu_range_check_div_remainder_inv, e lookup_alu_ff_gt_inv, e lookup_alu_int_gt_inv, e lookup_alu_shifts_two_pow_inv, e lookup_alu_large_trunc_canonical_dec_inv, e lookup_alu_range_check_trunc_mid_inv, e lookup_bitwise_integral_tag_length_inv, e lookup_bitwise_byte_operations_inv, e lookup_memory_range_check_limb_0_inv, e lookup_memory_range_check_limb_1_inv, e lookup_memory_range_check_limb_2_inv, e lookup_memory_tag_max_bits_inv, e lookup_memory_range_check_write_tagged_value_inv, e lookup_data_copy_offset_plus_size_is_gt_data_size_inv, e lookup_data_copy_check_src_addr_in_range_inv, e lookup_data_copy_check_dst_addr_in_range_inv, e lookup_data_copy_sel_has_reads_inv, e lookup_data_copy_col_read_inv, e lookup_ecc_mem_check_dst_addr_in_range_inv, e lookup_ecc_mem_input_output_ecc_add_inv, e lookup_keccakf1600_theta_xor_01_inv, e lookup_keccakf1600_theta_xor_02_inv, e lookup_keccakf1600_theta_xor_03_inv, e lookup_keccakf1600_theta_xor_row_0_inv, e lookup_keccakf1600_theta_xor_11_inv, e lookup_keccakf1600_theta_xor_12_inv, e lookup_keccakf1600_theta_xor_13_inv, e lookup_keccakf1600_theta_xor_row_1_inv, e lookup_keccakf1600_theta_xor_21_inv, e lookup_keccakf1600_theta_xor_22_inv, e lookup_keccakf1600_theta_xor_23_inv, e lookup_keccakf1600_theta_xor_row_2_inv, e lookup_keccakf1600_theta_xor_31_inv, e lookup_keccakf1600_theta_xor_32_inv, e lookup_keccakf1600_theta_xor_33_inv, e lookup_keccakf1600_theta_xor_row_3_inv, e lookup_keccakf1600_theta_xor_41_inv, e lookup_keccakf1600_theta_xor_42_inv, e lookup_keccakf1600_theta_xor_43_inv, e lookup_keccakf1600_theta_xor_row_4_inv, e lookup_keccakf1600_theta_combined_xor_0_inv, e lookup_keccakf1600_theta_combined_xor_1_inv, e lookup_keccakf1600_theta_combined_xor_2_inv, e lookup_keccakf1600_theta_combined_xor_3_inv, e lookup_keccakf1600_theta_combined_xor_4_inv, e lookup_keccakf1600_state_theta_00_inv, e lookup_keccakf1600_state_theta_01_inv, e lookup_keccakf1600_state_theta_02_inv, e lookup_keccakf1600_state_theta_03_inv, e lookup_keccakf1600_state_theta_04_inv, e lookup_keccakf1600_state_theta_10_inv, e lookup_keccakf1600_state_theta_11_inv, e lookup_keccakf1600_state_theta_12_inv, e lookup_keccakf1600_state_theta_13_inv, e lookup_keccakf1600_state_theta_14_inv, e lookup_keccakf1600_state_theta_20_inv, e lookup_keccakf1600_state_theta_21_inv, e lookup_keccakf1600_state_theta_22_inv, e lookup_keccakf1600_state_theta_23_inv, e lookup_keccakf1600_state_theta_24_inv, e lookup_keccakf1600_state_theta_30_inv, e lookup_keccakf1600_state_theta_31_inv, e lookup_keccakf1600_state_theta_32_inv, e lookup_keccakf1600_state_theta_33_inv, e lookup_keccakf1600_state_theta_34_inv, e lookup_keccakf1600_state_theta_40_inv, e lookup_keccakf1600_state_theta_41_inv, e lookup_keccakf1600_state_theta_42_inv, e lookup_keccakf1600_state_theta_43_inv, e lookup_keccakf1600_state_theta_44_inv, e lookup_keccakf1600_theta_limb_02_range_inv, e lookup_keccakf1600_theta_limb_04_range_inv, e lookup_keccakf1600_theta_limb_10_range_inv, e lookup_keccakf1600_theta_limb_12_range_inv, e lookup_keccakf1600_theta_limb_14_range_inv, e lookup_keccakf1600_theta_limb_21_range_inv, e lookup_keccakf1600_theta_limb_23_range_inv, e lookup_keccakf1600_theta_limb_30_range_inv, e lookup_keccakf1600_theta_limb_32_range_inv, e lookup_keccakf1600_theta_limb_33_range_inv, e lookup_keccakf1600_theta_limb_40_range_inv, e lookup_keccakf1600_theta_limb_41_range_inv, e lookup_keccakf1600_theta_limb_43_range_inv, e lookup_keccakf1600_theta_limb_44_range_inv, e lookup_keccakf1600_theta_limb_01_range_inv, e lookup_keccakf1600_theta_limb_03_range_inv, e lookup_keccakf1600_theta_limb_11_range_inv, e lookup_keccakf1600_theta_limb_13_range_inv, e lookup_keccakf1600_theta_limb_20_range_inv, e lookup_keccakf1600_theta_limb_22_range_inv, e lookup_keccakf1600_theta_limb_24_range_inv, e lookup_keccakf1600_theta_limb_31_range_inv, e lookup_keccakf1600_theta_limb_34_range_inv, e lookup_keccakf1600_theta_limb_42_range_inv, e lookup_keccakf1600_state_pi_and_00_inv, e lookup_keccakf1600_state_pi_and_01_inv, e lookup_keccakf1600_state_pi_and_02_inv, e lookup_keccakf1600_state_pi_and_03_inv, e lookup_keccakf1600_state_pi_and_04_inv, e lookup_keccakf1600_state_pi_and_10_inv, e lookup_keccakf1600_state_pi_and_11_inv, e lookup_keccakf1600_state_pi_and_12_inv, e lookup_keccakf1600_state_pi_and_13_inv, e lookup_keccakf1600_state_pi_and_14_inv, e lookup_keccakf1600_state_pi_and_20_inv, e lookup_keccakf1600_state_pi_and_21_inv, e lookup_keccakf1600_state_pi_and_22_inv, e lookup_keccakf1600_state_pi_and_23_inv, e lookup_keccakf1600_state_pi_and_24_inv, e lookup_keccakf1600_state_pi_and_30_inv, e lookup_keccakf1600_state_pi_and_31_inv, e lookup_keccakf1600_state_pi_and_32_inv, e lookup_keccakf1600_state_pi_and_33_inv, e lookup_keccakf1600_state_pi_and_34_inv, e lookup_keccakf1600_state_pi_and_40_inv, e lookup_keccakf1600_state_pi_and_41_inv, e lookup_keccakf1600_state_pi_and_42_inv, e lookup_keccakf1600_state_pi_and_43_inv, e lookup_keccakf1600_state_pi_and_44_inv, e lookup_keccakf1600_state_chi_00_inv, e lookup_keccakf1600_state_chi_01_inv, e lookup_keccakf1600_state_chi_02_inv, e lookup_keccakf1600_state_chi_03_inv, e lookup_keccakf1600_state_chi_04_inv, e lookup_keccakf1600_state_chi_10_inv, e lookup_keccakf1600_state_chi_11_inv, e lookup_keccakf1600_state_chi_12_inv, e lookup_keccakf1600_state_chi_13_inv, e lookup_keccakf1600_state_chi_14_inv, e lookup_keccakf1600_state_chi_20_inv, e lookup_keccakf1600_state_chi_21_inv, e lookup_keccakf1600_state_chi_22_inv, e lookup_keccakf1600_state_chi_23_inv, e lookup_keccakf1600_state_chi_24_inv, e lookup_keccakf1600_state_chi_30_inv, e lookup_keccakf1600_state_chi_31_inv, e lookup_keccakf1600_state_chi_32_inv, e lookup_keccakf1600_state_chi_33_inv, e lookup_keccakf1600_state_chi_34_inv, e lookup_keccakf1600_state_chi_40_inv, e lookup_keccakf1600_state_chi_41_inv, e lookup_keccakf1600_state_chi_42_inv, e lookup_keccakf1600_state_chi_43_inv, e lookup_keccakf1600_state_chi_44_inv, e lookup_keccakf1600_round_cst_inv, e lookup_keccakf1600_state_iota_00_inv, e lookup_keccakf1600_src_out_of_range_toggle_inv, e lookup_keccakf1600_dst_out_of_range_toggle_inv, e lookup_poseidon2_mem_check_src_addr_in_range_inv, e lookup_poseidon2_mem_check_dst_addr_in_range_inv, e lookup_poseidon2_mem_input_output_poseidon2_perm_inv, e lookup_to_radix_limb_range_inv, e lookup_to_radix_limb_less_than_radix_range_inv, e lookup_to_radix_fetch_safe_limbs_inv, e lookup_to_radix_fetch_p_limb_inv, e lookup_to_radix_limb_p_diff_range_inv, e lookup_scalar_mul_to_radix_inv, e lookup_scalar_mul_double_inv, e lookup_scalar_mul_add_inv, e lookup_sha256_range_comp_w_lhs_inv, e lookup_sha256_range_comp_w_rhs_inv, e lookup_sha256_range_rhs_w_7_inv, e lookup_sha256_range_rhs_w_18_inv, e lookup_sha256_range_rhs_w_3_inv, e lookup_sha256_w_s_0_xor_0_inv, e lookup_sha256_w_s_0_xor_1_inv, e lookup_sha256_range_rhs_w_17_inv, e lookup_sha256_range_rhs_w_19_inv, e lookup_sha256_range_rhs_w_10_inv, e lookup_sha256_w_s_1_xor_0_inv, e lookup_sha256_w_s_1_xor_1_inv, e lookup_sha256_range_rhs_e_6_inv, e lookup_sha256_range_rhs_e_11_inv, e lookup_sha256_range_rhs_e_25_inv, e lookup_sha256_s_1_xor_0_inv, e lookup_sha256_s_1_xor_1_inv, e lookup_sha256_ch_and_0_inv, e lookup_sha256_ch_and_1_inv, e lookup_sha256_ch_xor_inv, e lookup_sha256_round_constant_inv, e lookup_sha256_range_rhs_a_2_inv, e lookup_sha256_range_rhs_a_13_inv, e lookup_sha256_range_rhs_a_22_inv, e lookup_sha256_s_0_xor_0_inv, e lookup_sha256_s_0_xor_1_inv, e lookup_sha256_maj_and_0_inv, e lookup_sha256_maj_and_1_inv, e lookup_sha256_maj_and_2_inv, e lookup_sha256_maj_xor_0_inv, e lookup_sha256_maj_xor_1_inv, e lookup_sha256_range_comp_next_a_lhs_inv, e lookup_sha256_range_comp_next_a_rhs_inv, e lookup_sha256_range_comp_next_e_lhs_inv, e lookup_sha256_range_comp_next_e_rhs_inv, e lookup_sha256_range_comp_a_rhs_inv, e lookup_sha256_range_comp_b_rhs_inv, e lookup_sha256_range_comp_c_rhs_inv, e lookup_sha256_range_comp_d_rhs_inv, e lookup_sha256_range_comp_e_rhs_inv, e lookup_sha256_range_comp_f_rhs_inv, e lookup_sha256_range_comp_g_rhs_inv, e lookup_sha256_range_comp_h_rhs_inv, e lookup_sha256_mem_check_state_addr_in_range_inv, e lookup_sha256_mem_check_input_addr_in_range_inv, e lookup_sha256_mem_check_output_addr_in_range_inv, e lookup_to_radix_mem_check_dst_addr_in_range_inv, e lookup_to_radix_mem_check_radix_lt_2_inv, e lookup_to_radix_mem_check_radix_gt_256_inv, e lookup_to_radix_mem_input_output_to_radix_inv, e lookup_poseidon2_hash_poseidon2_perm_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv, e lookup_address_derivation_partial_address_poseidon2_inv, e lookup_address_derivation_public_keys_hash_poseidon2_0_inv, e lookup_address_derivation_public_keys_hash_poseidon2_1_inv, e lookup_address_derivation_public_keys_hash_poseidon2_2_inv, e lookup_address_derivation_public_keys_hash_poseidon2_3_inv, e lookup_address_derivation_public_keys_hash_poseidon2_4_inv, e lookup_address_derivation_preaddress_poseidon2_inv, e lookup_address_derivation_preaddress_scalar_mul_inv, e lookup_address_derivation_address_ecadd_inv, e lookup_bc_decomposition_bytes_are_bytes_inv, e lookup_bc_hashing_poseidon2_hash_inv, e lookup_merkle_check_merkle_poseidon2_read_inv, e lookup_merkle_check_merkle_poseidon2_write_inv, e lookup_indexed_tree_check_silo_poseidon2_inv, e lookup_indexed_tree_check_low_leaf_value_validation_inv, e lookup_indexed_tree_check_low_leaf_next_value_validation_inv, e lookup_indexed_tree_check_low_leaf_poseidon2_inv, e lookup_indexed_tree_check_updated_low_leaf_poseidon2_inv, e lookup_indexed_tree_check_low_leaf_merkle_check_inv, e lookup_indexed_tree_check_new_leaf_poseidon2_inv, e lookup_indexed_tree_check_new_leaf_merkle_check_inv, e lookup_indexed_tree_check_write_value_to_public_inputs_inv, e lookup_public_data_squash_leaf_slot_increase_ff_gt_inv, e lookup_public_data_squash_clk_diff_range_lo_inv, e lookup_public_data_squash_clk_diff_range_hi_inv, e lookup_public_data_check_clk_diff_range_lo_inv, e lookup_public_data_check_clk_diff_range_hi_inv, e lookup_public_data_check_silo_poseidon2_inv, e lookup_public_data_check_low_leaf_slot_validation_inv, e lookup_public_data_check_low_leaf_next_slot_validation_inv, e lookup_public_data_check_low_leaf_poseidon2_0_inv, e lookup_public_data_check_low_leaf_poseidon2_1_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_0_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_1_inv, e lookup_public_data_check_low_leaf_merkle_check_inv, e lookup_public_data_check_new_leaf_poseidon2_0_inv, e lookup_public_data_check_new_leaf_poseidon2_1_inv, e lookup_public_data_check_new_leaf_merkle_check_inv, e lookup_public_data_check_write_public_data_to_public_inputs_inv, e lookup_public_data_check_write_writes_length_to_public_inputs_inv, e lookup_update_check_timestamp_from_public_inputs_inv, e lookup_update_check_delayed_public_mutable_slot_poseidon2_inv, e lookup_update_check_update_hash_public_data_read_inv, e lookup_update_check_update_hash_poseidon2_inv, e lookup_update_check_update_hi_metadata_range_inv, e lookup_update_check_update_lo_metadata_range_inv, e lookup_update_check_timestamp_is_lt_timestamp_of_change_inv, e lookup_contract_instance_retrieval_check_protocol_address_range_inv, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_inv, e lookup_contract_instance_retrieval_deployment_nullifier_read_inv, e lookup_contract_instance_retrieval_address_derivation_inv, e lookup_contract_instance_retrieval_update_check_inv, e lookup_class_id_derivation_class_id_poseidon2_0_inv, e lookup_class_id_derivation_class_id_poseidon2_1_inv, e lookup_bc_retrieval_contract_instance_retrieval_inv, e lookup_bc_retrieval_class_id_derivation_inv, e lookup_bc_retrieval_is_new_class_check_inv, e lookup_bc_retrieval_retrieved_bytecodes_insertion_inv, e lookup_instr_fetching_pc_abs_diff_positive_inv, e lookup_instr_fetching_instr_abs_diff_positive_inv, e lookup_instr_fetching_tag_value_validation_inv, e lookup_instr_fetching_bytecode_size_from_bc_dec_inv, e lookup_instr_fetching_bytes_from_bc_dec_inv, e lookup_instr_fetching_wire_instruction_info_inv, e lookup_emit_public_log_check_memory_out_of_bounds_inv, e lookup_emit_public_log_check_log_fields_count_inv, e lookup_emit_public_log_write_data_to_public_inputs_inv, e lookup_get_contract_instance_precomputed_info_inv, e lookup_get_contract_instance_contract_instance_retrieval_inv, e lookup_l1_to_l2_message_tree_check_merkle_check_inv, e lookup_internal_call_unwind_call_stack_inv, e lookup_context_ctx_stack_rollback_inv, e lookup_context_ctx_stack_return_inv, e lookup_addressing_relative_overflow_result_0_inv, e lookup_addressing_relative_overflow_result_1_inv, e lookup_addressing_relative_overflow_result_2_inv, e lookup_addressing_relative_overflow_result_3_inv, e lookup_addressing_relative_overflow_result_4_inv, e lookup_addressing_relative_overflow_result_5_inv, e lookup_addressing_relative_overflow_result_6_inv, e lookup_gas_addressing_gas_read_inv, e lookup_gas_is_out_of_gas_l2_inv, e lookup_gas_is_out_of_gas_da_inv, e lookup_note_hash_tree_check_silo_poseidon2_inv, e lookup_note_hash_tree_check_read_first_nullifier_inv, e lookup_note_hash_tree_check_nonce_computation_poseidon2_inv, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_inv, e lookup_note_hash_tree_check_merkle_check_inv, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_inv, e lookup_emit_notehash_notehash_tree_write_inv, e lookup_emit_nullifier_write_nullifier_inv, e lookup_external_call_is_l2_gas_left_gt_allocated_inv, e lookup_external_call_is_da_gas_left_gt_allocated_inv, e lookup_get_env_var_precomputed_info_inv, e lookup_get_env_var_read_from_public_inputs_col0_inv, e lookup_get_env_var_read_from_public_inputs_col1_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_inv, e lookup_notehash_exists_note_hash_leaf_index_in_range_inv, e lookup_notehash_exists_note_hash_read_inv, e lookup_nullifier_exists_nullifier_exists_check_inv, e lookup_send_l2_to_l1_msg_recipient_check_inv, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_inv, e lookup_sload_storage_read_inv, e lookup_sstore_record_written_storage_slot_inv, e lookup_execution_bytecode_retrieval_result_inv, e lookup_execution_instruction_fetching_result_inv, e lookup_execution_instruction_fetching_body_inv, e lookup_execution_exec_spec_read_inv, e lookup_execution_dyn_l2_factor_bitwise_inv, e lookup_execution_check_radix_gt_256_inv, e lookup_execution_get_p_limbs_inv, e lookup_execution_get_max_limbs_inv, e lookup_execution_check_written_storage_slot_inv, e lookup_execution_dispatch_to_alu_inv, e lookup_execution_dispatch_to_bitwise_inv, e lookup_execution_dispatch_to_cast_inv, e lookup_execution_dispatch_to_set_inv, e lookup_calldata_hashing_get_calldata_field_0_inv, e lookup_calldata_hashing_get_calldata_field_1_inv, e lookup_calldata_hashing_get_calldata_field_2_inv, e lookup_calldata_hashing_poseidon2_hash_inv, e lookup_tx_context_public_inputs_note_hash_tree_inv, e lookup_tx_context_public_inputs_nullifier_tree_inv, e lookup_tx_context_public_inputs_public_data_tree_inv, e lookup_tx_context_public_inputs_l1_l2_tree_inv, e lookup_tx_context_public_inputs_gas_used_inv, e lookup_tx_context_public_inputs_read_gas_limit_inv, e lookup_tx_context_public_inputs_read_reverted_inv, e lookup_tx_context_restore_state_on_revert_inv, e lookup_tx_context_public_inputs_write_note_hash_count_inv, e lookup_tx_context_public_inputs_write_nullifier_count_inv, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_inv, e lookup_tx_context_public_inputs_write_public_log_count_inv, e lookup_tx_read_phase_spec_inv, e lookup_tx_read_phase_length_inv, e lookup_tx_read_public_call_request_phase_inv, e lookup_tx_read_tree_insert_value_inv, e lookup_tx_note_hash_append_inv, e lookup_tx_nullifier_append_inv, e lookup_tx_read_l2_l1_msg_inv, e lookup_tx_write_l2_l1_msg_inv, e lookup_tx_read_effective_fee_public_inputs_inv, e lookup_tx_read_fee_payer_public_inputs_inv, e lookup_tx_balance_slot_poseidon2_inv, e lookup_tx_balance_read_inv, e lookup_tx_balance_validation_inv, e lookup_tx_write_fee_public_inputs_inv +#define AVM2_PRECOMPUTED_ENTITIES_E(e) e precomputed_addressing_gas, e precomputed_bitwise_input_a, e precomputed_bitwise_input_b, e precomputed_bitwise_output_and, e precomputed_bitwise_output_or, e precomputed_bitwise_output_xor, e precomputed_dyn_gas_id, e precomputed_envvar_pi_row_idx, e precomputed_exec_opcode, e precomputed_exec_opcode_base_da_gas, e precomputed_exec_opcode_dynamic_da_gas, e precomputed_exec_opcode_dynamic_l2_gas, e precomputed_exec_opcode_opcode_gas, e precomputed_expected_tag_reg_0_, e precomputed_expected_tag_reg_1_, e precomputed_expected_tag_reg_2_, e precomputed_expected_tag_reg_3_, e precomputed_expected_tag_reg_4_, e precomputed_expected_tag_reg_5_, e precomputed_first_row, e precomputed_idx, e precomputed_instr_size, e precomputed_invalid_envvar_enum, e precomputed_is_address, e precomputed_is_class_id, e precomputed_is_cleanup, e precomputed_is_collect_fee, e precomputed_is_dagasleft, e precomputed_is_deployer, e precomputed_is_immutables_hash, e precomputed_is_init_hash, e precomputed_is_isstaticcall, e precomputed_is_l2gasleft, e precomputed_is_public_call_request, e precomputed_is_revertible, e precomputed_is_sender, e precomputed_is_teardown, e precomputed_is_transactionfee, e precomputed_is_tree_padding, e precomputed_is_valid_member_enum, e precomputed_keccak_round_constant, e precomputed_next_phase_on_revert, e precomputed_opcode_out_of_range, e precomputed_out_tag, e precomputed_p_decomposition_limb, e precomputed_p_decomposition_limb_index, e precomputed_p_decomposition_radix, e precomputed_power_of_2, e precomputed_read_pi_length_offset, e precomputed_read_pi_start_offset, e precomputed_rw_reg_0_, e precomputed_rw_reg_1_, e precomputed_rw_reg_2_, e precomputed_rw_reg_3_, e precomputed_rw_reg_4_, e precomputed_rw_reg_5_, e precomputed_sel_addressing_gas, e precomputed_sel_append_l2_l1_msg, e precomputed_sel_append_note_hash, e precomputed_sel_append_nullifier, e precomputed_sel_envvar_pi_lookup_col0, e precomputed_sel_envvar_pi_lookup_col1, e precomputed_sel_exec_spec, e precomputed_sel_has_tag, e precomputed_sel_keccak, e precomputed_sel_mem_op_reg_0_, e precomputed_sel_mem_op_reg_1_, e precomputed_sel_mem_op_reg_2_, e precomputed_sel_mem_op_reg_3_, e precomputed_sel_mem_op_reg_4_, e precomputed_sel_mem_op_reg_5_, e precomputed_sel_mem_tag_out_of_range, e precomputed_sel_op_dc_0, e precomputed_sel_op_dc_1, e precomputed_sel_op_dc_10, e precomputed_sel_op_dc_11, e precomputed_sel_op_dc_12, e precomputed_sel_op_dc_13, e precomputed_sel_op_dc_14, e precomputed_sel_op_dc_15, e precomputed_sel_op_dc_16, e precomputed_sel_op_dc_2, e precomputed_sel_op_dc_3, e precomputed_sel_op_dc_4, e precomputed_sel_op_dc_5, e precomputed_sel_op_dc_6, e precomputed_sel_op_dc_7, e precomputed_sel_op_dc_8, e precomputed_sel_op_dc_9, e precomputed_sel_op_is_address_0_, e precomputed_sel_op_is_address_1_, e precomputed_sel_op_is_address_2_, e precomputed_sel_op_is_address_3_, e precomputed_sel_op_is_address_4_, e precomputed_sel_op_is_address_5_, e precomputed_sel_op_is_address_6_, e precomputed_sel_p_decomposition, e precomputed_sel_phase, e precomputed_sel_range_16, e precomputed_sel_range_8, e precomputed_sel_sha256_compression, e precomputed_sel_tag_check_reg_0_, e precomputed_sel_tag_check_reg_1_, e precomputed_sel_tag_check_reg_2_, e precomputed_sel_tag_check_reg_3_, e precomputed_sel_tag_check_reg_4_, e precomputed_sel_tag_check_reg_5_, e precomputed_sel_tag_is_op2, e precomputed_sel_tag_parameters, e precomputed_sel_to_radix_p_limb_counts, e precomputed_sha256_compression_round_constant, e precomputed_subtrace_id, e precomputed_subtrace_operation_id, e precomputed_tag_byte_length, e precomputed_tag_max_bits, e precomputed_tag_max_value, e precomputed_to_radix_num_limbs_for_p, e precomputed_to_radix_safe_limbs, e precomputed_zero, e public_inputs_sel +#define AVM2_WIRE_ENTITIES_E(e) e public_inputs_cols_0_, e public_inputs_cols_1_, e public_inputs_cols_2_, e public_inputs_cols_3_, e address_derivation_address, e address_derivation_address_y, e address_derivation_class_id, e address_derivation_const_five, e address_derivation_const_three, e address_derivation_deployer_addr, e address_derivation_g1_x, e address_derivation_g1_y, e address_derivation_immutables_hash, e address_derivation_incoming_viewing_key_hash, e address_derivation_incoming_viewing_key_x, e address_derivation_incoming_viewing_key_y, e address_derivation_init_hash, e address_derivation_nullifier_key_hash, e address_derivation_outgoing_viewing_key_hash, e address_derivation_partial_address, e address_derivation_partial_address_domain_separator, e address_derivation_preaddress, e address_derivation_preaddress_domain_separator, e address_derivation_preaddress_public_key_x, e address_derivation_preaddress_public_key_y, e address_derivation_public_keys_hash, e address_derivation_public_keys_hash_domain_separator, e address_derivation_salt, e address_derivation_salted_init_hash, e address_derivation_salted_init_hash_domain_separator, e address_derivation_sel, e address_derivation_single_public_key_hash_domain_separator, e address_derivation_tagging_key_hash, e alu_a_hi, e alu_a_hi_bits, e alu_a_lo, e alu_a_lo_bits, e alu_ab_diff_inv, e alu_ab_tags_diff_inv, e alu_b_hi, e alu_b_inv, e alu_b_lo, e alu_c_hi, e alu_cf, e alu_constant_64, e alu_gt_input_a, e alu_gt_input_b, e alu_gt_result_c, e alu_helper1, e alu_ia, e alu_ia_tag, e alu_ib, e alu_ib_tag, e alu_ic, e alu_ic_tag, e alu_max_bits, e alu_max_value, e alu_mid, e alu_mid_bits, e alu_op_id, e alu_sel, e alu_sel_ab_tag_mismatch, e alu_sel_decompose_a, e alu_sel_div_0_err, e alu_sel_div_no_err, e alu_sel_err, e alu_sel_ff_gt, e alu_sel_int_gt, e alu_sel_is_ff, e alu_sel_is_u128, e alu_sel_mul_div_u128, e alu_sel_mul_no_err_non_ff, e alu_sel_op_add, e alu_sel_op_div, e alu_sel_op_eq, e alu_sel_op_fdiv, e alu_sel_op_lt, e alu_sel_op_lte, e alu_sel_op_mul, e alu_sel_op_not, e alu_sel_op_shl, e alu_sel_op_shr, e alu_sel_op_sub, e alu_sel_op_truncate, e alu_sel_shift_ops_no_overflow, e alu_sel_tag_err, e alu_sel_trunc_gte_128, e alu_sel_trunc_lt_128, e alu_sel_trunc_non_trivial, e alu_sel_trunc_trivial, e alu_shift_lo_bits, e alu_tag_ff_diff_inv, e alu_tag_u128_diff_inv, e alu_two_pow_shift_lo_bits, e bc_decomposition_bytes_pc_plus_36, e bc_decomposition_bytes_rem_inv, e bc_decomposition_bytes_rem_min_one_inv, e bc_decomposition_bytes_to_read, e bc_decomposition_last_of_contract, e bc_decomposition_next_packed_pc_min_pc_inv, e bc_decomposition_packed_field, e bc_decomposition_sel_packed, e bc_decomposition_sel_packed_read_0_, e bc_decomposition_sel_packed_read_1_, e bc_decomposition_sel_packed_read_2_, e bc_decomposition_sel_windows_eq_remaining, e bc_decomposition_windows_min_remaining_inv, e bc_hashing_end, e bc_hashing_input_len, e bc_hashing_packed_fields_0, e bc_hashing_packed_fields_1, e bc_hashing_packed_fields_2, e bc_hashing_pc_index, e bc_hashing_pc_index_2, e bc_hashing_sel_not_padding_1, e bc_hashing_sel_not_padding_2, e bc_hashing_size_in_bytes, e bc_retrieval_address, e bc_retrieval_artifact_hash, e bc_retrieval_bytecode_id, e bc_retrieval_current_class_id, e bc_retrieval_error, e bc_retrieval_instance_exists, e bc_retrieval_is_new_class, e bc_retrieval_next_retrieved_bytecodes_tree_root, e bc_retrieval_next_retrieved_bytecodes_tree_size, e bc_retrieval_no_remaining_bytecodes, e bc_retrieval_nullifier_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_size, e bc_retrieval_private_functions_root, e bc_retrieval_public_data_tree_root, e bc_retrieval_remaining_bytecodes_inv, e bc_retrieval_retrieved_bytecodes_merkle_separator, e bc_retrieval_retrieved_bytecodes_tree_height, e bc_retrieval_sel, e bc_retrieval_should_retrieve, e bitwise_ctr_min_one_inv, e bitwise_end, e bitwise_err, e bitwise_ia_byte, e bitwise_ib_byte, e bitwise_ic_byte, e bitwise_output_and, e bitwise_output_or, e bitwise_output_xor, e bitwise_sel_and, e bitwise_sel_compute, e bitwise_sel_get_ctr, e bitwise_sel_or, e bitwise_sel_tag_ff_err, e bitwise_sel_tag_mismatch_err, e bitwise_sel_xor, e bitwise_start_keccak, e bitwise_start_sha256, e bitwise_tag_a, e bitwise_tag_a_inv, e bitwise_tag_ab_diff_inv, e bitwise_tag_b, e bitwise_tag_c, e calldata_end, e calldata_hashing_end, e calldata_hashing_index_1_, e calldata_hashing_index_2_, e calldata_hashing_input_0_, e calldata_hashing_input_1_, e calldata_hashing_input_2_, e calldata_hashing_input_len, e calldata_hashing_sel_end_not_empty, e calldata_hashing_sel_not_padding_1, e calldata_hashing_sel_not_padding_2, e calldata_hashing_sel_not_start, e calldata_value, e class_id_derivation_artifact_hash, e class_id_derivation_class_id, e class_id_derivation_const_four, e class_id_derivation_gen_index_contract_class_id, e class_id_derivation_private_functions_root, e class_id_derivation_public_bytecode_commitment, e class_id_derivation_sel, e context_stack_bytecode_id, e context_stack_context_id, e context_stack_contract_address, e context_stack_entered_context_id, e context_stack_internal_call_id, e context_stack_internal_call_return_id, e context_stack_is_static, e context_stack_msg_sender, e context_stack_next_internal_call_id, e context_stack_next_pc, e context_stack_note_hash_tree_root, e context_stack_note_hash_tree_size, e context_stack_nullifier_tree_root, e context_stack_nullifier_tree_size, e context_stack_num_l2_to_l1_messages, e context_stack_num_note_hashes_emitted, e context_stack_num_nullifiers_emitted, e context_stack_num_public_log_fields, e context_stack_parent_calldata_addr, e context_stack_parent_calldata_size, e context_stack_parent_da_gas_limit, e context_stack_parent_da_gas_used, e context_stack_parent_id, e context_stack_parent_l2_gas_limit, e context_stack_parent_l2_gas_used, e context_stack_public_data_tree_root, e context_stack_public_data_tree_size, e context_stack_sel, e context_stack_written_public_data_slots_tree_root, e context_stack_written_public_data_slots_tree_size, e contract_instance_retrieval_address, e contract_instance_retrieval_address_sub_one, e contract_instance_retrieval_current_class_id, e contract_instance_retrieval_deployer_addr, e contract_instance_retrieval_deployer_protocol_contract_address, e contract_instance_retrieval_derived_address, e contract_instance_retrieval_derived_address_pi_index, e contract_instance_retrieval_exists, e contract_instance_retrieval_immutables_hash, e contract_instance_retrieval_incoming_viewing_key_x, e contract_instance_retrieval_incoming_viewing_key_y, e contract_instance_retrieval_init_hash, e contract_instance_retrieval_is_protocol_contract, e contract_instance_retrieval_max_protocol_contracts, e contract_instance_retrieval_nullifier_key_hash, e contract_instance_retrieval_nullifier_merkle_separator, e contract_instance_retrieval_nullifier_tree_height, e contract_instance_retrieval_nullifier_tree_root, e contract_instance_retrieval_original_class_id, e contract_instance_retrieval_outgoing_viewing_key_hash, e contract_instance_retrieval_protocol_contract_derived_address_inv, e contract_instance_retrieval_public_data_tree_root, e contract_instance_retrieval_salt, e contract_instance_retrieval_sel, e contract_instance_retrieval_should_check_for_update, e contract_instance_retrieval_should_check_nullifier, e contract_instance_retrieval_siloing_separator, e contract_instance_retrieval_tagging_key_hash, e data_copy_cd_copy_col_read, e data_copy_clamped_read_index_upper_bound, e data_copy_dst_out_of_range_err, e data_copy_end, e data_copy_is_top_level, e data_copy_mem_size, e data_copy_offset, e data_copy_offset_plus_size, e data_copy_offset_plus_size_is_gt, e data_copy_parent_id_inv, e data_copy_read_addr_plus_one, e data_copy_read_addr_upper_bound, e data_copy_reads_left_inv, e data_copy_sel_cd_copy_start, e data_copy_sel_has_reads, e data_copy_sel_mem_read, e data_copy_sel_mem_write, e data_copy_sel_rd_copy_start, e data_copy_sel_write_count_is_zero, e data_copy_src_addr, e data_copy_src_data_size, e data_copy_src_reads_exceed_mem, e data_copy_start_no_err, e data_copy_tag, e data_copy_value, e data_copy_write_addr_upper_bound, e data_copy_write_count_minus_one_inv, e data_copy_write_count_zero_inv, e ecc_add_mem_dst_addr_0_, e ecc_add_mem_dst_addr_1_, e ecc_add_mem_err, e ecc_add_mem_execution_clk, e ecc_add_mem_max_mem_addr, e ecc_add_mem_p_is_inf, e ecc_add_mem_p_is_on_curve_eqn, e ecc_add_mem_p_is_on_curve_eqn_inv, e ecc_add_mem_p_x, e ecc_add_mem_p_y, e ecc_add_mem_q_is_inf, e ecc_add_mem_q_is_on_curve_eqn, e ecc_add_mem_q_is_on_curve_eqn_inv, e ecc_add_mem_q_x, e ecc_add_mem_q_y, e ecc_add_mem_res_x, e ecc_add_mem_res_y, e ecc_add_mem_sel, e ecc_add_mem_sel_dst_out_of_range_err, e ecc_add_mem_sel_p_not_on_curve_err, e ecc_add_mem_sel_q_not_on_curve_err, e ecc_add_mem_sel_should_exec, e ecc_add_mem_space_id, e ecc_add_op, e ecc_double_op, e ecc_inv_2_p_y, e ecc_inv_x_diff, e ecc_inv_y_diff, e ecc_lambda, e ecc_p_is_inf, e ecc_p_x, e ecc_p_y, e ecc_q_is_inf, e ecc_q_x, e ecc_q_y, e ecc_r_x, e ecc_r_y, e ecc_result_infinity, e ecc_sel, e ecc_use_computed_result, e ecc_x_match, e ecc_y_match, e emit_public_log_discard, e emit_public_log_end, e emit_public_log_end_log_address_upper_bound, e emit_public_log_error, e emit_public_log_error_too_many_log_fields, e emit_public_log_expected_next_log_fields, e emit_public_log_is_static, e emit_public_log_log_size, e emit_public_log_max_mem_size, e emit_public_log_max_public_logs_payload_length, e emit_public_log_next_num_public_log_fields, e emit_public_log_prev_num_public_log_fields, e emit_public_log_public_inputs_value, e emit_public_log_remaining_rows_inv, e emit_public_log_sel_read_memory, e emit_public_log_tag, e emit_public_log_tag_inv, e emit_public_log_value, e execution_addressing_error_collection_inv, e execution_addressing_gas, e execution_addressing_mode, e execution_base_address_tag, e execution_base_address_tag_diff_inv, e execution_base_address_val, e execution_base_da_gas, e execution_batched_tags_diff_inv, e execution_batched_tags_diff_inv_reg, e execution_da_gas_left, e execution_da_gas_used, e execution_dying_context_diff_inv, e execution_dying_context_id_inv, e execution_dyn_gas_id, e execution_dynamic_da_gas, e execution_dynamic_da_gas_factor, e execution_dynamic_l2_gas, e execution_dynamic_l2_gas_factor, e execution_enqueued_call_end, e execution_envvar_pi_row_idx, e execution_exec_opcode, e execution_expected_tag_reg_0_, e execution_expected_tag_reg_1_, e execution_expected_tag_reg_2_, e execution_expected_tag_reg_3_, e execution_expected_tag_reg_4_, e execution_expected_tag_reg_5_, e execution_has_parent_ctx, e execution_highest_address, e execution_instr_size, e execution_internal_call_return_id_inv, e execution_is_address, e execution_is_da_gas_left_gt_allocated, e execution_is_dagasleft, e execution_is_dying_context, e execution_is_isstaticcall, e execution_is_l2_gas_left_gt_allocated, e execution_is_l2gasleft, e execution_is_parent_id_inv, e execution_is_sender, e execution_is_transactionfee, e execution_l1_to_l2_msg_leaf_in_range, e execution_l1_to_l2_msg_tree_leaf_count, e execution_l2_gas_left, e execution_l2_gas_used, e execution_max_data_writes_reached, e execution_max_eth_address_value, e execution_mem_tag_reg_0_, e execution_mem_tag_reg_1_, e execution_mem_tag_reg_2_, e execution_mem_tag_reg_3_, e execution_mem_tag_reg_4_, e execution_mem_tag_reg_5_, e execution_nested_failure, e execution_nested_return, e execution_next_pc, e execution_note_hash_leaf_in_range, e execution_note_hash_tree_leaf_count, e execution_note_hash_tree_root, e execution_note_hash_tree_size, e execution_nullifier_merkle_separator, e execution_nullifier_pi_offset, e execution_nullifier_siloing_separator, e execution_nullifier_tree_height, e execution_nullifier_tree_root, e execution_nullifier_tree_size, e execution_num_l2_to_l1_messages, e execution_num_note_hashes_emitted, e execution_num_nullifiers_emitted, e execution_num_p_limbs, e execution_num_public_log_fields, e execution_num_relative_operands_inv, e execution_op_0_, e execution_op_1_, e execution_op_2_, e execution_op_3_, e execution_op_4_, e execution_op_5_, e execution_op_6_, e execution_op_after_relative_0_, e execution_op_after_relative_1_, e execution_op_after_relative_2_, e execution_op_after_relative_3_, e execution_op_after_relative_4_, e execution_op_after_relative_5_, e execution_op_after_relative_6_, e execution_opcode_gas, e execution_out_of_gas_da, e execution_out_of_gas_l2, e execution_public_data_tree_root, e execution_public_data_tree_size, e execution_public_inputs_index, e execution_register_0_, e execution_register_1_, e execution_register_2_, e execution_register_3_, e execution_register_4_, e execution_register_5_, e execution_remaining_data_writes_inv, e execution_remaining_l2_to_l1_msgs_inv, e execution_remaining_note_hashes_inv, e execution_remaining_nullifiers_inv, e execution_retrieved_bytecodes_tree_root, e execution_retrieved_bytecodes_tree_size, e execution_rop_0_, e execution_rop_1_, e execution_rop_2_, e execution_rop_3_, e execution_rop_4_, e execution_rop_5_, e execution_rop_6_, e execution_rop_tag_0_, e execution_rop_tag_1_, e execution_rop_tag_2_, e execution_rop_tag_3_, e execution_rop_tag_4_, e execution_rop_tag_5_, e execution_rop_tag_6_, e execution_rw_reg_0_, e execution_rw_reg_1_, e execution_rw_reg_2_, e execution_rw_reg_3_, e execution_rw_reg_4_, e execution_rw_reg_5_, e execution_sel_addressing_error, e execution_sel_apply_indirection_0_, e execution_sel_apply_indirection_1_, e execution_sel_apply_indirection_2_, e execution_sel_apply_indirection_3_, e execution_sel_apply_indirection_4_, e execution_sel_apply_indirection_5_, e execution_sel_apply_indirection_6_, e execution_sel_base_address_failure, e execution_sel_bytecode_retrieval_failure, e execution_sel_bytecode_retrieval_success, e execution_sel_check_gas, e execution_sel_do_base_check, e execution_sel_enter_call, e execution_sel_envvar_pi_lookup_col0, e execution_sel_envvar_pi_lookup_col1, e execution_sel_error, e execution_sel_exec_dispatch_alu, e execution_sel_exec_dispatch_bitwise, e execution_sel_exec_dispatch_calldata_copy, e execution_sel_exec_dispatch_cast, e execution_sel_exec_dispatch_ecc_add, e execution_sel_exec_dispatch_emit_public_log, e execution_sel_exec_dispatch_execution, e execution_sel_exec_dispatch_get_contract_instance, e execution_sel_exec_dispatch_keccakf1600, e execution_sel_exec_dispatch_poseidon2_perm, e execution_sel_exec_dispatch_returndata_copy, e execution_sel_exec_dispatch_set, e execution_sel_exec_dispatch_sha256_compression, e execution_sel_exec_dispatch_to_radix, e execution_sel_execute_call, e execution_sel_execute_debug_log, e execution_sel_execute_emit_notehash, e execution_sel_execute_emit_nullifier, e execution_sel_execute_get_env_var, e execution_sel_execute_internal_call, e execution_sel_execute_internal_return, e execution_sel_execute_jump, e execution_sel_execute_jumpi, e execution_sel_execute_l1_to_l2_message_exists, e execution_sel_execute_mov, e execution_sel_execute_notehash_exists, e execution_sel_execute_nullifier_exists, e execution_sel_execute_opcode, e execution_sel_execute_return, e execution_sel_execute_returndata_size, e execution_sel_execute_revert, e execution_sel_execute_send_l2_to_l1_msg, e execution_sel_execute_sload, e execution_sel_execute_sstore, e execution_sel_execute_static_call, e execution_sel_execute_success_copy, e execution_sel_exit_call, e execution_sel_failure, e execution_sel_gas_bitwise, e execution_sel_gas_calldata_copy, e execution_sel_gas_emit_public_log, e execution_sel_gas_returndata_copy, e execution_sel_gas_sstore, e execution_sel_gas_to_radix, e execution_sel_instruction_fetching_failure, e execution_sel_instruction_fetching_success, e execution_sel_l2_to_l1_msg_limit_error, e execution_sel_lookup_num_p_limbs, e execution_sel_mem_op_reg_0_, e execution_sel_mem_op_reg_1_, e execution_sel_mem_op_reg_2_, e execution_sel_mem_op_reg_3_, e execution_sel_mem_op_reg_4_, e execution_sel_mem_op_reg_5_, e execution_sel_op_do_overflow_check_0_, e execution_sel_op_do_overflow_check_1_, e execution_sel_op_do_overflow_check_2_, e execution_sel_op_do_overflow_check_3_, e execution_sel_op_do_overflow_check_4_, e execution_sel_op_do_overflow_check_5_, e execution_sel_op_do_overflow_check_6_, e execution_sel_op_is_address_0_, e execution_sel_op_is_address_1_, e execution_sel_op_is_address_2_, e execution_sel_op_is_address_3_, e execution_sel_op_is_address_4_, e execution_sel_op_is_address_5_, e execution_sel_op_is_address_6_, e execution_sel_op_is_indirect_wire_0_, e execution_sel_op_is_indirect_wire_1_, e execution_sel_op_is_indirect_wire_2_, e execution_sel_op_is_indirect_wire_3_, e execution_sel_op_is_indirect_wire_4_, e execution_sel_op_is_indirect_wire_5_, e execution_sel_op_is_indirect_wire_6_, e execution_sel_op_is_indirect_wire_7_, e execution_sel_op_is_relative_wire_0_, e execution_sel_op_is_relative_wire_1_, e execution_sel_op_is_relative_wire_2_, e execution_sel_op_is_relative_wire_3_, e execution_sel_op_is_relative_wire_4_, e execution_sel_op_is_relative_wire_5_, e execution_sel_op_is_relative_wire_6_, e execution_sel_op_is_relative_wire_7_, e execution_sel_op_reg_effective_0_, e execution_sel_op_reg_effective_1_, e execution_sel_op_reg_effective_2_, e execution_sel_op_reg_effective_3_, e execution_sel_op_reg_effective_4_, e execution_sel_op_reg_effective_5_, e execution_sel_opcode_error, e execution_sel_out_of_gas, e execution_sel_radix_gt_256, e execution_sel_reached_max_note_hashes, e execution_sel_reached_max_nullifiers, e execution_sel_read_registers, e execution_sel_read_unwind_call_stack, e execution_sel_register_read_error, e execution_sel_relative_overflow_0_, e execution_sel_relative_overflow_1_, e execution_sel_relative_overflow_2_, e execution_sel_relative_overflow_3_, e execution_sel_relative_overflow_4_, e execution_sel_relative_overflow_5_, e execution_sel_relative_overflow_6_, e execution_sel_some_final_check_failed, e execution_sel_tag_check_reg_0_, e execution_sel_tag_check_reg_1_, e execution_sel_tag_check_reg_2_, e execution_sel_tag_check_reg_3_, e execution_sel_tag_check_reg_4_, e execution_sel_tag_check_reg_5_, e execution_sel_too_large_recipient_error, e execution_sel_use_num_limbs, e execution_sel_write_l2_to_l1_msg, e execution_sel_write_note_hash, e execution_sel_write_nullifier, e execution_sel_write_public_data, e execution_sel_write_registers, e execution_subtrace_id, e execution_subtrace_operation_id, e execution_total_gas_da, e execution_total_gas_l2, e execution_two_five_six, e execution_value_from_pi, e execution_written_public_data_slots_tree_root, e execution_written_public_data_slots_tree_size, e execution_written_slots_merkle_separator, e execution_written_slots_tree_height, e execution_written_slots_tree_siloing_separator, e ff_gt_a, e ff_gt_b, e ff_gt_borrow, e ff_gt_constant_128, e ff_gt_end, e ff_gt_p_a_borrow, e ff_gt_p_b_borrow, e ff_gt_res_hi, e ff_gt_res_lo, e ff_gt_result, e get_contract_instance_clk, e get_contract_instance_contract_address, e get_contract_instance_dst_offset, e get_contract_instance_dst_offset_diff_max_inv, e get_contract_instance_exists_tag, e get_contract_instance_instance_exists, e get_contract_instance_is_class_id, e get_contract_instance_is_deployer, e get_contract_instance_is_immutables_hash, e get_contract_instance_is_init_hash, e get_contract_instance_is_valid_member_enum, e get_contract_instance_is_valid_writes_in_bounds, e get_contract_instance_member_enum, e get_contract_instance_member_tag, e get_contract_instance_member_write_offset, e get_contract_instance_nullifier_tree_root, e get_contract_instance_public_data_tree_root, e get_contract_instance_retrieved_class_id, e get_contract_instance_retrieved_deployer_addr, e get_contract_instance_retrieved_immutables_hash, e get_contract_instance_retrieved_init_hash, e get_contract_instance_sel, e get_contract_instance_sel_error, e get_contract_instance_selected_member, e get_contract_instance_space_id, e gt_abs_diff, e gt_input_a, e gt_input_b, e gt_num_bits, e gt_res, e gt_sel, e gt_sel_addressing, e gt_sel_alu, e gt_sel_gas, e gt_sel_others, e gt_sel_sha256, e indexed_tree_check_address, e indexed_tree_check_const_three, e indexed_tree_check_discard, e indexed_tree_check_exists, e indexed_tree_check_intermediate_root, e indexed_tree_check_low_leaf_hash, e indexed_tree_check_low_leaf_index, e indexed_tree_check_low_leaf_next_index, e indexed_tree_check_low_leaf_next_value, e indexed_tree_check_low_leaf_value, e indexed_tree_check_merkle_hash_separator, e indexed_tree_check_new_leaf_hash, e indexed_tree_check_next_value_inv, e indexed_tree_check_next_value_is_nonzero, e indexed_tree_check_not_exists, e indexed_tree_check_public_inputs_index, e indexed_tree_check_root, e indexed_tree_check_sel, e indexed_tree_check_sel_insert, e indexed_tree_check_sel_silo, e indexed_tree_check_sel_write_to_public_inputs, e indexed_tree_check_siloed_value, e indexed_tree_check_siloing_separator, e indexed_tree_check_tree_height, e indexed_tree_check_tree_size_after_write, e indexed_tree_check_tree_size_before_write, e indexed_tree_check_updated_low_leaf_hash, e indexed_tree_check_updated_low_leaf_next_index, e indexed_tree_check_updated_low_leaf_next_value, e indexed_tree_check_value, e indexed_tree_check_value_low_leaf_value_diff_inv, e indexed_tree_check_write, e indexed_tree_check_write_root, e instr_fetching_addressing_mode, e instr_fetching_bd0, e instr_fetching_bd1, e instr_fetching_bd10, e instr_fetching_bd11, e instr_fetching_bd12, e instr_fetching_bd13, e instr_fetching_bd14, e instr_fetching_bd15, e instr_fetching_bd16, e instr_fetching_bd17, e instr_fetching_bd18, e instr_fetching_bd19, e instr_fetching_bd2, e instr_fetching_bd20, e instr_fetching_bd21, e instr_fetching_bd22, e instr_fetching_bd23, e instr_fetching_bd24, e instr_fetching_bd25, e instr_fetching_bd26, e instr_fetching_bd27, e instr_fetching_bd28, e instr_fetching_bd29, e instr_fetching_bd3, e instr_fetching_bd30, e instr_fetching_bd31, e instr_fetching_bd32, e instr_fetching_bd33, e instr_fetching_bd34, e instr_fetching_bd35, e instr_fetching_bd36, e instr_fetching_bd4, e instr_fetching_bd5, e instr_fetching_bd6, e instr_fetching_bd7, e instr_fetching_bd8, e instr_fetching_bd9, e instr_fetching_bytecode_id, e instr_fetching_bytecode_size, e instr_fetching_bytes_to_read, e instr_fetching_exec_opcode, e instr_fetching_instr_abs_diff, e instr_fetching_instr_out_of_range, e instr_fetching_instr_size, e instr_fetching_op1, e instr_fetching_op2, e instr_fetching_op3, e instr_fetching_op4, e instr_fetching_op5, e instr_fetching_op6, e instr_fetching_op7, e instr_fetching_opcode_out_of_range, e instr_fetching_pc, e instr_fetching_pc_abs_diff, e instr_fetching_pc_out_of_range, e instr_fetching_pc_size_in_bits, e instr_fetching_sel, e instr_fetching_sel_has_tag, e instr_fetching_sel_op_dc_0, e instr_fetching_sel_op_dc_1, e instr_fetching_sel_op_dc_10, e instr_fetching_sel_op_dc_11, e instr_fetching_sel_op_dc_12, e instr_fetching_sel_op_dc_13, e instr_fetching_sel_op_dc_14, e instr_fetching_sel_op_dc_15, e instr_fetching_sel_op_dc_16, e instr_fetching_sel_op_dc_2, e instr_fetching_sel_op_dc_3, e instr_fetching_sel_op_dc_4, e instr_fetching_sel_op_dc_5, e instr_fetching_sel_op_dc_6, e instr_fetching_sel_op_dc_7, e instr_fetching_sel_op_dc_8, e instr_fetching_sel_op_dc_9, e instr_fetching_sel_parsing_err, e instr_fetching_sel_pc_in_range, e instr_fetching_sel_tag_is_op2, e instr_fetching_tag_out_of_range, e instr_fetching_tag_value, e internal_call_stack_call_id, e internal_call_stack_context_id, e internal_call_stack_entered_call_id, e internal_call_stack_return_call_id, e internal_call_stack_return_pc, e internal_call_stack_sel, e keccak_memory_ctr_end, e keccak_memory_end, e keccak_memory_single_tag_error, e keccak_memory_state_size_min_ctr_inv, e keccak_memory_tag, e keccak_memory_tag_min_u64_inv, e keccak_memory_val_24_, e keccakf1600_bitwise_and_op_id, e keccakf1600_bitwise_xor_op_id, e keccakf1600_dst_out_of_range_error, e keccakf1600_end, e keccakf1600_error, e keccakf1600_highest_slice_address, e keccakf1600_rot_64_min_len_01, e keccakf1600_rot_64_min_len_03, e keccakf1600_rot_64_min_len_11, e keccakf1600_rot_64_min_len_13, e keccakf1600_rot_64_min_len_20, e keccakf1600_rot_64_min_len_22, e keccakf1600_rot_64_min_len_24, e keccakf1600_rot_64_min_len_31, e keccakf1600_rot_64_min_len_34, e keccakf1600_rot_64_min_len_42, e keccakf1600_rot_len_02, e keccakf1600_rot_len_04, e keccakf1600_rot_len_10, e keccakf1600_rot_len_12, e keccakf1600_rot_len_14, e keccakf1600_rot_len_21, e keccakf1600_rot_len_23, e keccakf1600_rot_len_30, e keccakf1600_rot_len_32, e keccakf1600_rot_len_33, e keccakf1600_rot_len_40, e keccakf1600_rot_len_41, e keccakf1600_rot_len_43, e keccakf1600_rot_len_44, e keccakf1600_round_cst, e keccakf1600_sel_slice_read, e keccakf1600_sel_slice_write, e keccakf1600_src_addr, e keccakf1600_src_out_of_range_error, e keccakf1600_state_chi_00, e keccakf1600_state_chi_01, e keccakf1600_state_chi_02, e keccakf1600_state_chi_03, e keccakf1600_state_chi_04, e keccakf1600_state_chi_10, e keccakf1600_state_chi_11, e keccakf1600_state_chi_12, e keccakf1600_state_chi_13, e keccakf1600_state_chi_14, e keccakf1600_state_chi_20, e keccakf1600_state_chi_21, e keccakf1600_state_chi_22, e keccakf1600_state_chi_23, e keccakf1600_state_chi_24, e keccakf1600_state_chi_30, e keccakf1600_state_chi_31, e keccakf1600_state_chi_32, e keccakf1600_state_chi_33, e keccakf1600_state_chi_34, e keccakf1600_state_chi_40, e keccakf1600_state_chi_41, e keccakf1600_state_chi_42, e keccakf1600_state_chi_43, e keccakf1600_state_chi_44, e keccakf1600_state_iota_00, e keccakf1600_state_pi_and_00, e keccakf1600_state_pi_and_01, e keccakf1600_state_pi_and_02, e keccakf1600_state_pi_and_03, e keccakf1600_state_pi_and_04, e keccakf1600_state_pi_and_10, e keccakf1600_state_pi_and_11, e keccakf1600_state_pi_and_12, e keccakf1600_state_pi_and_13, e keccakf1600_state_pi_and_14, e keccakf1600_state_pi_and_20, e keccakf1600_state_pi_and_21, e keccakf1600_state_pi_and_22, e keccakf1600_state_pi_and_23, e keccakf1600_state_pi_and_24, e keccakf1600_state_pi_and_30, e keccakf1600_state_pi_and_31, e keccakf1600_state_pi_and_32, e keccakf1600_state_pi_and_33, e keccakf1600_state_pi_and_34, e keccakf1600_state_pi_and_40, e keccakf1600_state_pi_and_41, e keccakf1600_state_pi_and_42, e keccakf1600_state_pi_and_43, e keccakf1600_state_pi_and_44, e keccakf1600_state_pi_not_00, e keccakf1600_state_pi_not_01, e keccakf1600_state_pi_not_02, e keccakf1600_state_pi_not_03, e keccakf1600_state_pi_not_04, e keccakf1600_state_pi_not_10, e keccakf1600_state_pi_not_11, e keccakf1600_state_pi_not_12, e keccakf1600_state_pi_not_13, e keccakf1600_state_pi_not_14, e keccakf1600_state_pi_not_20, e keccakf1600_state_pi_not_21, e keccakf1600_state_pi_not_22, e keccakf1600_state_pi_not_23, e keccakf1600_state_pi_not_24, e keccakf1600_state_pi_not_30, e keccakf1600_state_pi_not_31, e keccakf1600_state_pi_not_32, e keccakf1600_state_pi_not_33, e keccakf1600_state_pi_not_34, e keccakf1600_state_pi_not_40, e keccakf1600_state_pi_not_41, e keccakf1600_state_pi_not_42, e keccakf1600_state_pi_not_43, e keccakf1600_state_pi_not_44, e keccakf1600_state_rho_01, e keccakf1600_state_rho_02, e keccakf1600_state_rho_03, e keccakf1600_state_rho_04, e keccakf1600_state_rho_10, e keccakf1600_state_rho_11, e keccakf1600_state_rho_12, e keccakf1600_state_rho_13, e keccakf1600_state_rho_14, e keccakf1600_state_rho_20, e keccakf1600_state_rho_21, e keccakf1600_state_rho_22, e keccakf1600_state_rho_23, e keccakf1600_state_rho_24, e keccakf1600_state_rho_30, e keccakf1600_state_rho_31, e keccakf1600_state_rho_32, e keccakf1600_state_rho_33, e keccakf1600_state_rho_34, e keccakf1600_state_rho_40, e keccakf1600_state_rho_41, e keccakf1600_state_rho_42, e keccakf1600_state_rho_43, e keccakf1600_state_rho_44, e keccakf1600_state_theta_00, e keccakf1600_state_theta_01, e keccakf1600_state_theta_02, e keccakf1600_state_theta_03, e keccakf1600_state_theta_04, e keccakf1600_state_theta_10, e keccakf1600_state_theta_11, e keccakf1600_state_theta_12, e keccakf1600_state_theta_13, e keccakf1600_state_theta_14, e keccakf1600_state_theta_20, e keccakf1600_state_theta_21, e keccakf1600_state_theta_22, e keccakf1600_state_theta_23, e keccakf1600_state_theta_24, e keccakf1600_state_theta_30, e keccakf1600_state_theta_31, e keccakf1600_state_theta_32, e keccakf1600_state_theta_33, e keccakf1600_state_theta_34, e keccakf1600_state_theta_40, e keccakf1600_state_theta_41, e keccakf1600_state_theta_42, e keccakf1600_state_theta_43, e keccakf1600_state_theta_44, e keccakf1600_state_theta_hi_02, e keccakf1600_state_theta_hi_04, e keccakf1600_state_theta_hi_10, e keccakf1600_state_theta_hi_12, e keccakf1600_state_theta_hi_14, e keccakf1600_state_theta_hi_21, e keccakf1600_state_theta_hi_23, e keccakf1600_state_theta_hi_30, e keccakf1600_state_theta_hi_32, e keccakf1600_state_theta_hi_33, e keccakf1600_state_theta_hi_40, e keccakf1600_state_theta_hi_41, e keccakf1600_state_theta_hi_43, e keccakf1600_state_theta_hi_44, e keccakf1600_state_theta_low_01, e keccakf1600_state_theta_low_03, e keccakf1600_state_theta_low_11, e keccakf1600_state_theta_low_13, e keccakf1600_state_theta_low_20, e keccakf1600_state_theta_low_22, e keccakf1600_state_theta_low_24, e keccakf1600_state_theta_low_31, e keccakf1600_state_theta_low_34, e keccakf1600_state_theta_low_42, e keccakf1600_tag_error, e keccakf1600_tag_u64, e keccakf1600_theta_combined_xor_0, e keccakf1600_theta_combined_xor_1, e keccakf1600_theta_combined_xor_2, e keccakf1600_theta_combined_xor_3, e keccakf1600_theta_combined_xor_4, e keccakf1600_theta_xor_01, e keccakf1600_theta_xor_02, e keccakf1600_theta_xor_03, e keccakf1600_theta_xor_11, e keccakf1600_theta_xor_12, e keccakf1600_theta_xor_13, e keccakf1600_theta_xor_21, e keccakf1600_theta_xor_22, e keccakf1600_theta_xor_23, e keccakf1600_theta_xor_31, e keccakf1600_theta_xor_32, e keccakf1600_theta_xor_33, e keccakf1600_theta_xor_41, e keccakf1600_theta_xor_42, e keccakf1600_theta_xor_43, e keccakf1600_theta_xor_row_0, e keccakf1600_theta_xor_row_1, e keccakf1600_theta_xor_row_2, e keccakf1600_theta_xor_row_3, e keccakf1600_theta_xor_row_4, e keccakf1600_theta_xor_row_msb_0, e keccakf1600_theta_xor_row_msb_1, e keccakf1600_theta_xor_row_msb_2, e keccakf1600_theta_xor_row_msb_3, e keccakf1600_theta_xor_row_msb_4, e keccakf1600_theta_xor_row_rotl1_0, e keccakf1600_theta_xor_row_rotl1_1, e keccakf1600_theta_xor_row_rotl1_2, e keccakf1600_theta_xor_row_rotl1_3, e keccakf1600_theta_xor_row_rotl1_4, e l1_to_l2_message_tree_check_exists, e l1_to_l2_message_tree_check_l1_to_l2_message_tree_height, e l1_to_l2_message_tree_check_leaf_index, e l1_to_l2_message_tree_check_leaf_value, e l1_to_l2_message_tree_check_leaf_value_msg_hash_diff_inv, e l1_to_l2_message_tree_check_merkle_hash_separator, e l1_to_l2_message_tree_check_msg_hash, e l1_to_l2_message_tree_check_root, e l1_to_l2_message_tree_check_sel, e memory_diff, e memory_glob_addr_diff_inv, e memory_last_access, e memory_limb_0_, e memory_limb_1_, e memory_limb_2_, e memory_max_bits, e memory_sel_addressing_base, e memory_sel_addressing_indirect_0_, e memory_sel_addressing_indirect_1_, e memory_sel_addressing_indirect_2_, e memory_sel_addressing_indirect_3_, e memory_sel_addressing_indirect_4_, e memory_sel_addressing_indirect_5_, e memory_sel_addressing_indirect_6_, e memory_sel_data_copy_read, e memory_sel_data_copy_write, e memory_sel_ecc_write_0_, e memory_sel_ecc_write_1_, e memory_sel_get_contract_instance_exists_write, e memory_sel_get_contract_instance_member_write, e memory_sel_keccak, e memory_sel_poseidon2_read_0_, e memory_sel_poseidon2_read_1_, e memory_sel_poseidon2_read_2_, e memory_sel_poseidon2_read_3_, e memory_sel_poseidon2_write_0_, e memory_sel_poseidon2_write_1_, e memory_sel_poseidon2_write_2_, e memory_sel_poseidon2_write_3_, e memory_sel_public_log_read, e memory_sel_register_op_0_, e memory_sel_register_op_1_, e memory_sel_register_op_2_, e memory_sel_register_op_3_, e memory_sel_register_op_4_, e memory_sel_register_op_5_, e memory_sel_rng_chk, e memory_sel_rng_write, e memory_sel_sha256_op_0_, e memory_sel_sha256_op_1_, e memory_sel_sha256_op_2_, e memory_sel_sha256_op_3_, e memory_sel_sha256_op_4_, e memory_sel_sha256_op_5_, e memory_sel_sha256_op_6_, e memory_sel_sha256_op_7_, e memory_sel_sha256_read, e memory_sel_tag_is_ff, e memory_sel_to_radix_write, e memory_tag_ff_diff_inv, e merkle_check_const_three, e merkle_check_end, e merkle_check_index_is_even, e merkle_check_path_len_min_one_inv, e merkle_check_read_left_node, e merkle_check_read_output_hash, e merkle_check_read_right_node, e merkle_check_sibling, e merkle_check_write_left_node, e merkle_check_write_output_hash, e merkle_check_write_right_node, e note_hash_tree_check_address, e note_hash_tree_check_const_three, e note_hash_tree_check_discard, e note_hash_tree_check_exists, e note_hash_tree_check_first_nullifier, e note_hash_tree_check_first_nullifier_pi_index, e note_hash_tree_check_leaf_index, e note_hash_tree_check_merkle_hash_separator, e note_hash_tree_check_next_leaf_value, e note_hash_tree_check_next_root, e note_hash_tree_check_nonce, e note_hash_tree_check_nonce_separator, e note_hash_tree_check_note_hash, e note_hash_tree_check_note_hash_index, e note_hash_tree_check_note_hash_tree_height, e note_hash_tree_check_prev_leaf_value, e note_hash_tree_check_prev_leaf_value_unique_note_hash_diff_inv, e note_hash_tree_check_prev_root, e note_hash_tree_check_public_inputs_index, e note_hash_tree_check_sel, e note_hash_tree_check_sel_silo, e note_hash_tree_check_sel_unique, e note_hash_tree_check_sel_write_to_public_inputs, e note_hash_tree_check_siloed_note_hash, e note_hash_tree_check_siloing_separator, e note_hash_tree_check_unique_note_hash, e note_hash_tree_check_unique_note_hash_separator, e note_hash_tree_check_write, e poseidon2_hash_b_0, e poseidon2_hash_b_1, e poseidon2_hash_b_2, e poseidon2_hash_b_3, e poseidon2_hash_end, e poseidon2_hash_input_len, e poseidon2_hash_num_perm_rounds_rem_min_one_inv, e poseidon2_hash_padding, e poseidon2_perm_B_10_0, e poseidon2_perm_B_10_1, e poseidon2_perm_B_10_2, e poseidon2_perm_B_10_3, e poseidon2_perm_B_11_0, e poseidon2_perm_B_11_1, e poseidon2_perm_B_11_2, e poseidon2_perm_B_11_3, e poseidon2_perm_B_12_0, e poseidon2_perm_B_12_1, e poseidon2_perm_B_12_2, e poseidon2_perm_B_12_3, e poseidon2_perm_B_13_0, e poseidon2_perm_B_13_1, e poseidon2_perm_B_13_2, e poseidon2_perm_B_13_3, e poseidon2_perm_B_14_0, e poseidon2_perm_B_14_1, e poseidon2_perm_B_14_2, e poseidon2_perm_B_14_3, e poseidon2_perm_B_15_0, e poseidon2_perm_B_15_1, e poseidon2_perm_B_15_2, e poseidon2_perm_B_15_3, e poseidon2_perm_B_16_0, e poseidon2_perm_B_16_1, e poseidon2_perm_B_16_2, e poseidon2_perm_B_16_3, e poseidon2_perm_B_17_0, e poseidon2_perm_B_17_1, e poseidon2_perm_B_17_2, e poseidon2_perm_B_17_3, e poseidon2_perm_B_18_0, e poseidon2_perm_B_18_1, e poseidon2_perm_B_18_2, e poseidon2_perm_B_18_3, e poseidon2_perm_B_19_0, e poseidon2_perm_B_19_1, e poseidon2_perm_B_19_2, e poseidon2_perm_B_19_3, e poseidon2_perm_B_20_0, e poseidon2_perm_B_20_1, e poseidon2_perm_B_20_2, e poseidon2_perm_B_20_3, e poseidon2_perm_B_21_0, e poseidon2_perm_B_21_1, e poseidon2_perm_B_21_2, e poseidon2_perm_B_21_3, e poseidon2_perm_B_22_0, e poseidon2_perm_B_22_1, e poseidon2_perm_B_22_2, e poseidon2_perm_B_22_3, e poseidon2_perm_B_23_0, e poseidon2_perm_B_23_1, e poseidon2_perm_B_23_2, e poseidon2_perm_B_23_3, e poseidon2_perm_B_24_0, e poseidon2_perm_B_24_1, e poseidon2_perm_B_24_2, e poseidon2_perm_B_24_3, e poseidon2_perm_B_25_0, e poseidon2_perm_B_25_1, e poseidon2_perm_B_25_2, e poseidon2_perm_B_25_3, e poseidon2_perm_B_26_0, e poseidon2_perm_B_26_1, e poseidon2_perm_B_26_2, e poseidon2_perm_B_26_3, e poseidon2_perm_B_27_0, e poseidon2_perm_B_27_1, e poseidon2_perm_B_27_2, e poseidon2_perm_B_27_3, e poseidon2_perm_B_28_0, e poseidon2_perm_B_28_1, e poseidon2_perm_B_28_2, e poseidon2_perm_B_28_3, e poseidon2_perm_B_29_0, e poseidon2_perm_B_29_1, e poseidon2_perm_B_29_2, e poseidon2_perm_B_29_3, e poseidon2_perm_B_30_0, e poseidon2_perm_B_30_1, e poseidon2_perm_B_30_2, e poseidon2_perm_B_30_3, e poseidon2_perm_B_31_0, e poseidon2_perm_B_31_1, e poseidon2_perm_B_31_2, e poseidon2_perm_B_31_3, e poseidon2_perm_B_32_0, e poseidon2_perm_B_32_1, e poseidon2_perm_B_32_2, e poseidon2_perm_B_32_3, e poseidon2_perm_B_33_0, e poseidon2_perm_B_33_1, e poseidon2_perm_B_33_2, e poseidon2_perm_B_33_3, e poseidon2_perm_B_34_0, e poseidon2_perm_B_34_1, e poseidon2_perm_B_34_2, e poseidon2_perm_B_34_3, e poseidon2_perm_B_35_0, e poseidon2_perm_B_35_1, e poseidon2_perm_B_35_2, e poseidon2_perm_B_35_3, e poseidon2_perm_B_36_0, e poseidon2_perm_B_36_1, e poseidon2_perm_B_36_2, e poseidon2_perm_B_36_3, e poseidon2_perm_B_37_0, e poseidon2_perm_B_37_1, e poseidon2_perm_B_37_2, e poseidon2_perm_B_37_3, e poseidon2_perm_B_38_0, e poseidon2_perm_B_38_1, e poseidon2_perm_B_38_2, e poseidon2_perm_B_38_3, e poseidon2_perm_B_39_0, e poseidon2_perm_B_39_1, e poseidon2_perm_B_39_2, e poseidon2_perm_B_39_3, e poseidon2_perm_B_40_0, e poseidon2_perm_B_40_1, e poseidon2_perm_B_40_2, e poseidon2_perm_B_40_3, e poseidon2_perm_B_41_0, e poseidon2_perm_B_41_1, e poseidon2_perm_B_41_2, e poseidon2_perm_B_41_3, e poseidon2_perm_B_42_0, e poseidon2_perm_B_42_1, e poseidon2_perm_B_42_2, e poseidon2_perm_B_42_3, e poseidon2_perm_B_43_0, e poseidon2_perm_B_43_1, e poseidon2_perm_B_43_2, e poseidon2_perm_B_43_3, e poseidon2_perm_B_44_0, e poseidon2_perm_B_44_1, e poseidon2_perm_B_44_2, e poseidon2_perm_B_44_3, e poseidon2_perm_B_45_0, e poseidon2_perm_B_45_1, e poseidon2_perm_B_45_2, e poseidon2_perm_B_45_3, e poseidon2_perm_B_46_0, e poseidon2_perm_B_46_1, e poseidon2_perm_B_46_2, e poseidon2_perm_B_46_3, e poseidon2_perm_B_47_0, e poseidon2_perm_B_47_1, e poseidon2_perm_B_47_2, e poseidon2_perm_B_47_3, e poseidon2_perm_B_48_0, e poseidon2_perm_B_48_1, e poseidon2_perm_B_48_2, e poseidon2_perm_B_48_3, e poseidon2_perm_B_49_0, e poseidon2_perm_B_49_1, e poseidon2_perm_B_49_2, e poseidon2_perm_B_49_3, e poseidon2_perm_B_4_0, e poseidon2_perm_B_4_1, e poseidon2_perm_B_4_2, e poseidon2_perm_B_4_3, e poseidon2_perm_B_50_0, e poseidon2_perm_B_50_1, e poseidon2_perm_B_50_2, e poseidon2_perm_B_50_3, e poseidon2_perm_B_51_0, e poseidon2_perm_B_51_1, e poseidon2_perm_B_51_2, e poseidon2_perm_B_51_3, e poseidon2_perm_B_52_0, e poseidon2_perm_B_52_1, e poseidon2_perm_B_52_2, e poseidon2_perm_B_52_3, e poseidon2_perm_B_53_0, e poseidon2_perm_B_53_1, e poseidon2_perm_B_53_2, e poseidon2_perm_B_53_3, e poseidon2_perm_B_54_0, e poseidon2_perm_B_54_1, e poseidon2_perm_B_54_2, e poseidon2_perm_B_54_3, e poseidon2_perm_B_55_0, e poseidon2_perm_B_55_1, e poseidon2_perm_B_55_2, e poseidon2_perm_B_55_3, e poseidon2_perm_B_56_0, e poseidon2_perm_B_56_1, e poseidon2_perm_B_56_2, e poseidon2_perm_B_56_3, e poseidon2_perm_B_57_0, e poseidon2_perm_B_57_1, e poseidon2_perm_B_57_2, e poseidon2_perm_B_57_3, e poseidon2_perm_B_58_0, e poseidon2_perm_B_58_1, e poseidon2_perm_B_58_2, e poseidon2_perm_B_58_3, e poseidon2_perm_B_59_0, e poseidon2_perm_B_59_1, e poseidon2_perm_B_59_2, e poseidon2_perm_B_59_3, e poseidon2_perm_B_5_0, e poseidon2_perm_B_5_1, e poseidon2_perm_B_5_2, e poseidon2_perm_B_5_3, e poseidon2_perm_B_6_0, e poseidon2_perm_B_6_1, e poseidon2_perm_B_6_2, e poseidon2_perm_B_6_3, e poseidon2_perm_B_7_0, e poseidon2_perm_B_7_1, e poseidon2_perm_B_7_2, e poseidon2_perm_B_7_3, e poseidon2_perm_B_8_0, e poseidon2_perm_B_8_1, e poseidon2_perm_B_8_2, e poseidon2_perm_B_8_3, e poseidon2_perm_B_9_0, e poseidon2_perm_B_9_1, e poseidon2_perm_B_9_2, e poseidon2_perm_B_9_3, e poseidon2_perm_EXT_LAYER_4, e poseidon2_perm_EXT_LAYER_5, e poseidon2_perm_EXT_LAYER_6, e poseidon2_perm_EXT_LAYER_7, e poseidon2_perm_T_0_4, e poseidon2_perm_T_0_5, e poseidon2_perm_T_0_6, e poseidon2_perm_T_0_7, e poseidon2_perm_T_1_4, e poseidon2_perm_T_1_5, e poseidon2_perm_T_1_6, e poseidon2_perm_T_1_7, e poseidon2_perm_T_2_4, e poseidon2_perm_T_2_5, e poseidon2_perm_T_2_6, e poseidon2_perm_T_2_7, e poseidon2_perm_T_3_4, e poseidon2_perm_T_3_5, e poseidon2_perm_T_3_6, e poseidon2_perm_T_3_7, e poseidon2_perm_T_60_4, e poseidon2_perm_T_60_5, e poseidon2_perm_T_60_6, e poseidon2_perm_T_60_7, e poseidon2_perm_T_61_4, e poseidon2_perm_T_61_5, e poseidon2_perm_T_61_6, e poseidon2_perm_T_61_7, e poseidon2_perm_T_62_4, e poseidon2_perm_T_62_5, e poseidon2_perm_T_62_6, e poseidon2_perm_T_62_7, e poseidon2_perm_T_63_4, e poseidon2_perm_T_63_5, e poseidon2_perm_T_63_6, e poseidon2_perm_T_63_7, e poseidon2_perm_a_0, e poseidon2_perm_a_1, e poseidon2_perm_a_2, e poseidon2_perm_a_3, e poseidon2_perm_b_0, e poseidon2_perm_b_1, e poseidon2_perm_b_2, e poseidon2_perm_b_3, e poseidon2_perm_mem_batch_tag_inv, e poseidon2_perm_mem_err, e poseidon2_perm_mem_execution_clk, e poseidon2_perm_mem_input_0_, e poseidon2_perm_mem_input_1_, e poseidon2_perm_mem_input_2_, e poseidon2_perm_mem_input_3_, e poseidon2_perm_mem_input_tag_0_, e poseidon2_perm_mem_input_tag_1_, e poseidon2_perm_mem_input_tag_2_, e poseidon2_perm_mem_input_tag_3_, e poseidon2_perm_mem_max_mem_addr, e poseidon2_perm_mem_output_0_, e poseidon2_perm_mem_output_1_, e poseidon2_perm_mem_output_2_, e poseidon2_perm_mem_output_3_, e poseidon2_perm_mem_read_address_0_, e poseidon2_perm_mem_read_address_1_, e poseidon2_perm_mem_read_address_2_, e poseidon2_perm_mem_read_address_3_, e poseidon2_perm_mem_sel, e poseidon2_perm_mem_sel_dst_out_of_range_err, e poseidon2_perm_mem_sel_invalid_tag_err, e poseidon2_perm_mem_sel_should_exec, e poseidon2_perm_mem_sel_should_read_mem, e poseidon2_perm_mem_sel_src_out_of_range_err, e poseidon2_perm_mem_space_id, e poseidon2_perm_mem_write_address_0_, e poseidon2_perm_mem_write_address_1_, e poseidon2_perm_mem_write_address_2_, e poseidon2_perm_mem_write_address_3_, e poseidon2_perm_sel, e public_data_check_address, e public_data_check_clk_diff_hi, e public_data_check_clk_diff_lo, e public_data_check_const_four, e public_data_check_const_three, e public_data_check_discard, e public_data_check_end, e public_data_check_final_value, e public_data_check_intermediate_root, e public_data_check_leaf_not_exists, e public_data_check_leaf_slot, e public_data_check_leaf_slot_low_leaf_slot_diff_inv, e public_data_check_length_pi_idx, e public_data_check_low_leaf_hash, e public_data_check_low_leaf_index, e public_data_check_low_leaf_next_index, e public_data_check_low_leaf_next_slot, e public_data_check_low_leaf_slot, e public_data_check_low_leaf_value, e public_data_check_merkle_hash_separator, e public_data_check_new_leaf_hash, e public_data_check_next_slot_inv, e public_data_check_next_slot_is_nonzero, e public_data_check_non_discarded_write, e public_data_check_non_protocol_write, e public_data_check_not_end, e public_data_check_protocol_write, e public_data_check_public_data_writes_length, e public_data_check_root, e public_data_check_sel_write_to_public_inputs, e public_data_check_should_insert, e public_data_check_siloing_separator, e public_data_check_slot, e public_data_check_tree_height, e public_data_check_tree_size_after_write, e public_data_check_tree_size_before_write, e public_data_check_updated_low_leaf_hash, e public_data_check_updated_low_leaf_next_index, e public_data_check_updated_low_leaf_next_slot, e public_data_check_updated_low_leaf_value, e public_data_check_value, e public_data_check_write, e public_data_check_write_root, e public_data_squash_check_clock, e public_data_squash_clk_diff_hi, e public_data_squash_clk_diff_lo, e public_data_squash_leaf_slot_increase, e public_data_squash_value, e range_check_dyn_diff, e range_check_dyn_rng_chk_bits, e range_check_dyn_rng_chk_pow_2, e range_check_is_lte_u112, e range_check_is_lte_u128, e range_check_is_lte_u16, e range_check_is_lte_u32, e range_check_is_lte_u48, e range_check_is_lte_u64, e range_check_is_lte_u80, e range_check_is_lte_u96, e range_check_rng_chk_bits, e range_check_sel, e range_check_sel_alu, e range_check_sel_gt, e range_check_sel_keccak, e range_check_sel_memory, e range_check_sel_r0_16_bit_rng_lookup, e range_check_sel_r1_16_bit_rng_lookup, e range_check_sel_r2_16_bit_rng_lookup, e range_check_sel_r3_16_bit_rng_lookup, e range_check_sel_r4_16_bit_rng_lookup, e range_check_sel_r5_16_bit_rng_lookup, e range_check_sel_r6_16_bit_rng_lookup, e range_check_u16_r0, e range_check_u16_r1, e range_check_u16_r2, e range_check_u16_r3, e range_check_u16_r4, e range_check_u16_r5, e range_check_u16_r6, e range_check_u16_r7, e range_check_value, e scalar_mul_bit, e scalar_mul_const_two, e scalar_mul_end, e scalar_mul_sel_not_end, e scalar_mul_should_add, e sha256_a_and_b, e sha256_a_and_b_xor_a_and_c, e sha256_a_and_c, e sha256_a_rotr_13, e sha256_a_rotr_2, e sha256_a_rotr_22, e sha256_a_rotr_2_xor_a_rotr_13, e sha256_and_op_id, e sha256_b_and_c, e sha256_batch_tag_inv, e sha256_ch, e sha256_computed_w_lhs, e sha256_computed_w_rhs, e sha256_e_and_f, e sha256_e_rotr_11, e sha256_e_rotr_25, e sha256_e_rotr_6, e sha256_e_rotr_6_xor_e_rotr_11, e sha256_end, e sha256_err, e sha256_input, e sha256_input_rounds_rem_inv, e sha256_input_tag, e sha256_input_tag_diff_inv, e sha256_last, e sha256_lhs_w_10, e sha256_lhs_w_3, e sha256_maj, e sha256_max_input_addr, e sha256_max_mem_addr, e sha256_max_output_addr, e sha256_max_state_addr, e sha256_mem_out_of_range_err, e sha256_memory_address_0_, e sha256_memory_address_1_, e sha256_memory_address_2_, e sha256_memory_address_3_, e sha256_memory_address_4_, e sha256_memory_address_5_, e sha256_memory_address_6_, e sha256_memory_address_7_, e sha256_memory_register_0_, e sha256_memory_register_1_, e sha256_memory_register_2_, e sha256_memory_register_3_, e sha256_memory_register_4_, e sha256_memory_register_5_, e sha256_memory_register_6_, e sha256_memory_register_7_, e sha256_memory_tag_0_, e sha256_memory_tag_1_, e sha256_memory_tag_2_, e sha256_memory_tag_3_, e sha256_memory_tag_4_, e sha256_memory_tag_5_, e sha256_memory_tag_6_, e sha256_memory_tag_7_, e sha256_next_a_lhs, e sha256_next_a_rhs, e sha256_next_e_lhs, e sha256_next_e_rhs, e sha256_not_e, e sha256_not_e_and_g, e sha256_output_a_lhs, e sha256_output_a_rhs, e sha256_output_b_lhs, e sha256_output_b_rhs, e sha256_output_c_lhs, e sha256_output_c_rhs, e sha256_output_d_lhs, e sha256_output_d_rhs, e sha256_output_e_lhs, e sha256_output_e_rhs, e sha256_output_f_lhs, e sha256_output_f_rhs, e sha256_output_g_lhs, e sha256_output_g_rhs, e sha256_output_h_lhs, e sha256_output_h_rhs, e sha256_perform_round, e sha256_rhs_a_13, e sha256_rhs_a_2, e sha256_rhs_a_22, e sha256_rhs_e_11, e sha256_rhs_e_25, e sha256_rhs_e_6, e sha256_rhs_w_10, e sha256_rhs_w_17, e sha256_rhs_w_18, e sha256_rhs_w_19, e sha256_rhs_w_3, e sha256_rhs_w_7, e sha256_round_constant, e sha256_round_count, e sha256_rounds_remaining_inv, e sha256_rw, e sha256_s_0, e sha256_s_1, e sha256_sel_compute_w, e sha256_sel_input_out_of_range_err, e sha256_sel_invalid_input_row_tag_err, e sha256_sel_invalid_state_tag_err, e sha256_sel_is_input_round, e sha256_sel_mem_state_or_output, e sha256_sel_output_out_of_range_err, e sha256_sel_read_input_from_memory, e sha256_sel_state_out_of_range_err, e sha256_state_addr, e sha256_two_pow_10, e sha256_two_pow_11, e sha256_two_pow_13, e sha256_two_pow_17, e sha256_two_pow_18, e sha256_two_pow_19, e sha256_two_pow_2, e sha256_two_pow_22, e sha256_two_pow_25, e sha256_two_pow_3, e sha256_two_pow_32, e sha256_two_pow_6, e sha256_two_pow_7, e sha256_u32_tag, e sha256_w, e sha256_w_15_rotr_18, e sha256_w_15_rotr_7, e sha256_w_15_rotr_7_xor_w_15_rotr_18, e sha256_w_2_rotr_17, e sha256_w_2_rotr_17_xor_w_2_rotr_19, e sha256_w_2_rotr_19, e sha256_w_s_0, e sha256_w_s_1, e sha256_xor_op_id, e to_radix_end, e to_radix_found, e to_radix_is_unsafe_limb, e to_radix_limb_p_diff, e to_radix_limb_radix_diff, e to_radix_mem_err, e to_radix_mem_input_validation_error, e to_radix_mem_last, e to_radix_mem_limb_index_to_lookup, e to_radix_mem_limb_value, e to_radix_mem_max_mem_size, e to_radix_mem_num_limbs_inv, e to_radix_mem_num_limbs_minus_one_inv, e to_radix_mem_output_tag, e to_radix_mem_radix_min_two_inv, e to_radix_mem_sel_dst_out_of_range_err, e to_radix_mem_sel_invalid_bitwise_radix, e to_radix_mem_sel_num_limbs_is_zero, e to_radix_mem_sel_radix_eq_2, e to_radix_mem_sel_radix_gt_256_err, e to_radix_mem_sel_radix_lt_2_err, e to_radix_mem_sel_value_is_zero, e to_radix_mem_two, e to_radix_mem_two_five_six, e to_radix_mem_value_found, e to_radix_mem_value_inv, e to_radix_mem_write_addr_upper_bound, e to_radix_p_limb, e to_radix_rem_inverse, e to_radix_safety_diff_inverse, e tx_array_length_l2_to_l1_messages_pi_offset, e tx_array_length_note_hashes_pi_offset, e tx_array_length_nullifiers_pi_offset, e tx_calldata_hash, e tx_calldata_size, e tx_const_three, e tx_contract_addr, e tx_dom_sep_public_storage_map_slot, e tx_effective_fee_per_da_gas, e tx_effective_fee_per_l2_gas, e tx_end_phase, e tx_fee_juice_balance_slot, e tx_fee_juice_balances_slot_constant, e tx_fee_juice_contract_address, e tx_fee_payer, e tx_fee_payer_balance, e tx_fee_payer_new_balance, e tx_fee_payer_pi_offset, e tx_fields_length_public_logs_pi_offset, e tx_gas_limit_pi_offset, e tx_gas_used_pi_offset, e tx_is_cleanup, e tx_is_collect_fee, e tx_is_padded, e tx_is_public_call_request, e tx_is_static, e tx_is_tree_insert_phase, e tx_is_tree_padding, e tx_l1_l2_pi_offset, e tx_l2_l1_msg_content, e tx_l2_l1_msg_contract_address, e tx_l2_l1_msg_recipient, e tx_leaf_value, e tx_msg_sender, e tx_next_da_gas_used, e tx_next_da_gas_used_sent_to_enqueued_call, e tx_next_l2_gas_used, e tx_next_l2_gas_used_sent_to_enqueued_call, e tx_next_note_hash_tree_root, e tx_next_note_hash_tree_size, e tx_next_nullifier_tree_root, e tx_next_nullifier_tree_size, e tx_next_num_l2_to_l1_messages, e tx_next_num_note_hashes_emitted, e tx_next_num_nullifiers_emitted, e tx_next_num_public_log_fields, e tx_next_phase_on_revert, e tx_next_public_data_tree_root, e tx_next_public_data_tree_size, e tx_next_retrieved_bytecodes_tree_root, e tx_next_retrieved_bytecodes_tree_size, e tx_next_written_public_data_slots_tree_root, e tx_next_written_public_data_slots_tree_size, e tx_note_hash_pi_offset, e tx_nullifier_limit_error, e tx_nullifier_merkle_separator, e tx_nullifier_pi_offset, e tx_nullifier_tree_height, e tx_prev_da_gas_used_sent_to_enqueued_call, e tx_prev_l2_gas_used_sent_to_enqueued_call, e tx_public_data_pi_offset, e tx_read_pi_length_offset, e tx_read_pi_start_offset, e tx_remaining_phase_inv, e tx_remaining_phase_minus_one_inv, e tx_remaining_side_effects_inv, e tx_reverted_pi_offset, e tx_sel_append_l2_l1_msg, e tx_sel_append_note_hash, e tx_sel_append_nullifier, e tx_sel_l2_l1_msg_append, e tx_sel_note_hash_append, e tx_sel_nullifier_append, e tx_sel_process_call_request, e tx_sel_read_phase_length, e tx_sel_read_trees_and_gas_used, e tx_sel_try_l2_l1_msg_append, e tx_sel_try_note_hash_append, e tx_sel_try_nullifier_append, e tx_setup_phase_value, e tx_should_read_gas_limit, e tx_uint32_max, e tx_write_nullifier_pi_offset, e tx_write_pi_offset, e update_check_address, e update_check_const_three, e update_check_contract_instance_registry_address, e update_check_current_class_id, e update_check_delayed_public_mutable_hash_slot, e update_check_delayed_public_mutable_slot, e update_check_dom_sep_public_storage_map_slot, e update_check_hash_not_zero, e update_check_original_class_id, e update_check_public_data_tree_root, e update_check_sel, e update_check_timestamp, e update_check_timestamp_is_lt_timestamp_of_change, e update_check_timestamp_of_change, e update_check_timestamp_of_change_bit_size, e update_check_timestamp_pi_offset, e update_check_update_hash, e update_check_update_hash_inv, e update_check_update_hi_metadata, e update_check_update_hi_metadata_bit_size, e update_check_update_post_class_id_is_zero, e update_check_update_post_class_inv, e update_check_update_pre_class_id_is_zero, e update_check_update_pre_class_inv, e update_check_update_preimage_metadata, e update_check_update_preimage_post_class_id, e update_check_update_preimage_pre_class_id, e update_check_updated_class_ids_slot, e lookup_range_check_dyn_rng_chk_pow_2_counts, e lookup_range_check_dyn_diff_is_u16_counts, e lookup_range_check_r0_is_u16_counts, e lookup_range_check_r1_is_u16_counts, e lookup_range_check_r2_is_u16_counts, e lookup_range_check_r3_is_u16_counts, e lookup_range_check_r4_is_u16_counts, e lookup_range_check_r5_is_u16_counts, e lookup_range_check_r6_is_u16_counts, e lookup_range_check_r7_is_u16_counts, e lookup_ff_gt_a_lo_range_counts, e lookup_ff_gt_a_hi_range_counts, e lookup_gt_gt_range_counts, e lookup_alu_tag_max_bits_value_counts, e lookup_alu_range_check_decomposition_a_lo_counts, e lookup_alu_range_check_decomposition_a_hi_counts, e lookup_alu_range_check_decomposition_b_lo_counts, e lookup_alu_range_check_decomposition_b_hi_counts, e lookup_alu_range_check_mul_c_hi_counts, e lookup_alu_range_check_div_remainder_counts, e lookup_alu_ff_gt_counts, e lookup_alu_int_gt_counts, e lookup_alu_shifts_two_pow_counts, e lookup_alu_large_trunc_canonical_dec_counts, e lookup_alu_range_check_trunc_mid_counts, e lookup_bitwise_integral_tag_length_counts, e lookup_bitwise_byte_operations_counts, e lookup_memory_range_check_limb_0_counts, e lookup_memory_range_check_limb_1_counts, e lookup_memory_range_check_limb_2_counts, e lookup_memory_tag_max_bits_counts, e lookup_memory_range_check_write_tagged_value_counts, e lookup_data_copy_offset_plus_size_is_gt_data_size_counts, e lookup_data_copy_check_src_addr_in_range_counts, e lookup_data_copy_check_dst_addr_in_range_counts, e lookup_data_copy_sel_has_reads_counts, e lookup_data_copy_col_read_counts, e lookup_ecc_mem_check_dst_addr_in_range_counts, e lookup_ecc_mem_input_output_ecc_add_counts, e lookup_keccakf1600_theta_xor_01_counts, e lookup_keccakf1600_theta_xor_02_counts, e lookup_keccakf1600_theta_xor_03_counts, e lookup_keccakf1600_theta_xor_row_0_counts, e lookup_keccakf1600_theta_xor_11_counts, e lookup_keccakf1600_theta_xor_12_counts, e lookup_keccakf1600_theta_xor_13_counts, e lookup_keccakf1600_theta_xor_row_1_counts, e lookup_keccakf1600_theta_xor_21_counts, e lookup_keccakf1600_theta_xor_22_counts, e lookup_keccakf1600_theta_xor_23_counts, e lookup_keccakf1600_theta_xor_row_2_counts, e lookup_keccakf1600_theta_xor_31_counts, e lookup_keccakf1600_theta_xor_32_counts, e lookup_keccakf1600_theta_xor_33_counts, e lookup_keccakf1600_theta_xor_row_3_counts, e lookup_keccakf1600_theta_xor_41_counts, e lookup_keccakf1600_theta_xor_42_counts, e lookup_keccakf1600_theta_xor_43_counts, e lookup_keccakf1600_theta_xor_row_4_counts, e lookup_keccakf1600_theta_combined_xor_0_counts, e lookup_keccakf1600_theta_combined_xor_1_counts, e lookup_keccakf1600_theta_combined_xor_2_counts, e lookup_keccakf1600_theta_combined_xor_3_counts, e lookup_keccakf1600_theta_combined_xor_4_counts, e lookup_keccakf1600_state_theta_00_counts, e lookup_keccakf1600_state_theta_01_counts, e lookup_keccakf1600_state_theta_02_counts, e lookup_keccakf1600_state_theta_03_counts, e lookup_keccakf1600_state_theta_04_counts, e lookup_keccakf1600_state_theta_10_counts, e lookup_keccakf1600_state_theta_11_counts, e lookup_keccakf1600_state_theta_12_counts, e lookup_keccakf1600_state_theta_13_counts, e lookup_keccakf1600_state_theta_14_counts, e lookup_keccakf1600_state_theta_20_counts, e lookup_keccakf1600_state_theta_21_counts, e lookup_keccakf1600_state_theta_22_counts, e lookup_keccakf1600_state_theta_23_counts, e lookup_keccakf1600_state_theta_24_counts, e lookup_keccakf1600_state_theta_30_counts, e lookup_keccakf1600_state_theta_31_counts, e lookup_keccakf1600_state_theta_32_counts, e lookup_keccakf1600_state_theta_33_counts, e lookup_keccakf1600_state_theta_34_counts, e lookup_keccakf1600_state_theta_40_counts, e lookup_keccakf1600_state_theta_41_counts, e lookup_keccakf1600_state_theta_42_counts, e lookup_keccakf1600_state_theta_43_counts, e lookup_keccakf1600_state_theta_44_counts, e lookup_keccakf1600_theta_limb_02_range_counts, e lookup_keccakf1600_theta_limb_04_range_counts, e lookup_keccakf1600_theta_limb_10_range_counts, e lookup_keccakf1600_theta_limb_12_range_counts, e lookup_keccakf1600_theta_limb_14_range_counts, e lookup_keccakf1600_theta_limb_21_range_counts, e lookup_keccakf1600_theta_limb_23_range_counts, e lookup_keccakf1600_theta_limb_30_range_counts, e lookup_keccakf1600_theta_limb_32_range_counts, e lookup_keccakf1600_theta_limb_33_range_counts, e lookup_keccakf1600_theta_limb_40_range_counts, e lookup_keccakf1600_theta_limb_41_range_counts, e lookup_keccakf1600_theta_limb_43_range_counts, e lookup_keccakf1600_theta_limb_44_range_counts, e lookup_keccakf1600_theta_limb_01_range_counts, e lookup_keccakf1600_theta_limb_03_range_counts, e lookup_keccakf1600_theta_limb_11_range_counts, e lookup_keccakf1600_theta_limb_13_range_counts, e lookup_keccakf1600_theta_limb_20_range_counts, e lookup_keccakf1600_theta_limb_22_range_counts, e lookup_keccakf1600_theta_limb_24_range_counts, e lookup_keccakf1600_theta_limb_31_range_counts, e lookup_keccakf1600_theta_limb_34_range_counts, e lookup_keccakf1600_theta_limb_42_range_counts, e lookup_keccakf1600_state_pi_and_00_counts, e lookup_keccakf1600_state_pi_and_01_counts, e lookup_keccakf1600_state_pi_and_02_counts, e lookup_keccakf1600_state_pi_and_03_counts, e lookup_keccakf1600_state_pi_and_04_counts, e lookup_keccakf1600_state_pi_and_10_counts, e lookup_keccakf1600_state_pi_and_11_counts, e lookup_keccakf1600_state_pi_and_12_counts, e lookup_keccakf1600_state_pi_and_13_counts, e lookup_keccakf1600_state_pi_and_14_counts, e lookup_keccakf1600_state_pi_and_20_counts, e lookup_keccakf1600_state_pi_and_21_counts, e lookup_keccakf1600_state_pi_and_22_counts, e lookup_keccakf1600_state_pi_and_23_counts, e lookup_keccakf1600_state_pi_and_24_counts, e lookup_keccakf1600_state_pi_and_30_counts, e lookup_keccakf1600_state_pi_and_31_counts, e lookup_keccakf1600_state_pi_and_32_counts, e lookup_keccakf1600_state_pi_and_33_counts, e lookup_keccakf1600_state_pi_and_34_counts, e lookup_keccakf1600_state_pi_and_40_counts, e lookup_keccakf1600_state_pi_and_41_counts, e lookup_keccakf1600_state_pi_and_42_counts, e lookup_keccakf1600_state_pi_and_43_counts, e lookup_keccakf1600_state_pi_and_44_counts, e lookup_keccakf1600_state_chi_00_counts, e lookup_keccakf1600_state_chi_01_counts, e lookup_keccakf1600_state_chi_02_counts, e lookup_keccakf1600_state_chi_03_counts, e lookup_keccakf1600_state_chi_04_counts, e lookup_keccakf1600_state_chi_10_counts, e lookup_keccakf1600_state_chi_11_counts, e lookup_keccakf1600_state_chi_12_counts, e lookup_keccakf1600_state_chi_13_counts, e lookup_keccakf1600_state_chi_14_counts, e lookup_keccakf1600_state_chi_20_counts, e lookup_keccakf1600_state_chi_21_counts, e lookup_keccakf1600_state_chi_22_counts, e lookup_keccakf1600_state_chi_23_counts, e lookup_keccakf1600_state_chi_24_counts, e lookup_keccakf1600_state_chi_30_counts, e lookup_keccakf1600_state_chi_31_counts, e lookup_keccakf1600_state_chi_32_counts, e lookup_keccakf1600_state_chi_33_counts, e lookup_keccakf1600_state_chi_34_counts, e lookup_keccakf1600_state_chi_40_counts, e lookup_keccakf1600_state_chi_41_counts, e lookup_keccakf1600_state_chi_42_counts, e lookup_keccakf1600_state_chi_43_counts, e lookup_keccakf1600_state_chi_44_counts, e lookup_keccakf1600_round_cst_counts, e lookup_keccakf1600_state_iota_00_counts, e lookup_keccakf1600_src_out_of_range_toggle_counts, e lookup_keccakf1600_dst_out_of_range_toggle_counts, e lookup_poseidon2_mem_check_src_addr_in_range_counts, e lookup_poseidon2_mem_check_dst_addr_in_range_counts, e lookup_poseidon2_mem_input_output_poseidon2_perm_counts, e lookup_to_radix_limb_range_counts, e lookup_to_radix_limb_less_than_radix_range_counts, e lookup_to_radix_fetch_safe_limbs_counts, e lookup_to_radix_fetch_p_limb_counts, e lookup_to_radix_limb_p_diff_range_counts, e lookup_scalar_mul_to_radix_counts, e lookup_scalar_mul_double_counts, e lookup_scalar_mul_add_counts, e lookup_sha256_range_comp_w_lhs_counts, e lookup_sha256_range_comp_w_rhs_counts, e lookup_sha256_range_rhs_w_7_counts, e lookup_sha256_range_rhs_w_18_counts, e lookup_sha256_range_rhs_w_3_counts, e lookup_sha256_w_s_0_xor_0_counts, e lookup_sha256_w_s_0_xor_1_counts, e lookup_sha256_range_rhs_w_17_counts, e lookup_sha256_range_rhs_w_19_counts, e lookup_sha256_range_rhs_w_10_counts, e lookup_sha256_w_s_1_xor_0_counts, e lookup_sha256_w_s_1_xor_1_counts, e lookup_sha256_range_rhs_e_6_counts, e lookup_sha256_range_rhs_e_11_counts, e lookup_sha256_range_rhs_e_25_counts, e lookup_sha256_s_1_xor_0_counts, e lookup_sha256_s_1_xor_1_counts, e lookup_sha256_ch_and_0_counts, e lookup_sha256_ch_and_1_counts, e lookup_sha256_ch_xor_counts, e lookup_sha256_round_constant_counts, e lookup_sha256_range_rhs_a_2_counts, e lookup_sha256_range_rhs_a_13_counts, e lookup_sha256_range_rhs_a_22_counts, e lookup_sha256_s_0_xor_0_counts, e lookup_sha256_s_0_xor_1_counts, e lookup_sha256_maj_and_0_counts, e lookup_sha256_maj_and_1_counts, e lookup_sha256_maj_and_2_counts, e lookup_sha256_maj_xor_0_counts, e lookup_sha256_maj_xor_1_counts, e lookup_sha256_range_comp_next_a_lhs_counts, e lookup_sha256_range_comp_next_a_rhs_counts, e lookup_sha256_range_comp_next_e_lhs_counts, e lookup_sha256_range_comp_next_e_rhs_counts, e lookup_sha256_range_comp_a_rhs_counts, e lookup_sha256_range_comp_b_rhs_counts, e lookup_sha256_range_comp_c_rhs_counts, e lookup_sha256_range_comp_d_rhs_counts, e lookup_sha256_range_comp_e_rhs_counts, e lookup_sha256_range_comp_f_rhs_counts, e lookup_sha256_range_comp_g_rhs_counts, e lookup_sha256_range_comp_h_rhs_counts, e lookup_sha256_mem_check_state_addr_in_range_counts, e lookup_sha256_mem_check_input_addr_in_range_counts, e lookup_sha256_mem_check_output_addr_in_range_counts, e lookup_to_radix_mem_check_dst_addr_in_range_counts, e lookup_to_radix_mem_check_radix_lt_2_counts, e lookup_to_radix_mem_check_radix_gt_256_counts, e lookup_to_radix_mem_input_output_to_radix_counts, e lookup_poseidon2_hash_poseidon2_perm_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_counts, e lookup_address_derivation_partial_address_poseidon2_counts, e lookup_address_derivation_ivpk_m_hash_poseidon2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_0_counts, e lookup_address_derivation_public_keys_hash_poseidon2_1_counts, e lookup_address_derivation_preaddress_poseidon2_counts, e lookup_address_derivation_preaddress_scalar_mul_counts, e lookup_address_derivation_address_ecadd_counts, e lookup_bc_decomposition_bytes_are_bytes_counts, e lookup_bc_hashing_poseidon2_hash_counts, e lookup_merkle_check_merkle_poseidon2_read_counts, e lookup_merkle_check_merkle_poseidon2_write_counts, e lookup_indexed_tree_check_silo_poseidon2_counts, e lookup_indexed_tree_check_low_leaf_value_validation_counts, e lookup_indexed_tree_check_low_leaf_next_value_validation_counts, e lookup_indexed_tree_check_low_leaf_poseidon2_counts, e lookup_indexed_tree_check_updated_low_leaf_poseidon2_counts, e lookup_indexed_tree_check_low_leaf_merkle_check_counts, e lookup_indexed_tree_check_new_leaf_poseidon2_counts, e lookup_indexed_tree_check_new_leaf_merkle_check_counts, e lookup_indexed_tree_check_write_value_to_public_inputs_counts, e lookup_public_data_squash_leaf_slot_increase_ff_gt_counts, e lookup_public_data_squash_clk_diff_range_lo_counts, e lookup_public_data_squash_clk_diff_range_hi_counts, e lookup_public_data_check_clk_diff_range_lo_counts, e lookup_public_data_check_clk_diff_range_hi_counts, e lookup_public_data_check_silo_poseidon2_counts, e lookup_public_data_check_low_leaf_slot_validation_counts, e lookup_public_data_check_low_leaf_next_slot_validation_counts, e lookup_public_data_check_low_leaf_poseidon2_0_counts, e lookup_public_data_check_low_leaf_poseidon2_1_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_0_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_1_counts, e lookup_public_data_check_low_leaf_merkle_check_counts, e lookup_public_data_check_new_leaf_poseidon2_0_counts, e lookup_public_data_check_new_leaf_poseidon2_1_counts, e lookup_public_data_check_new_leaf_merkle_check_counts, e lookup_public_data_check_write_public_data_to_public_inputs_counts, e lookup_public_data_check_write_writes_length_to_public_inputs_counts, e lookup_update_check_timestamp_from_public_inputs_counts, e lookup_update_check_delayed_public_mutable_slot_poseidon2_counts, e lookup_update_check_update_hash_public_data_read_counts, e lookup_update_check_update_hash_poseidon2_counts, e lookup_update_check_update_hi_metadata_range_counts, e lookup_update_check_update_lo_metadata_range_counts, e lookup_update_check_timestamp_is_lt_timestamp_of_change_counts, e lookup_contract_instance_retrieval_check_protocol_address_range_counts, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_counts, e lookup_contract_instance_retrieval_deployment_nullifier_read_counts, e lookup_contract_instance_retrieval_address_derivation_counts, e lookup_contract_instance_retrieval_update_check_counts, e lookup_class_id_derivation_class_id_poseidon2_0_counts, e lookup_class_id_derivation_class_id_poseidon2_1_counts, e lookup_bc_retrieval_contract_instance_retrieval_counts, e lookup_bc_retrieval_class_id_derivation_counts, e lookup_bc_retrieval_is_new_class_check_counts, e lookup_bc_retrieval_retrieved_bytecodes_insertion_counts, e lookup_instr_fetching_pc_abs_diff_positive_counts, e lookup_instr_fetching_instr_abs_diff_positive_counts, e lookup_instr_fetching_tag_value_validation_counts, e lookup_instr_fetching_bytecode_size_from_bc_dec_counts, e lookup_instr_fetching_bytes_from_bc_dec_counts, e lookup_instr_fetching_wire_instruction_info_counts, e lookup_emit_public_log_check_memory_out_of_bounds_counts, e lookup_emit_public_log_check_log_fields_count_counts, e lookup_emit_public_log_write_data_to_public_inputs_counts, e lookup_get_contract_instance_precomputed_info_counts, e lookup_get_contract_instance_contract_instance_retrieval_counts, e lookup_l1_to_l2_message_tree_check_merkle_check_counts, e lookup_internal_call_unwind_call_stack_counts, e lookup_context_ctx_stack_rollback_counts, e lookup_context_ctx_stack_return_counts, e lookup_addressing_relative_overflow_result_0_counts, e lookup_addressing_relative_overflow_result_1_counts, e lookup_addressing_relative_overflow_result_2_counts, e lookup_addressing_relative_overflow_result_3_counts, e lookup_addressing_relative_overflow_result_4_counts, e lookup_addressing_relative_overflow_result_5_counts, e lookup_addressing_relative_overflow_result_6_counts, e lookup_gas_addressing_gas_read_counts, e lookup_gas_is_out_of_gas_l2_counts, e lookup_gas_is_out_of_gas_da_counts, e lookup_note_hash_tree_check_silo_poseidon2_counts, e lookup_note_hash_tree_check_read_first_nullifier_counts, e lookup_note_hash_tree_check_nonce_computation_poseidon2_counts, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_counts, e lookup_note_hash_tree_check_merkle_check_counts, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_counts, e lookup_emit_notehash_notehash_tree_write_counts, e lookup_emit_nullifier_write_nullifier_counts, e lookup_external_call_is_l2_gas_left_gt_allocated_counts, e lookup_external_call_is_da_gas_left_gt_allocated_counts, e lookup_get_env_var_precomputed_info_counts, e lookup_get_env_var_read_from_public_inputs_col0_counts, e lookup_get_env_var_read_from_public_inputs_col1_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_counts, e lookup_notehash_exists_note_hash_leaf_index_in_range_counts, e lookup_notehash_exists_note_hash_read_counts, e lookup_nullifier_exists_nullifier_exists_check_counts, e lookup_send_l2_to_l1_msg_recipient_check_counts, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_counts, e lookup_sload_storage_read_counts, e lookup_sstore_record_written_storage_slot_counts, e lookup_execution_bytecode_retrieval_result_counts, e lookup_execution_instruction_fetching_result_counts, e lookup_execution_instruction_fetching_body_counts, e lookup_execution_exec_spec_read_counts, e lookup_execution_dyn_l2_factor_bitwise_counts, e lookup_execution_check_radix_gt_256_counts, e lookup_execution_get_p_limbs_counts, e lookup_execution_get_max_limbs_counts, e lookup_execution_check_written_storage_slot_counts, e lookup_execution_dispatch_to_alu_counts, e lookup_execution_dispatch_to_bitwise_counts, e lookup_execution_dispatch_to_cast_counts, e lookup_execution_dispatch_to_set_counts, e lookup_calldata_hashing_get_calldata_field_0_counts, e lookup_calldata_hashing_get_calldata_field_1_counts, e lookup_calldata_hashing_get_calldata_field_2_counts, e lookup_calldata_hashing_poseidon2_hash_counts, e lookup_tx_context_public_inputs_note_hash_tree_counts, e lookup_tx_context_public_inputs_nullifier_tree_counts, e lookup_tx_context_public_inputs_public_data_tree_counts, e lookup_tx_context_public_inputs_l1_l2_tree_counts, e lookup_tx_context_public_inputs_gas_used_counts, e lookup_tx_context_public_inputs_read_gas_limit_counts, e lookup_tx_context_public_inputs_read_reverted_counts, e lookup_tx_context_restore_state_on_revert_counts, e lookup_tx_context_public_inputs_write_note_hash_count_counts, e lookup_tx_context_public_inputs_write_nullifier_count_counts, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_counts, e lookup_tx_context_public_inputs_write_public_log_count_counts, e lookup_tx_read_phase_spec_counts, e lookup_tx_read_phase_length_counts, e lookup_tx_read_public_call_request_phase_counts, e lookup_tx_read_tree_insert_value_counts, e lookup_tx_note_hash_append_counts, e lookup_tx_nullifier_append_counts, e lookup_tx_read_l2_l1_msg_counts, e lookup_tx_write_l2_l1_msg_counts, e lookup_tx_read_effective_fee_public_inputs_counts, e lookup_tx_read_fee_payer_public_inputs_counts, e lookup_tx_balance_slot_poseidon2_counts, e lookup_tx_balance_read_counts, e lookup_tx_balance_validation_counts, e lookup_tx_write_fee_public_inputs_counts, e bc_decomposition_bytes, e bc_decomposition_bytes_pc_plus_1, e bc_decomposition_bytes_pc_plus_10, e bc_decomposition_bytes_pc_plus_11, e bc_decomposition_bytes_pc_plus_12, e bc_decomposition_bytes_pc_plus_13, e bc_decomposition_bytes_pc_plus_14, e bc_decomposition_bytes_pc_plus_15, e bc_decomposition_bytes_pc_plus_16, e bc_decomposition_bytes_pc_plus_17, e bc_decomposition_bytes_pc_plus_18, e bc_decomposition_bytes_pc_plus_19, e bc_decomposition_bytes_pc_plus_2, e bc_decomposition_bytes_pc_plus_20, e bc_decomposition_bytes_pc_plus_21, e bc_decomposition_bytes_pc_plus_22, e bc_decomposition_bytes_pc_plus_23, e bc_decomposition_bytes_pc_plus_24, e bc_decomposition_bytes_pc_plus_25, e bc_decomposition_bytes_pc_plus_26, e bc_decomposition_bytes_pc_plus_27, e bc_decomposition_bytes_pc_plus_28, e bc_decomposition_bytes_pc_plus_29, e bc_decomposition_bytes_pc_plus_3, e bc_decomposition_bytes_pc_plus_30, e bc_decomposition_bytes_pc_plus_31, e bc_decomposition_bytes_pc_plus_32, e bc_decomposition_bytes_pc_plus_33, e bc_decomposition_bytes_pc_plus_34, e bc_decomposition_bytes_pc_plus_35, e bc_decomposition_bytes_pc_plus_4, e bc_decomposition_bytes_pc_plus_5, e bc_decomposition_bytes_pc_plus_6, e bc_decomposition_bytes_pc_plus_7, e bc_decomposition_bytes_pc_plus_8, e bc_decomposition_bytes_pc_plus_9, e bc_decomposition_bytes_remaining, e bc_decomposition_id, e bc_decomposition_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_windows_gt_remaining, e bc_decomposition_start, e bc_hashing_bytecode_id, e bc_hashing_padding, e bc_hashing_pc_index_1, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_sel_not_start, e bc_hashing_start, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e bitwise_sel, e bitwise_start, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_src_context_id, e data_copy_start, e emit_public_log_contract_address, e emit_public_log_correct_tag, e emit_public_log_error_out_of_bounds, e emit_public_log_error_tag_mismatch, e emit_public_log_execution_clk, e emit_public_log_is_write_contract_address, e emit_public_log_is_write_memory_value, e emit_public_log_log_address, e emit_public_log_public_inputs_index, e emit_public_log_remaining_rows, e emit_public_log_seen_wrong_tag, e emit_public_log_sel, e emit_public_log_sel_write_to_public_inputs, e emit_public_log_space_id, e emit_public_log_start, e execution_bytecode_id, e execution_clk, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_public_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_sel, e keccak_memory_space_id, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_start, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_address, e memory_clk, e memory_rw, e memory_sel, e memory_space_id, e memory_tag, e memory_value, e merkle_check_index, e merkle_check_merkle_hash_separator, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_start, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, e poseidon2_hash_a_0, e poseidon2_hash_a_1, e poseidon2_hash_a_2, e poseidon2_hash_a_3, e poseidon2_hash_input_0, e poseidon2_hash_input_1, e poseidon2_hash_input_2, e poseidon2_hash_num_perm_rounds_rem, e poseidon2_hash_output, e poseidon2_hash_sel, e poseidon2_hash_start, e public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, e scalar_mul_bit_idx, e scalar_mul_point_inf, e scalar_mul_point_x, e scalar_mul_point_y, e scalar_mul_res_inf, e scalar_mul_res_x, e scalar_mul_res_y, e scalar_mul_scalar, e scalar_mul_sel, e scalar_mul_start, e scalar_mul_temp_inf, e scalar_mul_temp_x, e scalar_mul_temp_y, e sha256_a, e sha256_b, e sha256_c, e sha256_d, e sha256_e, e sha256_execution_clk, e sha256_f, e sha256_g, e sha256_h, e sha256_helper_w0, e sha256_helper_w1, e sha256_helper_w10, e sha256_helper_w11, e sha256_helper_w12, e sha256_helper_w13, e sha256_helper_w14, e sha256_helper_w15, e sha256_helper_w2, e sha256_helper_w3, e sha256_helper_w4, e sha256_helper_w5, e sha256_helper_w6, e sha256_helper_w7, e sha256_helper_w8, e sha256_helper_w9, e sha256_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_power, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_public_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted +#define AVM2_DERIVED_WITNESS_ENTITIES_E(e) e perm_data_copy_mem_write_inv, e perm_data_copy_mem_read_inv, e perm_ecc_mem_write_mem_0_inv, e perm_ecc_mem_write_mem_1_inv, e perm_keccak_memory_slice_to_mem_inv, e perm_keccakf1600_read_to_slice_inv, e perm_keccakf1600_write_to_slice_inv, e perm_poseidon2_mem_pos_read_mem_0_inv, e perm_poseidon2_mem_pos_read_mem_1_inv, e perm_poseidon2_mem_pos_read_mem_2_inv, e perm_poseidon2_mem_pos_read_mem_3_inv, e perm_poseidon2_mem_pos_write_mem_0_inv, e perm_poseidon2_mem_pos_write_mem_1_inv, e perm_poseidon2_mem_pos_write_mem_2_inv, e perm_poseidon2_mem_pos_write_mem_3_inv, e perm_sha256_mem_mem_op_0_inv, e perm_sha256_mem_mem_op_1_inv, e perm_sha256_mem_mem_op_2_inv, e perm_sha256_mem_mem_op_3_inv, e perm_sha256_mem_mem_op_4_inv, e perm_sha256_mem_mem_op_5_inv, e perm_sha256_mem_mem_op_6_inv, e perm_sha256_mem_mem_op_7_inv, e perm_sha256_mem_mem_input_read_inv, e perm_to_radix_mem_write_mem_inv, e perm_bc_hashing_bytecode_length_bytes_inv, e perm_bc_hashing_get_packed_field_0_inv, e perm_bc_hashing_get_packed_field_1_inv, e perm_bc_hashing_get_packed_field_2_inv, e perm_public_data_check_squashing_inv, e perm_emit_public_log_read_mem_inv, e perm_get_contract_instance_mem_write_contract_instance_exists_inv, e perm_get_contract_instance_mem_write_contract_instance_member_inv, e perm_internal_call_push_call_stack_inv, e perm_context_ctx_stack_call_inv, e perm_addressing_base_address_from_memory_inv, e perm_addressing_indirect_from_memory_0_inv, e perm_addressing_indirect_from_memory_1_inv, e perm_addressing_indirect_from_memory_2_inv, e perm_addressing_indirect_from_memory_3_inv, e perm_addressing_indirect_from_memory_4_inv, e perm_addressing_indirect_from_memory_5_inv, e perm_addressing_indirect_from_memory_6_inv, e perm_registers_mem_op_0_inv, e perm_registers_mem_op_1_inv, e perm_registers_mem_op_2_inv, e perm_registers_mem_op_3_inv, e perm_registers_mem_op_4_inv, e perm_registers_mem_op_5_inv, e perm_sstore_storage_write_inv, e perm_execution_dispatch_to_cd_copy_inv, e perm_execution_dispatch_to_rd_copy_inv, e perm_execution_dispatch_to_get_contract_instance_inv, e perm_execution_dispatch_to_emit_public_log_inv, e perm_execution_dispatch_to_poseidon2_perm_inv, e perm_execution_dispatch_to_sha256_compression_inv, e perm_execution_dispatch_to_keccakf1600_inv, e perm_execution_dispatch_to_ecc_add_inv, e perm_execution_dispatch_to_to_radix_inv, e perm_calldata_hashing_check_final_size_inv, e perm_tx_read_calldata_hash_inv, e perm_tx_dispatch_exec_start_inv, e perm_tx_dispatch_exec_end_inv, e perm_tx_balance_update_inv, e lookup_range_check_dyn_rng_chk_pow_2_inv, e lookup_range_check_dyn_diff_is_u16_inv, e lookup_range_check_r0_is_u16_inv, e lookup_range_check_r1_is_u16_inv, e lookup_range_check_r2_is_u16_inv, e lookup_range_check_r3_is_u16_inv, e lookup_range_check_r4_is_u16_inv, e lookup_range_check_r5_is_u16_inv, e lookup_range_check_r6_is_u16_inv, e lookup_range_check_r7_is_u16_inv, e lookup_ff_gt_a_lo_range_inv, e lookup_ff_gt_a_hi_range_inv, e lookup_gt_gt_range_inv, e lookup_alu_tag_max_bits_value_inv, e lookup_alu_range_check_decomposition_a_lo_inv, e lookup_alu_range_check_decomposition_a_hi_inv, e lookup_alu_range_check_decomposition_b_lo_inv, e lookup_alu_range_check_decomposition_b_hi_inv, e lookup_alu_range_check_mul_c_hi_inv, e lookup_alu_range_check_div_remainder_inv, e lookup_alu_ff_gt_inv, e lookup_alu_int_gt_inv, e lookup_alu_shifts_two_pow_inv, e lookup_alu_large_trunc_canonical_dec_inv, e lookup_alu_range_check_trunc_mid_inv, e lookup_bitwise_integral_tag_length_inv, e lookup_bitwise_byte_operations_inv, e lookup_memory_range_check_limb_0_inv, e lookup_memory_range_check_limb_1_inv, e lookup_memory_range_check_limb_2_inv, e lookup_memory_tag_max_bits_inv, e lookup_memory_range_check_write_tagged_value_inv, e lookup_data_copy_offset_plus_size_is_gt_data_size_inv, e lookup_data_copy_check_src_addr_in_range_inv, e lookup_data_copy_check_dst_addr_in_range_inv, e lookup_data_copy_sel_has_reads_inv, e lookup_data_copy_col_read_inv, e lookup_ecc_mem_check_dst_addr_in_range_inv, e lookup_ecc_mem_input_output_ecc_add_inv, e lookup_keccakf1600_theta_xor_01_inv, e lookup_keccakf1600_theta_xor_02_inv, e lookup_keccakf1600_theta_xor_03_inv, e lookup_keccakf1600_theta_xor_row_0_inv, e lookup_keccakf1600_theta_xor_11_inv, e lookup_keccakf1600_theta_xor_12_inv, e lookup_keccakf1600_theta_xor_13_inv, e lookup_keccakf1600_theta_xor_row_1_inv, e lookup_keccakf1600_theta_xor_21_inv, e lookup_keccakf1600_theta_xor_22_inv, e lookup_keccakf1600_theta_xor_23_inv, e lookup_keccakf1600_theta_xor_row_2_inv, e lookup_keccakf1600_theta_xor_31_inv, e lookup_keccakf1600_theta_xor_32_inv, e lookup_keccakf1600_theta_xor_33_inv, e lookup_keccakf1600_theta_xor_row_3_inv, e lookup_keccakf1600_theta_xor_41_inv, e lookup_keccakf1600_theta_xor_42_inv, e lookup_keccakf1600_theta_xor_43_inv, e lookup_keccakf1600_theta_xor_row_4_inv, e lookup_keccakf1600_theta_combined_xor_0_inv, e lookup_keccakf1600_theta_combined_xor_1_inv, e lookup_keccakf1600_theta_combined_xor_2_inv, e lookup_keccakf1600_theta_combined_xor_3_inv, e lookup_keccakf1600_theta_combined_xor_4_inv, e lookup_keccakf1600_state_theta_00_inv, e lookup_keccakf1600_state_theta_01_inv, e lookup_keccakf1600_state_theta_02_inv, e lookup_keccakf1600_state_theta_03_inv, e lookup_keccakf1600_state_theta_04_inv, e lookup_keccakf1600_state_theta_10_inv, e lookup_keccakf1600_state_theta_11_inv, e lookup_keccakf1600_state_theta_12_inv, e lookup_keccakf1600_state_theta_13_inv, e lookup_keccakf1600_state_theta_14_inv, e lookup_keccakf1600_state_theta_20_inv, e lookup_keccakf1600_state_theta_21_inv, e lookup_keccakf1600_state_theta_22_inv, e lookup_keccakf1600_state_theta_23_inv, e lookup_keccakf1600_state_theta_24_inv, e lookup_keccakf1600_state_theta_30_inv, e lookup_keccakf1600_state_theta_31_inv, e lookup_keccakf1600_state_theta_32_inv, e lookup_keccakf1600_state_theta_33_inv, e lookup_keccakf1600_state_theta_34_inv, e lookup_keccakf1600_state_theta_40_inv, e lookup_keccakf1600_state_theta_41_inv, e lookup_keccakf1600_state_theta_42_inv, e lookup_keccakf1600_state_theta_43_inv, e lookup_keccakf1600_state_theta_44_inv, e lookup_keccakf1600_theta_limb_02_range_inv, e lookup_keccakf1600_theta_limb_04_range_inv, e lookup_keccakf1600_theta_limb_10_range_inv, e lookup_keccakf1600_theta_limb_12_range_inv, e lookup_keccakf1600_theta_limb_14_range_inv, e lookup_keccakf1600_theta_limb_21_range_inv, e lookup_keccakf1600_theta_limb_23_range_inv, e lookup_keccakf1600_theta_limb_30_range_inv, e lookup_keccakf1600_theta_limb_32_range_inv, e lookup_keccakf1600_theta_limb_33_range_inv, e lookup_keccakf1600_theta_limb_40_range_inv, e lookup_keccakf1600_theta_limb_41_range_inv, e lookup_keccakf1600_theta_limb_43_range_inv, e lookup_keccakf1600_theta_limb_44_range_inv, e lookup_keccakf1600_theta_limb_01_range_inv, e lookup_keccakf1600_theta_limb_03_range_inv, e lookup_keccakf1600_theta_limb_11_range_inv, e lookup_keccakf1600_theta_limb_13_range_inv, e lookup_keccakf1600_theta_limb_20_range_inv, e lookup_keccakf1600_theta_limb_22_range_inv, e lookup_keccakf1600_theta_limb_24_range_inv, e lookup_keccakf1600_theta_limb_31_range_inv, e lookup_keccakf1600_theta_limb_34_range_inv, e lookup_keccakf1600_theta_limb_42_range_inv, e lookup_keccakf1600_state_pi_and_00_inv, e lookup_keccakf1600_state_pi_and_01_inv, e lookup_keccakf1600_state_pi_and_02_inv, e lookup_keccakf1600_state_pi_and_03_inv, e lookup_keccakf1600_state_pi_and_04_inv, e lookup_keccakf1600_state_pi_and_10_inv, e lookup_keccakf1600_state_pi_and_11_inv, e lookup_keccakf1600_state_pi_and_12_inv, e lookup_keccakf1600_state_pi_and_13_inv, e lookup_keccakf1600_state_pi_and_14_inv, e lookup_keccakf1600_state_pi_and_20_inv, e lookup_keccakf1600_state_pi_and_21_inv, e lookup_keccakf1600_state_pi_and_22_inv, e lookup_keccakf1600_state_pi_and_23_inv, e lookup_keccakf1600_state_pi_and_24_inv, e lookup_keccakf1600_state_pi_and_30_inv, e lookup_keccakf1600_state_pi_and_31_inv, e lookup_keccakf1600_state_pi_and_32_inv, e lookup_keccakf1600_state_pi_and_33_inv, e lookup_keccakf1600_state_pi_and_34_inv, e lookup_keccakf1600_state_pi_and_40_inv, e lookup_keccakf1600_state_pi_and_41_inv, e lookup_keccakf1600_state_pi_and_42_inv, e lookup_keccakf1600_state_pi_and_43_inv, e lookup_keccakf1600_state_pi_and_44_inv, e lookup_keccakf1600_state_chi_00_inv, e lookup_keccakf1600_state_chi_01_inv, e lookup_keccakf1600_state_chi_02_inv, e lookup_keccakf1600_state_chi_03_inv, e lookup_keccakf1600_state_chi_04_inv, e lookup_keccakf1600_state_chi_10_inv, e lookup_keccakf1600_state_chi_11_inv, e lookup_keccakf1600_state_chi_12_inv, e lookup_keccakf1600_state_chi_13_inv, e lookup_keccakf1600_state_chi_14_inv, e lookup_keccakf1600_state_chi_20_inv, e lookup_keccakf1600_state_chi_21_inv, e lookup_keccakf1600_state_chi_22_inv, e lookup_keccakf1600_state_chi_23_inv, e lookup_keccakf1600_state_chi_24_inv, e lookup_keccakf1600_state_chi_30_inv, e lookup_keccakf1600_state_chi_31_inv, e lookup_keccakf1600_state_chi_32_inv, e lookup_keccakf1600_state_chi_33_inv, e lookup_keccakf1600_state_chi_34_inv, e lookup_keccakf1600_state_chi_40_inv, e lookup_keccakf1600_state_chi_41_inv, e lookup_keccakf1600_state_chi_42_inv, e lookup_keccakf1600_state_chi_43_inv, e lookup_keccakf1600_state_chi_44_inv, e lookup_keccakf1600_round_cst_inv, e lookup_keccakf1600_state_iota_00_inv, e lookup_keccakf1600_src_out_of_range_toggle_inv, e lookup_keccakf1600_dst_out_of_range_toggle_inv, e lookup_poseidon2_mem_check_src_addr_in_range_inv, e lookup_poseidon2_mem_check_dst_addr_in_range_inv, e lookup_poseidon2_mem_input_output_poseidon2_perm_inv, e lookup_to_radix_limb_range_inv, e lookup_to_radix_limb_less_than_radix_range_inv, e lookup_to_radix_fetch_safe_limbs_inv, e lookup_to_radix_fetch_p_limb_inv, e lookup_to_radix_limb_p_diff_range_inv, e lookup_scalar_mul_to_radix_inv, e lookup_scalar_mul_double_inv, e lookup_scalar_mul_add_inv, e lookup_sha256_range_comp_w_lhs_inv, e lookup_sha256_range_comp_w_rhs_inv, e lookup_sha256_range_rhs_w_7_inv, e lookup_sha256_range_rhs_w_18_inv, e lookup_sha256_range_rhs_w_3_inv, e lookup_sha256_w_s_0_xor_0_inv, e lookup_sha256_w_s_0_xor_1_inv, e lookup_sha256_range_rhs_w_17_inv, e lookup_sha256_range_rhs_w_19_inv, e lookup_sha256_range_rhs_w_10_inv, e lookup_sha256_w_s_1_xor_0_inv, e lookup_sha256_w_s_1_xor_1_inv, e lookup_sha256_range_rhs_e_6_inv, e lookup_sha256_range_rhs_e_11_inv, e lookup_sha256_range_rhs_e_25_inv, e lookup_sha256_s_1_xor_0_inv, e lookup_sha256_s_1_xor_1_inv, e lookup_sha256_ch_and_0_inv, e lookup_sha256_ch_and_1_inv, e lookup_sha256_ch_xor_inv, e lookup_sha256_round_constant_inv, e lookup_sha256_range_rhs_a_2_inv, e lookup_sha256_range_rhs_a_13_inv, e lookup_sha256_range_rhs_a_22_inv, e lookup_sha256_s_0_xor_0_inv, e lookup_sha256_s_0_xor_1_inv, e lookup_sha256_maj_and_0_inv, e lookup_sha256_maj_and_1_inv, e lookup_sha256_maj_and_2_inv, e lookup_sha256_maj_xor_0_inv, e lookup_sha256_maj_xor_1_inv, e lookup_sha256_range_comp_next_a_lhs_inv, e lookup_sha256_range_comp_next_a_rhs_inv, e lookup_sha256_range_comp_next_e_lhs_inv, e lookup_sha256_range_comp_next_e_rhs_inv, e lookup_sha256_range_comp_a_rhs_inv, e lookup_sha256_range_comp_b_rhs_inv, e lookup_sha256_range_comp_c_rhs_inv, e lookup_sha256_range_comp_d_rhs_inv, e lookup_sha256_range_comp_e_rhs_inv, e lookup_sha256_range_comp_f_rhs_inv, e lookup_sha256_range_comp_g_rhs_inv, e lookup_sha256_range_comp_h_rhs_inv, e lookup_sha256_mem_check_state_addr_in_range_inv, e lookup_sha256_mem_check_input_addr_in_range_inv, e lookup_sha256_mem_check_output_addr_in_range_inv, e lookup_to_radix_mem_check_dst_addr_in_range_inv, e lookup_to_radix_mem_check_radix_lt_2_inv, e lookup_to_radix_mem_check_radix_gt_256_inv, e lookup_to_radix_mem_input_output_to_radix_inv, e lookup_poseidon2_hash_poseidon2_perm_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv, e lookup_address_derivation_partial_address_poseidon2_inv, e lookup_address_derivation_ivpk_m_hash_poseidon2_inv, e lookup_address_derivation_public_keys_hash_poseidon2_0_inv, e lookup_address_derivation_public_keys_hash_poseidon2_1_inv, e lookup_address_derivation_preaddress_poseidon2_inv, e lookup_address_derivation_preaddress_scalar_mul_inv, e lookup_address_derivation_address_ecadd_inv, e lookup_bc_decomposition_bytes_are_bytes_inv, e lookup_bc_hashing_poseidon2_hash_inv, e lookup_merkle_check_merkle_poseidon2_read_inv, e lookup_merkle_check_merkle_poseidon2_write_inv, e lookup_indexed_tree_check_silo_poseidon2_inv, e lookup_indexed_tree_check_low_leaf_value_validation_inv, e lookup_indexed_tree_check_low_leaf_next_value_validation_inv, e lookup_indexed_tree_check_low_leaf_poseidon2_inv, e lookup_indexed_tree_check_updated_low_leaf_poseidon2_inv, e lookup_indexed_tree_check_low_leaf_merkle_check_inv, e lookup_indexed_tree_check_new_leaf_poseidon2_inv, e lookup_indexed_tree_check_new_leaf_merkle_check_inv, e lookup_indexed_tree_check_write_value_to_public_inputs_inv, e lookup_public_data_squash_leaf_slot_increase_ff_gt_inv, e lookup_public_data_squash_clk_diff_range_lo_inv, e lookup_public_data_squash_clk_diff_range_hi_inv, e lookup_public_data_check_clk_diff_range_lo_inv, e lookup_public_data_check_clk_diff_range_hi_inv, e lookup_public_data_check_silo_poseidon2_inv, e lookup_public_data_check_low_leaf_slot_validation_inv, e lookup_public_data_check_low_leaf_next_slot_validation_inv, e lookup_public_data_check_low_leaf_poseidon2_0_inv, e lookup_public_data_check_low_leaf_poseidon2_1_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_0_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_1_inv, e lookup_public_data_check_low_leaf_merkle_check_inv, e lookup_public_data_check_new_leaf_poseidon2_0_inv, e lookup_public_data_check_new_leaf_poseidon2_1_inv, e lookup_public_data_check_new_leaf_merkle_check_inv, e lookup_public_data_check_write_public_data_to_public_inputs_inv, e lookup_public_data_check_write_writes_length_to_public_inputs_inv, e lookup_update_check_timestamp_from_public_inputs_inv, e lookup_update_check_delayed_public_mutable_slot_poseidon2_inv, e lookup_update_check_update_hash_public_data_read_inv, e lookup_update_check_update_hash_poseidon2_inv, e lookup_update_check_update_hi_metadata_range_inv, e lookup_update_check_update_lo_metadata_range_inv, e lookup_update_check_timestamp_is_lt_timestamp_of_change_inv, e lookup_contract_instance_retrieval_check_protocol_address_range_inv, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_inv, e lookup_contract_instance_retrieval_deployment_nullifier_read_inv, e lookup_contract_instance_retrieval_address_derivation_inv, e lookup_contract_instance_retrieval_update_check_inv, e lookup_class_id_derivation_class_id_poseidon2_0_inv, e lookup_class_id_derivation_class_id_poseidon2_1_inv, e lookup_bc_retrieval_contract_instance_retrieval_inv, e lookup_bc_retrieval_class_id_derivation_inv, e lookup_bc_retrieval_is_new_class_check_inv, e lookup_bc_retrieval_retrieved_bytecodes_insertion_inv, e lookup_instr_fetching_pc_abs_diff_positive_inv, e lookup_instr_fetching_instr_abs_diff_positive_inv, e lookup_instr_fetching_tag_value_validation_inv, e lookup_instr_fetching_bytecode_size_from_bc_dec_inv, e lookup_instr_fetching_bytes_from_bc_dec_inv, e lookup_instr_fetching_wire_instruction_info_inv, e lookup_emit_public_log_check_memory_out_of_bounds_inv, e lookup_emit_public_log_check_log_fields_count_inv, e lookup_emit_public_log_write_data_to_public_inputs_inv, e lookup_get_contract_instance_precomputed_info_inv, e lookup_get_contract_instance_contract_instance_retrieval_inv, e lookup_l1_to_l2_message_tree_check_merkle_check_inv, e lookup_internal_call_unwind_call_stack_inv, e lookup_context_ctx_stack_rollback_inv, e lookup_context_ctx_stack_return_inv, e lookup_addressing_relative_overflow_result_0_inv, e lookup_addressing_relative_overflow_result_1_inv, e lookup_addressing_relative_overflow_result_2_inv, e lookup_addressing_relative_overflow_result_3_inv, e lookup_addressing_relative_overflow_result_4_inv, e lookup_addressing_relative_overflow_result_5_inv, e lookup_addressing_relative_overflow_result_6_inv, e lookup_gas_addressing_gas_read_inv, e lookup_gas_is_out_of_gas_l2_inv, e lookup_gas_is_out_of_gas_da_inv, e lookup_note_hash_tree_check_silo_poseidon2_inv, e lookup_note_hash_tree_check_read_first_nullifier_inv, e lookup_note_hash_tree_check_nonce_computation_poseidon2_inv, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_inv, e lookup_note_hash_tree_check_merkle_check_inv, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_inv, e lookup_emit_notehash_notehash_tree_write_inv, e lookup_emit_nullifier_write_nullifier_inv, e lookup_external_call_is_l2_gas_left_gt_allocated_inv, e lookup_external_call_is_da_gas_left_gt_allocated_inv, e lookup_get_env_var_precomputed_info_inv, e lookup_get_env_var_read_from_public_inputs_col0_inv, e lookup_get_env_var_read_from_public_inputs_col1_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_inv, e lookup_notehash_exists_note_hash_leaf_index_in_range_inv, e lookup_notehash_exists_note_hash_read_inv, e lookup_nullifier_exists_nullifier_exists_check_inv, e lookup_send_l2_to_l1_msg_recipient_check_inv, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_inv, e lookup_sload_storage_read_inv, e lookup_sstore_record_written_storage_slot_inv, e lookup_execution_bytecode_retrieval_result_inv, e lookup_execution_instruction_fetching_result_inv, e lookup_execution_instruction_fetching_body_inv, e lookup_execution_exec_spec_read_inv, e lookup_execution_dyn_l2_factor_bitwise_inv, e lookup_execution_check_radix_gt_256_inv, e lookup_execution_get_p_limbs_inv, e lookup_execution_get_max_limbs_inv, e lookup_execution_check_written_storage_slot_inv, e lookup_execution_dispatch_to_alu_inv, e lookup_execution_dispatch_to_bitwise_inv, e lookup_execution_dispatch_to_cast_inv, e lookup_execution_dispatch_to_set_inv, e lookup_calldata_hashing_get_calldata_field_0_inv, e lookup_calldata_hashing_get_calldata_field_1_inv, e lookup_calldata_hashing_get_calldata_field_2_inv, e lookup_calldata_hashing_poseidon2_hash_inv, e lookup_tx_context_public_inputs_note_hash_tree_inv, e lookup_tx_context_public_inputs_nullifier_tree_inv, e lookup_tx_context_public_inputs_public_data_tree_inv, e lookup_tx_context_public_inputs_l1_l2_tree_inv, e lookup_tx_context_public_inputs_gas_used_inv, e lookup_tx_context_public_inputs_read_gas_limit_inv, e lookup_tx_context_public_inputs_read_reverted_inv, e lookup_tx_context_restore_state_on_revert_inv, e lookup_tx_context_public_inputs_write_note_hash_count_inv, e lookup_tx_context_public_inputs_write_nullifier_count_inv, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_inv, e lookup_tx_context_public_inputs_write_public_log_count_inv, e lookup_tx_read_phase_spec_inv, e lookup_tx_read_phase_length_inv, e lookup_tx_read_public_call_request_phase_inv, e lookup_tx_read_tree_insert_value_inv, e lookup_tx_note_hash_append_inv, e lookup_tx_nullifier_append_inv, e lookup_tx_read_l2_l1_msg_inv, e lookup_tx_write_l2_l1_msg_inv, e lookup_tx_read_effective_fee_public_inputs_inv, e lookup_tx_read_fee_payer_public_inputs_inv, e lookup_tx_balance_slot_poseidon2_inv, e lookup_tx_balance_read_inv, e lookup_tx_balance_validation_inv, e lookup_tx_write_fee_public_inputs_inv #define AVM2_SHIFTED_ENTITIES_E(e) e bc_decomposition_bytes_shift, e bc_decomposition_bytes_pc_plus_1_shift, e bc_decomposition_bytes_pc_plus_10_shift, e bc_decomposition_bytes_pc_plus_11_shift, e bc_decomposition_bytes_pc_plus_12_shift, e bc_decomposition_bytes_pc_plus_13_shift, e bc_decomposition_bytes_pc_plus_14_shift, e bc_decomposition_bytes_pc_plus_15_shift, e bc_decomposition_bytes_pc_plus_16_shift, e bc_decomposition_bytes_pc_plus_17_shift, e bc_decomposition_bytes_pc_plus_18_shift, e bc_decomposition_bytes_pc_plus_19_shift, e bc_decomposition_bytes_pc_plus_2_shift, e bc_decomposition_bytes_pc_plus_20_shift, e bc_decomposition_bytes_pc_plus_21_shift, e bc_decomposition_bytes_pc_plus_22_shift, e bc_decomposition_bytes_pc_plus_23_shift, e bc_decomposition_bytes_pc_plus_24_shift, e bc_decomposition_bytes_pc_plus_25_shift, e bc_decomposition_bytes_pc_plus_26_shift, e bc_decomposition_bytes_pc_plus_27_shift, e bc_decomposition_bytes_pc_plus_28_shift, e bc_decomposition_bytes_pc_plus_29_shift, e bc_decomposition_bytes_pc_plus_3_shift, e bc_decomposition_bytes_pc_plus_30_shift, e bc_decomposition_bytes_pc_plus_31_shift, e bc_decomposition_bytes_pc_plus_32_shift, e bc_decomposition_bytes_pc_plus_33_shift, e bc_decomposition_bytes_pc_plus_34_shift, e bc_decomposition_bytes_pc_plus_35_shift, e bc_decomposition_bytes_pc_plus_4_shift, e bc_decomposition_bytes_pc_plus_5_shift, e bc_decomposition_bytes_pc_plus_6_shift, e bc_decomposition_bytes_pc_plus_7_shift, e bc_decomposition_bytes_pc_plus_8_shift, e bc_decomposition_bytes_pc_plus_9_shift, e bc_decomposition_bytes_remaining_shift, e bc_decomposition_id_shift, e bc_decomposition_next_packed_pc_shift, e bc_decomposition_pc_shift, e bc_decomposition_sel_shift, e bc_decomposition_sel_windows_gt_remaining_shift, e bc_decomposition_start_shift, e bc_hashing_bytecode_id_shift, e bc_hashing_padding_shift, e bc_hashing_pc_index_1_shift, e bc_hashing_rounds_rem_shift, e bc_hashing_sel_shift, e bc_hashing_sel_not_start_shift, e bc_hashing_start_shift, e bitwise_acc_ia_shift, e bitwise_acc_ib_shift, e bitwise_acc_ic_shift, e bitwise_ctr_shift, e bitwise_op_id_shift, e bitwise_sel_shift, e bitwise_start_shift, e calldata_context_id_shift, e calldata_hashing_calldata_size_shift, e calldata_hashing_context_id_shift, e calldata_hashing_index_0__shift, e calldata_hashing_output_hash_shift, e calldata_hashing_rounds_rem_shift, e calldata_hashing_sel_shift, e calldata_hashing_start_shift, e calldata_index_shift, e calldata_sel_shift, e data_copy_clk_shift, e data_copy_copy_size_shift, e data_copy_dst_addr_shift, e data_copy_dst_context_id_shift, e data_copy_padding_shift, e data_copy_read_addr_shift, e data_copy_reads_left_shift, e data_copy_sel_shift, e data_copy_sel_cd_copy_shift, e data_copy_src_context_id_shift, e data_copy_start_shift, e emit_public_log_contract_address_shift, e emit_public_log_correct_tag_shift, e emit_public_log_error_out_of_bounds_shift, e emit_public_log_error_tag_mismatch_shift, e emit_public_log_execution_clk_shift, e emit_public_log_is_write_contract_address_shift, e emit_public_log_is_write_memory_value_shift, e emit_public_log_log_address_shift, e emit_public_log_public_inputs_index_shift, e emit_public_log_remaining_rows_shift, e emit_public_log_seen_wrong_tag_shift, e emit_public_log_sel_shift, e emit_public_log_sel_write_to_public_inputs_shift, e emit_public_log_space_id_shift, e emit_public_log_start_shift, e execution_bytecode_id_shift, e execution_clk_shift, e execution_context_id_shift, e execution_contract_address_shift, e execution_da_gas_limit_shift, e execution_discard_shift, e execution_dying_context_id_shift, e execution_enqueued_call_start_shift, e execution_internal_call_id_shift, e execution_internal_call_return_id_shift, e execution_is_static_shift, e execution_l1_l2_tree_root_shift, e execution_l2_gas_limit_shift, e execution_last_child_id_shift, e execution_last_child_returndata_addr_shift, e execution_last_child_returndata_size_shift, e execution_last_child_success_shift, e execution_msg_sender_shift, e execution_next_context_id_shift, e execution_next_internal_call_id_shift, e execution_parent_calldata_addr_shift, e execution_parent_calldata_size_shift, e execution_parent_da_gas_limit_shift, e execution_parent_da_gas_used_shift, e execution_parent_id_shift, e execution_parent_l2_gas_limit_shift, e execution_parent_l2_gas_used_shift, e execution_pc_shift, e execution_prev_da_gas_used_shift, e execution_prev_l2_gas_used_shift, e execution_prev_note_hash_tree_root_shift, e execution_prev_note_hash_tree_size_shift, e execution_prev_nullifier_tree_root_shift, e execution_prev_nullifier_tree_size_shift, e execution_prev_num_l2_to_l1_messages_shift, e execution_prev_num_note_hashes_emitted_shift, e execution_prev_num_nullifiers_emitted_shift, e execution_prev_num_public_log_fields_shift, e execution_prev_public_data_tree_root_shift, e execution_prev_public_data_tree_size_shift, e execution_prev_retrieved_bytecodes_tree_root_shift, e execution_prev_retrieved_bytecodes_tree_size_shift, e execution_prev_written_public_data_slots_tree_root_shift, e execution_prev_written_public_data_slots_tree_size_shift, e execution_sel_shift, e execution_sel_first_row_in_context_shift, e execution_transaction_fee_shift, e ff_gt_a_hi_shift, e ff_gt_a_lo_shift, e ff_gt_b_hi_shift, e ff_gt_b_lo_shift, e ff_gt_cmp_rng_ctr_shift, e ff_gt_p_sub_a_hi_shift, e ff_gt_p_sub_a_lo_shift, e ff_gt_p_sub_b_hi_shift, e ff_gt_p_sub_b_lo_shift, e ff_gt_sel_shift, e ff_gt_sel_dec_shift, e ff_gt_sel_gt_shift, e keccak_memory_addr_shift, e keccak_memory_clk_shift, e keccak_memory_ctr_shift, e keccak_memory_rw_shift, e keccak_memory_sel_shift, e keccak_memory_space_id_shift, e keccak_memory_start_read_shift, e keccak_memory_start_write_shift, e keccak_memory_tag_error_shift, e keccak_memory_val_0__shift, e keccak_memory_val_10__shift, e keccak_memory_val_11__shift, e keccak_memory_val_12__shift, e keccak_memory_val_13__shift, e keccak_memory_val_14__shift, e keccak_memory_val_15__shift, e keccak_memory_val_16__shift, e keccak_memory_val_17__shift, e keccak_memory_val_18__shift, e keccak_memory_val_19__shift, e keccak_memory_val_1__shift, e keccak_memory_val_20__shift, e keccak_memory_val_21__shift, e keccak_memory_val_22__shift, e keccak_memory_val_23__shift, e keccak_memory_val_2__shift, e keccak_memory_val_3__shift, e keccak_memory_val_4__shift, e keccak_memory_val_5__shift, e keccak_memory_val_6__shift, e keccak_memory_val_7__shift, e keccak_memory_val_8__shift, e keccak_memory_val_9__shift, e keccakf1600_clk_shift, e keccakf1600_dst_addr_shift, e keccakf1600_round_shift, e keccakf1600_sel_shift, e keccakf1600_sel_no_error_shift, e keccakf1600_space_id_shift, e keccakf1600_start_shift, e keccakf1600_state_in_00_shift, e keccakf1600_state_in_01_shift, e keccakf1600_state_in_02_shift, e keccakf1600_state_in_03_shift, e keccakf1600_state_in_04_shift, e keccakf1600_state_in_10_shift, e keccakf1600_state_in_11_shift, e keccakf1600_state_in_12_shift, e keccakf1600_state_in_13_shift, e keccakf1600_state_in_14_shift, e keccakf1600_state_in_20_shift, e keccakf1600_state_in_21_shift, e keccakf1600_state_in_22_shift, e keccakf1600_state_in_23_shift, e keccakf1600_state_in_24_shift, e keccakf1600_state_in_30_shift, e keccakf1600_state_in_31_shift, e keccakf1600_state_in_32_shift, e keccakf1600_state_in_33_shift, e keccakf1600_state_in_34_shift, e keccakf1600_state_in_40_shift, e keccakf1600_state_in_41_shift, e keccakf1600_state_in_42_shift, e keccakf1600_state_in_43_shift, e keccakf1600_state_in_44_shift, e memory_address_shift, e memory_clk_shift, e memory_rw_shift, e memory_sel_shift, e memory_space_id_shift, e memory_tag_shift, e memory_value_shift, e merkle_check_index_shift, e merkle_check_merkle_hash_separator_shift, e merkle_check_path_len_shift, e merkle_check_read_node_shift, e merkle_check_read_root_shift, e merkle_check_sel_shift, e merkle_check_start_shift, e merkle_check_write_shift, e merkle_check_write_node_shift, e merkle_check_write_root_shift, e poseidon2_hash_a_0_shift, e poseidon2_hash_a_1_shift, e poseidon2_hash_a_2_shift, e poseidon2_hash_a_3_shift, e poseidon2_hash_input_0_shift, e poseidon2_hash_input_1_shift, e poseidon2_hash_input_2_shift, e poseidon2_hash_num_perm_rounds_rem_shift, e poseidon2_hash_output_shift, e poseidon2_hash_sel_shift, e poseidon2_hash_start_shift, e public_data_check_clk_shift, e public_data_check_sel_shift, e public_data_check_write_idx_shift, e public_data_squash_clk_shift, e public_data_squash_final_value_shift, e public_data_squash_leaf_slot_shift, e public_data_squash_sel_shift, e public_data_squash_write_to_public_inputs_shift, e scalar_mul_bit_idx_shift, e scalar_mul_point_inf_shift, e scalar_mul_point_x_shift, e scalar_mul_point_y_shift, e scalar_mul_res_inf_shift, e scalar_mul_res_x_shift, e scalar_mul_res_y_shift, e scalar_mul_scalar_shift, e scalar_mul_sel_shift, e scalar_mul_start_shift, e scalar_mul_temp_inf_shift, e scalar_mul_temp_x_shift, e scalar_mul_temp_y_shift, e sha256_a_shift, e sha256_b_shift, e sha256_c_shift, e sha256_d_shift, e sha256_e_shift, e sha256_execution_clk_shift, e sha256_f_shift, e sha256_g_shift, e sha256_h_shift, e sha256_helper_w0_shift, e sha256_helper_w1_shift, e sha256_helper_w10_shift, e sha256_helper_w11_shift, e sha256_helper_w12_shift, e sha256_helper_w13_shift, e sha256_helper_w14_shift, e sha256_helper_w15_shift, e sha256_helper_w2_shift, e sha256_helper_w3_shift, e sha256_helper_w4_shift, e sha256_helper_w5_shift, e sha256_helper_w6_shift, e sha256_helper_w7_shift, e sha256_helper_w8_shift, e sha256_helper_w9_shift, e sha256_init_a_shift, e sha256_init_b_shift, e sha256_init_c_shift, e sha256_init_d_shift, e sha256_init_e_shift, e sha256_init_f_shift, e sha256_init_g_shift, e sha256_init_h_shift, e sha256_input_addr_shift, e sha256_input_rounds_rem_shift, e sha256_output_addr_shift, e sha256_rounds_remaining_shift, e sha256_sel_shift, e sha256_sel_invalid_input_tag_err_shift, e sha256_space_id_shift, e sha256_start_shift, e to_radix_acc_shift, e to_radix_acc_under_p_shift, e to_radix_limb_shift, e to_radix_limb_eq_p_shift, e to_radix_limb_index_shift, e to_radix_limb_lt_p_shift, e to_radix_mem_dst_addr_shift, e to_radix_mem_execution_clk_shift, e to_radix_mem_is_output_bits_shift, e to_radix_mem_num_limbs_shift, e to_radix_mem_radix_shift, e to_radix_mem_sel_shift, e to_radix_mem_sel_should_decompose_shift, e to_radix_mem_sel_should_write_mem_shift, e to_radix_mem_space_id_shift, e to_radix_mem_start_shift, e to_radix_mem_value_to_decompose_shift, e to_radix_not_padding_limb_shift, e to_radix_power_shift, e to_radix_radix_shift, e to_radix_safe_limbs_shift, e to_radix_sel_shift, e to_radix_start_shift, e to_radix_value_shift, e tx_da_gas_limit_shift, e tx_discard_shift, e tx_fee_shift, e tx_is_revertible_shift, e tx_is_teardown_shift, e tx_l1_l2_tree_root_shift, e tx_l1_l2_tree_size_shift, e tx_l2_gas_limit_shift, e tx_next_context_id_shift, e tx_phase_value_shift, e tx_prev_da_gas_used_shift, e tx_prev_l2_gas_used_shift, e tx_prev_note_hash_tree_root_shift, e tx_prev_note_hash_tree_size_shift, e tx_prev_nullifier_tree_root_shift, e tx_prev_nullifier_tree_size_shift, e tx_prev_num_l2_to_l1_messages_shift, e tx_prev_num_note_hashes_emitted_shift, e tx_prev_num_nullifiers_emitted_shift, e tx_prev_num_public_log_fields_shift, e tx_prev_public_data_tree_root_shift, e tx_prev_public_data_tree_size_shift, e tx_prev_retrieved_bytecodes_tree_root_shift, e tx_prev_retrieved_bytecodes_tree_size_shift, e tx_prev_written_public_data_slots_tree_root_shift, e tx_prev_written_public_data_slots_tree_size_shift, e tx_read_pi_offset_shift, e tx_remaining_phase_counter_shift, e tx_reverted_shift, e tx_sel_shift, e tx_start_phase_shift, e tx_start_tx_shift, e tx_tx_reverted_shift #define AVM2_TO_BE_SHIFTED_E(e) e bc_decomposition_bytes, e bc_decomposition_bytes_pc_plus_1, e bc_decomposition_bytes_pc_plus_10, e bc_decomposition_bytes_pc_plus_11, e bc_decomposition_bytes_pc_plus_12, e bc_decomposition_bytes_pc_plus_13, e bc_decomposition_bytes_pc_plus_14, e bc_decomposition_bytes_pc_plus_15, e bc_decomposition_bytes_pc_plus_16, e bc_decomposition_bytes_pc_plus_17, e bc_decomposition_bytes_pc_plus_18, e bc_decomposition_bytes_pc_plus_19, e bc_decomposition_bytes_pc_plus_2, e bc_decomposition_bytes_pc_plus_20, e bc_decomposition_bytes_pc_plus_21, e bc_decomposition_bytes_pc_plus_22, e bc_decomposition_bytes_pc_plus_23, e bc_decomposition_bytes_pc_plus_24, e bc_decomposition_bytes_pc_plus_25, e bc_decomposition_bytes_pc_plus_26, e bc_decomposition_bytes_pc_plus_27, e bc_decomposition_bytes_pc_plus_28, e bc_decomposition_bytes_pc_plus_29, e bc_decomposition_bytes_pc_plus_3, e bc_decomposition_bytes_pc_plus_30, e bc_decomposition_bytes_pc_plus_31, e bc_decomposition_bytes_pc_plus_32, e bc_decomposition_bytes_pc_plus_33, e bc_decomposition_bytes_pc_plus_34, e bc_decomposition_bytes_pc_plus_35, e bc_decomposition_bytes_pc_plus_4, e bc_decomposition_bytes_pc_plus_5, e bc_decomposition_bytes_pc_plus_6, e bc_decomposition_bytes_pc_plus_7, e bc_decomposition_bytes_pc_plus_8, e bc_decomposition_bytes_pc_plus_9, e bc_decomposition_bytes_remaining, e bc_decomposition_id, e bc_decomposition_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_windows_gt_remaining, e bc_decomposition_start, e bc_hashing_bytecode_id, e bc_hashing_padding, e bc_hashing_pc_index_1, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_sel_not_start, e bc_hashing_start, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e bitwise_sel, e bitwise_start, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_src_context_id, e data_copy_start, e emit_public_log_contract_address, e emit_public_log_correct_tag, e emit_public_log_error_out_of_bounds, e emit_public_log_error_tag_mismatch, e emit_public_log_execution_clk, e emit_public_log_is_write_contract_address, e emit_public_log_is_write_memory_value, e emit_public_log_log_address, e emit_public_log_public_inputs_index, e emit_public_log_remaining_rows, e emit_public_log_seen_wrong_tag, e emit_public_log_sel, e emit_public_log_sel_write_to_public_inputs, e emit_public_log_space_id, e emit_public_log_start, e execution_bytecode_id, e execution_clk, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_public_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_sel, e keccak_memory_space_id, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_start, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_address, e memory_clk, e memory_rw, e memory_sel, e memory_space_id, e memory_tag, e memory_value, e merkle_check_index, e merkle_check_merkle_hash_separator, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_start, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, e poseidon2_hash_a_0, e poseidon2_hash_a_1, e poseidon2_hash_a_2, e poseidon2_hash_a_3, e poseidon2_hash_input_0, e poseidon2_hash_input_1, e poseidon2_hash_input_2, e poseidon2_hash_num_perm_rounds_rem, e poseidon2_hash_output, e poseidon2_hash_sel, e poseidon2_hash_start, e public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, e scalar_mul_bit_idx, e scalar_mul_point_inf, e scalar_mul_point_x, e scalar_mul_point_y, e scalar_mul_res_inf, e scalar_mul_res_x, e scalar_mul_res_y, e scalar_mul_scalar, e scalar_mul_sel, e scalar_mul_start, e scalar_mul_temp_inf, e scalar_mul_temp_x, e scalar_mul_temp_y, e sha256_a, e sha256_b, e sha256_c, e sha256_d, e sha256_e, e sha256_execution_clk, e sha256_f, e sha256_g, e sha256_h, e sha256_helper_w0, e sha256_helper_w1, e sha256_helper_w10, e sha256_helper_w11, e sha256_helper_w12, e sha256_helper_w13, e sha256_helper_w14, e sha256_helper_w15, e sha256_helper_w2, e sha256_helper_w3, e sha256_helper_w4, e sha256_helper_w5, e sha256_helper_w6, e sha256_helper_w7, e sha256_helper_w8, e sha256_helper_w9, e sha256_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_power, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_public_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted #define AVM2_ALL_ENTITIES_E(e) AVM2_PRECOMPUTED_ENTITIES_E(e), AVM2_WIRE_ENTITIES_E(e), AVM2_DERIVED_WITNESS_ENTITIES_E(e), AVM2_SHIFTED_ENTITIES_E(e) @@ -36,16 +36,16 @@ enum class ColumnAndShifts { SENTINEL_DO_NOT_USE, }; -constexpr auto NUM_COLUMNS_WITH_SHIFTS = 3438; -constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 3074; -constexpr auto NUM_PRECOMPUTED_ENTITIES = 119; -constexpr auto NUM_WIRE_ENTITIES = 2511; -constexpr auto NUM_DERIVED_ENTITIES = 444; +constexpr auto NUM_COLUMNS_WITH_SHIFTS = 3424; +constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 3060; +constexpr auto NUM_PRECOMPUTED_ENTITIES = 120; +constexpr auto NUM_WIRE_ENTITIES = 2499; +constexpr auto NUM_DERIVED_ENTITIES = 441; constexpr auto NUM_WITNESS_ENTITIES = NUM_WIRE_ENTITIES + NUM_DERIVED_ENTITIES; constexpr auto NUM_WIRES_TO_BE_SHIFTED = 364; constexpr auto NUM_SHIFTED_ENTITIES = 364; constexpr auto NUM_UNSHIFTED_ENTITIES = NUM_COLUMNS_WITHOUT_SHIFTS; -constexpr auto NUM_ALL_ENTITIES = 3438; +constexpr auto NUM_ALL_ENTITIES = 3424; /* * Layout for all entities is: diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp index 22c2e6bc3473..01e4c415f56e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp @@ -140,11 +140,11 @@ namespace bb::avm2 { struct AvmFlavorVariables { - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 119; - static constexpr size_t NUM_WITNESS_ENTITIES = 2955; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 120; + static constexpr size_t NUM_WITNESS_ENTITIES = 2940; static constexpr size_t NUM_SHIFTED_ENTITIES = 364; - static constexpr size_t NUM_WIRES = 2511; - static constexpr size_t NUM_ALL_ENTITIES = 3438; + static constexpr size_t NUM_WIRES = 2499; + static constexpr size_t NUM_ALL_ENTITIES = 3424; // Need to be templated for recursive verifier template @@ -216,14 +216,12 @@ struct AvmFlavorVariables { using LookupRelations_ = flat_tuple::tuple< // Lookups lookup_address_derivation_address_ecadd_relation, + lookup_address_derivation_ivpk_m_hash_poseidon2_relation, lookup_address_derivation_partial_address_poseidon2_relation, lookup_address_derivation_preaddress_poseidon2_relation, lookup_address_derivation_preaddress_scalar_mul_relation, lookup_address_derivation_public_keys_hash_poseidon2_0_relation, lookup_address_derivation_public_keys_hash_poseidon2_1_relation, - lookup_address_derivation_public_keys_hash_poseidon2_2_relation, - lookup_address_derivation_public_keys_hash_poseidon2_3_relation, - lookup_address_derivation_public_keys_hash_poseidon2_4_relation, lookup_address_derivation_salted_initialization_hash_poseidon2_0_relation, lookup_address_derivation_salted_initialization_hash_poseidon2_1_relation, lookup_addressing_relative_overflow_result_0_relation, @@ -612,7 +610,6 @@ struct AvmFlavorVariables { perm_data_copy_mem_write_relation, perm_ecc_mem_write_mem_0_relation, perm_ecc_mem_write_mem_1_relation, - perm_ecc_mem_write_mem_2_relation, perm_emit_public_log_read_mem_relation, perm_execution_dispatch_to_cd_copy_relation, perm_execution_dispatch_to_ecc_add_relation, diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/address_derivation.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/address_derivation.hpp index 4ebd488f9576..fbaf2e0d85b8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/address_derivation.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/address_derivation.hpp @@ -14,7 +14,7 @@ template class address_derivationImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5 }; template inline static bool skip(const AllEntities& in) { @@ -35,7 +35,7 @@ template class address_derivation : public Relation::accumulate(ContainerOverSubrelations& evals, FF(uint256_t{ 9457493854555940652UL, 3253583849847263892UL, 14921373847124204899UL, 2UL }); const auto constants_DOM_SEP__SALTED_INITIALIZATION_HASH = FF(2763052992UL); const auto constants_DOM_SEP__PUBLIC_KEYS_HASH = FF(777457226); + const auto constants_DOM_SEP__SINGLE_PUBLIC_KEY_HASH = FF(3452068255UL); const auto constants_DOM_SEP__PARTIAL_ADDRESS = FF(2103633018); - const auto constants_DOM_SEP__CONTRACT_ADDRESS_V1 = FF(1788365517); + const auto constants_DOM_SEP__CONTRACT_ADDRESS_V2 = FF(4099338721UL); const auto address_derivation_X3 = in.get(C::address_derivation_incoming_viewing_key_x) * in.get(C::address_derivation_incoming_viewing_key_x) * in.get(C::address_derivation_incoming_viewing_key_x); @@ -37,72 +38,67 @@ void address_derivationImpl::accumulate(ContainerOverSubrelations& evals, { using View = typename std::tuple_element_t<1, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_const_two)) - FF(2)); + (static_cast(in.get(C::address_derivation_const_three)) - FF(3)); std::get<1>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<2, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_const_three)) - FF(3)); + (static_cast(in.get(C::address_derivation_const_five)) - FF(5)); std::get<2>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_const_four)) - FF(4)); + (static_cast(in.get(C::address_derivation_salted_init_hash_domain_separator)) - + CView(constants_DOM_SEP__SALTED_INITIALIZATION_HASH)); std::get<3>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_const_thirteen)) - FF(13)); + (static_cast(in.get(C::address_derivation_partial_address_domain_separator)) - + CView(constants_DOM_SEP__PARTIAL_ADDRESS)); std::get<4>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_salted_init_hash_domain_separator)) - - CView(constants_DOM_SEP__SALTED_INITIALIZATION_HASH)); + (static_cast(in.get(C::address_derivation_single_public_key_hash_domain_separator)) - + CView(constants_DOM_SEP__SINGLE_PUBLIC_KEY_HASH)); std::get<5>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_partial_address_domain_separator)) - - CView(constants_DOM_SEP__PARTIAL_ADDRESS)); + (static_cast(in.get(C::address_derivation_public_keys_hash_domain_separator)) - + CView(constants_DOM_SEP__PUBLIC_KEYS_HASH)); std::get<6>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_public_keys_hash_domain_separator)) - - CView(constants_DOM_SEP__PUBLIC_KEYS_HASH)); + (static_cast(in.get(C::address_derivation_preaddress_domain_separator)) - + CView(constants_DOM_SEP__CONTRACT_ADDRESS_V2)); std::get<7>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_preaddress_domain_separator)) - - CView(constants_DOM_SEP__CONTRACT_ADDRESS_V1)); + (static_cast(in.get(C::address_derivation_g1_x)) - CView(constants_GRUMPKIN_ONE_X)); std::get<8>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::address_derivation_sel)) * - (static_cast(in.get(C::address_derivation_g1_x)) - CView(constants_GRUMPKIN_ONE_X)); - std::get<9>(evals) += (tmp * scaling_factor); - } - { - using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * (static_cast(in.get(C::address_derivation_g1_y)) - CView(constants_GRUMPKIN_ONE_Y)); - std::get<10>(evals) += (tmp * scaling_factor); + std::get<9>(evals) += (tmp * scaling_factor); } { // IVK_ON_CURVE_CHECK - using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::address_derivation_sel)) * (CView(address_derivation_Y2) - (CView(address_derivation_X3) - FF(17))); - std::get<11>(evals) += (tmp * scaling_factor); + std::get<10>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/contract_instance_retrieval.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/contract_instance_retrieval.hpp index 20d2e8432637..c58b25b8e2d6 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/contract_instance_retrieval.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/contract_instance_retrieval.hpp @@ -14,8 +14,8 @@ template class contract_instance_retrievalImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 2, 3, 3, 5, 3, 3, - 3, 3, 4, 4, 4, 4, 4, 4, 3 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 2, 3, 3, 5, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 4, 3 }; template inline static bool skip(const AllEntities& in) { @@ -47,6 +47,7 @@ template class contract_instance_retrieval : public Relation class contract_instance_retrieval : public Relation::accumulate(ContainerOverSubrelations& static_cast(in.get(C::contract_instance_retrieval_init_hash)); std::get<16>(evals) += (tmp * scaling_factor); } - { + { // INSTANCE_MEMBER_IMMUTABLES_HASH_IS_ZERO_IF_DNE using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::contract_instance_retrieval_sel)) * + (FF(1) - static_cast(in.get(C::contract_instance_retrieval_exists))) * + static_cast(in.get(C::contract_instance_retrieval_immutables_hash)); + std::get<17>(evals) += (tmp * scaling_factor); + } + { + using View = typename std::tuple_element_t<18, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::contract_instance_retrieval_should_check_for_update)) - static_cast(in.get(C::contract_instance_retrieval_should_check_nullifier)) * static_cast(in.get(C::contract_instance_retrieval_exists))); - std::get<17>(evals) += (tmp * scaling_factor); + std::get<18>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc.hpp index 93df40ba85c2..b1d717c5f2ca 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc.hpp @@ -14,8 +14,8 @@ template class eccImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, - 5, 3, 3, 5, 6, 6, 5, 6, 6, 3 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 5, 3, + 5, 3, 3, 5, 6, 6, 5, 6, 6 }; template inline static bool skip(const AllEntities& in) { @@ -37,14 +37,13 @@ template class ecc : public Relation> { // Subrelation indices constants, to be used in tests. static constexpr size_t SR_OP_CHECK = 3; - static constexpr size_t SR_X_MATCH = 8; - static constexpr size_t SR_Y_MATCH = 10; - static constexpr size_t SR_DOUBLE_PRED = 11; - static constexpr size_t SR_COMPUTED_LAMBDA = 14; - static constexpr size_t SR_INFINITY_RESULT = 16; - static constexpr size_t SR_OUTPUT_X_COORD = 17; - static constexpr size_t SR_OUTPUT_Y_COORD = 18; - static constexpr size_t SR_OUTPUT_INF_FLAG = 19; + static constexpr size_t SR_X_MATCH = 7; + static constexpr size_t SR_Y_MATCH = 9; + static constexpr size_t SR_DOUBLE_PRED = 10; + static constexpr size_t SR_COMPUTED_LAMBDA = 13; + static constexpr size_t SR_INFINITY_RESULT = 15; + static constexpr size_t SR_OUTPUT_X_COORD = 16; + static constexpr size_t SR_OUTPUT_Y_COORD = 17; static std::string get_subrelation_label(size_t index) { @@ -65,8 +64,6 @@ template class ecc : public Relation> { return "OUTPUT_X_COORD"; case SR_OUTPUT_Y_COORD: return "OUTPUT_Y_COORD"; - case SR_OUTPUT_INF_FLAG: - return "OUTPUT_INF_FLAG"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_impl.hpp index 5b709819d443..335cdcd557e0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_impl.hpp @@ -62,83 +62,78 @@ void eccImpl::accumulate(ContainerOverSubrelations& evals, } { using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_r_is_inf)) * (FF(1) - static_cast(in.get(C::ecc_r_is_inf))); - std::get<6>(evals) += (tmp * scaling_factor); - } - { - using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_x_match)) * (FF(1) - static_cast(in.get(C::ecc_x_match))); - std::get<7>(evals) += (tmp * scaling_factor); + std::get<6>(evals) += (tmp * scaling_factor); } { // X_MATCH - using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * ((CView(ecc_X_DIFF) * (static_cast(in.get(C::ecc_x_match)) * (FF(1) - static_cast(in.get(C::ecc_inv_x_diff))) + static_cast(in.get(C::ecc_inv_x_diff))) - FF(1)) + static_cast(in.get(C::ecc_x_match))); - std::get<8>(evals) += (tmp * scaling_factor); + std::get<7>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_y_match)) * (FF(1) - static_cast(in.get(C::ecc_y_match))); - std::get<9>(evals) += (tmp * scaling_factor); + std::get<8>(evals) += (tmp * scaling_factor); } { // Y_MATCH - using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * ((CView(ecc_Y_DIFF) * (static_cast(in.get(C::ecc_y_match)) * (FF(1) - static_cast(in.get(C::ecc_inv_y_diff))) + static_cast(in.get(C::ecc_inv_y_diff))) - FF(1)) + static_cast(in.get(C::ecc_y_match))); - std::get<10>(evals) += (tmp * scaling_factor); + std::get<9>(evals) += (tmp * scaling_factor); } { // DOUBLE_PRED - using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_double_op)) - static_cast(in.get(C::ecc_x_match)) * static_cast(in.get(C::ecc_y_match))); - std::get<11>(evals) += (tmp * scaling_factor); + std::get<10>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_double_op)) * (static_cast(in.get(C::ecc_p_is_inf)) - static_cast(in.get(C::ecc_q_is_inf))); - std::get<12>(evals) += (tmp * scaling_factor); + std::get<11>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; auto tmp = (FF(1) - static_cast(in.get(C::ecc_result_infinity))) * static_cast(in.get(C::ecc_double_op)) * (FF(2) * static_cast(in.get(C::ecc_p_y)) * static_cast(in.get(C::ecc_inv_2_p_y)) - FF(1)); - std::get<13>(evals) += (tmp * scaling_factor); + std::get<12>(evals) += (tmp * scaling_factor); } { // COMPUTED_LAMBDA - using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * (static_cast(in.get(C::ecc_lambda)) - (static_cast(in.get(C::ecc_double_op)) * FF(3) * static_cast(in.get(C::ecc_p_x)) * static_cast(in.get(C::ecc_p_x)) * static_cast(in.get(C::ecc_inv_2_p_y)) + static_cast(in.get(C::ecc_add_op)) * CView(ecc_Y_DIFF) * static_cast(in.get(C::ecc_inv_x_diff)))); - std::get<14>(evals) += (tmp * scaling_factor); + std::get<13>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_use_computed_result)) - static_cast(in.get(C::ecc_sel)) * CView(ecc_BOTH_NON_INF) * (FF(1) - CView(ecc_INVERSE_PRED))); - std::get<15>(evals) += (tmp * scaling_factor); + std::get<14>(evals) += (tmp * scaling_factor); } { // INFINITY_RESULT - using View = typename std::tuple_element_t<16, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_result_infinity)) - (CView(ecc_INVERSE_PRED) * CView(ecc_BOTH_NON_INF) + CView(ecc_BOTH_INF))); - std::get<16>(evals) += (tmp * scaling_factor); + std::get<15>(evals) += (tmp * scaling_factor); } { // OUTPUT_X_COORD - using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<16, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * (((static_cast(in.get(C::ecc_r_x)) - CView(ecc_EITHER_INF) * @@ -146,10 +141,10 @@ void eccImpl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::ecc_q_is_inf)) * static_cast(in.get(C::ecc_p_x)))) - static_cast(in.get(C::ecc_result_infinity)) * CView(ecc_INFINITY_X)) - static_cast(in.get(C::ecc_use_computed_result)) * CView(ecc_COMPUTED_R_X)); - std::get<17>(evals) += (tmp * scaling_factor); + std::get<16>(evals) += (tmp * scaling_factor); } { // OUTPUT_Y_COORD - using View = typename std::tuple_element_t<18, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_sel)) * (((static_cast(in.get(C::ecc_r_y)) - CView(ecc_EITHER_INF) * @@ -157,13 +152,7 @@ void eccImpl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::ecc_q_is_inf)) * static_cast(in.get(C::ecc_p_y)))) - static_cast(in.get(C::ecc_result_infinity)) * CView(ecc_INFINITY_Y)) - static_cast(in.get(C::ecc_use_computed_result)) * CView(ecc_COMPUTED_R_Y)); - std::get<18>(evals) += (tmp * scaling_factor); - } - { // OUTPUT_INF_FLAG - using View = typename std::tuple_element_t<19, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_sel)) * - (static_cast(in.get(C::ecc_r_is_inf)) - static_cast(in.get(C::ecc_result_infinity))); - std::get<19>(evals) += (tmp * scaling_factor); + std::get<17>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem.hpp index 5e7671b889ed..93c24d10d2e7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem.hpp @@ -14,8 +14,9 @@ template class ecc_memImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 6, 5, - 6, 5, 4, 3, 4, 4, 4, 4 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { + 3, 3, 3, 3, 3, 6, 5, 6, 5, 4, 3, 4, 4, 4, 4 + }; template inline static bool skip(const AllEntities& in) { @@ -37,10 +38,14 @@ template class ecc_mem : public Relation> { // Subrelation indices constants, to be used in tests. static constexpr size_t SR_WRITE_INCR_DST_ADDR = 1; - static constexpr size_t SR_P_CURVE_EQN = 6; - static constexpr size_t SR_P_ON_CURVE_CHECK = 7; - static constexpr size_t SR_Q_CURVE_EQN = 8; - static constexpr size_t SR_Q_ON_CURVE_CHECK = 9; + static constexpr size_t SR_P_CURVE_EQN = 5; + static constexpr size_t SR_P_ON_CURVE_CHECK = 6; + static constexpr size_t SR_Q_CURVE_EQN = 7; + static constexpr size_t SR_Q_ON_CURVE_CHECK = 8; + static constexpr size_t SR_P_INF_X_CHECK = 11; + static constexpr size_t SR_P_INF_Y_CHECK = 12; + static constexpr size_t SR_Q_INF_X_CHECK = 13; + static constexpr size_t SR_Q_INF_Y_CHECK = 14; static std::string get_subrelation_label(size_t index) { @@ -55,6 +60,14 @@ template class ecc_mem : public Relation> { return "Q_CURVE_EQN"; case SR_Q_ON_CURVE_CHECK: return "Q_ON_CURVE_CHECK"; + case SR_P_INF_X_CHECK: + return "P_INF_X_CHECK"; + case SR_P_INF_Y_CHECK: + return "P_INF_Y_CHECK"; + case SR_Q_INF_X_CHECK: + return "Q_INF_X_CHECK"; + case SR_Q_INF_Y_CHECK: + return "Q_INF_Y_CHECK"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem_impl.hpp index 7a90c736ffb9..215eb8578019 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/ecc_mem_impl.hpp @@ -38,116 +38,97 @@ void ecc_memImpl::accumulate(ContainerOverSubrelations& evals, } { using View = typename std::tuple_element_t<2, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::ecc_add_mem_dst_addr_2_)) - - static_cast(in.get(C::ecc_add_mem_sel)) * - (static_cast(in.get(C::ecc_add_mem_dst_addr_0_)) + FF(2))); - std::get<2>(evals) += (tmp * scaling_factor); - } - { - using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * (static_cast(in.get(C::ecc_add_mem_max_mem_addr)) - CView(constants_AVM_HIGHEST_MEM_ADDRESS)); - std::get<3>(evals) += (tmp * scaling_factor); + std::get<2>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err)) * (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err))); - std::get<4>(evals) += (tmp * scaling_factor); + std::get<3>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err)) * (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err))); - std::get<5>(evals) += (tmp * scaling_factor); + std::get<4>(evals) += (tmp * scaling_factor); } { // P_CURVE_EQN - using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_add_mem_p_is_on_curve_eqn)) - static_cast(in.get(C::ecc_add_mem_sel)) * (CView(ecc_add_mem_P_Y2) - (CView(ecc_add_mem_P_X3) - FF(17))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_p_is_inf)))); - std::get<6>(evals) += (tmp * scaling_factor); + std::get<5>(evals) += (tmp * scaling_factor); } { // P_ON_CURVE_CHECK - using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * (static_cast(in.get(C::ecc_add_mem_p_is_on_curve_eqn)) * ((FF(1) - static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_p_is_on_curve_eqn_inv))) + static_cast(in.get(C::ecc_add_mem_p_is_on_curve_eqn_inv))) - static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err))); - std::get<7>(evals) += (tmp * scaling_factor); + std::get<6>(evals) += (tmp * scaling_factor); } { // Q_CURVE_EQN - using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_add_mem_q_is_on_curve_eqn)) - static_cast(in.get(C::ecc_add_mem_sel)) * (CView(ecc_add_mem_Q_Y2) - (CView(ecc_add_mem_Q_X3) - FF(17))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_q_is_inf)))); - std::get<8>(evals) += (tmp * scaling_factor); + std::get<7>(evals) += (tmp * scaling_factor); } { // Q_ON_CURVE_CHECK - using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * (static_cast(in.get(C::ecc_add_mem_q_is_on_curve_eqn)) * ((FF(1) - static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_q_is_on_curve_eqn_inv))) + static_cast(in.get(C::ecc_add_mem_q_is_on_curve_eqn_inv))) - static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err))); - std::get<9>(evals) += (tmp * scaling_factor); + std::get<8>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_add_mem_err)) - (FF(1) - (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_dst_out_of_range_err))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_p_not_on_curve_err))) * (FF(1) - static_cast(in.get(C::ecc_add_mem_sel_q_not_on_curve_err))))); - std::get<10>(evals) += (tmp * scaling_factor); + std::get<9>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::ecc_add_mem_sel_should_exec)) - static_cast(in.get(C::ecc_add_mem_sel)) * (FF(1) - static_cast(in.get(C::ecc_add_mem_err)))); + std::get<10>(evals) += (tmp * scaling_factor); + } + { // P_INF_X_CHECK + using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * static_cast(in.get(C::ecc_add_mem_p_is_inf)) * + (static_cast(in.get(C::ecc_add_mem_p_x)) - CView(ecc_INFINITY_X)); std::get<11>(evals) += (tmp * scaling_factor); } - { + { // P_INF_Y_CHECK using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_add_mem_sel_should_exec)) * - ((static_cast(in.get(C::ecc_add_mem_p_x_n)) - - (FF(1) - static_cast(in.get(C::ecc_add_mem_p_is_inf))) * - static_cast(in.get(C::ecc_add_mem_p_x))) - - static_cast(in.get(C::ecc_add_mem_p_is_inf)) * CView(ecc_INFINITY_X)); + auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * static_cast(in.get(C::ecc_add_mem_p_is_inf)) * + (static_cast(in.get(C::ecc_add_mem_p_y)) - CView(ecc_INFINITY_Y)); std::get<12>(evals) += (tmp * scaling_factor); } - { + { // Q_INF_X_CHECK using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_add_mem_sel_should_exec)) * - ((static_cast(in.get(C::ecc_add_mem_p_y_n)) - - (FF(1) - static_cast(in.get(C::ecc_add_mem_p_is_inf))) * - static_cast(in.get(C::ecc_add_mem_p_y))) - - static_cast(in.get(C::ecc_add_mem_p_is_inf)) * CView(ecc_INFINITY_Y)); + auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * static_cast(in.get(C::ecc_add_mem_q_is_inf)) * + (static_cast(in.get(C::ecc_add_mem_q_x)) - CView(ecc_INFINITY_X)); std::get<13>(evals) += (tmp * scaling_factor); } - { + { // Q_INF_Y_CHECK using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_add_mem_sel_should_exec)) * - ((static_cast(in.get(C::ecc_add_mem_q_x_n)) - - (FF(1) - static_cast(in.get(C::ecc_add_mem_q_is_inf))) * - static_cast(in.get(C::ecc_add_mem_q_x))) - - static_cast(in.get(C::ecc_add_mem_q_is_inf)) * CView(ecc_INFINITY_X)); + auto tmp = static_cast(in.get(C::ecc_add_mem_sel)) * static_cast(in.get(C::ecc_add_mem_q_is_inf)) * + (static_cast(in.get(C::ecc_add_mem_q_y)) - CView(ecc_INFINITY_Y)); std::get<14>(evals) += (tmp * scaling_factor); } - { - using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::ecc_add_mem_sel_should_exec)) * - ((static_cast(in.get(C::ecc_add_mem_q_y_n)) - - (FF(1) - static_cast(in.get(C::ecc_add_mem_q_is_inf))) * - static_cast(in.get(C::ecc_add_mem_q_y))) - - static_cast(in.get(C::ecc_add_mem_q_is_inf)) * CView(ecc_INFINITY_Y)); - std::get<15>(evals) += (tmp * scaling_factor); - } } } // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp index c807d2b34b16..f27fca3e9db1 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp @@ -74,7 +74,9 @@ void get_contract_instanceImpl::accumulate(ContainerOverSubrelations& evals static_cast(in.get(C::get_contract_instance_is_class_id)) * static_cast(in.get(C::get_contract_instance_retrieved_class_id)) + static_cast(in.get(C::get_contract_instance_is_init_hash)) * - static_cast(in.get(C::get_contract_instance_retrieved_init_hash)))); + static_cast(in.get(C::get_contract_instance_retrieved_init_hash)) + + static_cast(in.get(C::get_contract_instance_is_immutables_hash)) * + static_cast(in.get(C::get_contract_instance_retrieved_immutables_hash)))); std::get<6>(evals) += (tmp * scaling_factor); } { // MEMBER_WRITE_OFFSET diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.cpp index 4537e24b46a4..786b2c635dfa 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.cpp @@ -28,11 +28,9 @@ namespace bb::avm2 { INSTANTIATE_LOOKUP(lookup_address_derivation_salted_initialization_hash_poseidon2_0_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_salted_initialization_hash_poseidon2_1_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_partial_address_poseidon2_relation); +INSTANTIATE_LOOKUP(lookup_address_derivation_ivpk_m_hash_poseidon2_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_0_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_1_relation); -INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_2_relation); -INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_3_relation); -INSTANTIATE_LOOKUP(lookup_address_derivation_public_keys_hash_poseidon2_4_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_preaddress_poseidon2_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_preaddress_scalar_mul_relation); INSTANTIATE_LOOKUP(lookup_address_derivation_address_ecadd_relation); diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.hpp index dd7af40e2658..38fa5107200e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_address_derivation.hpp @@ -26,7 +26,7 @@ struct lookup_address_derivation_salted_initialization_hash_poseidon2_0_settings ColumnAndShifts::address_derivation_salt, ColumnAndShifts::address_derivation_init_hash, ColumnAndShifts::address_derivation_salted_init_hash, - ColumnAndShifts::address_derivation_const_four + ColumnAndShifts::address_derivation_const_five }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::poseidon2_hash_input_0, @@ -55,7 +55,7 @@ struct lookup_address_derivation_salted_initialization_hash_poseidon2_1_settings static constexpr Column INVERSES = Column::lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv; static constexpr std::array SRC_COLUMNS = { ColumnAndShifts::address_derivation_deployer_addr, - ColumnAndShifts::precomputed_zero, + ColumnAndShifts::address_derivation_immutables_hash, ColumnAndShifts::precomputed_zero, ColumnAndShifts::address_derivation_salted_init_hash }; @@ -105,85 +105,21 @@ template using lookup_address_derivation_partial_address_poseidon2_relation = lookup_relation_base; -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_0 /////////////////// +/////////////////// lookup_address_derivation_ivpk_m_hash_poseidon2 /////////////////// -struct lookup_address_derivation_public_keys_hash_poseidon2_0_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_0"; +struct lookup_address_derivation_ivpk_m_hash_poseidon2_settings_ { + static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_IVPK_M_HASH_POSEIDON2"; static constexpr std::string_view RELATION_NAME = "address_derivation"; static constexpr size_t LOOKUP_TUPLE_SIZE = 5; static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; static constexpr Column DST_SELECTOR = Column::poseidon2_hash_start; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_0_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_0_inv; - static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::address_derivation_public_keys_hash_domain_separator, - ColumnAndShifts::address_derivation_nullifier_key_x, - ColumnAndShifts::address_derivation_nullifier_key_y, - ColumnAndShifts::address_derivation_public_keys_hash, - ColumnAndShifts::address_derivation_const_thirteen - }; - static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::poseidon2_hash_input_0, - ColumnAndShifts::poseidon2_hash_input_1, - ColumnAndShifts::poseidon2_hash_input_2, - ColumnAndShifts::poseidon2_hash_output, - ColumnAndShifts::poseidon2_hash_input_len - }; -}; - -using lookup_address_derivation_public_keys_hash_poseidon2_0_settings = - lookup_settings; -template -using lookup_address_derivation_public_keys_hash_poseidon2_0_relation = - lookup_relation_base; - -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_1 /////////////////// - -struct lookup_address_derivation_public_keys_hash_poseidon2_1_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_1"; - static constexpr std::string_view RELATION_NAME = "address_derivation"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 5; - static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; - static constexpr Column DST_SELECTOR = Column::poseidon2_hash_sel; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_1_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_1_inv; + static constexpr Column COUNTS = Column::lookup_address_derivation_ivpk_m_hash_poseidon2_counts; + static constexpr Column INVERSES = Column::lookup_address_derivation_ivpk_m_hash_poseidon2_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::precomputed_zero, + ColumnAndShifts::address_derivation_single_public_key_hash_domain_separator, ColumnAndShifts::address_derivation_incoming_viewing_key_x, ColumnAndShifts::address_derivation_incoming_viewing_key_y, - ColumnAndShifts::address_derivation_public_keys_hash, - ColumnAndShifts::address_derivation_const_four - }; - static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::poseidon2_hash_input_0, - ColumnAndShifts::poseidon2_hash_input_1, - ColumnAndShifts::poseidon2_hash_input_2, - ColumnAndShifts::poseidon2_hash_output, - ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem - }; -}; - -using lookup_address_derivation_public_keys_hash_poseidon2_1_settings = - lookup_settings; -template -using lookup_address_derivation_public_keys_hash_poseidon2_1_relation = - lookup_relation_base; - -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_2 /////////////////// - -struct lookup_address_derivation_public_keys_hash_poseidon2_2_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_2"; - static constexpr std::string_view RELATION_NAME = "address_derivation"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 5; - static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; - static constexpr Column DST_SELECTOR = Column::poseidon2_hash_sel; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_2_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_2_inv; - static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::precomputed_zero, - ColumnAndShifts::address_derivation_outgoing_viewing_key_x, - ColumnAndShifts::address_derivation_outgoing_viewing_key_y, - ColumnAndShifts::address_derivation_public_keys_hash, + ColumnAndShifts::address_derivation_incoming_viewing_key_hash, ColumnAndShifts::address_derivation_const_three }; static constexpr std::array DST_COLUMNS = { @@ -191,61 +127,61 @@ struct lookup_address_derivation_public_keys_hash_poseidon2_2_settings_ { ColumnAndShifts::poseidon2_hash_input_1, ColumnAndShifts::poseidon2_hash_input_2, ColumnAndShifts::poseidon2_hash_output, - ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem + ColumnAndShifts::poseidon2_hash_input_len }; }; -using lookup_address_derivation_public_keys_hash_poseidon2_2_settings = - lookup_settings; +using lookup_address_derivation_ivpk_m_hash_poseidon2_settings = + lookup_settings; template -using lookup_address_derivation_public_keys_hash_poseidon2_2_relation = - lookup_relation_base; +using lookup_address_derivation_ivpk_m_hash_poseidon2_relation = + lookup_relation_base; -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_3 /////////////////// +/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_0 /////////////////// -struct lookup_address_derivation_public_keys_hash_poseidon2_3_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_3"; +struct lookup_address_derivation_public_keys_hash_poseidon2_0_settings_ { + static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_0"; static constexpr std::string_view RELATION_NAME = "address_derivation"; static constexpr size_t LOOKUP_TUPLE_SIZE = 5; static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; - static constexpr Column DST_SELECTOR = Column::poseidon2_hash_sel; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_3_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_3_inv; + static constexpr Column DST_SELECTOR = Column::poseidon2_hash_start; + static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_0_counts; + static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_0_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::precomputed_zero, - ColumnAndShifts::address_derivation_tagging_key_x, - ColumnAndShifts::address_derivation_tagging_key_y, + ColumnAndShifts::address_derivation_public_keys_hash_domain_separator, + ColumnAndShifts::address_derivation_nullifier_key_hash, + ColumnAndShifts::address_derivation_incoming_viewing_key_hash, ColumnAndShifts::address_derivation_public_keys_hash, - ColumnAndShifts::address_derivation_const_two + ColumnAndShifts::address_derivation_const_five }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::poseidon2_hash_input_0, ColumnAndShifts::poseidon2_hash_input_1, ColumnAndShifts::poseidon2_hash_input_2, ColumnAndShifts::poseidon2_hash_output, - ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem + ColumnAndShifts::poseidon2_hash_input_len }; }; -using lookup_address_derivation_public_keys_hash_poseidon2_3_settings = - lookup_settings; +using lookup_address_derivation_public_keys_hash_poseidon2_0_settings = + lookup_settings; template -using lookup_address_derivation_public_keys_hash_poseidon2_3_relation = - lookup_relation_base; +using lookup_address_derivation_public_keys_hash_poseidon2_0_relation = + lookup_relation_base; -/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_4 /////////////////// +/////////////////// lookup_address_derivation_public_keys_hash_poseidon2_1 /////////////////// -struct lookup_address_derivation_public_keys_hash_poseidon2_4_settings_ { - static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_4"; +struct lookup_address_derivation_public_keys_hash_poseidon2_1_settings_ { + static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_PUBLIC_KEYS_HASH_POSEIDON2_1"; static constexpr std::string_view RELATION_NAME = "address_derivation"; static constexpr size_t LOOKUP_TUPLE_SIZE = 4; static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; static constexpr Column DST_SELECTOR = Column::poseidon2_hash_end; - static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_4_counts; - static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_4_inv; + static constexpr Column COUNTS = Column::lookup_address_derivation_public_keys_hash_poseidon2_1_counts; + static constexpr Column INVERSES = Column::lookup_address_derivation_public_keys_hash_poseidon2_1_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::precomputed_zero, - ColumnAndShifts::precomputed_zero, + ColumnAndShifts::address_derivation_outgoing_viewing_key_hash, + ColumnAndShifts::address_derivation_tagging_key_hash, ColumnAndShifts::precomputed_zero, ColumnAndShifts::address_derivation_public_keys_hash }; @@ -257,11 +193,11 @@ struct lookup_address_derivation_public_keys_hash_poseidon2_4_settings_ { }; }; -using lookup_address_derivation_public_keys_hash_poseidon2_4_settings = - lookup_settings; +using lookup_address_derivation_public_keys_hash_poseidon2_1_settings = + lookup_settings; template -using lookup_address_derivation_public_keys_hash_poseidon2_4_relation = - lookup_relation_base; +using lookup_address_derivation_public_keys_hash_poseidon2_1_relation = + lookup_relation_base; /////////////////// lookup_address_derivation_preaddress_poseidon2 /////////////////// @@ -332,7 +268,7 @@ using lookup_address_derivation_preaddress_scalar_mul_relation = struct lookup_address_derivation_address_ecadd_settings_ { static constexpr std::string_view NAME = "LOOKUP_ADDRESS_DERIVATION_ADDRESS_ECADD"; static constexpr std::string_view RELATION_NAME = "address_derivation"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 9; + static constexpr size_t LOOKUP_TUPLE_SIZE = 8; static constexpr Column SRC_SELECTOR = Column::address_derivation_sel; static constexpr Column DST_SELECTOR = Column::ecc_sel; static constexpr Column COUNTS = Column::lookup_address_derivation_address_ecadd_counts; @@ -345,13 +281,12 @@ struct lookup_address_derivation_address_ecadd_settings_ { ColumnAndShifts::address_derivation_incoming_viewing_key_y, ColumnAndShifts::precomputed_zero, ColumnAndShifts::address_derivation_address, - ColumnAndShifts::address_derivation_address_y, - ColumnAndShifts::precomputed_zero + ColumnAndShifts::address_derivation_address_y }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::ecc_p_x, ColumnAndShifts::ecc_p_y, ColumnAndShifts::ecc_p_is_inf, ColumnAndShifts::ecc_q_x, ColumnAndShifts::ecc_q_y, ColumnAndShifts::ecc_q_is_inf, - ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_r_is_inf + ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_contract_instance_retrieval.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_contract_instance_retrieval.hpp index a314f368785e..a646a48affed 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_contract_instance_retrieval.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_contract_instance_retrieval.hpp @@ -108,7 +108,7 @@ using lookup_contract_instance_retrieval_deployment_nullifier_read_relation = struct lookup_contract_instance_retrieval_address_derivation_settings_ { static constexpr std::string_view NAME = "LOOKUP_CONTRACT_INSTANCE_RETRIEVAL_ADDRESS_DERIVATION"; static constexpr std::string_view RELATION_NAME = "contract_instance_retrieval"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 13; + static constexpr size_t LOOKUP_TUPLE_SIZE = 11; static constexpr Column SRC_SELECTOR = Column::contract_instance_retrieval_exists; static constexpr Column DST_SELECTOR = Column::address_derivation_sel; static constexpr Column COUNTS = Column::lookup_contract_instance_retrieval_address_derivation_counts; @@ -119,14 +119,12 @@ struct lookup_contract_instance_retrieval_address_derivation_settings_ { ColumnAndShifts::contract_instance_retrieval_deployer_addr, ColumnAndShifts::contract_instance_retrieval_original_class_id, ColumnAndShifts::contract_instance_retrieval_init_hash, - ColumnAndShifts::contract_instance_retrieval_nullifier_key_x, - ColumnAndShifts::contract_instance_retrieval_nullifier_key_y, + ColumnAndShifts::contract_instance_retrieval_immutables_hash, + ColumnAndShifts::contract_instance_retrieval_nullifier_key_hash, ColumnAndShifts::contract_instance_retrieval_incoming_viewing_key_x, ColumnAndShifts::contract_instance_retrieval_incoming_viewing_key_y, - ColumnAndShifts::contract_instance_retrieval_outgoing_viewing_key_x, - ColumnAndShifts::contract_instance_retrieval_outgoing_viewing_key_y, - ColumnAndShifts::contract_instance_retrieval_tagging_key_x, - ColumnAndShifts::contract_instance_retrieval_tagging_key_y + ColumnAndShifts::contract_instance_retrieval_outgoing_viewing_key_hash, + ColumnAndShifts::contract_instance_retrieval_tagging_key_hash }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::address_derivation_address, @@ -134,14 +132,12 @@ struct lookup_contract_instance_retrieval_address_derivation_settings_ { ColumnAndShifts::address_derivation_deployer_addr, ColumnAndShifts::address_derivation_class_id, ColumnAndShifts::address_derivation_init_hash, - ColumnAndShifts::address_derivation_nullifier_key_x, - ColumnAndShifts::address_derivation_nullifier_key_y, + ColumnAndShifts::address_derivation_immutables_hash, + ColumnAndShifts::address_derivation_nullifier_key_hash, ColumnAndShifts::address_derivation_incoming_viewing_key_x, ColumnAndShifts::address_derivation_incoming_viewing_key_y, - ColumnAndShifts::address_derivation_outgoing_viewing_key_x, - ColumnAndShifts::address_derivation_outgoing_viewing_key_y, - ColumnAndShifts::address_derivation_tagging_key_x, - ColumnAndShifts::address_derivation_tagging_key_y + ColumnAndShifts::address_derivation_outgoing_viewing_key_hash, + ColumnAndShifts::address_derivation_tagging_key_hash }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_ecc_mem.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_ecc_mem.hpp index f8ccded46702..f10d3530128e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_ecc_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_ecc_mem.hpp @@ -22,7 +22,7 @@ struct lookup_ecc_mem_check_dst_addr_in_range_settings_ { static constexpr Column COUNTS = Column::lookup_ecc_mem_check_dst_addr_in_range_counts; static constexpr Column INVERSES = Column::lookup_ecc_mem_check_dst_addr_in_range_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::ecc_add_mem_dst_addr_2_, + ColumnAndShifts::ecc_add_mem_dst_addr_1_, ColumnAndShifts::ecc_add_mem_max_mem_addr, ColumnAndShifts::ecc_add_mem_sel_dst_out_of_range_err }; @@ -42,20 +42,20 @@ using lookup_ecc_mem_check_dst_addr_in_range_relation = struct lookup_ecc_mem_input_output_ecc_add_settings_ { static constexpr std::string_view NAME = "LOOKUP_ECC_MEM_INPUT_OUTPUT_ECC_ADD"; static constexpr std::string_view RELATION_NAME = "ecc_mem"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 9; + static constexpr size_t LOOKUP_TUPLE_SIZE = 8; static constexpr Column SRC_SELECTOR = Column::ecc_add_mem_sel_should_exec; static constexpr Column DST_SELECTOR = Column::ecc_sel; static constexpr Column COUNTS = Column::lookup_ecc_mem_input_output_ecc_add_counts; static constexpr Column INVERSES = Column::lookup_ecc_mem_input_output_ecc_add_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::ecc_add_mem_p_x_n, ColumnAndShifts::ecc_add_mem_p_y_n, ColumnAndShifts::ecc_add_mem_p_is_inf, - ColumnAndShifts::ecc_add_mem_q_x_n, ColumnAndShifts::ecc_add_mem_q_y_n, ColumnAndShifts::ecc_add_mem_q_is_inf, - ColumnAndShifts::ecc_add_mem_res_x, ColumnAndShifts::ecc_add_mem_res_y, ColumnAndShifts::ecc_add_mem_res_is_inf + ColumnAndShifts::ecc_add_mem_p_x, ColumnAndShifts::ecc_add_mem_p_y, ColumnAndShifts::ecc_add_mem_p_is_inf, + ColumnAndShifts::ecc_add_mem_q_x, ColumnAndShifts::ecc_add_mem_q_y, ColumnAndShifts::ecc_add_mem_q_is_inf, + ColumnAndShifts::ecc_add_mem_res_x, ColumnAndShifts::ecc_add_mem_res_y }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::ecc_p_x, ColumnAndShifts::ecc_p_y, ColumnAndShifts::ecc_p_is_inf, ColumnAndShifts::ecc_q_x, ColumnAndShifts::ecc_q_y, ColumnAndShifts::ecc_q_is_inf, - ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_r_is_inf + ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp index 44537395dab7..557d30fd5643 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp @@ -16,7 +16,7 @@ namespace bb::avm2 { struct lookup_get_contract_instance_precomputed_info_settings_ { static constexpr std::string_view NAME = "LOOKUP_GET_CONTRACT_INSTANCE_PRECOMPUTED_INFO"; static constexpr std::string_view RELATION_NAME = "get_contract_instance"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 5; + static constexpr size_t LOOKUP_TUPLE_SIZE = 6; static constexpr Column SRC_SELECTOR = Column::get_contract_instance_is_valid_writes_in_bounds; static constexpr Column DST_SELECTOR = Column::precomputed_sel_range_8; static constexpr Column COUNTS = Column::lookup_get_contract_instance_precomputed_info_counts; @@ -26,14 +26,13 @@ struct lookup_get_contract_instance_precomputed_info_settings_ { ColumnAndShifts::get_contract_instance_is_valid_member_enum, ColumnAndShifts::get_contract_instance_is_deployer, ColumnAndShifts::get_contract_instance_is_class_id, - ColumnAndShifts::get_contract_instance_is_init_hash + ColumnAndShifts::get_contract_instance_is_init_hash, + ColumnAndShifts::get_contract_instance_is_immutables_hash }; static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::precomputed_idx, - ColumnAndShifts::precomputed_is_valid_member_enum, - ColumnAndShifts::precomputed_is_deployer, - ColumnAndShifts::precomputed_is_class_id, - ColumnAndShifts::precomputed_is_init_hash + ColumnAndShifts::precomputed_idx, ColumnAndShifts::precomputed_is_valid_member_enum, + ColumnAndShifts::precomputed_is_deployer, ColumnAndShifts::precomputed_is_class_id, + ColumnAndShifts::precomputed_is_init_hash, ColumnAndShifts::precomputed_is_immutables_hash }; }; @@ -48,7 +47,7 @@ using lookup_get_contract_instance_precomputed_info_relation = struct lookup_get_contract_instance_contract_instance_retrieval_settings_ { static constexpr std::string_view NAME = "LOOKUP_GET_CONTRACT_INSTANCE_CONTRACT_INSTANCE_RETRIEVAL"; static constexpr std::string_view RELATION_NAME = "get_contract_instance"; - static constexpr size_t LOOKUP_TUPLE_SIZE = 7; + static constexpr size_t LOOKUP_TUPLE_SIZE = 8; static constexpr Column SRC_SELECTOR = Column::get_contract_instance_is_valid_member_enum; static constexpr Column DST_SELECTOR = Column::contract_instance_retrieval_sel; static constexpr Column COUNTS = Column::lookup_get_contract_instance_contract_instance_retrieval_counts; @@ -60,7 +59,8 @@ struct lookup_get_contract_instance_contract_instance_retrieval_settings_ { ColumnAndShifts::get_contract_instance_instance_exists, ColumnAndShifts::get_contract_instance_retrieved_deployer_addr, ColumnAndShifts::get_contract_instance_retrieved_class_id, - ColumnAndShifts::get_contract_instance_retrieved_init_hash + ColumnAndShifts::get_contract_instance_retrieved_init_hash, + ColumnAndShifts::get_contract_instance_retrieved_immutables_hash }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::contract_instance_retrieval_address, @@ -69,7 +69,8 @@ struct lookup_get_contract_instance_contract_instance_retrieval_settings_ { ColumnAndShifts::contract_instance_retrieval_exists, ColumnAndShifts::contract_instance_retrieval_deployer_addr, ColumnAndShifts::contract_instance_retrieval_current_class_id, - ColumnAndShifts::contract_instance_retrieval_init_hash + ColumnAndShifts::contract_instance_retrieval_init_hash, + ColumnAndShifts::contract_instance_retrieval_immutables_hash }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_scalar_mul.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_scalar_mul.hpp index 55f174a4a09b..b1878c5ca4a0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_scalar_mul.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_scalar_mul.hpp @@ -56,7 +56,7 @@ struct lookup_scalar_mul_double_settings_ { ColumnAndShifts::scalar_mul_sel_not_end }; static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_r_is_inf, + ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_result_infinity, ColumnAndShifts::ecc_p_x, ColumnAndShifts::ecc_p_y, ColumnAndShifts::ecc_p_is_inf, ColumnAndShifts::ecc_double_op }; @@ -84,7 +84,7 @@ struct lookup_scalar_mul_add_settings_ { ColumnAndShifts::scalar_mul_temp_inf }; static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_r_is_inf, + ColumnAndShifts::ecc_r_x, ColumnAndShifts::ecc_r_y, ColumnAndShifts::ecc_result_infinity, ColumnAndShifts::ecc_p_x, ColumnAndShifts::ecc_p_y, ColumnAndShifts::ecc_p_is_inf, ColumnAndShifts::ecc_q_x, ColumnAndShifts::ecc_q_y, ColumnAndShifts::ecc_q_is_inf }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory.hpp index 1a9fcea17707..774d0abe47ee 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory.hpp @@ -14,10 +14,10 @@ template class memoryImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, - 3, 3, 3, 5, 5, 2, 4, 4, 4, 4, 5, 3 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, + 3, 3, 3, 3, 3, 5, 5, 2, 4, 4, 4, 4, 5, 3 }; template inline static bool skip(const AllEntities& in) { @@ -38,18 +38,18 @@ template class memory : public Relation> { static constexpr const std::string_view NAME = "memory"; // Subrelation indices constants, to be used in tests. - static constexpr size_t SR_ACTIVE_ROW_NEEDS_PERM_SELECTOR = 41; - static constexpr size_t SR_MEM_CONTINUITY = 46; - static constexpr size_t SR_SEL_RNG_CHK = 47; - static constexpr size_t SR_LAST_ACCESS = 48; - static constexpr size_t SR_DIFF = 49; - static constexpr size_t SR_DIFF_DECOMP = 50; - static constexpr size_t SR_MEMORY_INIT_VALUE = 51; - static constexpr size_t SR_MEMORY_INIT_TAG = 52; - static constexpr size_t SR_READ_WRITE_CONSISTENCY_VALUE = 53; - static constexpr size_t SR_READ_WRITE_CONSISTENCY_TAG = 54; - static constexpr size_t SR_TAG_IS_FF = 55; - static constexpr size_t SR_SEL_RNG_WRITE = 56; + static constexpr size_t SR_ACTIVE_ROW_NEEDS_PERM_SELECTOR = 40; + static constexpr size_t SR_MEM_CONTINUITY = 45; + static constexpr size_t SR_SEL_RNG_CHK = 46; + static constexpr size_t SR_LAST_ACCESS = 47; + static constexpr size_t SR_DIFF = 48; + static constexpr size_t SR_DIFF_DECOMP = 49; + static constexpr size_t SR_MEMORY_INIT_VALUE = 50; + static constexpr size_t SR_MEMORY_INIT_TAG = 51; + static constexpr size_t SR_READ_WRITE_CONSISTENCY_VALUE = 52; + static constexpr size_t SR_READ_WRITE_CONSISTENCY_TAG = 53; + static constexpr size_t SR_TAG_IS_FF = 54; + static constexpr size_t SR_SEL_RNG_WRITE = 55; static std::string get_subrelation_label(size_t index) { diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory_impl.hpp index 796a1744fad2..b79718f77609 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/memory_impl.hpp @@ -261,18 +261,12 @@ void memoryImpl::accumulate(ContainerOverSubrelations& evals, } { using View = typename std::tuple_element_t<39, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::memory_sel_ecc_write_2_)) * - (FF(1) - static_cast(in.get(C::memory_sel_ecc_write_2_))); - std::get<39>(evals) += (tmp * scaling_factor); - } - { - using View = typename std::tuple_element_t<40, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel_to_radix_write)) * (FF(1) - static_cast(in.get(C::memory_sel_to_radix_write))); - std::get<40>(evals) += (tmp * scaling_factor); + std::get<39>(evals) += (tmp * scaling_factor); } { // ACTIVE_ROW_NEEDS_PERM_SELECTOR - using View = typename std::tuple_element_t<41, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<40, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_sel)) - (static_cast(in.get(C::memory_sel_addressing_base)) + @@ -313,118 +307,117 @@ void memoryImpl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::memory_sel_sha256_op_7_)) + static_cast(in.get(C::memory_sel_ecc_write_0_)) + static_cast(in.get(C::memory_sel_ecc_write_1_)) + - static_cast(in.get(C::memory_sel_ecc_write_2_)) + static_cast(in.get(C::memory_sel_to_radix_write)))); - std::get<41>(evals) += (tmp * scaling_factor); + std::get<40>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<42, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<41, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel)) * (FF(1) - static_cast(in.get(C::memory_sel))); - std::get<42>(evals) += (tmp * scaling_factor); + std::get<41>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<43, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<42, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_last_access)) * (FF(1) - static_cast(in.get(C::memory_last_access))); - std::get<43>(evals) += (tmp * scaling_factor); + std::get<42>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<44, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<43, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_rw)) * (FF(1) - static_cast(in.get(C::memory_rw))); - std::get<44>(evals) += (tmp * scaling_factor); + std::get<43>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<45, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<44, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel_tag_is_ff)) * (FF(1) - static_cast(in.get(C::memory_sel_tag_is_ff))); - std::get<45>(evals) += (tmp * scaling_factor); + std::get<44>(evals) += (tmp * scaling_factor); } { // MEM_CONTINUITY - using View = typename std::tuple_element_t<46, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<45, ContainerOverSubrelations>::View; auto tmp = ((FF(1) - static_cast(in.get(C::precomputed_first_row))) - static_cast(in.get(C::memory_sel))) * static_cast(in.get(C::memory_sel_shift)); - std::get<46>(evals) += (tmp * scaling_factor); + std::get<45>(evals) += (tmp * scaling_factor); } { // SEL_RNG_CHK - using View = typename std::tuple_element_t<47, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<46, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_sel_rng_chk)) - static_cast(in.get(C::memory_sel)) * static_cast(in.get(C::memory_sel_shift))); - std::get<47>(evals) += (tmp * scaling_factor); + std::get<46>(evals) += (tmp * scaling_factor); } { // LAST_ACCESS - using View = typename std::tuple_element_t<48, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<47, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel_rng_chk)) * (CView(memory_GLOBAL_ADDR_DIFF) * ((FF(1) - static_cast(in.get(C::memory_last_access))) * (FF(1) - static_cast(in.get(C::memory_glob_addr_diff_inv))) + static_cast(in.get(C::memory_glob_addr_diff_inv))) - static_cast(in.get(C::memory_last_access))); - std::get<48>(evals) += (tmp * scaling_factor); + std::get<47>(evals) += (tmp * scaling_factor); } { // DIFF - using View = typename std::tuple_element_t<49, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<48, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_diff)) - static_cast(in.get(C::memory_sel_rng_chk)) * (static_cast(in.get(C::memory_last_access)) * CView(memory_GLOBAL_ADDR_DIFF) + (FF(1) - static_cast(in.get(C::memory_last_access))) * (CView(memory_TIMESTAMP_DIFF) - static_cast(in.get(C::memory_rw_shift)) * static_cast(in.get(C::memory_rw))))); - std::get<49>(evals) += (tmp * scaling_factor); + std::get<48>(evals) += (tmp * scaling_factor); } { // DIFF_DECOMP - using View = typename std::tuple_element_t<50, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<49, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_diff)) - (static_cast(in.get(C::memory_limb_0_)) + static_cast(in.get(C::memory_limb_1_)) * FF(65536) + static_cast(in.get(C::memory_limb_2_)) * FF(4294967296UL))); - std::get<50>(evals) += (tmp * scaling_factor); + std::get<49>(evals) += (tmp * scaling_factor); } { // MEMORY_INIT_VALUE - using View = typename std::tuple_element_t<51, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<50, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_last_access)) + static_cast(in.get(C::precomputed_first_row))) * (FF(1) - static_cast(in.get(C::memory_rw_shift))) * static_cast(in.get(C::memory_value_shift)); - std::get<51>(evals) += (tmp * scaling_factor); + std::get<50>(evals) += (tmp * scaling_factor); } { // MEMORY_INIT_TAG - using View = typename std::tuple_element_t<52, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<51, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_last_access)) + static_cast(in.get(C::precomputed_first_row))) * (FF(1) - static_cast(in.get(C::memory_rw_shift))) * (static_cast(in.get(C::memory_tag_shift)) - CView(constants_MEM_TAG_FF)); - std::get<52>(evals) += (tmp * scaling_factor); + std::get<51>(evals) += (tmp * scaling_factor); } { // READ_WRITE_CONSISTENCY_VALUE - using View = typename std::tuple_element_t<53, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<52, ContainerOverSubrelations>::View; auto tmp = (FF(1) - static_cast(in.get(C::memory_last_access))) * (FF(1) - static_cast(in.get(C::memory_rw_shift))) * (static_cast(in.get(C::memory_value_shift)) - static_cast(in.get(C::memory_value))); - std::get<53>(evals) += (tmp * scaling_factor); + std::get<52>(evals) += (tmp * scaling_factor); } { // READ_WRITE_CONSISTENCY_TAG - using View = typename std::tuple_element_t<54, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<53, ContainerOverSubrelations>::View; auto tmp = (FF(1) - static_cast(in.get(C::memory_last_access))) * (FF(1) - static_cast(in.get(C::memory_rw_shift))) * (static_cast(in.get(C::memory_tag_shift)) - static_cast(in.get(C::memory_tag))); - std::get<54>(evals) += (tmp * scaling_factor); + std::get<53>(evals) += (tmp * scaling_factor); } { // TAG_IS_FF - using View = typename std::tuple_element_t<55, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<54, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::memory_sel)) * ((CView(memory_TAG_FF_DIFF) * (static_cast(in.get(C::memory_sel_tag_is_ff)) * (FF(1) - static_cast(in.get(C::memory_tag_ff_diff_inv))) + static_cast(in.get(C::memory_tag_ff_diff_inv))) + static_cast(in.get(C::memory_sel_tag_is_ff))) - FF(1)); - std::get<55>(evals) += (tmp * scaling_factor); + std::get<54>(evals) += (tmp * scaling_factor); } { // SEL_RNG_WRITE - using View = typename std::tuple_element_t<56, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<55, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::memory_sel_rng_write)) - static_cast(in.get(C::memory_rw)) * (FF(1) - static_cast(in.get(C::memory_sel_tag_is_ff)))); - std::get<56>(evals) += (tmp * scaling_factor); + std::get<55>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_ecc_mem.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_ecc_mem.hpp index 57a85acc0089..f4965a2e1901 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_ecc_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_ecc_mem.hpp @@ -59,28 +59,4 @@ using perm_ecc_mem_write_mem_1_settings = permutation_settings using perm_ecc_mem_write_mem_1_relation = permutation_relation_base; -/////////////////// perm_ecc_mem_write_mem_2 /////////////////// - -struct perm_ecc_mem_write_mem_2_settings_ { - static constexpr std::string_view NAME = "PERM_ECC_MEM_WRITE_MEM_2"; - static constexpr std::string_view RELATION_NAME = "ecc_mem"; - static constexpr size_t COLUMNS_PER_SET = 6; - static constexpr Column SRC_SELECTOR = Column::ecc_add_mem_sel_should_exec; - static constexpr Column DST_SELECTOR = Column::memory_sel_ecc_write_2_; - static constexpr Column INVERSES = Column::perm_ecc_mem_write_mem_2_inv; - static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::ecc_add_mem_execution_clk, ColumnAndShifts::ecc_add_mem_space_id, - ColumnAndShifts::ecc_add_mem_dst_addr_2_, ColumnAndShifts::ecc_add_mem_res_is_inf, - ColumnAndShifts::ecc_add_mem_sel_should_exec, ColumnAndShifts::ecc_add_mem_sel_should_exec - }; - static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::memory_clk, ColumnAndShifts::memory_space_id, ColumnAndShifts::memory_address, - ColumnAndShifts::memory_value, ColumnAndShifts::memory_tag, ColumnAndShifts::memory_rw - }; -}; - -using perm_ecc_mem_write_mem_2_settings = permutation_settings; -template -using perm_ecc_mem_write_mem_2_relation = permutation_relation_base; - } // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_execution.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_execution.hpp index a171ea2203bc..0cc2e72ecab0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_execution.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/perms_execution.hpp @@ -256,7 +256,7 @@ using perm_execution_dispatch_to_keccakf1600_relation = struct perm_execution_dispatch_to_ecc_add_settings_ { static constexpr std::string_view NAME = "PERM_EXECUTION_DISPATCH_TO_ECC_ADD"; static constexpr std::string_view RELATION_NAME = "execution"; - static constexpr size_t COLUMNS_PER_SET = 10; + static constexpr size_t COLUMNS_PER_SET = 8; static constexpr Column SRC_SELECTOR = Column::execution_sel_exec_dispatch_ecc_add; static constexpr Column DST_SELECTOR = Column::ecc_add_mem_sel; static constexpr Column INVERSES = Column::perm_execution_dispatch_to_ecc_add_inv; @@ -264,14 +264,12 @@ struct perm_execution_dispatch_to_ecc_add_settings_ { ColumnAndShifts::execution_clk, ColumnAndShifts::execution_context_id, ColumnAndShifts::execution_register_0_, ColumnAndShifts::execution_register_1_, ColumnAndShifts::execution_register_2_, ColumnAndShifts::execution_register_3_, - ColumnAndShifts::execution_register_4_, ColumnAndShifts::execution_register_5_, - ColumnAndShifts::execution_rop_6_, ColumnAndShifts::execution_sel_opcode_error + ColumnAndShifts::execution_rop_4_, ColumnAndShifts::execution_sel_opcode_error }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::ecc_add_mem_execution_clk, ColumnAndShifts::ecc_add_mem_space_id, ColumnAndShifts::ecc_add_mem_p_x, ColumnAndShifts::ecc_add_mem_p_y, - ColumnAndShifts::ecc_add_mem_p_is_inf, ColumnAndShifts::ecc_add_mem_q_x, - ColumnAndShifts::ecc_add_mem_q_y, ColumnAndShifts::ecc_add_mem_q_is_inf, + ColumnAndShifts::ecc_add_mem_q_x, ColumnAndShifts::ecc_add_mem_q_y, ColumnAndShifts::ecc_add_mem_dst_addr_0_, ColumnAndShifts::ecc_add_mem_err }; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/address_derivation_event.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/address_derivation_event.hpp index d84d9391653e..1dbc56aff5f9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/address_derivation_event.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/address_derivation_event.hpp @@ -10,6 +10,7 @@ struct AddressDerivationEvent { ContractInstance instance{}; FF salted_initialization_hash = 0; FF partial_address = 0; + FF incoming_viewing_key_hash = 0; FF public_keys_hash = 0; FF preaddress = 0; EmbeddedCurvePoint preaddress_public_key = EmbeddedCurvePoint::infinity(); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/get_contract_instance_event.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/get_contract_instance_event.hpp index a9d7b7195c10..bbc0ecc89a1c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/get_contract_instance_event.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/get_contract_instance_event.hpp @@ -26,12 +26,13 @@ struct GetContractInstanceEvent { FF nullifier_tree_root = 0; FF public_data_tree_root = 0; - // Instance retrieval results including all three members which are all needed for tracegen + // Instance retrieval results including all four members which are all needed for tracegen // despite only needing the selected member in simulation. bool instance_exists = false; FF retrieved_deployer_addr = 0; FF retrieved_class_id = 0; FF retrieved_init_hash = 0; + FF retrieved_immutables_hash = 0; }; } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.cpp index a52fb7c0ef01..db1d13f6ed24 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.cpp @@ -15,19 +15,21 @@ namespace bb::avm2::simulation { * If the address has already been derived, an event has already been emitted and we skip * repeating the computation and emission. Otherwise, we compute the address from the instance * members using the poseidon2, scalar_mul, and ecc traces, which is given as: - * 1. salted_init_hash = Poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr) - * 2. partial_address = Poseidon2(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash) - * 3. public_keys_hash = Poseidon2(DOM_SEP__PUBLIC_KEYS_HASH, [...public_keys.to_fields()]) - * 4. preaddress = Poseidon2(DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address) - * 5. preaddress_public_key = preaddress * G1 (Grumpkin scalar multiplication) - * 6. address = (preaddress_public_key + incoming_viewing_key).x (Grumpkin EC add) + * 1. salted_init_hash = Poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr, + * immutables_hash) + * 2. partial_address = Poseidon2(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash) + * 3. incoming_viewing_key_hash = Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, ivpk.x, ivpk.y) + * 4. public_keys_hash = Poseidon2(DOM_SEP__PUBLIC_KEYS_HASH, + * nullifier_key_hash, incoming_viewing_key_hash, outgoing_viewing_key_hash, + * tagging_key_hash) + * 5. preaddress = Poseidon2(DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address) + * 6. preaddress_public_key = preaddress * G1 (Grumpkin scalar multiplication) + * 7. address = (preaddress_public_key + incoming_viewing_key).x (Grumpkin EC add) * and we add the output to the local cache. * - * @throws Unexpected exception if - * - the calculated address does not match @p address. - * * @param address The expected derived address. - * @param instance The contract instance containing the address preimage. + * @param instance The contract instance containing the address preimage members. + * @throws Unexpected exception if the calculated address does not match @p address. */ void AddressDerivation::assert_derivation(const AztecAddress& address, const ContractInstance& instance) { @@ -44,28 +46,31 @@ void AddressDerivation::assert_derivation(const AztecAddress& address, const Con // First time seeing this address - do the actual derivation. // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[SALTED_INITIALIZATION_HASH_POSEIDON2_i] in // address_derivation.pil. - FF salted_initialization_hash = poseidon2.hash( - { DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer }); + FF salted_initialization_hash = poseidon2.hash({ DOM_SEP__SALTED_INITIALIZATION_HASH, + instance.salt, + instance.initialization_hash, + instance.deployer, + instance.immutables_hash }); + // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PARTIAL_ADDRESS_POSEIDON2] in // address_derivation.pil. FF partial_address = poseidon2.hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash }); - std::vector public_keys_hash_fields = instance.public_keys.to_fields(); - std::vector public_key_hash_vec{ DOM_SEP__PUBLIC_KEYS_HASH }; - for (size_t i = 0; i < public_keys_hash_fields.size(); i += 2) { - // Public key x coordinate. - public_key_hash_vec.push_back(public_keys_hash_fields[i]); - // Public key y coordinate. - public_key_hash_vec.push_back(public_keys_hash_fields[i + 1]); - // TODO(#7529): Public key is_infinity will be removed from address preimage, assuming false. - public_key_hash_vec.push_back(FF::zero()); - } - // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PUBLIC_KEYS_HASH_POSEIDON2_i] in - // address_derivation.pil. - FF public_keys_hash = poseidon2.hash(public_key_hash_vec); + // incoming_viewing_key_hash is the only single-key hash computed in-circuit (see #[IVPK_M_HASH_POSEIDON2]). + FF incoming_viewing_key_hash = poseidon2.hash({ DOM_SEP__SINGLE_PUBLIC_KEY_HASH, + instance.public_keys.incoming_viewing_key.x, + instance.public_keys.incoming_viewing_key.y }); + + // public_keys_hash combines the four single-key hashes (see #[PUBLIC_KEYS_HASH_POSEIDON2_0..1]). + FF public_keys_hash = poseidon2.hash({ DOM_SEP__PUBLIC_KEYS_HASH, + instance.public_keys.nullifier_key_hash, + incoming_viewing_key_hash, + instance.public_keys.outgoing_viewing_key_hash, + instance.public_keys.tagging_key_hash }); + // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PREADDRESS_POSEIDON2] in address_derivation.pil. - FF preaddress = poseidon2.hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }); + FF preaddress = poseidon2.hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }); // Note: the below ecc calls assume points are on the curve. We know preaddress_public_key is (by definition), // but it may be possible that incoming_viewing_key is not. @@ -91,6 +96,7 @@ void AddressDerivation::assert_derivation(const AztecAddress& address, const Con .instance = instance, .salted_initialization_hash = salted_initialization_hash, .partial_address = partial_address, + .incoming_viewing_key_hash = incoming_viewing_key_hash, .public_keys_hash = public_keys_hash, .preaddress = preaddress, .preaddress_public_key = preaddress_public_key, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.test.cpp index 523e7ee6fd5a..aae699067b58 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/address_derivation.test.cpp @@ -40,9 +40,11 @@ TEST(AvmSimulationAddressDerivationTest, Positive) ContractInstance instance = testing::random_contract_instance(); AztecAddress derived_address = compute_contract_address(instance); - std::vector salted_init_hash_inputs = { - DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer - }; + std::vector salted_init_hash_inputs = { DOM_SEP__SALTED_INITIALIZATION_HASH, + instance.salt, + instance.initialization_hash, + instance.deployer, + instance.immutables_hash }; FF salted_init_hash = poseidon2::hash(salted_init_hash_inputs); std::vector partial_address_inputs = { DOM_SEP__PARTIAL_ADDRESS, @@ -52,7 +54,7 @@ TEST(AvmSimulationAddressDerivationTest, Positive) FF public_keys_hash = hash_public_keys(instance.public_keys); - std::vector preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }; + std::vector preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }; FF preaddress = poseidon2::hash(preaddress_inputs); EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one(); @@ -93,9 +95,11 @@ TEST(AvmSimulationAddressDerivationTest, Negative) ContractInstance instance = testing::random_contract_instance(); AztecAddress derived_address = compute_contract_address(instance); - std::vector salted_init_hash_inputs = { - DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer - }; + std::vector salted_init_hash_inputs = { DOM_SEP__SALTED_INITIALIZATION_HASH, + instance.salt, + instance.initialization_hash, + instance.deployer, + instance.immutables_hash }; FF salted_init_hash = poseidon2::hash(salted_init_hash_inputs); std::vector partial_address_inputs = { DOM_SEP__PARTIAL_ADDRESS, @@ -105,7 +109,7 @@ TEST(AvmSimulationAddressDerivationTest, Negative) FF public_keys_hash = hash_public_keys(instance.public_keys); - std::vector preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }; + std::vector preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }; FF preaddress = poseidon2::hash(preaddress_inputs); EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one(); @@ -120,10 +124,10 @@ TEST(AvmSimulationAddressDerivationTest, Negative) EXPECT_THROW(address_derivation.assert_derivation(derived_address + 1, instance), std::runtime_error); // Should fail on mutated instance for unseen address. - instance.public_keys.nullifier_key = AffinePoint::one(); + instance.public_keys.nullifier_key_hash = FF(0xdeadbeef); public_keys_hash = hash_public_keys(instance.public_keys); - preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }; + preaddress_inputs = { DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }; preaddress = poseidon2::hash(preaddress_inputs); preaddress_public_key = g1 * Fq(preaddress); address_point = preaddress_public_key + instance.public_keys.incoming_viewing_key; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp index 0f3e66759b28..5d4244697de8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp @@ -18,7 +18,7 @@ class InternalEccException : public std::runtime_error { * @brief Adds Grumpkin curve points P and Q and emits an EccAddEvent. * Corresponds to the non-memory aware subtrace ecc.pil. * - * @throws Unexpected exception if points are not on the curve or not normalized. + * @throws Unexpected exception if points are not on the curve. * Note: This function assumes that the points p and q are on the curve. You should only use this function internally * if you can guarantee this. Otherwise it is called via the opcode ECADD, see the overloaded function Ecc::add (which * performs the curve check). @@ -32,13 +32,6 @@ EmbeddedCurvePoint Ecc::add(const EmbeddedCurvePoint& p, const EmbeddedCurvePoin // Check if points are on the curve. These will throw an unexpected exception if they fail. BB_ASSERT(p.on_curve(), "Point p is not on the curve"); BB_ASSERT(q.on_curve(), "Point q is not on the curve"); - // Check if the points are normalized (infinity points must be (0, 0, true)). - if (p.is_infinity()) { - BB_ASSERT((p.x() == 0) && (p.y() == 0), "Point p is not normalized"); - } - if (q.is_infinity()) { - BB_ASSERT((q.x() == 0) && (q.y() == 0), "Point q is not normalized"); - } EmbeddedCurvePoint result = p + q; add_events.emit({ .p = p, .q = q, .result = result }); @@ -70,14 +63,11 @@ EmbeddedCurvePoint Ecc::scalar_mul(const EmbeddedCurvePoint& point, const FF& sc // Emits ToRadixEvent, see #[TO_RADIX] in scalar_mul.pil. auto bits = to_radix.to_le_bits(scalar, 254).first; - // Normalize input infinity point (infinity points must be (0, 0, true)). - EmbeddedCurvePoint point_input = point.is_infinity() ? EmbeddedCurvePoint::infinity() : point; - // First iteration does conditional assignment instead of addition. Note: in circuit we perform reverse aggregation, // so the corresponding constraints for below are gated by 'end'. // See 'Temp Computation' section in scalar_mul.pil. - EmbeddedCurvePoint temp = point_input; + EmbeddedCurvePoint temp = point; bool bit = bits[0]; // See 'Result Computation' section in scalar_mul.pil. @@ -94,10 +84,8 @@ EmbeddedCurvePoint Ecc::scalar_mul(const EmbeddedCurvePoint& point, const FF& sc } intermediate_states[i] = { result, temp, bit }; } - scalar_mul_events.emit({ .point = point_input, - .scalar = scalar, - .intermediate_states = std::move(intermediate_states), - .result = result }); + scalar_mul_events.emit( + { .point = point, .scalar = scalar, .intermediate_states = std::move(intermediate_states), .result = result }); return result; } @@ -124,11 +112,9 @@ void Ecc::add(MemoryInterface& memory, uint16_t space_id = memory.get_space_id(); try { - // The resulting EmbeddedCurvePoint is a triple of (x, y, is_infinity). - // The x and y coordinates are stored at dst_address and dst_address + 1 respectively, - // and the is_infinity flag is stored at dst_address + 2. - // Therefore, the maximum address that needs to be written to is dst_address + 2. - uint64_t max_write_address = static_cast(dst_address) + 2; + // The resulting EmbeddedCurvePoint is (x, y), stored at dst_address and dst_address + 1 respectively. + // Therefore, the maximum address that needs to be written to is dst_address + 1. + uint64_t max_write_address = static_cast(dst_address) + 1; // Emits GreaterThanEvent, see #[CHECK_DST_ADDR_IN_RANGE] in ecc_mem.pil. if (gt.gt(max_write_address, AVM_HIGHEST_MEM_ADDRESS)) { throw InternalEccException("dst address out of range"); @@ -138,18 +124,12 @@ void Ecc::add(MemoryInterface& memory, throw InternalEccException("One of the points is not on the curve"); } - // Normalize input infinity points. - EmbeddedCurvePoint p_input = p.is_infinity() ? EmbeddedCurvePoint::infinity() : p; - EmbeddedCurvePoint q_input = q.is_infinity() ? EmbeddedCurvePoint::infinity() : q; - // Emits EccAddEvent, see #[INPUT_OUTPUT_ECC_ADD] in ecc_mem.pil. - EmbeddedCurvePoint result = - add(p_input, q_input); // Cannot throw since we have checked on_curve() and normalized. + EmbeddedCurvePoint result = add(p, q); // Cannot throw since we have checked on_curve(). - // Emits MemoryEvents, see #[WRITE_MEM_i] for i = 0, 1, 2, in ecc_mem.pil. + // Emits MemoryEvents, see #[WRITE_MEM_i] for i = 0, 1 in ecc_mem.pil. memory.set(dst_address, MemoryValue::from(result.x())); memory.set(dst_address + 1, MemoryValue::from(result.y())); - memory.set(dst_address + 2, MemoryValue::from(result.is_infinity() ? 1 : 0)); add_memory_events.emit({ .execution_clk = execution_clk, .space_id = space_id, @@ -158,9 +138,11 @@ void Ecc::add(MemoryInterface& memory, .result = result, .dst_address = dst_address }); } catch (const InternalEccException& e) { - // Note this point is not on the curve, but corresponds - // to default values the circuit will assign. - EmbeddedCurvePoint res = EmbeddedCurvePoint(0, 0, false); + // Note this point is technically infinity, but we are treating it as 'empty' to corresponds + // to default values the circuit will assign. Since we have caught an InternalEccException, + // we have an error which the circuit should recognise and assign sel_should_exec == 0, so res will not be + // treated as inf. + EmbeddedCurvePoint res = EmbeddedCurvePoint(0, 0); add_memory_events.emit({ .execution_clk = execution_clk, .space_id = space_id, .p = p, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp index c47cdef79b2e..6667c3573883 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp @@ -37,11 +37,11 @@ TEST(AvmSimulationEccTest, Add) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); EmbeddedCurvePoint result = ecc.add(p, q); @@ -74,7 +74,7 @@ TEST(AvmSimulationEccTest, ScalarMul) FF scalar("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); uint256_t scalar_num = scalar; - std::vector bits(254, false); + std::vector bits(254); for (size_t i = 0; i < 254; ++i) { bits[i] = scalar_num.get_bit(i); } @@ -83,7 +83,7 @@ TEST(AvmSimulationEccTest, ScalarMul) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); EmbeddedCurvePoint result = ecc.scalar_mul(p, scalar); @@ -128,7 +128,7 @@ TEST(AvmSimulationEccDeathTest, ScalarMulNotOnCurve) // Point P is not on the curve FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); FF scalar("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); @@ -148,29 +148,27 @@ TEST(AvmSimulationEccTest, AddWithMemory) MemoryStore memory; EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); - EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + EXPECT_CALL(gt, gt(0x1000 + 1, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); Ecc ecc( execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint expected_result(r_x, r_y, false); + EmbeddedCurvePoint expected_result(r_x, r_y); uint32_t dst_address = 0x1000; ecc.add(memory, p, q, dst_address); - EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(), - memory.get(dst_address + 1).as_ff(), - static_cast(memory.get(dst_address + 2).as_ff()) }; + EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(), memory.get(dst_address + 1).as_ff() }; EXPECT_EQ(result, expected_result); } @@ -186,7 +184,7 @@ TEST(AvmSimulationEccTest, AddNotOnCurve) MemoryStore memory; EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); - EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + EXPECT_CALL(gt, gt(0x1000 + 1, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); Ecc ecc( execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); @@ -194,12 +192,12 @@ TEST(AvmSimulationEccTest, AddNotOnCurve) // Point P is not on the curve FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); // Point Q is on the curve FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); uint32_t dst_address = 0x1000; EXPECT_THROW(ecc.add(memory, p, q, dst_address), EccException); @@ -217,7 +215,7 @@ TEST(AvmSimulationEccTest, InfinityOnCurve) MemoryStore memory; EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); - EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + EXPECT_CALL(gt, gt(0x1000 + 1, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); Ecc ecc( execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); @@ -228,14 +226,12 @@ TEST(AvmSimulationEccTest, InfinityOnCurve) // Point Q is on the curve FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); uint32_t dst_address = 0x1000; ecc.add(memory, p, q, dst_address); - EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(), - memory.get(dst_address + 1).as_ff(), - static_cast(memory.get(dst_address + 2).as_ff()) }; + EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(), memory.get(dst_address + 1).as_ff() }; // INF + Q = Q EXPECT_EQ(result, q); } @@ -252,7 +248,7 @@ TEST(AvmSimulationEccTest, AddsUpToInfinity) MemoryStore memory; EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); - EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + EXPECT_CALL(gt, gt(0x1000 + 1, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); Ecc ecc( execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); @@ -260,7 +256,7 @@ TEST(AvmSimulationEccTest, AddsUpToInfinity) // Both points on the curve, q = -p FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); EmbeddedCurvePoint q = -p; @@ -270,8 +266,6 @@ TEST(AvmSimulationEccTest, AddsUpToInfinity) // Zero as coordinates EXPECT_EQ(memory.get(dst_address).as_ff(), FF(0)); EXPECT_EQ(memory.get(dst_address + 1).as_ff(), FF(0)); - // Infinity - EXPECT_EQ(memory.get(dst_address + 2).as_ff(), 1); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp index 8677802581c5..d7198445dee9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp @@ -1469,19 +1469,15 @@ void Execution::poseidon2_permutation(ContextInterface& context, MemoryAddress s * @param context The context. * @param p_x_addr The resolved address of the x coordinate of the first point. * @param p_y_addr The resolved address of the y coordinate of the first point. - * @param p_inf_addr The resolved address of the infinity flag of the first point. * @param q_x_addr The resolved address of the x coordinate of the second point. * @param q_y_addr The resolved address of the y coordinate of the second point. - * @param q_inf_addr The resolved address of the infinity flag of the second point. * @param dst_addr The resolved address of the destination memory address. * * @throws RegisterValidationException if the tags of the input values do not match the expected tags: * - tag of the memory value at p_x_addr is not FF. * - tag of the memory value at p_y_addr is not FF. - * - tag of the memory value at p_inf_addr is not U1. * - tag of the memory value at q_x_addr is not FF. * - tag of the memory value at q_y_addr is not FF. - * - tag of the memory value at q_inf_addr is not U1. * @throws OutOfGasException if the gas limit is exceeded. * @throws OpcodeExecutionException if the elliptic curve addition operation fails: * - memory write out of bounds. @@ -1490,10 +1486,8 @@ void Execution::poseidon2_permutation(ContextInterface& context, MemoryAddress s void Execution::ecc_add(ContextInterface& context, MemoryAddress p_x_addr, MemoryAddress p_y_addr, - MemoryAddress p_inf_addr, MemoryAddress q_x_addr, MemoryAddress q_y_addr, - MemoryAddress q_inf_addr, MemoryAddress dst_addr) { BB_BENCH_NAME("Execution::ecc_add"); @@ -1503,19 +1497,17 @@ void Execution::ecc_add(ContextInterface& context, // Read the points from memory. const auto& p_x = memory.get(p_x_addr); const auto& p_y = memory.get(p_y_addr); - const auto& p_inf = memory.get(p_inf_addr); const auto& q_x = memory.get(q_x_addr); const auto& q_y = memory.get(q_y_addr); - const auto& q_inf = memory.get(q_inf_addr); - set_and_validate_inputs(opcode, { p_x, p_y, p_inf, q_x, q_y, q_inf }); + set_and_validate_inputs(opcode, { p_x, p_y, q_x, q_y }); get_gas_tracker().consume_gas(); // Once inputs are tag checked the conversion to EmbeddedCurvePoint is safe, on curve checks are done in the add // method. - EmbeddedCurvePoint p = EmbeddedCurvePoint(p_x.as_ff(), p_y.as_ff(), p_inf == MemoryValue::from(1)); - EmbeddedCurvePoint q = EmbeddedCurvePoint(q_x.as_ff(), q_y.as_ff(), q_inf == MemoryValue::from(1)); + EmbeddedCurvePoint p = EmbeddedCurvePoint(p_x.as_ff(), p_y.as_ff()); + EmbeddedCurvePoint q = EmbeddedCurvePoint(q_x.as_ff(), q_y.as_ff()); try { embedded_curve.add(memory, p, q, dst_addr); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp index 2c40a5d412f3..af2ade7692ad 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp @@ -173,10 +173,8 @@ class Execution : public ExecutionInterface { void ecc_add(ContextInterface& context, MemoryAddress p_x_addr, MemoryAddress p_y_addr, - MemoryAddress p_inf_addr, MemoryAddress q_x_addr, MemoryAddress q_y_addr, - MemoryAddress q_inf_addr, MemoryAddress dst_addr); void to_radix_be(ContextInterface& context, MemoryAddress value_addr, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp index 8824c8fe91a0..234e8b4e409b 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp @@ -1034,29 +1034,24 @@ TEST_F(ExecutionSimulationTest, EccAdd) { MemoryAddress p_x_addr = 10; MemoryAddress p_y_addr = 15; - MemoryAddress p_is_inf_addr = 25; MemoryAddress q_x_addr = 20; MemoryAddress q_y_addr = 30; - MemoryAddress q_is_inf_addr = 35; MemoryAddress dst_addr = 40; MemoryValue p_x = MemoryValue::from(FF("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a")); MemoryValue p_y = MemoryValue::from(FF("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60")); - EmbeddedCurvePoint p(p_x.as_ff(), p_y, false); + EmbeddedCurvePoint p(p_x.as_ff(), p_y); MemoryValue q_x = MemoryValue::from(FF("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7")); MemoryValue q_y = MemoryValue::from(FF("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3")); - EmbeddedCurvePoint q(q_x.as_ff(), q_y.as_ff(), false); + EmbeddedCurvePoint q(q_x.as_ff(), q_y.as_ff()); // Mock the context and memory interactions - MemoryValue zero = MemoryValue::from(0); EXPECT_CALL(context, get_memory()).WillRepeatedly(ReturnRef(memory)); EXPECT_CALL(Const(memory), get(p_x_addr)).WillOnce(ReturnRef(p_x)); EXPECT_CALL(memory, get(p_y_addr)).WillOnce(ReturnRef(p_y)); - EXPECT_CALL(memory, get(p_is_inf_addr)).WillOnce(ReturnRef(zero)); // p is not infinity EXPECT_CALL(memory, get(q_x_addr)).WillOnce(ReturnRef(q_x)); EXPECT_CALL(memory, get(q_y_addr)).WillOnce(ReturnRef(q_y)); - EXPECT_CALL(memory, get(q_is_inf_addr)).WillOnce(ReturnRef(zero)); // q is not infinity EXPECT_CALL(gas_tracker, consume_gas); @@ -1064,7 +1059,7 @@ TEST_F(ExecutionSimulationTest, EccAdd) EXPECT_CALL(ecc, add(_, _, _, dst_addr)); // Execute the ECC add operation - execution.ecc_add(context, p_x_addr, p_y_addr, p_is_inf_addr, q_x_addr, q_y_addr, q_is_inf_addr, dst_addr); + execution.ecc_add(context, p_x_addr, p_y_addr, q_x_addr, q_y_addr, dst_addr); } TEST_F(ExecutionSimulationTest, ToRadixBE) diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/get_contract_instance.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/get_contract_instance.cpp index 91b2818a724c..c79ed4ae21b7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/get_contract_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/get_contract_instance.cpp @@ -39,7 +39,8 @@ GetContractInstance::GetContractInstance(ExecutionIdManagerInterface& execution_ * @param memory The memory interface for the current context. * @param contract_address The address of the contract to look up. * @param dst_offset The memory offset at which to write the exists flag. - * @param member_enum The enum selecting which instance member to retrieve (deployer/class_id/init_hash). + * @param member_enum The enum selecting which instance member to retrieve + * (deployer/class_id/init_hash/immutables_hash). * @throws GetContractInstanceException If dst_offset+1 is out of bounds (checked first). * @throws GetContractInstanceException If member_enum is invalid (checked after bounds check). */ @@ -90,17 +91,20 @@ void GetContractInstance::get_contract_instance(MemoryInterface& memory, instance_exists ? select_instance_member(maybe_instance.value(), member_enum) : FF(0); write_results(memory, dst_offset, instance_exists, selected_member_value); - event_emitter.emit({ .execution_clk = execution_clk, - .contract_address = contract_address, - .dst_offset = dst_offset, - .member_enum = member_enum, - .space_id = space_id, - .nullifier_tree_root = nullifier_tree_root, - .public_data_tree_root = public_data_tree_root, - .instance_exists = instance_exists, - .retrieved_deployer_addr = instance_exists ? maybe_instance->deployer : FF(0), - .retrieved_class_id = instance_exists ? maybe_instance->current_contract_class_id : FF(0), - .retrieved_init_hash = instance_exists ? maybe_instance->initialization_hash : FF(0) }); + event_emitter.emit({ + .execution_clk = execution_clk, + .contract_address = contract_address, + .dst_offset = dst_offset, + .member_enum = member_enum, + .space_id = space_id, + .nullifier_tree_root = nullifier_tree_root, + .public_data_tree_root = public_data_tree_root, + .instance_exists = instance_exists, + .retrieved_deployer_addr = instance_exists ? maybe_instance->deployer : FF(0), + .retrieved_class_id = instance_exists ? maybe_instance->current_contract_class_id : FF(0), + .retrieved_init_hash = instance_exists ? maybe_instance->initialization_hash : FF(0), + .retrieved_immutables_hash = instance_exists ? maybe_instance->immutables_hash : FF(0), + }); } /** @@ -139,6 +143,8 @@ FF GetContractInstance::select_instance_member(const ContractInstance& instance, return instance.current_contract_class_id; case ContractInstanceMember::INIT_HASH: return instance.initialization_hash; + case ContractInstanceMember::IMMUTABLES_HASH: + return instance.immutables_hash; default: throw std::runtime_error("This error should have been handled earlier! Invalid member enum: " + std::to_string(member_enum)); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp index 77db48bc7606..dc6df18c382d 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp @@ -74,18 +74,17 @@ FF compute_contract_class_id(const FF& artifact_hash, const FF& private_fn_root, return poseidon2::hash({ DOM_SEP__CONTRACT_CLASS_ID, artifact_hash, private_fn_root, public_bytecode_commitment }); } +// public_keys_hash combines the four hashes (with the ivpk_m one computed in-circuit +// from its (x, y) coordinates) under DOM_SEP__PUBLIC_KEYS_HASH. FF hash_public_keys(const PublicKeys& public_keys) { - std::vector public_keys_hash_fields = public_keys.to_fields(); - - std::vector public_key_hash_vec{ DOM_SEP__PUBLIC_KEYS_HASH }; - for (size_t i = 0; i < public_keys_hash_fields.size(); i += 2) { - public_key_hash_vec.push_back(public_keys_hash_fields[i]); - public_key_hash_vec.push_back(public_keys_hash_fields[i + 1]); - // TODO(#7529): is_infinity will be removed from address preimage, assuming false. - public_key_hash_vec.push_back(FF::zero()); - } - return poseidon2::hash({ public_key_hash_vec }); + FF incoming_viewing_key_hash = poseidon2::hash( + { DOM_SEP__SINGLE_PUBLIC_KEY_HASH, public_keys.incoming_viewing_key.x, public_keys.incoming_viewing_key.y }); + return poseidon2::hash({ DOM_SEP__PUBLIC_KEYS_HASH, + public_keys.nullifier_key_hash, + incoming_viewing_key_hash, + public_keys.outgoing_viewing_key_hash, + public_keys.tagging_key_hash }); } // Computes a contract instance's derived address. Follows method of AddressDerivation::assert_derivation() (noir's @@ -95,12 +94,13 @@ FF compute_contract_address(const ContractInstance& contract_instance) FF salted_initialization_hash = poseidon2::hash({ DOM_SEP__SALTED_INITIALIZATION_HASH, contract_instance.salt, contract_instance.initialization_hash, - contract_instance.deployer }); + contract_instance.deployer, + contract_instance.immutables_hash }); FF partial_address = poseidon2::hash( { DOM_SEP__PARTIAL_ADDRESS, contract_instance.original_contract_class_id, salted_initialization_hash }); FF public_keys_hash = hash_public_keys(contract_instance.public_keys); - FF h = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address }); + FF h = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address }); // This is safe since BN254_Fr < GRUMPKIN_Fr so we know there is no modulo reduction grumpkin::fr h_fq = grumpkin::fr(h); BB_ASSERT(contract_instance.public_keys.incoming_viewing_key.on_curve(), diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/hinting_dbs.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/hinting_dbs.cpp index 71f55503510f..937aa2098302 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/hinting_dbs.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/hinting_dbs.cpp @@ -31,11 +31,11 @@ std::optional HintingContractsDB::get_contract_instance(const .current_contract_class_id = instance->current_contract_class_id, .original_contract_class_id = instance->original_contract_class_id, .initialization_hash = instance->initialization_hash, - .public_keys = - PublicKeysHint{ .master_nullifier_public_key = instance->public_keys.nullifier_key, - .master_incoming_viewing_public_key = instance->public_keys.incoming_viewing_key, - .master_outgoing_viewing_public_key = instance->public_keys.outgoing_viewing_key, - .master_tagging_public_key = instance->public_keys.tagging_key } + .immutables_hash = instance->immutables_hash, + .public_keys = PublicKeysHint{ .npk_m_hash = instance->public_keys.nullifier_key_hash, + .ivpk_m = instance->public_keys.incoming_viewing_key, + .ovpk_m_hash = instance->public_keys.outgoing_viewing_key_hash, + .tpk_m_hash = instance->public_keys.tagging_key_hash } }; } diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp index 43789d46d53e..31656d511065 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp @@ -113,12 +113,13 @@ std::optional HintedRawContractDB::get_contract_instance(const .current_contract_class_id = contract_instance_hint.current_contract_class_id, .original_contract_class_id = contract_instance_hint.original_contract_class_id, .initialization_hash = contract_instance_hint.initialization_hash, + .immutables_hash = contract_instance_hint.immutables_hash, .public_keys = PublicKeys{ - .nullifier_key = contract_instance_hint.public_keys.master_nullifier_public_key, - .incoming_viewing_key = contract_instance_hint.public_keys.master_incoming_viewing_public_key, - .outgoing_viewing_key = contract_instance_hint.public_keys.master_outgoing_viewing_public_key, - .tagging_key = contract_instance_hint.public_keys.master_tagging_public_key, + .nullifier_key_hash = contract_instance_hint.public_keys.npk_m_hash, + .incoming_viewing_key = contract_instance_hint.public_keys.ivpk_m, + .outgoing_viewing_key_hash = contract_instance_hint.public_keys.ovpk_m_hash, + .tagging_key_hash = contract_instance_hint.public_keys.tpk_m_hash, }, }); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp index 54446cb8fe27..b879a8ff1ea3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp @@ -188,10 +188,8 @@ const std::unordered_map>& get_wire_opcode_ { OperandType::INDIRECT16, OperandType::UINT16, // lhs.x OperandType::UINT16, // lhs.y - OperandType::UINT16, // lhs.is_infinite OperandType::UINT16, // rhs.x OperandType::UINT16, // rhs.y - OperandType::UINT16, // rhs.is_infinite OperandType::UINT16 } }, // dst_offset // Gadget - Conversion { WireOpCode::TORADIXBE, diff --git a/barretenberg/cpp/src/barretenberg/vm2/testing/avm_inputs.testdata.bin b/barretenberg/cpp/src/barretenberg/vm2/testing/avm_inputs.testdata.bin index 515bb19cc8da277e82a21918549876e8753e9e1a..1a42b7d8a10febafd5e6d8ef0c14e23c2235aaed 100644 GIT binary patch delta 1936 zcmZ|PTS(JU90zc>_IEBTXEp0&Mh`ZEh>YxI1p&sTz16&UC;R?7Cu7U;72n*qAxCX9;CRha5!Syk)IG{1ae-D5in*3<6 zqoc34r8U&nqqckorK;{SFe;JG?!%t+dmbtq3LYhInlLb{+lN7^zIL=L{R{bCk1Ubi ze;+HzmdY{2KMYFc)Q}*TXXP&u;M7|<)XJiEf=+~`Xd)t@yR+z#Vc^Q;OdD%DhA zW|~mNSa)A*D0s-#cDyH*qhs5sVB46C;sR`3h@FNQkrRiEvt=Y(yTeo3czd<{PqZe%%ss_OLl0V`7e*<|xQZ7D(QdE--srfNNOT zGl;8kbJciQxsJ#q38@^tE6BA}cIrJG>SfV-f}Wa`qGulns3nV5-xKe89c%iCdEmax zG$HHKcil>7HmjdTaT|5q;Po`bh#GJRz3Ww(^K74%ooD%DVGkP{RQympPan-ucTT78 zdch;vHfqsRLAJB<`D=IuAGbmSr4{5SJ$-#5mA}mhvLh?ckK;eD1`gdzQ6p;Pda23u zvhYmS%S=+paI({nJ{NoO(;Njgk>M}BkPaVyCBQBgE=k~8{M-hOtQ;Wnv6oW$#9Kjj zXXV#-a4n4-+Qg#G1ogdi_@% delta 3702 zcmb7`TSyd97=U$K%P!u!&atc`OjZxkTTrQ`mAbRK>v~yTqX(01+wf9eh=Q=8sU!lY+pxhFX_^0$ZV zOWrkfuIp5DxXB&7*s+l09B*mt=nS@dx|*BAr^CVaO7lzY%YBmPIMk?P@h!<%pN76|aVd8oI?h$59*LJm(5Il~2z182gmognqSx?js$B)hfo z2V~inY_uoSLILnRP3adEjTWUc%QO6(1knnLp6j<+h(Zqw@!lE`AD-myIlqgO& zqNY8>CiV<)n?P4GJtBnpaZnT!ok>a}O#JU?m!?2#IkNhOkhNuy&kCMoTEt`h@rZES z)lik>wj_*BL%bDn@gCIUee>9Eyr52|#XRzun1*3d%cxK)w>*Pm1}uBf^5CU5qa+mY{NCdZv)p5EfeB} z(JIDk`Xg$UC3CgTtc^s86JCSPzeMPplYD60MbyQEhC$0OI`%eY$RldCC2x(+o2k~u z;T^-=S%U5jsYI=@JWH+FiywRWGi4+3*ao9+A#NDFg4~8&qSjh+ z`%UgT7GKQ!P+zmRnLp^a_nI~{%!?hKzZE)p8l=#>pw>X{LrL#%ac>i53PaW|k=?X-3A0sYaHj z7O5$zhGqtdDW)lDW)>#N$(F_z$rh=mW}D|R9$``tKd@$o*lCBzz3Y}tx>DYo7}v|r zdwz;Sd9$i(#)V2I{>cx5Z8z^{QD(B>T%M7cSK^&o$+$c*C8a2}xcCS`-AjrSbEYpm z%cMNnmi;pKy3E|%(vrlaoYdmU6P;8Y7*`dPCgo%%1I;YH$H1~8uOQpkBe6K+h=Ss} z%@aIMJ8!<(9P(mtQY1J8^xc6vyq} z{vGf0lM^K+C%@)NGn))_KP-IiF)%GD%Fi!3qM(`JAHvhndwB26JsV`2cW63%?=vt@ zSt@UIZQD+zue0NU+9f8>=T%bR{90<)X*TaC+jlv(m_UB>tudz-(r^8XN0W@{BNS=n8M;yzK11FuM;umBKckU=wJ2hu6>#cv5eqoINBi;$pDvoYsch2` z1--j|8B=`Mls3628kqlnc}?l~q27doj~PjuU(86Dut`1)hhkT zZx>fA{mrEn>SXWhs}PwfA!&F-L3sx+-$&aLub^M6zorVNT zd3i?^B##Ghw<(8bFOp$xKPIdmmc+-)AELbNqicv~(p#=?d)zl)5OH8(21dZ-OsSB~ ztAwYs5)*H=#KsQSWCba91wF3R_xlWUC&p=KO%GZxDG>8Ga<#a)-Q?Rf73DT5`|eI| zl$M{ICKac^{eG#?fyF(lg4PdwFE5!GQpECamzMw2KaZj>P5rZDg7@TAk|vX@r97uE zI>V$mxk=iIWzszcW}wr(WtL{=IsLf>v^}znmy> zcF*VKocvpR5<&Ynuho%aR8UoC5vkB+U)2Bc7-RD8?_c^A53;App8ED&PSu6W>xtIp z^L#BVle3LhDX`C;+7y_jc)?(zQl o5a*%SJVBc`+wzJLEb%r!2%h3dl;4}zOl@B?m2vx;sZ5J~0RC8s7XSbN delta 1296 zcmex_Mu|q2 zN#=$YmT5-j29|~+~I_oFp!%K}e z-(Eg#Pt$ReXV+(j?wai2DZ6<-i!+l2$MTHKyb|x!O2*}hDJey%#l=Sm>RwWum@{4R zDwFbLTlUNKs|re!ax#;FMik#;VA+wISX`1?YdA1v92(k*uzZI1}x<*)p?XI0#@0N)3fwk@nYq9A%YYx#dQ!8b0u{`Ih~TzK5< z@2A|DV(!^LWh6dV{q5Yc4`PRBUUGhJrchpbSY~Q@W?nkns>ux;-t|yL{-q`9`9Mi@ zHBjd$1_k(jGI;;KQ*llSng1&_>@-1wOv&6U$cikz4F{57~aqy65j z%}SiVm=sjQC5}k=DQw_$Ybl~dT^6ul|txJK5MCR0!Ha)PNMv7$NbCRr diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.cpp index cc0cf036fe3a..eb9579da5105 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.cpp @@ -17,13 +17,17 @@ namespace bb::avm2::tracegen { * Corresponds to the subtrace address_derivation.pil. * * This trace is non memory-aware and does not handle any errors. It relies on the poseidon2, - * scalar_mul, and ecc traces to constrain correctness of the address, which is derived as: - * 1. salted_init_hash = Poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr) - * 2. partial_address = Poseidon2(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash) - * 3. public_keys_hash = Poseidon2(DOM_SEP__PUBLIC_KEYS_HASH, [...public_keys.to_fields()]) - * 4. preaddress = Poseidon2(DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address) - * 5. preaddress_public_key = preaddress * G1 (Grumpkin scalar multiplication) - * 6. address = (preaddress_public_key + incoming_viewing_key).x (Grumpkin EC add) + * scalar_mul, and ecc traces to constrain correctness of the address. Only the + * incoming_viewing_key is held as a Grumpkin point; the other three master public keys are + * exposed as their hashes (DOM_SEP__SINGLE_PUBLIC_KEY_HASH). The address is derived as: + * 1. salted_init_hash = Poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr, + * immutables_hash) + * 2. partial_address = Poseidon2(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash) + * 3. incoming_viewing_key_hash = Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, ivpk.x, ivpk.y) + * 4. public_keys_hash = Poseidon2(DOM_SEP__PUBLIC_KEYS_HASH, npk_hash, ivpk_m_hash, ovpk_hash, tpk_hash) + * 5. preaddress = Poseidon2(DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address) + * 6. preaddress_public_key = preaddress * G1 (Grumpkin scalar multiplication) + * 7. address = (preaddress_public_key + incoming_viewing_key).x (Grumpkin EC add) * * @param events The container of address derivation events to process. * @param trace The trace container. @@ -48,18 +52,18 @@ void AddressDerivationTraceBuilder::process( { C::address_derivation_deployer_addr, event.instance.deployer }, { C::address_derivation_class_id, event.instance.original_contract_class_id }, { C::address_derivation_init_hash, event.instance.initialization_hash }, - // Public keys (Grumpkin curve points). - { C::address_derivation_nullifier_key_x, event.instance.public_keys.nullifier_key.x }, - { C::address_derivation_nullifier_key_y, event.instance.public_keys.nullifier_key.y }, + { C::address_derivation_immutables_hash, event.instance.immutables_hash }, + // Public keys: only ivpk_m as a point, the other three as hashes. + { C::address_derivation_nullifier_key_hash, event.instance.public_keys.nullifier_key_hash }, { C::address_derivation_incoming_viewing_key_x, event.instance.public_keys.incoming_viewing_key.x }, { C::address_derivation_incoming_viewing_key_y, event.instance.public_keys.incoming_viewing_key.y }, - { C::address_derivation_outgoing_viewing_key_x, event.instance.public_keys.outgoing_viewing_key.x }, - { C::address_derivation_outgoing_viewing_key_y, event.instance.public_keys.outgoing_viewing_key.y }, - { C::address_derivation_tagging_key_x, event.instance.public_keys.tagging_key.x }, - { C::address_derivation_tagging_key_y, event.instance.public_keys.tagging_key.y }, + { C::address_derivation_outgoing_viewing_key_hash, + event.instance.public_keys.outgoing_viewing_key_hash }, + { C::address_derivation_tagging_key_hash, event.instance.public_keys.tagging_key_hash }, // Intermediate hash results. { C::address_derivation_salted_init_hash, event.salted_initialization_hash }, { C::address_derivation_partial_address, event.partial_address }, + { C::address_derivation_incoming_viewing_key_hash, event.incoming_viewing_key_hash }, { C::address_derivation_public_keys_hash, event.public_keys_hash }, { C::address_derivation_preaddress, event.preaddress }, // Intermediate EC results. @@ -69,14 +73,13 @@ void AddressDerivationTraceBuilder::process( // Constant columns (this is temp because aliasing is not allowed in lookups). { C::address_derivation_salted_init_hash_domain_separator, DOM_SEP__SALTED_INITIALIZATION_HASH }, { C::address_derivation_partial_address_domain_separator, DOM_SEP__PARTIAL_ADDRESS }, + { C::address_derivation_single_public_key_hash_domain_separator, DOM_SEP__SINGLE_PUBLIC_KEY_HASH }, { C::address_derivation_public_keys_hash_domain_separator, DOM_SEP__PUBLIC_KEYS_HASH }, - { C::address_derivation_preaddress_domain_separator, DOM_SEP__CONTRACT_ADDRESS_V1 }, + { C::address_derivation_preaddress_domain_separator, DOM_SEP__CONTRACT_ADDRESS_V2 }, { C::address_derivation_g1_x, g1.x() }, { C::address_derivation_g1_y, g1.y() }, - { C::address_derivation_const_two, 2 }, { C::address_derivation_const_three, 3 }, - { C::address_derivation_const_four, 4 }, - { C::address_derivation_const_thirteen, 13 } } }); + { C::address_derivation_const_five, 5 } } }); row++; } } @@ -88,11 +91,9 @@ const InteractionDefinition AddressDerivationTraceBuilder::interactions = .add() .add() + .add() .add() .add() - .add() - .add() - .add() .add() .add() .add(); diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.test.cpp index 42fc8dda7bae..febf919118c3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/address_derivation_trace.test.cpp @@ -35,6 +35,7 @@ TEST(AddressDerivationTraceGenTest, TraceGeneration) .instance = instance, .salted_initialization_hash = FF(12), .partial_address = FF(23), + .incoming_viewing_key_hash = FF(56), .public_keys_hash = FF(34), .preaddress = FF(45), .preaddress_public_key = preaddress_public_key, @@ -52,16 +53,16 @@ TEST(AddressDerivationTraceGenTest, TraceGeneration) ROW_FIELD_EQ(address_derivation_deployer_addr, instance.deployer), ROW_FIELD_EQ(address_derivation_class_id, instance.original_contract_class_id), ROW_FIELD_EQ(address_derivation_init_hash, instance.initialization_hash), - ROW_FIELD_EQ(address_derivation_nullifier_key_x, instance.public_keys.nullifier_key.x), - ROW_FIELD_EQ(address_derivation_nullifier_key_y, instance.public_keys.nullifier_key.y), + ROW_FIELD_EQ(address_derivation_immutables_hash, instance.immutables_hash), + ROW_FIELD_EQ(address_derivation_nullifier_key_hash, instance.public_keys.nullifier_key_hash), ROW_FIELD_EQ(address_derivation_incoming_viewing_key_x, instance.public_keys.incoming_viewing_key.x), ROW_FIELD_EQ(address_derivation_incoming_viewing_key_y, instance.public_keys.incoming_viewing_key.y), - ROW_FIELD_EQ(address_derivation_outgoing_viewing_key_x, instance.public_keys.outgoing_viewing_key.x), - ROW_FIELD_EQ(address_derivation_outgoing_viewing_key_y, instance.public_keys.outgoing_viewing_key.y), - ROW_FIELD_EQ(address_derivation_tagging_key_x, instance.public_keys.tagging_key.x), - ROW_FIELD_EQ(address_derivation_tagging_key_y, instance.public_keys.tagging_key.y), + ROW_FIELD_EQ(address_derivation_outgoing_viewing_key_hash, + instance.public_keys.outgoing_viewing_key_hash), + ROW_FIELD_EQ(address_derivation_tagging_key_hash, instance.public_keys.tagging_key_hash), ROW_FIELD_EQ(address_derivation_salted_init_hash, FF(12)), ROW_FIELD_EQ(address_derivation_partial_address, FF(23)), + ROW_FIELD_EQ(address_derivation_incoming_viewing_key_hash, FF(56)), ROW_FIELD_EQ(address_derivation_public_keys_hash, FF(34)), ROW_FIELD_EQ(address_derivation_preaddress, FF(45)), ROW_FIELD_EQ(address_derivation_preaddress_public_key_x, preaddress_public_key.x()), @@ -69,14 +70,14 @@ TEST(AddressDerivationTraceGenTest, TraceGeneration) ROW_FIELD_EQ(address_derivation_address_y, address_point.y()), ROW_FIELD_EQ(address_derivation_salted_init_hash_domain_separator, DOM_SEP__SALTED_INITIALIZATION_HASH), ROW_FIELD_EQ(address_derivation_partial_address_domain_separator, DOM_SEP__PARTIAL_ADDRESS), + ROW_FIELD_EQ(address_derivation_single_public_key_hash_domain_separator, + DOM_SEP__SINGLE_PUBLIC_KEY_HASH), ROW_FIELD_EQ(address_derivation_public_keys_hash_domain_separator, DOM_SEP__PUBLIC_KEYS_HASH), - ROW_FIELD_EQ(address_derivation_preaddress_domain_separator, DOM_SEP__CONTRACT_ADDRESS_V1), + ROW_FIELD_EQ(address_derivation_preaddress_domain_separator, DOM_SEP__CONTRACT_ADDRESS_V2), ROW_FIELD_EQ(address_derivation_g1_x, EmbeddedCurvePoint::one().x()), ROW_FIELD_EQ(address_derivation_g1_y, EmbeddedCurvePoint::one().y()), - ROW_FIELD_EQ(address_derivation_const_two, 2), ROW_FIELD_EQ(address_derivation_const_three, 3), - ROW_FIELD_EQ(address_derivation_const_four, 4), - ROW_FIELD_EQ(address_derivation_const_thirteen, 13)))); + ROW_FIELD_EQ(address_derivation_const_five, 5)))); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.cpp index 1ca1e17954c2..827c6cbbaee4 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.cpp @@ -62,20 +62,20 @@ void ContractInstanceRetrievalTraceBuilder::process( { C::contract_instance_retrieval_original_class_id, event.contract_instance.original_contract_class_id }, { C::contract_instance_retrieval_init_hash, event.contract_instance.initialization_hash }, + { C::contract_instance_retrieval_immutables_hash, event.contract_instance.immutables_hash }, - // Public keys (hinted) - { C::contract_instance_retrieval_nullifier_key_x, event.contract_instance.public_keys.nullifier_key.x }, - { C::contract_instance_retrieval_nullifier_key_y, event.contract_instance.public_keys.nullifier_key.y }, + // Public keys (hinted). Only ivpk_m is held as a Grumpkin point; + // the others are field-element hashes computed off-circuit by the PXE. + { C::contract_instance_retrieval_nullifier_key_hash, + event.contract_instance.public_keys.nullifier_key_hash }, { C::contract_instance_retrieval_incoming_viewing_key_x, event.contract_instance.public_keys.incoming_viewing_key.x }, { C::contract_instance_retrieval_incoming_viewing_key_y, event.contract_instance.public_keys.incoming_viewing_key.y }, - { C::contract_instance_retrieval_outgoing_viewing_key_x, - event.contract_instance.public_keys.outgoing_viewing_key.x }, - { C::contract_instance_retrieval_outgoing_viewing_key_y, - event.contract_instance.public_keys.outgoing_viewing_key.y }, - { C::contract_instance_retrieval_tagging_key_x, event.contract_instance.public_keys.tagging_key.x }, - { C::contract_instance_retrieval_tagging_key_y, event.contract_instance.public_keys.tagging_key.y }, + { C::contract_instance_retrieval_outgoing_viewing_key_hash, + event.contract_instance.public_keys.outgoing_viewing_key_hash }, + { C::contract_instance_retrieval_tagging_key_hash, + event.contract_instance.public_keys.tagging_key_hash }, // Tree context { C::contract_instance_retrieval_public_data_tree_root, event.public_data_tree_root }, diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.test.cpp index 865470f908cd..7c7857e7c49d 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/contract_instance_retrieval_trace.test.cpp @@ -28,12 +28,13 @@ ContractInstance create_test_contract_instance(uint32_t salt_value = 123) .current_contract_class_id = FF(0xdeadbeefULL), .original_contract_class_id = FF(0xcafebabeULL), .initialization_hash = FF(0x11111111ULL), + .immutables_hash = FF(0x22222222ULL), .public_keys = PublicKeys{ - .nullifier_key = { FF(0x100), FF(0x101) }, + .nullifier_key_hash = FF(0x100), .incoming_viewing_key = { FF(0x200), FF(0x201) }, - .outgoing_viewing_key = { FF(0x300), FF(0x301) }, - .tagging_key = { FF(0x400), FF(0x401) }, + .outgoing_viewing_key_hash = FF(0x300), + .tagging_key_hash = FF(0x400), }, }; } @@ -98,16 +99,14 @@ TEST(ContractInstanceRetrievalTraceGenTest, SingleEvent) ROW_FIELD_EQ(contract_instance_retrieval_current_class_id, 0xdeadbeefULL), ROW_FIELD_EQ(contract_instance_retrieval_original_class_id, 0xcafebabeULL), ROW_FIELD_EQ(contract_instance_retrieval_init_hash, 0x11111111ULL), + ROW_FIELD_EQ(contract_instance_retrieval_immutables_hash, 0x22222222ULL), - // Public keys - ROW_FIELD_EQ(contract_instance_retrieval_nullifier_key_x, 0x100), - ROW_FIELD_EQ(contract_instance_retrieval_nullifier_key_y, 0x101), + // Public keys (ivpk_m as a point, others as hashes) + ROW_FIELD_EQ(contract_instance_retrieval_nullifier_key_hash, 0x100), ROW_FIELD_EQ(contract_instance_retrieval_incoming_viewing_key_x, 0x200), ROW_FIELD_EQ(contract_instance_retrieval_incoming_viewing_key_y, 0x201), - ROW_FIELD_EQ(contract_instance_retrieval_outgoing_viewing_key_x, 0x300), - ROW_FIELD_EQ(contract_instance_retrieval_outgoing_viewing_key_y, 0x301), - ROW_FIELD_EQ(contract_instance_retrieval_tagging_key_x, 0x400), - ROW_FIELD_EQ(contract_instance_retrieval_tagging_key_y, 0x401), + ROW_FIELD_EQ(contract_instance_retrieval_outgoing_viewing_key_hash, 0x300), + ROW_FIELD_EQ(contract_instance_retrieval_tagging_key_hash, 0x400), // Tree context ROW_FIELD_EQ(contract_instance_retrieval_public_data_tree_root, public_data_tree_root), diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp index 4c494f898176..8860f534f83e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp @@ -131,7 +131,6 @@ void EccTraceBuilder::process_add(const simulation::EventEmitterInterface(event.dst_address); // Error handling, check if the destination address is out of range. - // The max write address is dst_addr + 2, since we write 3 values for R (x, y, is_inf). - bool dst_out_of_range_err = dst_addr + 2 > AVM_HIGHEST_MEM_ADDRESS; + // The max write address is dst_addr + 1, since we write 2 values for R (x, y). + bool dst_out_of_range_err = dst_addr + 1 > AVM_HIGHEST_MEM_ADDRESS; // Error handling, check if the points are on the curve. // We do not use batch inversions as we do not need to invert in the happy path. @@ -297,10 +295,6 @@ void EccTraceBuilder::process_add_with_memory( bool error = dst_out_of_range_err || !p_is_on_curve || !q_is_on_curve; - // Normalized points, ensures that input infinity points are represented by (0, 0) in the ecc subtrace. - EmbeddedCurvePoint p_n = event.p.is_infinity() ? EmbeddedCurvePoint::infinity() : event.p; - EmbeddedCurvePoint q_n = event.q.is_infinity() ? EmbeddedCurvePoint::infinity() : event.q; - trace.set(row, { { { C::ecc_add_mem_sel, 1 }, @@ -322,26 +316,19 @@ void EccTraceBuilder::process_add_with_memory( // Memory Writes { C::ecc_add_mem_dst_addr_0_, dst_addr }, { C::ecc_add_mem_dst_addr_1_, dst_addr + 1 }, - { C::ecc_add_mem_dst_addr_2_, dst_addr + 2 }, // Input - Point P { C::ecc_add_mem_p_x, event.p.x() }, { C::ecc_add_mem_p_y, event.p.y() }, - { C::ecc_add_mem_p_is_inf, event.p.is_infinity() ? 1 : 0 }, // Input - Point Q { C::ecc_add_mem_q_x, event.q.x() }, { C::ecc_add_mem_q_y, event.q.y() }, + // Input - Infinity flags required for ECC trace + { C::ecc_add_mem_p_is_inf, event.p.is_infinity() ? 1 : 0 }, { C::ecc_add_mem_q_is_inf, event.q.is_infinity() ? 1 : 0 }, - // Normalized input - Point P - { C::ecc_add_mem_p_x_n, p_n.x() }, - { C::ecc_add_mem_p_y_n, p_n.y() }, - // Normalized input - Point Q - { C::ecc_add_mem_q_x_n, q_n.x() }, - { C::ecc_add_mem_q_y_n, q_n.y() }, // Output { C::ecc_add_mem_sel_should_exec, error ? 0 : 1 }, { C::ecc_add_mem_res_x, event.result.x() }, { C::ecc_add_mem_res_y, event.result.y() }, - { C::ecc_add_mem_res_is_inf, event.result.is_infinity() ? 1 : 0 }, } }); row++; diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.test.cpp index fd639b225c27..9296470c388c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.test.cpp @@ -21,13 +21,13 @@ TEST(EccTraceGenTest, TraceGenerationAdd) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"); FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"); - EmbeddedCurvePoint q(q_x, q_y, false); + EmbeddedCurvePoint q(q_x, q_y); FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); builder.process_add({ { .p = p, .q = q, .result = r } }, trace); EXPECT_THAT(trace.as_rows(), @@ -45,10 +45,9 @@ TEST(EccTraceGenTest, TraceGenerationAdd) ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()), ROW_FIELD_EQ(ecc_q_x, q.x()), ROW_FIELD_EQ(ecc_q_y, q.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 0), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 0), ROW_FIELD_EQ(ecc_y_match, 0)))); @@ -61,11 +60,11 @@ TEST(EccTraceGenTest, TraceGenerationDouble) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); EmbeddedCurvePoint q = p; FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"); FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"); - EmbeddedCurvePoint r(r_x, r_y, false); + EmbeddedCurvePoint r(r_x, r_y); builder.process_add({ { .p = p, .q = q, .result = r } }, trace); @@ -84,10 +83,9 @@ TEST(EccTraceGenTest, TraceGenerationDouble) ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()), ROW_FIELD_EQ(ecc_q_x, p.x()), ROW_FIELD_EQ(ecc_q_y, p.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 0), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 1), ROW_FIELD_EQ(ecc_y_match, 1)))); @@ -100,9 +98,9 @@ TEST(EccTraceGenTest, TraceGenerationInfResult) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); - EmbeddedCurvePoint q(p.x(), -p.y(), false); + EmbeddedCurvePoint q(p.x(), -p.y()); EmbeddedCurvePoint r = p + q; builder.process_add({ { .p = p, .q = q, .result = r } }, trace); @@ -122,10 +120,9 @@ TEST(EccTraceGenTest, TraceGenerationInfResult) ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()), ROW_FIELD_EQ(ecc_q_x, q.x()), ROW_FIELD_EQ(ecc_q_y, q.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 1), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 1), ROW_FIELD_EQ(ecc_y_match, 0)))); @@ -138,7 +135,7 @@ TEST(EccTraceGenTest, TraceGenerationInfAdd) FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); - EmbeddedCurvePoint p(p_x, p_y, false); + EmbeddedCurvePoint p(p_x, p_y); // We always assume infinity coordinates have been normalized to (0,0) before reaching tracegen EmbeddedCurvePoint q = EmbeddedCurvePoint::infinity(); @@ -161,10 +158,9 @@ TEST(EccTraceGenTest, TraceGenerationInfAdd) ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()), ROW_FIELD_EQ(ecc_q_x, q.x()), ROW_FIELD_EQ(ecc_q_y, q.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 0), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 0), ROW_FIELD_EQ(ecc_y_match, 0)))); @@ -195,10 +191,9 @@ TEST(EccTraceGenTest, TraceGenerationInfDouble) ROW_FIELD_EQ(ecc_q_is_inf, p.is_infinity()), ROW_FIELD_EQ(ecc_q_x, p.x()), ROW_FIELD_EQ(ecc_q_y, p.y()), - ROW_FIELD_EQ(ecc_r_is_inf, r.is_infinity()), ROW_FIELD_EQ(ecc_r_x, r.x()), ROW_FIELD_EQ(ecc_r_y, r.y()), - ROW_FIELD_EQ(ecc_result_infinity, 1), + ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()), ROW_FIELD_EQ(ecc_sel, 1), ROW_FIELD_EQ(ecc_x_match, 1), ROW_FIELD_EQ(ecc_y_match, 1)))); diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.cpp index 3522e60e2187..4fef6af7e196 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.cpp @@ -9,7 +9,7 @@ namespace bb::avm2::tracegen { * Returns boolean selectors indicating whether the enum is valid and which member it selects. * See the ASCII table in get_contract_instance.pil for the full mapping. * - * @param member_enum The member enum value (0=deployer, 1=class_id, 2=init_hash, 3+=invalid). + * @param member_enum The member enum value (0=deployer, 1=class_id, 2=init_hash, 3=immutables_hash, 4+=invalid). * @return A Table struct with is_valid_member_enum and the per-member selector flags. */ GetContractInstanceSpec::Table GetContractInstanceSpec::get_table(uint8_t member_enum) @@ -20,6 +20,7 @@ GetContractInstanceSpec::Table GetContractInstanceSpec::get_table(uint8_t member .is_deployer = false, .is_class_id = false, .is_init_hash = false, + .is_immutables_hash = false, }; switch (static_cast(member_enum)) { @@ -35,6 +36,10 @@ GetContractInstanceSpec::Table GetContractInstanceSpec::get_table(uint8_t member table.is_valid_member_enum = true; table.is_init_hash = true; return table; + case ContractInstanceMember::IMMUTABLES_HASH: + table.is_valid_member_enum = true; + table.is_immutables_hash = true; + return table; default: // Invalid enum - return defaults (all false) return table; diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.hpp index 18509f022d31..b925c9c85c59 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/get_contract_instance_spec.hpp @@ -11,6 +11,7 @@ class GetContractInstanceSpec { bool is_deployer; bool is_class_id; bool is_init_hash; + bool is_immutables_hash; }; static Table get_table(uint8_t member_enum); diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.cpp index 23832be47578..78b9226168d7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.cpp @@ -8,20 +8,25 @@ namespace bb::avm2::tracegen { void order_jobs_by_destination_columns(std::vector>& jobs) { - // Identify first occurrences of each fingerprint. + // Tag each job with whether its destination-columns fingerprint is being seen for the first + // time. The tag is captured up front so the partition predicate doesn't depend on the + // unique_ptrs, which the partition implementation may null out via moves. unordered_flat_set seen_fingerprints; - unordered_flat_set first_occurrence_jobs; + std::vector>> tagged; + tagged.reserve(jobs.size()); - for (const auto& job : jobs) { + for (auto& job : jobs) { auto fp = job->get_destination_columns_fingerprint(); auto [_, inserted] = seen_fingerprints.insert(fp); - if (inserted) { - first_occurrence_jobs.insert(job.get()); - } + tagged.emplace_back(inserted, std::move(job)); } // Stable partition: first occurrences come first. - std::ranges::stable_partition(jobs, [&](const auto& job) { return first_occurrence_jobs.contains(job.get()); }); + std::ranges::stable_partition(tagged, [](const auto& t) { return t.first; }); + + for (size_t i = 0; i < tagged.size(); ++i) { + jobs[i] = std::move(tagged[i].second); + } } } // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.hpp index 2aacdf9239b1..bc6331c97fb1 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_builder.hpp @@ -1,9 +1,13 @@ #pragma once +#include #include #include +#include #include +#include "barretenberg/common/tuple.hpp" +#include "barretenberg/vm2/common/field.hpp" #include "barretenberg/vm2/generated/columns.hpp" #include "barretenberg/vm2/tracegen/lib/shared_index_cache.hpp" #include "barretenberg/vm2/tracegen/trace_container.hpp" @@ -20,6 +24,20 @@ template struct RefTupleHelper using RefTuple = typename detail::RefTupleHelper::type; +// Same as TraceContainer::get_multiple but copies the values into an owning std::array. Use when +// the result must outlive a subsequent column write (e.g. when stored as a hash-map key): the +// references returned by get_multiple point into column storage and can dangle on reallocation. +template +std::array get_multiple_as_array(const TraceContainer& trace, + const std::array& cols, + uint32_t row) +{ + auto refs = trace.get_multiple(cols, row); + return [&](std::index_sequence) { + return std::array{ flat_tuple::get(refs)... }; + }(std::make_index_sequence{}); +} + class InteractionBuilderInterface { public: virtual ~InteractionBuilderInterface() = default; @@ -33,8 +51,9 @@ class InteractionBuilderInterface { // A concatenate that works with movable objects. template std::vector concatenate_jobs(std::vector&& first, auto&&... rest) { + const size_t total_size = first.size() + (rest.size() + ...); std::vector result = std::move(first); - result.reserve(first.size() + (rest.size() + ...)); + result.reserve(total_size); (std::move(rest.begin(), rest.end(), std::back_inserter(result)), ...); return result; } diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_def.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_def.hpp index 73410b4e21fa..dbb36f7c613e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_def.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/interaction_def.hpp @@ -5,10 +5,11 @@ #include #include +#include "barretenberg/common/assert.hpp" #include "barretenberg/vm2/tracegen/lib/interaction_builder.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_builder.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_into_bitwise.hpp" -#include "barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp" +#include "barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_row.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_into_p_decomposition.hpp" #include "barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp" #include "barretenberg/vm2/tracegen/lib/permutation_builder.hpp" @@ -34,8 +35,12 @@ class InteractionDefinition { template InteractionDefinition& add(auto&&... args) { std::string name = (std::string(InteractionSettings::NAME) + ...); - interactions[name] = - get_interaction_factory(std::forward(args)...); + auto [_, inserted] = interactions.emplace( + name, get_interaction_factory(std::forward(args)...)); + + // Safeguard detecting a collision in the interaction names (we do not use separators to have an injective + // serialization). + BB_ASSERT_DEBUG(inserted, "InteractionDefinition::add: collision in interaction name: " + name); return *this; } diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_row.hpp similarity index 100% rename from barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp rename to barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_row.hpp diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp index 1598321f08ca..488aaea46aca 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/multi_permutation_builder.hpp @@ -55,7 +55,7 @@ template class MultiPermutationBuilder : publ { // Find each source tuple in the destination table, and set a 1 in the destination selector. trace.visit_column(PermutationSettings::SRC_SELECTOR, [&](uint32_t row, const FF&) { - auto src_values = trace.get_multiple(PermutationSettings::SRC_COLUMNS, row); + auto src_values = get_multiple_as_array(trace, PermutationSettings::SRC_COLUMNS, row); auto index_it = row_idx.find(src_values); if (index_it == row_idx.end() || index_it->second.empty()) { throw std::runtime_error("Failed setting selectors for " + std::string(PermutationSettings::NAME) + @@ -82,8 +82,7 @@ template class MultiPermutationBuilder : publ // and add the row number to the index. See the comment on `row_idx` for more details. row_idx.reserve(trace.get_column_rows(dst_table_selector)); trace.visit_column(dst_table_selector, [&](uint32_t row, const FF&) { - auto dst_values = trace.get_multiple(DST_COLUMNS, row); - row_idx[dst_values].push_back(row); + row_idx[get_multiple_as_array(trace, DST_COLUMNS, row)].push_back(row); }); } @@ -97,11 +96,12 @@ template class MultiPermutationBuilder : publ // We need an extra "destination TABLE selector" which is the selector of the whole table. Column dst_table_selector; - // In a permutation (or lookup) you are trying to find a src suple of values + // In a permutation (or lookup) you are trying to find a src tuple of values // (a, b, c, ...) in some destination table. That is, you want a row number in the destination table. // The following map contains (a, b, c, ...) -> [row_number_1, row_number_2, ...]. // That is, you can efficiently find all the rows in the destination table that match the src tuple. - unordered_flat_map, /*rows*/ std::vector> row_idx; + // Keys are stored as owning value arrays (see get_multiple_as_array in interaction_builder.hpp for rationale). + unordered_flat_map, /*rows*/ std::vector> row_idx; }; } // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/shared_index_cache.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/shared_index_cache.hpp index bf0679b8c40e..8082c19b3c21 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/shared_index_cache.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/shared_index_cache.hpp @@ -80,7 +80,21 @@ class SharedIndexCache { promise->set_value(index); return *index; } catch (...) { - promise->set_exception(std::current_exception()); + // Evict the failed entry so a subsequent get_or_build can retry rather than + // re-throwing the cached exception forever (and broadcasting it to all jobs + // that share this destination). + { + std::unique_lock lock(mutex_); + cache_.erase(key); + } + // Wake any threads already waiting on this future with the build error. + // Swallow any secondary failure here (e.g. promise_already_satisfied if + // set_value partially completed) so the original exception always + // propagates and we never leave waiters blocked. + try { + promise->set_exception(std::current_exception()); + } catch (...) { + } throw; } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/test_interaction_builder.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/test_interaction_builder.hpp index 867ecf31c03e..5db4a345e6e4 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/test_interaction_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/test_interaction_builder.hpp @@ -53,7 +53,7 @@ template class AddChecksToBuilder : public BaseBuilder { template class CheckingPermutationBuilder : public PermutationBuilder { public: - // Use array for storage in map keys (tuples of references can't be stored). + // Owning value array; see get_multiple_as_array in interaction_builder.hpp for why we can't key on RefTuple. using ArrayTuple = std::array; void process(TraceContainer& trace) override @@ -63,13 +63,11 @@ class CheckingPermutationBuilder : public PermutationBuilder static ArrayTuple to_array(const flat_tuple::tuple& tup) - { - return [&](std::index_sequence) { - return ArrayTuple{ flat_tuple::get(tup)... }; - }(std::make_index_sequence{}); - } - unordered_flat_map> source_tuples; unordered_flat_map> destination_tuples; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/memory_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/memory_trace.cpp index 5e62de95961a..8830923b6efd 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/memory_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/memory_trace.cpp @@ -174,7 +174,6 @@ const InteractionDefinition MemoryTraceBuilder::interactions = // ECADD perm_ecc_mem_write_mem_0_settings, perm_ecc_mem_write_mem_1_settings, - perm_ecc_mem_write_mem_2_settings, // To Radix. perm_to_radix_mem_write_mem_settings // Others. diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.cpp index 2801db9e1b02..58e4b9d8b0a0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.cpp @@ -45,6 +45,7 @@ void GetContractInstanceTraceBuilder::process( bool is_deployer = false; bool is_class_id = false; bool is_init_hash = false; + bool is_immutables_hash = false; if (writes_are_in_bounds) { // Get precomputed table values for this member enum @@ -54,14 +55,16 @@ void GetContractInstanceTraceBuilder::process( is_deployer = spec.is_deployer; is_class_id = spec.is_class_id; is_init_hash = spec.is_init_hash; + is_immutables_hash = spec.is_immutables_hash; } bool has_error = !(writes_are_in_bounds && is_valid_member_enum); - FF selected_member = is_deployer ? event.retrieved_deployer_addr - : is_class_id ? event.retrieved_class_id - : is_init_hash ? event.retrieved_init_hash - : FF(0); + FF selected_member = is_deployer ? event.retrieved_deployer_addr + : is_class_id ? event.retrieved_class_id + : is_init_hash ? event.retrieved_init_hash + : is_immutables_hash ? event.retrieved_immutables_hash + : FF(0); trace.set( row, @@ -86,11 +89,13 @@ void GetContractInstanceTraceBuilder::process( { C::get_contract_instance_is_deployer, is_deployer ? 1 : 0 }, { C::get_contract_instance_is_class_id, is_class_id ? 1 : 0 }, { C::get_contract_instance_is_init_hash, is_init_hash ? 1 : 0 }, + { C::get_contract_instance_is_immutables_hash, is_immutables_hash ? 1 : 0 }, // Retrieval results { C::get_contract_instance_instance_exists, event.instance_exists ? 1 : 0 }, { C::get_contract_instance_retrieved_deployer_addr, event.retrieved_deployer_addr }, { C::get_contract_instance_retrieved_class_id, event.retrieved_class_id }, { C::get_contract_instance_retrieved_init_hash, event.retrieved_init_hash }, + { C::get_contract_instance_retrieved_immutables_hash, event.retrieved_immutables_hash }, { C::get_contract_instance_selected_member, selected_member }, // Memory writing { C::get_contract_instance_member_write_offset, writes_are_in_bounds ? (event.dst_offset + 1) : 0 }, diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.test.cpp index 84a2177fdfbf..776bed4461ea 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/opcodes/get_contract_instance_trace.test.cpp @@ -205,5 +205,79 @@ TEST(GetContractInstanceTraceTest, OutOfBoundsWrite) ))); } +TEST(GetContractInstanceTraceTest, ValidImmutablesHashEnum) +{ + // Test constants + const uint32_t execution_clk = 42; + const FF nullifier_tree_root = 0x1234; + const FF public_data_tree_root = 0x5678; + const FF contract_address = 0x1234; + const uint32_t dst_offset = 100; + const uint16_t space_id = 1; + const FF deployer_addr = 0x5678; + const FF class_id = 0x9ABC; + const FF init_hash = 0xDEF0; + const FF immutables_hash = 0xCAFE; + const uint32_t dst_offset_plus_one = dst_offset + 1; + const uint8_t immutables_hash_enum = static_cast(ContractInstanceMember::IMMUTABLES_HASH); + const uint8_t u1_tag = static_cast(ValueTag::U1); + const uint8_t ff_tag = static_cast(ValueTag::FF); + + TestTraceContainer trace; + GetContractInstanceTraceBuilder builder; + simulation::EventEmitter emitter; + + simulation::GetContractInstanceEvent event = { + .execution_clk = execution_clk, + .contract_address = contract_address, + .dst_offset = dst_offset, + .member_enum = immutables_hash_enum, + .space_id = space_id, + .nullifier_tree_root = nullifier_tree_root, + .public_data_tree_root = public_data_tree_root, + .instance_exists = true, + .retrieved_deployer_addr = deployer_addr, + .retrieved_class_id = class_id, + .retrieved_init_hash = init_hash, + .retrieved_immutables_hash = immutables_hash, + }; + + emitter.emit(std::move(event)); + auto events = emitter.dump_events(); + + builder.process(events, trace); + + EXPECT_THAT(trace.as_rows(), + ElementsAre( + // Row 0: Skippable gadget selector + AllOf(ROW_FIELD_EQ(get_contract_instance_sel, 0)), + // Row 1: Active GetContractInstance gadget for IMMUTABLES_HASH + AllOf(ROW_FIELD_EQ(get_contract_instance_sel, 1), + ROW_FIELD_EQ(get_contract_instance_clk, execution_clk), + ROW_FIELD_EQ(get_contract_instance_contract_address, contract_address), + ROW_FIELD_EQ(get_contract_instance_dst_offset, dst_offset), + ROW_FIELD_EQ(get_contract_instance_member_enum, immutables_hash_enum), + ROW_FIELD_EQ(get_contract_instance_space_id, space_id), + // Member selection flags + ROW_FIELD_EQ(get_contract_instance_is_valid_member_enum, 1), + ROW_FIELD_EQ(get_contract_instance_is_deployer, 0), + ROW_FIELD_EQ(get_contract_instance_is_class_id, 0), + ROW_FIELD_EQ(get_contract_instance_is_init_hash, 0), + ROW_FIELD_EQ(get_contract_instance_is_immutables_hash, 1), + // Error flags + ROW_FIELD_EQ(get_contract_instance_sel_error, 0), + // Retrieved members + ROW_FIELD_EQ(get_contract_instance_retrieved_deployer_addr, deployer_addr), + ROW_FIELD_EQ(get_contract_instance_retrieved_class_id, class_id), + ROW_FIELD_EQ(get_contract_instance_retrieved_init_hash, init_hash), + ROW_FIELD_EQ(get_contract_instance_retrieved_immutables_hash, immutables_hash), + // Selected member is the immutables hash + ROW_FIELD_EQ(get_contract_instance_selected_member, immutables_hash), + // Memory write columns + ROW_FIELD_EQ(get_contract_instance_member_write_offset, dst_offset_plus_one), + ROW_FIELD_EQ(get_contract_instance_exists_tag, u1_tag), + ROW_FIELD_EQ(get_contract_instance_member_tag, ff_tag)))); +} + } // namespace } // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp index f39415ef39df..e83d96f7b9e8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp @@ -466,7 +466,7 @@ void PrecomputedTraceBuilder::process_get_env_var_table(TraceContainer& trace) /** * @brief Populate the GETCONTRACTINSTANCE lookup table. - * @details One row per ContractInstanceMember enum value (DEPLOYER=0, CLASS_ID=1, INIT_HASH=2). + * @details One row per ContractInstanceMember enum value (DEPLOYER=0, CLASS_ID=1, INIT_HASH=2, IMMUTABLES_HASH=3). * Each row holds a validity flag and one-hot member selectors. See * `opcodes/get_contract_instance.pil` for an ascii version of this table. */ @@ -482,6 +482,7 @@ void PrecomputedTraceBuilder::process_get_contract_instance_table(TraceContainer { C::precomputed_is_deployer, spec.is_deployer ? 1 : 0 }, { C::precomputed_is_class_id, spec.is_class_id ? 1 : 0 }, { C::precomputed_is_init_hash, spec.is_init_hash ? 1 : 0 }, + { C::precomputed_is_immutables_hash, spec.is_immutables_hash ? 1 : 0 }, } }); } } diff --git a/bootstrap.sh b/bootstrap.sh index 2d231035ebb6..e3f209b4fc3a 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -724,21 +724,24 @@ case "$cmd" in ;; "ci-network-bench") # Args: [docker_image] - # Deploys network and runs benchmarks. Cleanup should be done separately. + # Deploys network and runs benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI=1 env_file="${1:?env_file is required}" namespace="${2:?namespace is required}" docker_image="${3:-}" build - # If no docker image provided, build and push to aztecdev - if [ -z "$docker_image" ]; then - release-image/bootstrap.sh push_pr - docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" - fi - # Set up environment and deploy using spartan export NAMESPACE="$namespace" - export AZTEC_DOCKER_IMAGE="$docker_image" - spartan/bootstrap.sh network_deploy "${env_file}" + if [ "${SKIP_NETWORK_DEPLOY:-0}" != "1" ]; then + # If no docker image provided, build and push to aztecdev + if [ -z "$docker_image" ]; then + release-image/bootstrap.sh push_pr + docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" + fi + export AZTEC_DOCKER_IMAGE="$docker_image" + spartan/bootstrap.sh network_deploy "${env_file}" + else + echo "SKIP_NETWORK_DEPLOY=1, running benchmarks against existing network '$namespace'." + fi # Run benchmarks spartan/bootstrap.sh network_bench "${env_file}" rm -rf bench-out @@ -748,22 +751,24 @@ case "$cmd" in ;; "ci-network-proving-bench") # Args: [docker_image] - # Deploys network and runs proving benchmarks. Cleanup should be done separately. + # Deploys network and runs proving benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI=1 env_file="${1:?env_file is required}" namespace="${2:?namespace is required}" docker_image="${3:-}" build - # If no docker image provided, build and push to aztecdev - if [ -z "$docker_image" ]; then - release-image/bootstrap.sh push_pr - docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" - fi - # Set up environment and deploy using spartan export NAMESPACE="$namespace" - export AZTEC_DOCKER_IMAGE="$docker_image" - spartan/bootstrap.sh network_deploy "${env_file}" - # Run proving benchmarks + if [ "${SKIP_NETWORK_DEPLOY:-0}" != "1" ]; then + # If no docker image provided, build and push to aztecdev + if [ -z "$docker_image" ]; then + release-image/bootstrap.sh push_pr + docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" + fi + export AZTEC_DOCKER_IMAGE="$docker_image" + spartan/bootstrap.sh network_deploy "${env_file}" + else + echo "SKIP_NETWORK_DEPLOY=1, running proving benchmarks against existing network '$namespace'." + fi spartan/bootstrap.sh proving_bench "${env_file}" rm -rf bench-out mkdir -p bench-out @@ -772,21 +777,24 @@ case "$cmd" in ;; "ci-network-block-capacity-bench") # Args: [docker_image] - # Deploys network and runs block capacity benchmarks. Cleanup should be done separately. + # Deploys network and runs block capacity benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI=1 env_file="${1:?env_file is required}" namespace="${2:?namespace is required}" docker_image="${3:-}" build - # If no docker image provided, build and push to aztecdev - if [ -z "$docker_image" ]; then - release-image/bootstrap.sh push_pr - docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" - fi - # Set up environment and deploy using spartan export NAMESPACE="$namespace" - export AZTEC_DOCKER_IMAGE="$docker_image" - spartan/bootstrap.sh network_deploy "${env_file}" + if [ "${SKIP_NETWORK_DEPLOY:-0}" != "1" ]; then + # If no docker image provided, build and push to aztecdev + if [ -z "$docker_image" ]; then + release-image/bootstrap.sh push_pr + docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" + fi + export AZTEC_DOCKER_IMAGE="$docker_image" + spartan/bootstrap.sh network_deploy "${env_file}" + else + echo "SKIP_NETWORK_DEPLOY=1, running block capacity benchmarks against existing network '$namespace'." + fi # Run block capacity benchmarks spartan/bootstrap.sh block_capacity_bench "${env_file}" rm -rf bench-out @@ -797,21 +805,25 @@ case "$cmd" in "ci-network-bench-10tps") # Args: [docker_image] # Deploys bench-10tps and runs the 10-min sustained 10 TPS benchmark. + # Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. # Cleanup is done separately via ci-network-teardown. export CI=1 env_file="${1:?env_file is required}" namespace="${2:?namespace is required}" docker_image="${3:-}" build - # If no docker image provided, build and push to aztecdev - if [ -z "$docker_image" ]; then - release-image/bootstrap.sh push_pr - docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" - fi - # Set up environment and deploy using spartan export NAMESPACE="$namespace" - export AZTEC_DOCKER_IMAGE="$docker_image" - spartan/bootstrap.sh network_deploy "${env_file}" + if [ "${SKIP_NETWORK_DEPLOY:-0}" != "1" ]; then + # If no docker image provided, build and push to aztecdev + if [ -z "$docker_image" ]; then + release-image/bootstrap.sh push_pr + docker_image="aztecprotocol/aztecdev:$(git rev-parse HEAD)" + fi + export AZTEC_DOCKER_IMAGE="$docker_image" + spartan/bootstrap.sh network_deploy "${env_file}" + else + echo "SKIP_NETWORK_DEPLOY=1, running the 10 TPS benchmark against existing network '$namespace'." + fi # Run the 10 TPS benchmark spartan/bootstrap.sh bench_10tps "${env_file}" rm -rf bench-out diff --git a/ci.sh b/ci.sh index c1230d142a9e..837e98820ee3 100755 --- a/ci.sh +++ b/ci.sh @@ -31,6 +31,7 @@ function print_usage { echo_cmd "network-scenarios" "Spin up EC2 instances to run network scenario tests in parallel." echo_cmd "network-tests" "Spin up an EC2 instance to run tests on a network." echo_cmd "network-bench" "Spin up an EC2 instance to run benchmarks on a network." + echo_cmd "network-proving-bench" "Spin up an EC2 instance to deploy a network and run proving benchmarks. Set SKIP_NETWORK_DEPLOY=1 to skip deploy." echo_cmd "network-bench-10tps" "Spin up an EC2 instance to run the 10 TPS benchmark on bench-10tps." echo_cmd "network-teardown" "Spin up an EC2 instance to teardown a network deployment." echo_cmd "network-tests-kind" "Spin up an EC2 instance to run a KIND-based spartan test." @@ -250,38 +251,48 @@ case "$cmd" in network-bench) # Args: [docker_image] # If docker_image is not provided, ci-network-bench will build and push to aztecdev. + # Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI_DASHBOARD="network" export JOB_ID="x-${2:?namespace is required}-network-bench" export INSTANCE_POSTFIX="n-bench" # Enough for the build, which should have a lot of caching, and the test harness. # Resources are on GCP. export CPUS=16 - bootstrap_ec2 "./bootstrap.sh ci-network-bench $*" + skip_network_deploy=0 + [ "${SKIP_NETWORK_DEPLOY:-0}" = "1" ] && skip_network_deploy=1 + bootstrap_ec2 "SKIP_NETWORK_DEPLOY=$skip_network_deploy ./bootstrap.sh ci-network-bench $*" ;; network-proving-bench) # Args: [docker_image] - # Deploys network and runs proving benchmarks. + # Deploys network and runs proving benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI_DASHBOARD="network" export JOB_ID="x-${2:?namespace is required}-network-proving-bench" CPUS=16 export INSTANCE_POSTFIX="n-proving-bench" - bootstrap_ec2 "./bootstrap.sh ci-network-proving-bench $*" + skip_network_deploy=0 + [ "${SKIP_NETWORK_DEPLOY:-0}" = "1" ] && skip_network_deploy=1 + bootstrap_ec2 "SKIP_NETWORK_DEPLOY=$skip_network_deploy ./bootstrap.sh ci-network-proving-bench $*" ;; network-block-capacity-bench) # Args: [docker_image] - # Deploys network and runs block capacity benchmarks. + # Deploys network and runs block capacity benchmarks. Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI_DASHBOARD="network" export JOB_ID="x-${2:?namespace is required}-network-block-capacity-bench" CPUS=16 export INSTANCE_POSTFIX="n-block-cap-bench" - bootstrap_ec2 "./bootstrap.sh ci-network-block-capacity-bench $*" + skip_network_deploy=0 + [ "${SKIP_NETWORK_DEPLOY:-0}" = "1" ] && skip_network_deploy=1 + bootstrap_ec2 "SKIP_NETWORK_DEPLOY=$skip_network_deploy ./bootstrap.sh ci-network-block-capacity-bench $*" ;; network-bench-10tps) # Args: [docker_image] # Deploys the bench-10tps network and runs the 10-min 10 TPS benchmark. + # Set SKIP_NETWORK_DEPLOY=1 to run against an existing network. export CI_DASHBOARD="network" export JOB_ID="x-${2:?namespace is required}-network-bench-10tps" CPUS=16 export AWS_SHUTDOWN_TIME=${AWS_SHUTDOWN_TIME:-180} export INSTANCE_POSTFIX="n-bench-10tps" - bootstrap_ec2 "./bootstrap.sh ci-network-bench-10tps $*" + skip_network_deploy=0 + [ "${SKIP_NETWORK_DEPLOY:-0}" = "1" ] && skip_network_deploy=1 + bootstrap_ec2 "SKIP_NETWORK_DEPLOY=$skip_network_deploy ./bootstrap.sh ci-network-bench-10tps $*" ;; network-teardown) # Args: diff --git a/ci3/bootstrap_ec2 b/ci3/bootstrap_ec2 index 117ee3e1e321..39fb276d0f2c 100755 --- a/ci3/bootstrap_ec2 +++ b/ci3/bootstrap_ec2 @@ -346,6 +346,7 @@ start_build() { -e NPM_TOKEN=${NPM_TOKEN:-} \ -e CARGO_REGISTRY_TOKEN=${CARGO_REGISTRY_TOKEN:-} \ -e SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN:-} \ + -e AZTEC_FOUNDATION_CI_SLACK_BOT_TOKEN=${AZTEC_FOUNDATION_CI_SLACK_BOT_TOKEN:-} \ -e SOCKET_SECURITY_API_TOKEN=${SOCKET_SECURITY_API_TOKEN:-} \ -e AWS_TOKEN=\$aws_token \ -e NAMESPACE=${NAMESPACE:-} \ diff --git a/docs/developer_versioned_docs/version-v4.3.0/docs/aztec-nr/debugging.md b/docs/developer_versioned_docs/version-v4.3.0/docs/aztec-nr/debugging.md index f5980ea4aa85..cb9d5b3d32ba 100644 --- a/docs/developer_versioned_docs/version-v4.3.0/docs/aztec-nr/debugging.md +++ b/docs/developer_versioned_docs/version-v4.3.0/docs/aztec-nr/debugging.md @@ -19,7 +19,7 @@ Enable different levels of logging on the local network or node by setting `LOG_ ```bash # Set log level (options: fatal, error, warn, info, verbose, debug, trace) -LOG_LEVEL=debug aztec start --local-network +LOG_LEVEL="debug; info: json-rpc, simulator" aztec start --local-network # Different levels for different services LOG_LEVEL="verbose;info:sequencer" aztec start --local-network diff --git a/docs/docs-developers/docs/aztec-js/how_to_read_data.md b/docs/docs-developers/docs/aztec-js/how_to_read_data.md index 2fd4e438921d..2cc3b2ecca88 100644 --- a/docs/docs-developers/docs/aztec-js/how_to_read_data.md +++ b/docs/docs-developers/docs/aztec-js/how_to_read_data.md @@ -49,6 +49,10 @@ When simulating private functions, the caller must have access to any private st If the caller doesn't have access to another address's notes, the simulation will fail with an error. +:::tip +If `.simulate()` is prompting the user to sign every call, or failing with `min_revertible_side_effect_counter must not be 0` when you pass `from: AztecAddress.ZERO`, see [Simulate without signing prompts](./how_to_simulate_without_signing.md). +::: + :::warning Simulation runs locally without generating proofs. No correctness guarantees are provided on the result. See [Call Types](../foundational-topics/call_types.md#simulate) for more details. ::: diff --git a/docs/docs-developers/docs/aztec-js/how_to_simulate_without_signing.md b/docs/docs-developers/docs/aztec-js/how_to_simulate_without_signing.md new file mode 100644 index 000000000000..72daff7d9c0f --- /dev/null +++ b/docs/docs-developers/docs/aztec-js/how_to_simulate_without_signing.md @@ -0,0 +1,112 @@ +--- +title: Simulate without signing prompts +tags: [simulation, authwit, wallet] +sidebar_position: 6 +description: How to call .simulate() on a view function or estimate gas without prompting the user to sign authentication witnesses. +--- + +You want to call `.simulate()` from an app and not have the user's wallet pop up a signing prompt. This page covers the symptoms that lead to that prompt, why the obvious workarounds do not work, and the right fix. + +For the conceptual model of what kernelless simulation is, see [Kernelless simulations](../foundational-topics/pxe/kernelless_simulations.md). + +## Symptoms + +You are probably here because of one of these: + +- The wallet prompts the user for a signature on every `.simulate()` call, including reads of view-style functions. +- `.simulate()` fails with one of: + - `Account "0x0000…0000" does not exist on this wallet.` (from `EmbeddedWallet`) + - `Account not found in wallet for address: 0x0000…0000` (from other wallets built on `BaseWallet`) + - `Circuit execution failed: min_revertible_side_effect_counter must not be 0 for tail_to_public` (from a custom wallet that does not intercept the zero address, where the call reaches the kernel) + +All three are the same root cause: passing `from: AztecAddress.ZERO`. + +- A custom fee payment method breaks during simulation because `from` is `AztecAddress.ZERO`. +- Simulations take long enough that you want to skip the kernel circuits entirely. + +## The wrong fix + +Do not pass `from: AztecAddress.ZERO`. That value was the old way to express "no account context," and it is no longer a supported input for `.simulate()`. The replacement is `NO_FROM` (from `@aztec/aztec.js/account`), which tells the wallet to execute the payload through the default entrypoint with no account contract mediation. `NO_FROM` is still only appropriate for calls that genuinely have no sender; use a real account address for everything else. + +## The right fix + +A simulation uses a **stub account contract override**: the wallet provides a `SimulationOverrides` payload whose `contracts` map swaps the caller's account contract for a stub whose `is_valid` always returns true, and the PXE applies that override during the kernelless simulation. With the stub in place, authwit validity checks pass without a signature, and the wallet collects any `CallAuthorizationRequest` offchain effects emitted during the run to turn them into real authentication witnesses for the eventual `.send()`. + +`EmbeddedWallet` installs this override automatically on every `.simulate()` call, so most apps do not need to construct overrides themselves. The two ways to wire this up below correspond to "use the default" and "implement it in your own wallet." + +### Calling .simulate() from an app + +For a normal `.simulate()` you do not need to pass overrides yourself. The default simulation path is already kernelless, and wallets such as `EmbeddedWallet` install the stub-account override internally for you. Three things to remember: + +- Pass a real account address as `from`, or `NO_FROM` if the call genuinely has no sender. Do not use `AztecAddress.ZERO`. +- For simple reads, you can omit the `fee` block. +- For a transaction whose real fee path uses a fee payment contract (FPC) with private side effects (the FPC emits notes during fee payment), include that FPC in the simulation's fee options so gas estimation accounts for the FPC's side effects. Kernelless still applies; the gas number stays accurate. +- If you have a stale call site that uses `from: AztecAddress.ZERO` plus a no-op fee payment method as a workaround, replace it with a real `from` (or `NO_FROM`) and drop the no-op fee contract. + +#include_code simulate-view-without-signing /docs/examples/ts/aztecjs_kernelless_simulation/index.ts typescript + +If you genuinely need to construct your own `SimulationOverrides` (for example, to combine a contract-instance swap with a `fastForwardContractUpdate` for upgrade testing), you can pass them through `.simulate()`: + +```typescript +import { SimulationOverrides } from "@aztec/aztec.js/wallet"; + +const { result } = await contract.methods + .transfer_in_private(sender, recipient, amount, nonce) + .simulate({ + from: sender, + overrides: new SimulationOverrides({ + /* contracts and/or publicStorage */ + }), + }); +``` + +The override map itself has to be built by code that knows the contract class id and live contract instance. That is normally the wallet, not the app. Note that `overrides` does not apply to [utility functions](../foundational-topics/pxe/kernelless_simulations.md#where-kernelless-does-not-apply), those are simulated through `wallet.executeUtility`, which rejects `SimulationOverrides`. If your wallet does not handle the override path for you and you are tempted to reimplement it in app code, read the next section instead. + +### Implementing the override in a custom wallet + +`EmbeddedWallet` (`yarn-project/wallets/src/embedded/embedded_wallet.ts`, in `@aztec/wallets`) is the canonical implementation of the override pattern and the reference any custom wallet should follow. The three pieces it wires up are: + +1. **Register the stub contract class with the PXE at wallet startup.** Inside `initStubClasses`, `EmbeddedWallet` calls `pxe.registerContractClass` for each supported account type's stub artifact and caches the resulting class id by account type. +2. **Build an override map for every account in scope.** Inside `buildAccountOverrides`, it fetches the live contract instance for each scoped address and returns a `ContractOverrides` map that copies the instance with `currentContractClassId` rewritten to the stub class id. The map covers every account in scope, not only `from`. +3. **Use the stub entrypoint and pass the override to `pxe.simulateTx`.** Inside the overridden `simulateViaEntrypoint`, it constructs the `TxExecutionRequest` through the stub account's `DefaultAccountEntrypoint` (so the request is signed by the stub's empty-signature provider) and calls `pxe.simulateTx` with the resulting `SimulationOverrides`. + +The key constraints on this path: + +- `skipKernels` must be `true` to use `contracts` overrides. The PXE rejects the combination otherwise. `pxe.simulateTx` already defaults `skipKernels` to `true`. +- The stub contract class must be registered with the PXE before you reference it in an override. +- The override map must cover every scoped account, not only `from`. + +## Collecting authwit requests + +A simulation with the stub override active will reach `#[authorize_once]` call sites in app and token contracts without prompting for signatures. Each such site emits a `CallAuthorizationRequest` as an offchain effect, which the wallet can collect and turn into a real authentication witness for the eventual `.send()`. + +The example below uses the canonical contract-mediated pattern: Alice calls `Crowdfunding.donate(amount)`, which internally calls `transfer_in_private(alice, crowdfunding, amount, 0)` with `msg_sender = crowdfunding`. The token's `#[authorize_once]` macro requires an authwit from Alice authorizing the crowdfunding contract. Because Alice is the transaction sender, her PXE already has her notes and nullifier key, so the simulation can run end-to-end against her own state without any cross-wallet state sharing. + +Run the simulation and filter the offchain effects by the `CallAuthorizationRequest` selector: + +#include_code simulate-and-collect-effects /docs/examples/ts/aztecjs_kernelless_simulation/index.ts typescript + +Decode each effect into a `CallAuthorizationRequest`. The `innerHash` field is the piece the authorizing account needs to sign: + +#include_code decode-call-authorization /docs/examples/ts/aztecjs_kernelless_simulation/index.ts typescript + +Build a real authentication witness from each inner hash and send the transaction with the collected witnesses attached: + +#include_code build-authwits-and-send /docs/examples/ts/aztecjs_kernelless_simulation/index.ts typescript + +The app does not need to know which calls require authwits ahead of time. The simulation discovers them; the wallet signs them at send time. + +`EmbeddedWallet.sendTx` runs this same simulate-then-collect flow internally before delegating to `BaseWallet.sendTx`, so an app that uses `EmbeddedWallet` does not need to call `.simulate()` manually and pass `authWitnesses` to `.send()`. The explicit pattern above is the one a wallet that does not auto-collect must implement, either inside its `sendTx` (as `EmbeddedWallet` does) or inside the app call site. + +## Things to watch out for + +- **`AztecAddress.ZERO` is not "no sender".** Use `NO_FROM` (from `@aztec/aztec.js/account`) for calls that genuinely have no account context, and a real account address otherwise. +- **A private FPC needs to be included in fee options for accurate gas.** Kernelless simulation matches full simulation on gas, but only if the simulation sees the same fee path as the real transaction. If the user will pay through a fee payment contract (FPC) that emits private notes, pass that FPC in the simulation's fee options so its side effects are accounted for. Kernelless plus a private FPC is the supported path; you do not need a full simulation to get accurate gas. +- **`profile()` is not kernelless.** If you call `.profile()` to count circuit gates, the kernels run regardless. Use `.simulate()` if you only need return values, offchain effects, or gas estimates. +- **Utility functions reject overrides.** `FunctionType.UTILITY` calls go through `wallet.executeUtility`, and `ContractFunctionInteraction.simulate` throws `overrides are not supported for utility function simulation` if you pass non-empty `overrides.publicStorage` or `overrides.contracts`. Utility functions do not need an override anyway, since they do not run through an account contract. + +## Related + +- [Kernelless simulations](../foundational-topics/pxe/kernelless_simulations.md) for the conceptual model. +- [Reading contract data](./how_to_read_data.md) for the basic `.simulate()` API. +- [Authentication witnesses](../foundational-topics/advanced/authwit.md) for what `CallAuthorizationRequest` represents. diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md b/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md index d8ade3b69093..4abf4d9a75b0 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md @@ -162,8 +162,8 @@ impl NoteHash for CustomHashNote { note_hash_for_nullification: Field, ) -> Field { // Standard nullifier using owner's nullifier hiding key - let owner_npk_m = get_public_keys(owner).npk_m; - let secret = context.request_nhk_app(owner_npk_m.hash()); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; + let secret = context.request_nhk_app(owner_npk_m_hash); poseidon2_hash_with_separator( [note_hash_for_nullification, secret], DOM_SEP__NOTE_NULLIFIER, @@ -176,7 +176,7 @@ impl NoteHash for CustomHashNote { note_hash_for_nullification: Field, ) -> Option { try_get_public_keys(owner).map(|public_keys| { - let secret = get_nhk_app(public_keys.npk_m.hash()); + let secret = get_nhk_app(public_keys.npk_m_hash); poseidon2_hash_with_separator( [note_hash_for_nullification, secret], DOM_SEP__NOTE_NULLIFIER, diff --git a/docs/docs-developers/docs/foundational-topics/accounts/keys.md b/docs/docs-developers/docs/foundational-topics/accounts/keys.md index 0c673087ca92..70a064e2d124 100644 --- a/docs/docs-developers/docs/foundational-topics/accounts/keys.md +++ b/docs/docs-developers/docs/foundational-topics/accounts/keys.md @@ -68,9 +68,11 @@ The nullifier hiding key (`nhk`) — sometimes referred to in older documentatio To get the owner's master nullifier public key hash (needed as input): ```rust -let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); +let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; ``` +`PublicKeys` exposes the nullifier, outgoing-viewing, and tagging keys directly as their hashes; only `ivpk_m` is held as a Grumpkin point (it is required as a point for address derivation and encrypt-to-address). + :::warning Do not compute nullifier keys by hand or derive custom blinding factors. The protocol kernel validates that `nhk_app` derives correctly from the master key — a hand-rolled value will fail verification. ::: @@ -122,17 +124,23 @@ Your Aztec address is deterministically computed from your public keys and accou ![Address derivation](/img/address_derivation.svg) +:::note +The diagram above is being updated to reflect the new key-hashing scheme described below. Treat the text formulas as authoritative until a refresh lands. +::: + ```text pre_address = hash(public_keys_hash, partial_address) where: - public_keys_hash = hash(Npk_m, Ivpk_m, Ovpk_m, Tpk_m) - partial_address = hash(contract_class_id, salted_initialization_hash) + public_keys_hash = hash(npk_m_hash, ivpk_m_hash, ovpk_m_hash, tpk_m_hash) + ivpk_m_hash = hash(Ivpk_m.x, Ivpk_m.y) // computed in-circuit + npk_m_hash, ovpk_m_hash, tpk_m_hash // computed off-circuit (PXE) + partial_address = hash(contract_class_id, salted_initialization_hash) contract_class_id = hash(artifact_hash, fn_tree_root, public_bytecode_commitment) - salted_initialization_hash = hash(deployer_address, salt, constructor_hash) + salted_initialization_hash = hash(salt, constructor_hash, deployer_address, immutables_hash) ``` -The final address is derived as `address = (pre_address * G + Ivpk_m).x` - only the x-coordinate of the resulting elliptic curve point. +The final address is derived as `address = (pre_address * G + Ivpk_m).x` - only the x-coordinate of the resulting elliptic curve point. Note that `Ivpk_m` (the master incoming viewing key) is the only public key still represented as an elliptic curve point: address derivation needs it as a point so that anyone can encrypt to the address without further information. The other three master keys are exposed only as their hashes. This derivation ensures: diff --git a/docs/docs-developers/docs/foundational-topics/pxe/index.md b/docs/docs-developers/docs/foundational-topics/pxe/index.md index 93bbbb4e3efb..3323efa88a2f 100644 --- a/docs/docs-developers/docs/foundational-topics/pxe/index.md +++ b/docs/docs-developers/docs/foundational-topics/pxe/index.md @@ -40,7 +40,7 @@ flowchart TB ``` :::note[Privacy consideration] -When the PXE queries the node for world state (e.g., to check if a nullifier exists), the node learns which data the user is interested in. This is a known tradeoff—users can mitigate this by running their own node. +When the PXE queries the node for world state (e.g., to check if a nullifier exists), the node learns which data the user is interested in. This is a known tradeoff. Users can mitigate this by running their own node. ::: ## Components @@ -51,7 +51,7 @@ An application prompts the user's PXE to execute a transaction (e.g. execute fun The contract function simulator handles execution of smart contract functions by simulating transactions. It generates the required data and inputs for these functions, including partial witnesses and public inputs. -Until simulated simulations are implemented ([#9133](https://github.com/AztecProtocol/aztec-packages/issues/9133)), authentication witnesses are required for simulation before proving. +By default, the simulator runs in a [kernelless mode](./kernelless_simulations.md): it executes the private bytecode and computes the values the private kernels would have produced in TypeScript, instead of running the kernel circuits themselves. This is faster than a full simulation and lets the wallet capture authentication witness requests as offchain effects without prompting the user to sign during simulation. ### Proof Generation @@ -93,7 +93,7 @@ The set of oracles that the PXE exposes to private and utility functions is vers The version uses two components, `major.minor`, with the following compatibility rules: -- **`major`** must match exactly. A major bump is a breaking change — oracles were removed or their signatures changed — and a PXE on a different major cannot safely run the contract. +- **`major`** must match exactly. A major bump is a breaking change: oracles were removed or their signatures changed, and a PXE on a different major cannot safely run the contract. - **`minor`** indicates additive changes (new oracles). The PXE uses a best-effort approach here: a contract compiled against a higher `minor` than the PXE supports is still allowed to run, and an error is only thrown if the contract actually invokes an oracle the PXE does not know about. In practice, a contract built with a newer Aztec.nr may not use any of the newly added oracles at all, in which case it runs fine on an older PXE. The canonical version constants live in the PXE (`ORACLE_VERSION_MAJOR` / `ORACLE_VERSION_MINOR` in `yarn-project/pxe/src/oracle_version.ts`) and in Aztec.nr (`noir-projects/aztec-nr/aztec/src/oracle/version.nr`). The two are kept in lockstep as part of each release. diff --git a/docs/docs-developers/docs/foundational-topics/pxe/kernelless_simulations.md b/docs/docs-developers/docs/foundational-topics/pxe/kernelless_simulations.md new file mode 100644 index 000000000000..380ef3366348 --- /dev/null +++ b/docs/docs-developers/docs/foundational-topics/pxe/kernelless_simulations.md @@ -0,0 +1,98 @@ +--- +title: Kernelless simulations +sidebar_position: 2 +tags: [pxe, simulation, gas estimation] +description: How the PXE simulates transactions without running the private kernel circuits, why it is the default for .simulate(), and what it skips. +--- + +This page explains what kernelless simulation is in the Private eXecution Environment (PXE), how it differs from a full simulation, and where it does and does not apply. If you are looking for the recipe to make `.simulate()` succeed without signing prompts, see [Simulate without signing prompts](../../aztec-js/how_to_simulate_without_signing.md). + +## Overview + +A "full" simulation in the PXE runs the user's private function bytecode, then runs every private kernel circuit (init, inner, reset, tail) over the resulting execution trace. The kernels enforce protocol rules such as side-effect counter sequencing. + +A **kernelless simulation** runs the same private bytecode, but skips the kernel circuits. Instead, the PXE computes the values the kernel would have produced in TypeScript via `generateSimulatedProvingResult`. The output of a kernelless simulation is the same shape as a full simulation, so callers can read return values, offchain effects, and gas estimates from it without caring which path produced them. + +Kernelless simulation is the **default** for `PXE.simulateTx`. The `skipKernels` option in `SimulateTxOpts` defaults to `true`, and `BaseWallet` inherits that default. In normal use, every call to `.simulate()` on a contract method already runs without the kernels. + +The main consequence is speed. Skipping the kernels removes the most expensive part of simulation, so a kernelless run is faster than a full run on typical transactions. + +## What the PXE still does + +A kernelless simulation is not a partial execution. The PXE still: + +- runs the real ACIR bytecode for every private function in the call chain +- executes oracles, decrypts notes, builds nullifiers, and captures offchain effects +- simulates public calls against an ephemeral fork of public state +- runs `node.isValidTx` against the resulting transaction, unless `skipTxValidation` is set +- at the raw `PXE.simulateTx` level, enforces fee payer presence unless `skipFeeEnforcement` is set. Contract `.simulate()` calls through `BaseWallet` already pass `skipFeeEnforcement: true` for estimation, so you do not need to provide a fee block for normal read simulations + +What it skips with `skipKernels: true`: + +- the private kernel init, inner, reset, and tail circuits +- the proof generation associated with those kernels + +The kernels themselves do not check authentication witnesses. Authwit validity is checked by user-contract code (the `is_valid` call that the `#[authorize_once]` macro injects into the called function). What lets a kernelless simulation skip the signing prompt is the **stub-account override**, not the absence of the kernels: replacing the caller's account contract with a stub whose `is_valid` always returns true lets that user-contract check pass without a signature. + +## Simulation overrides + +A kernelless simulation accepts an optional `SimulationOverrides` payload that lets you replace pieces of the state the PXE would otherwise read from chain. The shape (in `yarn-project/stdlib/src/tx/simulated_tx.ts`) is: + +```typescript +type ContractOverrides = Record< + string, + { instance: ContractInstanceWithAddress } +>; + +class SimulationOverrides { + publicStorage?: PublicStorageOverride[]; + contracts?: ContractOverrides; +} +``` + +Two parts: + +- `publicStorage` rewrites slots in the ephemeral public-data fork before simulation. This is compatible with kernel execution; you can use it with or without `skipKernels`. +- `contracts` swaps a contract instance in the simulator's contract DB by replacing its `currentContractClassId`. There is no `artifact` field; the new class id must already be registered with the PXE via `pxe.registerContractClass(...)` so the simulator can resolve the bytecode. This requires `skipKernels: true`: PXE explicitly rejects contract overrides combined with kernel execution, because the kernels would fail validations against the swapped class. + +The `contracts` override path is what makes "simulate without signing" possible. Replacing the caller's account contract with a stub whose `is_valid` always returns true lets the simulation reach `#[authorize_once]` call sites without prompting the user to sign anything. + +For the cheat that simulates a contract as if it had already been upgraded to a new class, see [`fastForwardContractUpdate`](../../aztec-js/how_to_test.md#fast-forwarding-a-contract-update), which returns a `SimulationOverrides` covering both the registry storage rewrite and the upgraded instance entry. + +## Stub account contracts + +The stub-account pattern is the standard way to drive a kernelless simulation without authwit prompts. + +The Noir sources live at `noir-projects/noir-contracts/contracts/account/simulated_schnorr_account_contract/` and `simulated_ecdsa_account_contract/`. Both implement `is_valid` to always return `IS_VALID_SELECTOR`, so authwit validity checks pass without a real signature. Their constructors deliberately emit the same shape of side effects as the real account contracts (one nullifier for the contract init, one nullifier for the `SinglePrivateImmutable` signing-key state, one note hash for the key note, and a private log) so that gas estimation against the stub produces the same numbers as the real account. + +## Authwit requests come from the app, not the stub + +The `CallAuthorizationRequest` offchain effects you see during a kernelless simulation are emitted by the **app or token contract's `#[authorize_once]` macro** during private execution. The stub account's only job is to let the validity check pass so the simulation can reach those call sites in the first place. The wallet then collects the requests via `collectOffchainEffects(privateExecutionResult)`, filters them by `CallAuthorizationRequest.getSelector()`, and decodes each one to build a real `AuthWitness`. + +## Where kernelless does not apply + +The default applies to `simulateTx`, but not to every entry point that looks like simulation: + +- **`profileTx`** is not kernelless. `PXE.profileTx` always runs the private kernels after private execution; `skipProofGeneration` controls only whether a proof is produced, not whether kernel logic runs. If you call `.profile()` to measure circuit gates, expect the full kernel cost. +- **Public-only fast path**. When `BaseWallet.simulateTx` detects a leading run of public static calls, it sends them straight to `node.simulatePublicCalls` through `simulateViaNode`, bypassing the PXE private path entirely. There is no kernel to skip. `SimulationOverrides` still applies on that path. +- **Utility functions**. `FunctionType.UTILITY` calls go through `wallet.executeUtility`, not `pxe.simulateTx`. `ContractFunctionInteraction.simulate` rejects `overrides.publicStorage` and `overrides.contracts` for utility functions. + +## Gas estimation parity + +If the real transaction will pay through a fee payment contract (FPC) with private side effects (the FPC emits notes during fee payment), include that FPC in the simulation's fee options. The FPC's side effects feed into gas estimation, and you can run kernelless with the FPC attached to get both the speed benefit and accurate gas numbers. The default of "omit the fee block" only produces accurate gas for transactions whose fee path has no private side effects. + +## Multi-account scopes + +A simulation can run with multiple scoped accounts via `additionalScopes`. If you build a stub-account override for the sender only, the simulation will still prompt for authwits from any other in-scope account it touches. The override map must cover every account in scope, not just `from`. + +The canonical implementation is `EmbeddedWallet.buildAccountOverrides` in `yarn-project/wallets/src/embedded/embedded_wallet.ts`: for each scoped address, fetch the live contract instance from the PXE, copy it, and rewrite `currentContractClassId` to point at the stub class id registered at wallet startup. When implementing overrides in your own wallet, follow this pattern and make sure the scope list you build against matches the one the simulation will run with. + +## When you might still want a full simulation + +Kernelless is the right default. Reach for `skipKernels: false` only when you are validating kernel-level behavior itself. For everything else, including accurate gas estimation through a fee payment contract with private side effects, run kernelless with the appropriate fee options. + +## Related + +- [Simulate without signing prompts](../../aztec-js/how_to_simulate_without_signing.md) for the recipe-oriented version of this page. +- [Reading contract data](../../aztec-js/how_to_read_data.md) for the basic `.simulate()` API. +- [Wallets](../wallets.md) for the wallet's role in capturing private authorizations during simulation. diff --git a/docs/docs-developers/docs/foundational-topics/wallets.md b/docs/docs-developers/docs/foundational-topics/wallets.md index 4c0bc46c4457..895570670b5c 100644 --- a/docs/docs-developers/docs/foundational-topics/wallets.md +++ b/docs/docs-developers/docs/foundational-topics/wallets.md @@ -35,7 +35,7 @@ Private functions use a UTXO model, so their execution trace is determined entir Public functions use an account model (like Ethereum), so their execution trace depends on chain state at inclusion time, which may differ from simulation. ::: -Before sending, the wallet may run a **simulation** — a lightweight execution using a stub account contract that avoids expensive kernel circuit execution. This simulation estimates gas limits for the transaction and captures any required private authorization data (see [Authorizing actions](#authorizing-actions) below). The `EmbeddedWallet` runs this step automatically on every send. +Before sending, the wallet may run a **simulation**, a lightweight execution using a stub account contract that avoids expensive kernel circuit execution. This simulation estimates gas limits for the transaction and captures any required private authorization data (see [Authorizing actions](#authorizing-actions) below). The `EmbeddedWallet` runs this step automatically on every send. For details on what the PXE skips in this mode and how to wire it up in your own wallet, see [Kernelless simulations](./pxe/kernelless_simulations.md). Finally, the wallet **sends** the resulting _transaction_ object, which includes the proof of execution, to an Aztec Node. The transaction is then broadcasted through the peer-to-peer network, to be eventually picked up by a sequencer and included in a block. diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 42e923dd34ef..9963d2727a37 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -79,6 +79,82 @@ If you need to customize source or block range, construct the struct manually wi `source` controls which RPCs are queried: `LogSource.PRIVATE`, `LogSource.PUBLIC`, or `LogSource.PUBLIC_AND_PRIVATE`. `from_block` and `to_block` define a half-open `[from, to)` block range filter. Both are `Option` and default to `Option::none()` (no filtering). +### [Protocol] Public-key hashes replace points in `PublicKeys` + +Ships together with immutables hash changes (shown below). + +Per [AZIP-8](https://github.com/AztecProtocol/governance/blob/main/AZIPs/azip-8.md), `PublicKeys` no longer carries the four master public keys as elliptic curve points. Three of them (`npk_m`, `ovpk_m`, `tpk_m`) are now exposed only as their poseidon2 hash digests; only `ivpk_m` (the master incoming viewing key) remains a point because address derivation needs it as a curve point. + +**This is a hard fork:** every contract address and account address derived from a non-default `PublicKeys` changes. + +**Contract author migration.** Read the master nullifier hash directly off `PublicKeys` instead of computing it from a point: + +```diff +- let owner_npk_m = get_public_keys(owner).npk_m; +- let secret = context.request_nhk_app(owner_npk_m.hash()); ++ let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; ++ let secret = context.request_nhk_app(owner_npk_m_hash); +``` + +The same field-rename applies to `.ovpk_m` and `.tpk_m`: these are now `.ovpk_m_hash` and `.tpk_m_hash` respectively. Code that needed those keys as points will not compile; the points are no longer accessible to contract code. + +**Custom account contracts.** Wallets that ship their own Noir account contracts must recompile. Macro-generated calldata extraction and the `request_nsk_app` / `request_ovsk_app` paths use the hash form natively. + +**TS / wallet author migration.** The `PublicKeys` constructor signature changes from four `Point`s to `(npkMHash: Fr, ivpkM: Point, ovpkMHash: Fr, tpkMHash: Fr)`. `KeyValidationRequest` carries `pkMHash: Fr` instead of `pkM: Point`. `KeyStore.getMasterSecretKey` now takes a `pkMHash: Fr` rather than a `Point`. Callers using the auto-generated TS binding pick this up automatically; callers that hand-roll the arg buffer must update. + +**Wallet UI.** Any panel that displayed `masterNullifierPublicKey`, `masterOutgoingViewingPublicKey`, or `masterTaggingPublicKey` as Grumpkin points will no longer compile against the new `PublicKeys` class. The points themselves are no longer in `ContractInstancePublished` and cannot be recovered from the onchain record. Switch to displaying the hashes (`npkMHash`, `ovpkMHash`, `tpkMHash`) or drop the display. + +**PXE storage migration.** `DatabaseVersionManager` deletes pre-v6 databases on first open: users will see registered accounts, contacts, address aliases, and synced notes wiped. Wallets should surface a "your local state was reset, please re-register accounts and re-sync" path. There is no forward migration because the address derived from a given secret changes (the new `public_keys_hash` is over four single-key digests, not four raw points). Previous addresses are not recoverable from the same secret; assets and notes attached to them are inaccessible at the protocol level. + +**Indexer / event-decoder migration.** The `ContractInstancePublished` private log payload is now 13 fields: + +```text +[ MAGIC, address, version, salt, class_id, init_hash, + immutables_hash, + npk_m_hash, + ivpk_m.x, ivpk_m.y, + ovpk_m_hash, + tpk_m_hash, + deployer ] +``` + +`version` is `2`. v1 events should be rejected. + +**Security note (PXE side).** The kernel circuit no longer checks that `npk_m`, `ovpk_m`, `tpk_m` are on-curve or non-infinity (those points are no longer in the witness). The PXE / key store relies on `deriveKeys`'s by-construction guarantee that derived points are on-curve and non-infinity. Account-creation flows that bypass `deriveKeys` (e.g. importing pre-derived public keys from an external source) must validate this themselves, or risk producing unspendable notes. + +### [Contracts] `ContractInstance` gains `immutablesHash`, address derivation changes + +`ContractInstance` now has a new `immutablesHash: Fr` field that commits to a contract's immutable storage values. The field is folded into the salted initialization hash, so contract addresses are impacted: + +``` +salted_initialization_hash = poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, [salt, initialization_hash, deployer, immutables_hash]) +``` + +**You may need to act if:** + +- You hardcode contract addresses computed from instance fields outside the SDK. Recompute them under the new derivation. +- You parse the `ContractInstancePublished` private log directly. The event payload has an extra field, with `immutables_hash` inserted between `initialization_hash` and the public-keys block: + + ``` + [tag, address, version, salt, classId, initialization_hash, immutables_hash, ...publicKeys(5), deployer] + ``` + +- You call `ContractInstanceRegistry.publish_for_public_execution` directly. The function now takes 6 arguments instead of 5, with `immutables_hash` inserted between `initialization_hash` and `public_keys`: + + ```diff + - publish_for_public_execution(salt, contract_class_id, initialization_hash, public_keys, universal_deploy) + + publish_for_public_execution(salt, contract_class_id, initialization_hash, immutables_hash, public_keys, universal_deploy) + ``` + +- You call the `GetContractInstance` AVM opcode directly or use the per-member helpers in `aztec-nr`. A new enum value `ContractInstanceMember::IMMUTABLES_HASH = 3` selects `immutables_hash`. Use the wrapper helper from `aztec::oracle::get_contract_instance`: + + ```rust + use aztec::oracle::get_contract_instance::get_contract_instance_immutables_hash_avm; + let immutables_hash: Option = get_contract_instance_immutables_hash_avm(address); + ``` + +The `aztec.js` `publishInstance` helper handles this automatically. + ### [Aztec.nr] `emit_private_log_unsafe` / `emit_raw_note_log_unsafe` now take `BoundedVec` The old array-based `emit_private_log_unsafe(tag, log: [Field; N], length)` and `emit_raw_note_log_unsafe(tag, log: [Field; N], length, note_hash_counter)` have been removed. The temporary `_vec_unsafe` variants introduced in a prior release have been renamed to take their place. @@ -172,7 +248,7 @@ The `Schnorr` TypeScript API in `@aztec/foundation/crypto/schnorr` keeps the sam + env.call_public_incognito(SampleContract::at(addr).some_function()); ``` -If you need to call a public function *with* a sender, use `call_public` instead. +If you need to call a public function _with_ a sender, use `call_public` instead. ### [Aztec.nr] TXE `view_public_incognito` is deprecated @@ -325,7 +401,13 @@ If you set `Noir: Nargo Path` in the VS Code Noir extension to `$HOME/.aztec/cur ```typescript const result = await contract.methods.read_balance(account).simulate({ overrides: { - publicStorage: [{ contract: contract.address, slot: BALANCE_SLOT, value: new Fr(1_000_000n) }], + publicStorage: [ + { + contract: contract.address, + slot: BALANCE_SLOT, + value: new Fr(1_000_000n), + }, + ], }, }); ``` @@ -342,7 +424,7 @@ Direct callers of the `SimulationOverrides` constructor must switch from a posit `overrides.contracts` swaps contract instances in the simulator's contract DB — useful for simulating a contract being on a different class than the one it was deployed with. To simulate a complete onchain upgrade flow, use the `fastForwardContractUpdate` helper which returns a `SimulationOverrides` covering both registry storage rewrites and the upgraded instance entry: ```typescript -import { fastForwardContractUpdate } from '@aztec/aztec.js'; +import { fastForwardContractUpdate } from "@aztec/aztec.js"; const overrides = await fastForwardContractUpdate({ instanceAddress: contract.address, @@ -469,8 +551,8 @@ If you want the latest L1-confirmed checkpoint regardless of proposed state, swi ```ts // Throws BadRequestError when a proposed entry exists at the resolved number: -await node.getCheckpoint('proposed', { includeAttestations: true }); -await node.getCheckpoint('proposed', { includeL1PublishInfo: true }); +await node.getCheckpoint("proposed", { includeAttestations: true }); +await node.getCheckpoint("proposed", { includeL1PublishInfo: true }); // And when a by-number / by-slot lookup falls back to a proposed entry: await node.getCheckpoint({ number: N }, { includeAttestations: true }); diff --git a/docs/docs-operate/operators/reference/ethereum-rpc-reference.md b/docs/docs-operate/operators/reference/ethereum-rpc-reference.md index d8c56741a84c..51aedf0e8589 100644 --- a/docs/docs-operate/operators/reference/ethereum-rpc-reference.md +++ b/docs/docs-operate/operators/reference/ethereum-rpc-reference.md @@ -270,7 +270,7 @@ Aztec automatically retries failed requests on alternative endpoints when multip Enable detailed RPC logging: ```bash -LOG_LEVEL=debug # or verbose +LOG_LEVEL="debug; info: json-rpc, simulator" # or verbose ``` Look for log entries related to: diff --git a/docs/docs-operate/operators/sequencer-management/slashing-configuration.md b/docs/docs-operate/operators/sequencer-management/slashing-configuration.md index b6ccfee9757e..53a8d0008b62 100644 --- a/docs/docs-operate/operators/sequencer-management/slashing-configuration.md +++ b/docs/docs-operate/operators/sequencer-management/slashing-configuration.md @@ -161,7 +161,7 @@ SLASH_DATA_WITHHOLDING_PENALTY=0 # Set to >0 to enable # Invalid attestations and blocks SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY=2000000000000000000000 # 2000 tokens -SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY=2000000000000000000000 # 2000 tokens +SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY=2000000000000000000000 # 2000 tokens SLASH_INVALID_BLOCK_PENALTY=2000000000000000000000 # 2000 tokens # Offense expiration diff --git a/docs/docs-operate/operators/setup/registering-sequencer.md b/docs/docs-operate/operators/setup/registering-sequencer.md index cd7cd9d07d89..45a3483dc810 100644 --- a/docs/docs-operate/operators/setup/registering-sequencer.md +++ b/docs/docs-operate/operators/setup/registering-sequencer.md @@ -18,7 +18,7 @@ Before proceeding, ensure you have completed the [Sequencer Setup Guide](./seque - Completed sequencer node setup with keystore generated - Access to your **public keystore** file (`keyN_staker_output.json`) -- Sufficient ATP/ATV tokens for staking +- Sufficient **Aztec Token Position (ATP)** or **Aztec Token Vault (ATV)** balance for staking - Wallet with ETH for gas fees - Web browser for accessing the staking dashboard @@ -124,7 +124,7 @@ Follow these steps to register your sequencer(s) through the staking dashboard: 1. **Navigate to the staking dashboard** at https://stake.aztec.network -2. **Connect your wallet** with the account that holds your ATP/ATV tokens +2. **Connect your wallet** with the account that holds your Aztec Token Position (ATP) or Aztec Token Vault (ATV) balance 3. **Click "Stake"** @@ -136,7 +136,7 @@ Follow these steps to register your sequencer(s) through the staking dashboard: 5. **Click through "Start Registration"** after reviewing the requirements -6. **Select the ATP/ATV tokens you want to stake** +6. **Select the ATP or ATV balance you want to stake** 7. **Upload your keystore JSON file** (either single or combined multi-sequencer file) diff --git a/docs/docs-words.txt b/docs/docs-words.txt index 9bd7144a966b..1f2af786d273 100644 --- a/docs/docs-words.txt +++ b/docs/docs-words.txt @@ -182,6 +182,7 @@ jumpi JUMPI kalypso Keccakf +kernelless keypair knwon lbwop @@ -360,6 +361,7 @@ unncessary unreverted unrleated unshield +unspendable unstake unstakes usermod diff --git a/docs/examples/bootstrap.sh b/docs/examples/bootstrap.sh index fb7e32eec2dc..7f5efda660d2 100755 --- a/docs/examples/bootstrap.sh +++ b/docs/examples/bootstrap.sh @@ -210,7 +210,10 @@ function execute-examples { } function test_cmds { - echo "$hash:ONLY_TERM_PARENT=1 docs/examples/bootstrap.sh execute" + # Bumped from the default 600s by ~50% (now 15m) to absorb cumulative-runtime growth + # under merge-queue load — example_swap's `wait-for-proven` poll was tipping SIGTERM + # near the old limit. See PR #23253 dequeue log http://ci.aztec-labs.com/b08ac48286302949. + echo "$hash:ONLY_TERM_PARENT=1:TIMEOUT=15m docs/examples/bootstrap.sh execute" } function test { diff --git a/docs/examples/ts/aztecjs_kernelless_simulation/config.yaml b/docs/examples/ts/aztecjs_kernelless_simulation/config.yaml new file mode 100644 index 000000000000..103036595a84 --- /dev/null +++ b/docs/examples/ts/aztecjs_kernelless_simulation/config.yaml @@ -0,0 +1,16 @@ +# Configuration for aztecjs_kernelless_simulation example +# Demonstrates kernelless simulation with stub account overrides: +# - Calling .simulate() on a view function without signing prompts +# - Harvesting CallAuthorizationRequest offchain effects to build authwits + +# No custom contracts needed - using pre-built contracts from @aztec/noir-contracts.js +contracts: [] + +# Dependencies: +# - @aztec/* packages are auto-linked from yarn-project/ +# - Use npm:package-name for external npm packages +dependencies: + - "@aztec/aztec.js" + - "@aztec/accounts" + - "@aztec/wallets" + - "@aztec/noir-contracts.js" diff --git a/docs/examples/ts/aztecjs_kernelless_simulation/index.ts b/docs/examples/ts/aztecjs_kernelless_simulation/index.ts new file mode 100644 index 000000000000..c23a6222ebb8 --- /dev/null +++ b/docs/examples/ts/aztecjs_kernelless_simulation/index.ts @@ -0,0 +1,167 @@ +import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node"; +import { EmbeddedWallet } from "@aztec/wallets/embedded"; +import { getInitialTestAccountsData } from "@aztec/accounts/testing"; +import { TokenContract } from "@aztec/noir-contracts.js/Token"; +import { CrowdfundingContract } from "@aztec/noir-contracts.js/Crowdfunding"; +import { Fr } from "@aztec/aztec.js/fields"; +import { deriveKeys } from "@aztec/aztec.js/keys"; +import { CallAuthorizationRequest } from "@aztec/aztec.js/authorization"; + +// Setup: connect to network, create alice and bob, deploy a token, mint to alice. +// EmbeddedWallet runs every .simulate() call in kernelless mode with a stub-account +// override applied automatically. The examples below rely on that default. +const node = createAztecNodeClient( + process.env.AZTEC_NODE_URL ?? "http://localhost:8080", +); +await waitForNode(node); +const wallet = await EmbeddedWallet.create(node, { ephemeral: true }); + +const testAccounts = await getInitialTestAccountsData(); +const [aliceAddress, bobAddress] = await Promise.all( + testAccounts.slice(0, 2).map(async (account) => { + return ( + await wallet.createSchnorrAccount( + account.secret, + account.salt, + account.signingKey, + ) + ).address; + }), +); + +const { contract: tokenContract } = await TokenContract.deploy( + wallet, + aliceAddress, + "TestToken", + "TST", + 18, +).send({ from: aliceAddress }); + +await tokenContract.methods + .mint_to_private(aliceAddress, 1000n) + .send({ from: aliceAddress }); + +// docs:start:simulate-view-without-signing +// Reading a private view function would normally route through the account +// contract's entrypoint, whose is_valid check would prompt the user to sign. +// With EmbeddedWallet, .simulate() runs kernelless with a stub-account +// override applied to alice's account, so no signing prompt is triggered. +const { result: decimals } = await tokenContract.methods + .private_get_decimals() + .simulate({ from: aliceAddress }); + +console.log("Token decimals (read via private view):", decimals); +// docs:end:simulate-view-without-signing + +// Deploy a Crowdfunding contract with Bob as the operator and the previously +// deployed token as the donation token. The contract receives donation notes +// for donors, so it needs its own keys (a contract-account-style deployment). +const crowdfundingSecretKey = Fr.random(); +const crowdfundingPublicKeys = (await deriveKeys(crowdfundingSecretKey)) + .publicKeys; +const deadline = Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60; + +const crowdfundingDeployment = CrowdfundingContract.deploy( + wallet, + tokenContract.address, + bobAddress, + deadline, + { publicKeys: crowdfundingPublicKeys, deployer: aliceAddress }, +); +const crowdfundingInstance = await crowdfundingDeployment.getInstance(); +await wallet.registerContract( + crowdfundingInstance, + CrowdfundingContract.artifact, + crowdfundingSecretKey, +); +const { contract: crowdfundingContract } = await crowdfundingDeployment.send({ + from: aliceAddress, + additionalScopes: [crowdfundingInstance.address], +}); + +// docs:start:simulate-and-collect-effects +// Alice calls Crowdfunding.donate(amount). Internally the contract calls +// transfer_in_private(alice, crowdfunding, amount, 0) with msg_sender = +// crowdfunding, so the token's #[authorize_once] macro requires an authwit +// from Alice authorizing the crowdfunding contract. Alice is the sender, so +// her PXE has her notes and nullifier key — no cross-wallet state sharing +// is required. +// +// With kernelless + stub override (default in EmbeddedWallet), the simulation +// runs without prompting Alice to sign; the macro emits a +// CallAuthorizationRequest as an offchain effect that the wallet can turn +// into a real authwit before .send(). +const donationAmount = 100n; +const donateAction = crowdfundingContract.methods.donate(donationAmount); + +const { offchainEffects } = await donateAction.simulate({ + from: aliceAddress, + includeMetadata: true, +}); + +// Filter offchain effects for authwit requests by selector. +const authwitSelector = await CallAuthorizationRequest.getSelector(); +const authwitEffects = offchainEffects.filter( + (effect) => + effect.data.length > 0 && effect.data[0].equals(authwitSelector.toField()), +); + +if (authwitEffects.length !== 1) { + throw new Error( + `Expected exactly one CallAuthorizationRequest, got ${authwitEffects.length}`, + ); +} +// docs:end:simulate-and-collect-effects + +// docs:start:decode-call-authorization +// Decode each effect into a CallAuthorizationRequest. The inner hash is the +// piece the authorizing account (Alice) needs to sign. +const authorizationRequests = await Promise.all( + authwitEffects.map((effect) => + CallAuthorizationRequest.fromFields(effect.data), + ), +); + +for (const request of authorizationRequests) { + console.log("Authwit needed:", { + onBehalfOf: request.onBehalfOf.toString(), + msgSender: request.msgSender.toString(), + functionSelector: request.functionSelector.toString(), + }); +} + +if (!authorizationRequests[0].onBehalfOf.equals(aliceAddress)) { + throw new Error( + `Expected onBehalfOf to be alice (${aliceAddress.toString()}), got ${authorizationRequests[0].onBehalfOf.toString()}`, + ); +} +// docs:end:decode-call-authorization + +// docs:start:build-authwits-and-send +// Alice creates a real authentication witness from each inner hash. The +// `consumer` is the contract that consumes the authwit — here, the token, +// because that's where the inner transfer_in_private (and its #[authorize_once] +// site) runs. +const authWitnesses = await Promise.all( + authorizationRequests.map((request) => + wallet.createAuthWit(request.onBehalfOf, { + consumer: tokenContract.address, + innerHash: request.innerHash, + }), + ), +); + +// Alice now sends the real donate transaction with the collected authwits +// attached. +// +// Note: EmbeddedWallet.sendTx already runs this pre-simulation + authwit +// collection internally, so passing `authWitnesses` here is redundant for +// EmbeddedWallet. We pass them explicitly anyway because this is the pattern +// a wallet that does not auto-collect needs to follow. +await donateAction.send({ + from: aliceAddress, + authWitnesses, +}); +// docs:end:build-authwits-and-send + +console.log("Kernelless simulation example completed successfully"); diff --git a/docs/examples/ts/aztecjs_kernelless_simulation/yarn.lock b/docs/examples/ts/aztecjs_kernelless_simulation/yarn.lock new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/examples/ts/aztecjs_runner/run.sh b/docs/examples/ts/aztecjs_runner/run.sh index cb06cff29ac7..c7210f24c827 100755 --- a/docs/examples/ts/aztecjs_runner/run.sh +++ b/docs/examples/ts/aztecjs_runner/run.sh @@ -44,6 +44,26 @@ fi echo -e "${GREEN}✓ Network is running${NC}" echo "" +# Run `yarn add` with retries. Silences output on early attempts but lets +# stderr surface on the final attempt so transient flakes don't disappear +# under set -euo pipefail (silent rc=1 from setup_project was the root cause +# of the docs-examples merge-queue dequeue on aztecjs_advanced). +yarn_add_with_retry() { + local max_attempts=3 + local attempt=1 + while [ "$attempt" -lt "$max_attempts" ]; do + if yarn add "$@" > /dev/null 2>&1; then + return 0 + fi + echo -e "${YELLOW} yarn add attempt $attempt failed, retrying in 5s...${NC}" + sleep 5 + attempt=$((attempt + 1)) + done + # Final attempt: surface yarn's output so the failure is visible in CI logs. + echo -e "${YELLOW} yarn add attempt $attempt (final, output unsilenced):${NC}" + yarn add "$@" +} + # Setup function for a project setup_project() { local project_name=$1 @@ -91,11 +111,11 @@ setup_project() { parse_dependencies config.yaml "$REPO_ROOT" if [ "$PARSED_DEPS_FOUND" = true ]; then local all_link_deps=("${AZTEC_DEPS[@]}" "${EXPLICIT_LINK_DEPS[@]}") - [ ${#all_link_deps[@]} -gt 0 ] && yarn add "${all_link_deps[@]}" > /dev/null 2>&1 - [ ${#NPM_DEPS[@]} -gt 0 ] && yarn add "${NPM_DEPS[@]}" > /dev/null 2>&1 + [ ${#all_link_deps[@]} -gt 0 ] && yarn_add_with_retry "${all_link_deps[@]}" + [ ${#NPM_DEPS[@]} -gt 0 ] && yarn_add_with_retry "${NPM_DEPS[@]}" fi - yarn add -D typescript tsx > /dev/null 2>&1 + yarn_add_with_retry -D typescript tsx # Copy tsconfig cp "$EXAMPLES_DIR/tsconfig.template.json" tsconfig.json diff --git a/docs/examples/ts/docker-compose.yml b/docs/examples/ts/docker-compose.yml index d881961f4f74..247b321c6912 100644 --- a/docs/examples/ts/docker-compose.yml +++ b/docs/examples/ts/docker-compose.yml @@ -28,6 +28,7 @@ services: WS_BLOCK_CHECK_INTERVAL_MS: 500 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 P2P_MIN_TX_POOL_AGE_MS: 0 + SEQ_ENABLE_PROPOSER_PIPELINING: 'true' HARDWARE_CONCURRENCY: ${HARDWARE_CONCURRENCY:-} docs-examples: diff --git a/docs/network_versioned_docs/version-v4.3.0/operators/reference/ethereum-rpc-reference.md b/docs/network_versioned_docs/version-v4.3.0/operators/reference/ethereum-rpc-reference.md index a75fc770f303..2a6f2d29e8eb 100644 --- a/docs/network_versioned_docs/version-v4.3.0/operators/reference/ethereum-rpc-reference.md +++ b/docs/network_versioned_docs/version-v4.3.0/operators/reference/ethereum-rpc-reference.md @@ -270,7 +270,7 @@ Aztec automatically retries failed requests on alternative endpoints when multip Enable detailed RPC logging: ```bash -LOG_LEVEL=debug # or verbose +LOG_LEVEL="debug; info: json-rpc, simulator" # or verbose ``` Look for log entries related to: diff --git a/docs/network_versioned_docs/version-v4.3.0/operators/setup/registering-sequencer.md b/docs/network_versioned_docs/version-v4.3.0/operators/setup/registering-sequencer.md index cd7cd9d07d89..45a3483dc810 100644 --- a/docs/network_versioned_docs/version-v4.3.0/operators/setup/registering-sequencer.md +++ b/docs/network_versioned_docs/version-v4.3.0/operators/setup/registering-sequencer.md @@ -18,7 +18,7 @@ Before proceeding, ensure you have completed the [Sequencer Setup Guide](./seque - Completed sequencer node setup with keystore generated - Access to your **public keystore** file (`keyN_staker_output.json`) -- Sufficient ATP/ATV tokens for staking +- Sufficient **Aztec Token Position (ATP)** or **Aztec Token Vault (ATV)** balance for staking - Wallet with ETH for gas fees - Web browser for accessing the staking dashboard @@ -124,7 +124,7 @@ Follow these steps to register your sequencer(s) through the staking dashboard: 1. **Navigate to the staking dashboard** at https://stake.aztec.network -2. **Connect your wallet** with the account that holds your ATP/ATV tokens +2. **Connect your wallet** with the account that holds your Aztec Token Position (ATP) or Aztec Token Vault (ATV) balance 3. **Click "Stake"** @@ -136,7 +136,7 @@ Follow these steps to register your sequencer(s) through the staking dashboard: 5. **Click through "Start Registration"** after reviewing the requirements -6. **Select the ATP/ATV tokens you want to stake** +6. **Select the ATP or ATV balance you want to stake** 7. **Upload your keystore JSON file** (either single or combined multi-sequencer file) diff --git a/docs/static/typescript-api/mainnet/foundation.md b/docs/static/typescript-api/mainnet/foundation.md index 0ff014eea53b..b8c9f0b59ff3 100644 --- a/docs/static/typescript-api/mainnet/foundation.md +++ b/docs/static/typescript-api/mainnet/foundation.md @@ -1422,7 +1422,7 @@ type NetworkConfigMap = z.infer ### NetworkNames ```typescript -type NetworkNames = "local" | "staging-ignition" | "staging-public" | "testnet" | "mainnet" | "next-net" | "devnet" +type NetworkNames = "local" | "staging-public" | "testnet" | "mainnet" | "next-net" | "devnet" ``` ### PartialBy diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index 92a79ad91365..f00d4d5ffc48 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -18,8 +18,11 @@ function download_solc { echo_stderr "Downloading solc $solc_version via svm..." # svm-rs always uses ~/.svm if it exists. Make sure it does for a consistent path across OS/architecture. mkdir -p "$HOME/.svm" - # We build a minimal file to trigger svm download of solc. - forge build --use "$solc_version" src/core/libraries/ConstantsGen.sol 2>/dev/null + # We build a minimal file to trigger svm download of solc. svm fetches the + # binary from binaries.soliditylang.org, which intermittently fails to resolve + # under heavy parallel CI load; retry to ride out transient DNS drops. (The + # merge queue disables the cache above, so this download path runs every time.) + retry "forge build --use \"$solc_version\" src/core/libraries/ConstantsGen.sol 2>/dev/null" # Copy from svm cache to local path local svm_path="$HOME/.svm/$solc_version/solc-$solc_version" diff --git a/l1-contracts/src/core/slashing/SlashingProposer.sol b/l1-contracts/src/core/slashing/SlashingProposer.sol index 143220d1df60..6cf723ad6630 100644 --- a/l1-contracts/src/core/slashing/SlashingProposer.sol +++ b/l1-contracts/src/core/slashing/SlashingProposer.sol @@ -50,12 +50,11 @@ import {SafeCast} from "@oz/utils/math/SafeCast.sol"; * * About SLASH_OFFSET_IN_ROUNDS: * - This offset gives us time to detect an offense and then vote on it in a later - * round. For instance, an `VALID_EPOCH_PRUNED` offense for epoch N is only triggered after - * `PROOF_SUBMISSION_WINDOW` epochs. Consider the following: - * - Epoch 1 is valid - * - At the end of epoch 3, the proof for 1 has not landed, so epoch 1 is pruned - * - Network decides to slash the committee of epoch 1 - * - This means that only starting from epoch 4 we should be voting for slashing the committee of epoch 1 + * round. For instance, a `DATA_WITHHOLDING` offense for slot S is only triggered after + * `DATA_WITHHOLDING_TOLERANCE_SLOTS` slots. Consider: + * - Slot S publishes a checkpoint + * - At slot S + tolerance, observers find missing data and want to slash the attesters + * - Voting on that slash needs to happen in a round that starts after detection * - In terms of voting, this parameter means that in round R we are voting for the committee of epochs starting * from (R - SLASH_OFFSET_IN_ROUNDS) * ROUND_SIZE_IN_EPOCHS. * - For example, with SLASH_OFFSET_IN_ROUNDS=2, ROUND_SIZE=10, and EPOCH_DURATION=2 diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 7631593cefb5..47cf714965b3 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -42,7 +42,7 @@ use crate::protocol::{ hash::compute_contract_class_log_hash, messaging::l2_to_l1_message::L2ToL1Message, side_effect::{Counted, scoped::Scoped}, - traits::{Empty, Hash, ToField}, + traits::{Empty, ToField}, utils::arrays::{ClaimedLengthArray, trimmed_array_length_hint}, }; @@ -754,39 +754,42 @@ impl PrivateContext { /// request validation of this claim, by making a "key validation request" to the protocol's kernel circuits (which /// _are_ allowed to see certain master secret keys). /// - /// When a Key Validation Request tuple of (sk_app, Pk_m, app_address) is submitted to the kernel, it will perform - /// the following derivations to validate the relationship between the claimed sk_app and the user's Pk_m: + /// The app circuit only sees `pk_m_hash` (not the raw point). The kernel derives the + /// point from `sk_m`, hashes it, and asserts equality. When a Key Validation Request tuple of + /// (sk_app, pk_m_hash, app_address) is submitted to the kernel, it performs the following + /// derivations to validate the relationship between the claimed sk_app and the user's pk_m_hash: /// - /// (sk_m) ----> * G ----> Pk_m - /// | | - /// v We use the kernel to prove this - /// h(sk_m, app_address) | sk_app-Pk_m relationship, because app - /// | circuits must not be trusted to see sk_m. - /// v | - /// sk_app - - - - - - - - - + /// (sk_m) ----> * G ----> pk_m ----> hash_public_key(pk_m) + /// | | + /// v | We use the kernel to prove this + /// h(sk_m, app_address) | sk_app-pk_m_hash relationship, because app + /// | | circuits must not be trusted to see sk_m. + /// v | + /// sk_app - - - - - - - - - - - - - - - - - - /// /// The function is named "request_" instead of "get_" to remind the user that a Key Validation Request will be /// emitted to the kernel. /// fn request_sk_app(&mut self, pk_m_hash: Field, key_index: Field) -> Field { - let cached_request = - self.last_key_validation_requests[key_index as u32].unwrap_or(KeyValidationRequest::empty()); + // Match against the cache only when a request is actually present in the slot. + let cached_slot = self.last_key_validation_requests[key_index as u32]; + let cache_hit = cached_slot.is_some() & (cached_slot.unwrap_unchecked().pk_m_hash == pk_m_hash); - if cached_request.pk_m.hash() == pk_m_hash { + if cache_hit { // We get a match so the cached request is the latest one - cached_request.sk_app + cached_slot.unwrap_unchecked().sk_app } else { - // We didn't get a match meaning the cached result is stale Typically we'd validate keys by showing that - // they are the preimage of `pk_m_hash`, but that'd require the oracle returning the master secret keys, - // which could cause malicious contracts to leak it or learn about secrets from other contracts. We - // therefore silo secret keys, and rely on the private kernel to validate that we siloed secret key - // corresponds to correct siloing of the master secret key that hashes to `pk_m_hash`. + // We didn't get a match meaning the cached result is stale. Typically we'd validate keys by showing that + // the master secret key derives to a public key matching `pk_m_hash`, but that'd require the oracle + // returning the master secret keys, which could cause malicious contracts to leak it or learn about + // secrets from other contracts. We therefore silo secret keys, and rely on the private kernel to validate + // that the siloed secret key corresponds to correct siloing of the master secret key that hashes to + // `pk_m_hash`. // Safety: Kernels verify that the key validation request is valid and below we verify that a request for // the correct public key has been received. let request = unsafe { get_key_validation_request(pk_m_hash, key_index) }; - assert(!request.pk_m.is_infinite, "Infinite public key points are not allowed"); - assert_eq(request.pk_m.hash(), pk_m_hash, "Obtained invalid key validation request"); + assert_eq(request.pk_m_hash, pk_m_hash, "Obtained key validation request for wrong pk_m_hash"); self.key_validation_requests_and_separators.push( KeyValidationRequestAndSeparator { diff --git a/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr b/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr index 4770d3e7cc65..091ccff3161a 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr @@ -2,7 +2,7 @@ use crate::protocol::{ address::aztec_address::AztecAddress, constants::{DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY}, hash::poseidon2_hash_with_separator, - point::Point, + point::EmbeddedCurvePoint, scalar::Scalar, traits::{FromField, ToField}, }; @@ -18,16 +18,14 @@ use std::{embedded_curve_ops::multi_scalar_mul, ops::Neg}; /// Shared secret S = esk * Pk = sk * Epk /// /// See also: https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman -pub fn derive_ecdh_shared_secret(secret: Scalar, public_key: Point) -> Point { - // TODO(F-553): Drop the `.to_embedded()` / `.into()` round-trip once the custom `Point` wrapper is removed and we - // use `EmbeddedCurvePoint` directly. - multi_scalar_mul([public_key.to_embedded()], [secret]).into() +pub fn derive_ecdh_shared_secret(secret: Scalar, public_key: EmbeddedCurvePoint) -> EmbeddedCurvePoint { + multi_scalar_mul([public_key], [secret]) } /// Computes an app-siloed shared secret from a raw ECDH shared secret point and a contract address. /// /// `s_app = h(DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, S.x, S.y, contract_address)` -pub fn compute_app_siloed_shared_secret(shared_secret: Point, contract_address: AztecAddress) -> Field { +pub fn compute_app_siloed_shared_secret(shared_secret: EmbeddedCurvePoint, contract_address: AztecAddress) -> Field { poseidon2_hash_with_separator( [shared_secret.x, shared_secret.y, contract_address.to_field()], DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, @@ -54,10 +52,9 @@ unconstrained fn test_consistency_with_typescript() { lo: 0x00000000000000000000000000000000649e7ca01d9de27b21624098b897babd, hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06, }; - let point = Point { + let point = EmbeddedCurvePoint { x: 0x2688431c705a5ff3e6c6f2573c9e3ba1c1026d2251d0dbbf2d810aa53fd1d186, y: 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e, - is_infinite: false, }; let shared_secret = derive_ecdh_shared_secret(secret, point); @@ -65,10 +62,9 @@ unconstrained fn test_consistency_with_typescript() { // This is just pasted from a test run. The original typescript code from which this could be generated seems to // have been deleted by someone, and soon the typescript code for encryption and decryption won't be needed, so // this will have to do. - let hard_coded_shared_secret = Point { + let hard_coded_shared_secret = EmbeddedCurvePoint { x: 0x15d55a5b3b2caa6a6207f313f05c5113deba5da9927d6421bcaa164822b911bc, y: 0x0974c3d0825031ae933243d653ebb1a0b08b90ee7f228f94c5c74739ea3c871e, - is_infinite: false, }; assert_eq(shared_secret, hard_coded_shared_secret); } @@ -78,8 +74,8 @@ unconstrained fn test_shared_secret_computation_in_both_directions() { let secret_a = Scalar { lo: 0x1234, hi: 0x2345 }; let secret_b = Scalar { lo: 0x3456, hi: 0x4567 }; - let pk_a: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a).into(); - let pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b).into(); + let pk_a = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a); + let pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b); let shared_secret = derive_ecdh_shared_secret(secret_a, pk_b); let shared_secret_alt = derive_ecdh_shared_secret(secret_b, pk_a); @@ -92,8 +88,8 @@ unconstrained fn test_shared_secret_computation_from_address_in_both_directions( let secret_a = Scalar { lo: 0x1234, hi: 0x2345 }; let secret_b = Scalar { lo: 0x3456, hi: 0x4567 }; - let mut pk_a: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a).into(); - let mut pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b).into(); + let mut pk_a = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a); + let mut pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b); let address_b = AztecAddress::from_field(pk_b.x); @@ -120,7 +116,7 @@ unconstrained fn test_shared_secret_computation_from_address_in_both_directions( #[test] unconstrained fn test_app_siloed_shared_secret_differs_per_contract() { let secret_a = Scalar { lo: 0x1234, hi: 0x2345 }; - let pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(Scalar { lo: 0x3456, hi: 0x4567 }).into(); + let pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(Scalar { lo: 0x3456, hi: 0x4567 }); let shared_secret = derive_ecdh_shared_secret(secret_a, pk_b); diff --git a/noir-projects/aztec-nr/aztec/src/keys/ephemeral.nr b/noir-projects/aztec-nr/aztec/src/keys/ephemeral.nr index e7758e43579a..d0947c61d281 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/ephemeral.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/ephemeral.nr @@ -1,11 +1,11 @@ use std::embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul}; -use crate::protocol::{point::Point, scalar::Scalar}; +use crate::protocol::{point::EmbeddedCurvePoint, scalar::Scalar}; use crate::{oracle::random::random, utils::point::get_sign_of_point}; /// Generates a random ephemeral key pair. -pub fn generate_ephemeral_key_pair() -> (Scalar, Point) { +pub fn generate_ephemeral_key_pair() -> (Scalar, EmbeddedCurvePoint) { // @todo Need to draw randomness from the full domain of Fq not only Fr // Safety: we use the randomness to preserve the privacy of both the sender and recipient via encryption, so a @@ -17,9 +17,7 @@ pub fn generate_ephemeral_key_pair() -> (Scalar, Point) { // TODO(#12757): compute the key pair without constraining eph_sk twice (once in from_field, once in the black box // called by fixed_base_scalar_mul). let eph_sk = EmbeddedCurveScalar::from_field(randomness); - // TODO(F-553): Drop the `.into()` once the custom `Point` wrapper is removed and we use `EmbeddedCurvePoint` - // directly. Applies to the other `fixed_base_scalar_mul(...).into()` call sites in this file as well. - let eph_pk: Point = fixed_base_scalar_mul(eph_sk).into(); + let eph_pk = fixed_base_scalar_mul(eph_sk); (eph_sk, eph_pk) } @@ -31,13 +29,13 @@ pub fn generate_ephemeral_key_pair() -> (Scalar, Point) { /// /// This is useful as it means it is possible to just broadcast the x-coordinate as a single `Field` and then /// reconstruct the original public key using [`crate::utils::point::point_from_x_coord_and_sign`] with `sign: true`. -pub fn generate_positive_ephemeral_key_pair() -> (Scalar, Point) { +pub fn generate_positive_ephemeral_key_pair() -> (Scalar, EmbeddedCurvePoint) { // Safety: we use the randomness to preserve the privacy of both the sender and recipient via encryption, so a // malicious sender could use non-random values to reveal the plaintext. But they already know it themselves // anyway, and so the recipient already trusts them to not disclose this information. We can therefore assume that // the sender will cooperate in the random value generation. let eph_sk = unsafe { generate_secret_key_for_positive_public_key() }; - let eph_pk: Point = fixed_base_scalar_mul(eph_sk).into(); + let eph_pk = fixed_base_scalar_mul(eph_sk); assert(get_sign_of_point(eph_pk), "Got an ephemeral public key with a negative y coordinate"); @@ -53,7 +51,7 @@ unconstrained fn generate_secret_key_for_positive_public_key() -> EmbeddedCurveS // @todo Need to draw randomness from the full domain of Fq not only Fr sk = EmbeddedCurveScalar::from_field(random()); - let pk: Point = fixed_base_scalar_mul(sk).into(); + let pk = fixed_base_scalar_mul(sk); if get_sign_of_point(pk) { break; } diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr b/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr index d52b43d389e4..aa72b16d3da0 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr @@ -41,7 +41,7 @@ mod test { use crate::test::helpers::test_environment::TestEnvironment; use std::test::OracleMock; - global KEY_ORACLE_RESPONSE_LENGTH: u32 = 13; // 12 fields for the keys, one field for the partial address + global KEY_ORACLE_RESPONSE_LENGTH: u32 = 6; // 3 key hashes + 1 key point + 1 partial address #[test(should_fail_with = "Invalid public keys hint for address")] unconstrained fn get_public_keys_fails_with_bad_hint() { @@ -50,26 +50,19 @@ mod test { // Instead of querying for some unknown account, which would result in the oracle erroring out, we mock a bad // oracle response to check that the circuit properly checks the address derivation. + // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, partial_address]. let mut random_keys_and_partial_address = [0; KEY_ORACLE_RESPONSE_LENGTH]; - // We use randomly generated points on the curve, and a random partial address to ensure that this combination - // does not derive the address and we should see the assertion fail. npk_m + // npk_m_hash random_keys_and_partial_address[0] = 0x292364b852c6c6f01472951e76a39cbcf074591fd0e063a81965e7b51ad868a5; - random_keys_and_partial_address[1] = 0x0a687b46cdc9238f1c311f126aaaa4acbd7a737bff2efd7aeabdb8d805843a27; - random_keys_and_partial_address[2] = 0x0000000000000000000000000000000000000000000000000000000000000000; - // ivpk_m - random_keys_and_partial_address[3] = 0x173c5229a00c5425255680dd6edc27e278c48883991f348fe6985de43b4ec25f; - random_keys_and_partial_address[4] = 0x1698608e23b5f6c2f43c49a559108bb64e2247b8fc2da842296a416817f40b7f; - random_keys_and_partial_address[5] = 0x0000000000000000000000000000000000000000000000000000000000000000; - // ovpk_m - random_keys_and_partial_address[6] = 0x1bad2f7d1ad960a1bd0fe4d2c8d17f5ab4a86ef8b103e0a9e7f67ec0d3b4795e; - random_keys_and_partial_address[7] = 0x206db87110abbecc9fbaef2c865189d94ef2c106202f734ee4eba9257fd28bf1; - random_keys_and_partial_address[8] = 0x0000000000000000000000000000000000000000000000000000000000000000; - // tpk_m - random_keys_and_partial_address[9] = 0x05e3bd9cfe6b47daa139613619cf7d7fd8bb0112b6f2908caa6d9b536ed948ed; - random_keys_and_partial_address[10] = 0x051066f877c9df47552d02e7dc32127ff4edefc8498e813bca1cbd3f5d1be429; - random_keys_and_partial_address[11] = 0x0000000000000000000000000000000000000000000000000000000000000000; + // ivpk_m (x, y) -- arbitrary, doesn't have to be on-curve to make this test fail + random_keys_and_partial_address[1] = 0x173c5229a00c5425255680dd6edc27e278c48883991f348fe6985de43b4ec25f; + random_keys_and_partial_address[2] = 0x1698608e23b5f6c2f43c49a559108bb64e2247b8fc2da842296a416817f40b7f; + // ovpk_m_hash + random_keys_and_partial_address[3] = 0x1bad2f7d1ad960a1bd0fe4d2c8d17f5ab4a86ef8b103e0a9e7f67ec0d3b4795e; + // tpk_m_hash + random_keys_and_partial_address[4] = 0x05e3bd9cfe6b47daa139613619cf7d7fd8bb0112b6f2908caa6d9b536ed948ed; // partial address - random_keys_and_partial_address[12] = 0x236703e2cb00a182e024e98e9f759231b556d25ff19f98896cebb69e9e678cc9; + random_keys_and_partial_address[5] = 0x236703e2cb00a182e024e98e9f759231b556d25ff19f98896cebb69e9e678cc9; let _ = OracleMock::mock("aztec_utl_getPublicKeysAndPartialAddress").returns(Option::some( random_keys_and_partial_address, diff --git a/noir-projects/aztec-nr/aztec/src/macros/notes.nr b/noir-projects/aztec-nr/aztec/src/macros/notes.nr index 2836182df312..f50634480dab 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/notes.nr @@ -88,10 +88,7 @@ comptime fn generate_note_hash_trait_impl(s: TypeDefinition) -> Quoted { owner: aztec::protocol::address::AztecAddress, note_hash_for_nullification: Field, ) -> Field { - let owner_npk_m = aztec::keys::getters::get_public_keys(owner).npk_m; - // We invoke hash as a static trait function rather than calling owner_npk_m.hash() directly - // in the quote to avoid "trait not in scope" compiler warnings. - let owner_npk_m_hash = aztec::protocol::traits::Hash::hash(owner_npk_m); + let owner_npk_m_hash = aztec::keys::getters::get_public_keys(owner).npk_m_hash; let secret = context.request_nhk_app(owner_npk_m_hash); aztec::note::utils::compute_note_nullifier(note_hash_for_nullification, [secret]) } @@ -105,10 +102,7 @@ comptime fn generate_note_hash_trait_impl(s: TypeDefinition) -> Quoted { // hiding key (nhk) is also available, so we don't need to handle get_nhk_app potentially // failing. The Option is only needed for the try_get_public_keys call. aztec::keys::getters::try_get_public_keys(owner).map(|public_keys| { - let owner_npk_m = public_keys.npk_m; - // We invoke hash as a static trait function rather than calling owner_npk_m.hash() directly - // in the quote to avoid "trait not in scope" compiler warnings. - let owner_npk_m_hash = aztec::protocol::traits::Hash::hash(owner_npk_m); + let owner_npk_m_hash = public_keys.npk_m_hash; let secret = aztec::keys::getters::get_nhk_app(owner_npk_m_hash); aztec::note::utils::compute_note_nullifier(note_hash_for_nullification, [secret]) }) diff --git a/noir-projects/aztec-nr/aztec/src/messages/encryption/poseidon2.nr b/noir-projects/aztec-nr/aztec/src/messages/encryption/poseidon2.nr index 1704be0162b0..c2ecac779d3f 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/encryption/poseidon2.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/encryption/poseidon2.nr @@ -1,7 +1,7 @@ use std::hash::poseidon2_permutation; use std::option::Option; -use crate::protocol::point::Point; +use crate::protocol::point::EmbeddedCurvePoint; global TWO_POW_128: Field = 0x100000000000000000000000000000000; @@ -27,7 +27,7 @@ global TWO_POW_128: Field = 0x100000000000000000000000000000000; /// @param encryption_nonce is only needed if your use case needs to protect against replay attacks. pub fn poseidon2_encrypt( msg: [Field; L], - shared_secret: Point, + shared_secret: EmbeddedCurvePoint, encryption_nonce: Field, ) -> [Field; ((L + 2) / 3) * 3 + 1] { // TODO: assert(encryption_nonce < 2^128), assert(L < 2^120); @@ -78,7 +78,7 @@ pub fn poseidon2_encrypt( pub fn poseidon2_decrypt( ciphertext: [Field; ((L + 3 - 1) / 3) * 3 + 1], - shared_secret: Point, + shared_secret: EmbeddedCurvePoint, encryption_nonce: Field, ) -> Option<[Field; L]> { let mut s = [0, shared_secret.x, shared_secret.y, encryption_nonce + (L as Field) * TWO_POW_128]; @@ -139,7 +139,6 @@ pub fn poseidon2_decrypt( } mod test { - use crate::protocol::point::Point; use super::{poseidon2_decrypt, poseidon2_encrypt, TWO_POW_128}; use std::embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul, multi_scalar_mul}; @@ -152,7 +151,7 @@ mod test { let eph_sk = 0x5678; let eph_pk = fixed_base_scalar_mul(EmbeddedCurveScalar::from_field(eph_sk)); - let shared_secret: Point = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]).into(); + let shared_secret = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]); let encryption_nonce = 3; // TODO. Can even be a timestamp. Why is this even needed? @@ -162,7 +161,7 @@ mod test { // Bob sees: [Epk, ciphertext, encryption_nonce]: - let shared_secret: Point = multi_scalar_mul([eph_pk], [EmbeddedCurveScalar::from_field(bob_sk)]).into(); + let shared_secret = multi_scalar_mul([eph_pk], [EmbeddedCurveScalar::from_field(bob_sk)]); let result = poseidon2_decrypt(ciphertext, shared_secret, encryption_nonce); @@ -193,7 +192,7 @@ mod test { let eph_sk = 0x5678; let eph_pk = fixed_base_scalar_mul(EmbeddedCurveScalar::from_field(eph_sk)); - let shared_secret: Point = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]).into(); + let shared_secret = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]); let msg = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; @@ -205,7 +204,7 @@ mod test { // Bob sees: [Epk, ciphertext, encryption_nonce]: - let mut shared_secret: Point = multi_scalar_mul([eph_pk], [EmbeddedCurveScalar::from_field(bob_sk)]).into(); + let mut shared_secret = multi_scalar_mul([eph_pk], [EmbeddedCurveScalar::from_field(bob_sk)]); // Let's intentionally corrupt the shared secret, so that decryption should fail shared_secret.x += 1; @@ -222,7 +221,7 @@ mod test { let bob_pk = fixed_base_scalar_mul(EmbeddedCurveScalar::from_field(bob_sk)); let eph_sk = 0x5678; - let shared_secret: Point = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]).into(); + let shared_secret = multi_scalar_mul([bob_pk], [EmbeddedCurveScalar::from_field(eph_sk)]); let encryption_nonce = 3; // TODO. Can even be a timestamp. Why is this even needed? diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr index 11eace998fa6..372729c37a9e 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr @@ -35,6 +35,10 @@ unconstrained fn get_contract_instance_class_id_oracle_avm(_address: AztecAddres unconstrained fn get_contract_instance_initialization_hash_oracle_avm( _address: AztecAddress, ) -> [GetContractInstanceResult; 1] {} +#[oracle(aztec_avm_getContractInstanceImmutablesHash)] +unconstrained fn get_contract_instance_immutables_hash_oracle_avm( + _address: AztecAddress, +) -> [GetContractInstanceResult; 1] {} unconstrained fn get_contract_instance_deployer_internal_avm(address: AztecAddress) -> [GetContractInstanceResult; 1] { get_contract_instance_deployer_oracle_avm(address) @@ -47,6 +51,11 @@ unconstrained fn get_contract_instance_initialization_hash_internal_avm( ) -> [GetContractInstanceResult; 1] { get_contract_instance_initialization_hash_oracle_avm(address) } +unconstrained fn get_contract_instance_immutables_hash_internal_avm( + address: AztecAddress, +) -> [GetContractInstanceResult; 1] { + get_contract_instance_immutables_hash_oracle_avm(address) +} pub fn get_contract_instance_deployer_avm(address: AztecAddress) -> Option { // Safety: AVM opcodes are constrained by the AVM itself @@ -78,3 +87,13 @@ pub fn get_contract_instance_initialization_hash_avm(address: AztecAddress) -> O Option::none() } } +pub fn get_contract_instance_immutables_hash_avm(address: AztecAddress) -> Option { + // Safety: AVM opcodes are constrained by the AVM itself + let GetContractInstanceResult { exists, member } = + unsafe { get_contract_instance_immutables_hash_internal_avm(address)[0] }; + if exists { + Option::some(member) + } else { + Option::none() + } +} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 8f3d2788bf7a..c1ba98a4794c 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -1,7 +1,7 @@ use crate::protocol::{ address::{AztecAddress, PartialAddress}, - point::Point, - public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, TpkM}, + point::EmbeddedCurvePoint, + public_keys::{IvpkM, PublicKeys}, }; // TODO(F-498): review naming consistency @@ -9,25 +9,27 @@ pub unconstrained fn get_public_keys_and_partial_address(address: AztecAddress) try_get_public_keys_and_partial_address(address).expect(f"Public keys not registered for account {address}") } -// TODO(F-553): The oracle returns 13 fields because each public key is serialized as 3 fields (x, y, is_infinite) by -// the custom `Point` wrapper. Once we drop the wrapper and use `EmbeddedCurvePoint` directly each point will -// serialize to 2 fields and this should become `[Field; 9]` again, with the indices below shifted accordingly. +/// Oracle wire format: `[npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, partial_address]`. +/// +/// Three of the four master public keys are exposed only as hashes; `ivpk_m` is sent +/// as its affine coordinates because address derivation and encrypt-to-address require the point +/// in-circuit. This point is assumed to be non-infinite. #[oracle(aztec_utl_getPublicKeysAndPartialAddress)] -unconstrained fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> Option<[Field; 13]> {} +unconstrained fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> Option<[Field; 6]> {} // TODO(F-498): review naming consistency pub unconstrained fn try_get_public_keys_and_partial_address( address: AztecAddress, ) -> Option<(PublicKeys, PartialAddress)> { - get_public_keys_and_partial_address_oracle(address).map(|result: [Field; 13]| { + get_public_keys_and_partial_address_oracle(address).map(|result: [Field; 6]| { let keys = PublicKeys { - npk_m: NpkM { inner: Point { x: result[0], y: result[1], is_infinite: result[2] != 0 } }, - ivpk_m: IvpkM { inner: Point { x: result[3], y: result[4], is_infinite: result[5] != 0 } }, - ovpk_m: OvpkM { inner: Point { x: result[6], y: result[7], is_infinite: result[8] != 0 } }, - tpk_m: TpkM { inner: Point { x: result[9], y: result[10], is_infinite: result[11] != 0 } }, + npk_m_hash: result[0], + ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: result[1], y: result[2] } }, + ovpk_m_hash: result[3], + tpk_m_hash: result[4], }; - let partial_address = PartialAddress::from_field(result[12]); + let partial_address = PartialAddress::from_field(result[5]); (keys, partial_address) }) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr b/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr index cbcd9390d71a..bc3780876922 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr @@ -1,20 +1,19 @@ use crate::ephemeral::EphemeralArray; -use crate::protocol::{address::AztecAddress, hash::sha256_to_field, point::Point}; +use crate::protocol::{address::AztecAddress, hash::sha256_to_field, point::EmbeddedCurvePoint}; -global GET_SHARED_SECRETS_REQUEST_SLOT: Field = - sha256_to_field("AZTEC_NR::GET_SHARED_SECRETS_REQUEST_SLOT".as_bytes()); +global GET_SHARED_SECRETS_REQUEST_SLOT: Field = sha256_to_field("AZTEC_NR::GET_SHARED_SECRETS_REQUEST_SLOT".as_bytes()); #[oracle(aztec_utl_getSharedSecrets)] unconstrained fn get_shared_secrets_oracle( address: AztecAddress, - eph_pks: EphemeralArray, + eph_pks: EphemeralArray, contract_address: AztecAddress, ) -> EphemeralArray {} /// Convenience wrapper around [`get_shared_secrets`] for a single ephemeral public key. pub unconstrained fn get_shared_secret( address: AztecAddress, - eph_pk: Point, + eph_pk: EmbeddedCurvePoint, contract_address: AztecAddress, ) -> Field { get_shared_secrets::<1>(address, BoundedVec::from_array([eph_pk]), contract_address).get(0) @@ -41,18 +40,14 @@ pub unconstrained fn get_shared_secret( /// [`derive_shared_secret_subkey`](crate::keys::ecdh_shared_secret::derive_shared_secret_subkey). pub unconstrained fn get_shared_secrets( address: AztecAddress, - eph_pks: BoundedVec, + eph_pks: BoundedVec, contract_address: AztecAddress, ) -> BoundedVec { - let request_array: EphemeralArray = - EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT).clear(); + let request_array: EphemeralArray = EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT).clear(); eph_pks.for_each(|pk| request_array.push(pk)); let response_array = get_shared_secrets_oracle(address, request_array, contract_address); - assert( - response_array.len() == eph_pks.len(), - "get_shared_secrets: response length does not match request length", - ); + assert(response_array.len() == eph_pks.len(), "get_shared_secrets: response length does not match request length"); let mut results: BoundedVec = BoundedVec::new(); for i in 0..eph_pks.len() { @@ -63,7 +58,7 @@ pub unconstrained fn get_shared_secrets( mod test { use crate::ephemeral::EphemeralArray; - use crate::oracle::shared_secret::{GET_SHARED_SECRETS_REQUEST_SLOT, get_shared_secrets}; + use crate::oracle::shared_secret::{get_shared_secrets, GET_SHARED_SECRETS_REQUEST_SLOT}; use crate::protocol::{address::AztecAddress, traits::FromField}; use crate::test::helpers::test_environment::TestEnvironment; use crate::utils::point::point_from_x_coord; @@ -85,8 +80,7 @@ mod test { AztecAddress::from_field(2), ); - let request_array: EphemeralArray<_> = - EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT); + let request_array: EphemeralArray<_> = EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT); assert_eq(request_array.get(0), pk_a); assert_eq(request_array.get(1), pk_b); assert_eq(request_array.get(2), pk_c); diff --git a/noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr b/noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr index 6cd429499339..07556ba42a95 100644 --- a/noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr +++ b/noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr @@ -19,30 +19,34 @@ pub fn publish_contract_instance_for_public_execution(context: &mut PrivateConte } // Adapted from - // noir-contracts/contracts/protocol/contract_instance_registry_contract/src/interface/ContractInstanceRegistry.nr + // noir-contracts/contracts/protocol/contract_instance_registry_contract/src/interface/ContractInstanceRegistry.ts // That file // was autogenerated running the following command from noir-projects/noir-contracts: - // ../../yarn-project/node_modules/.bin/aztec-cli codegen - // target/contract_instance_registry_contract-ContractInstanceRegistry.json --nr -o + // ../../yarn-project/node_modules/.bin/aztec codegen + // target/contract_instance_registry_contract-ContractInstanceRegistry.json -o // ./contracts/contract_instance_registry_contract/src/interface - let mut serialized_args = [0; 16]; + // + // PublicKeys serializes to 5 fields (npk_m_hash, ivpk_m as a 2-field point, ovpk_m_hash, tpk_m_hash). Total args: 4 + // (salt, class_id, init_hash, immutables_hash) + 5 (public_keys) + 1 (universal_deploy) = 10. + let mut serialized_args = [0; 10]; serialized_args[0] = instance.salt; serialized_args[1] = instance.contract_class_id.to_field(); serialized_args[2] = instance.initialization_hash; + serialized_args[3] = instance.immutables_hash; let serialized_public_keys = instance.public_keys.serialize(); - for i in 0..12 { - serialized_args[i + 3] = serialized_public_keys[i]; + for i in 0..5 { + serialized_args[i + 4] = serialized_public_keys[i]; } - serialized_args[15] = universal_deploy as Field; + serialized_args[9] = universal_deploy as Field; let _call_result = context.call_private_function( CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, comptime { FunctionSelector::from_signature( - "publish_for_public_execution(Field,(Field),Field,(((Field,Field,bool)),((Field,Field,bool)),((Field,Field,bool)),((Field,Field,bool))),bool)", + "publish_for_public_execution(Field,(Field),Field,Field,(Field,((Field,Field)),Field,Field),bool)", ) }, serialized_args, diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr index 019b8219cabc..2d797d503f59 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr @@ -12,10 +12,8 @@ use crate::{ }; use crate::protocol::{ - address::AztecAddress, - constants::DOM_SEP__INITIALIZATION_NULLIFIER, - hash::poseidon2_hash_with_separator, - traits::{Hash, Packable}, + address::AztecAddress, constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, + traits::Packable, }; mod test; @@ -82,8 +80,7 @@ impl PrivateImmutable { /// that need to check if a PrivateImmutable has been initialized. /// fn get_initialization_nullifier(self) -> Field { - let owner_npk_m = get_public_keys(self.owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(self.owner).npk_m_hash; let secret = self.context.request_nhk_app(owner_npk_m_hash); self.compute_initialization_nullifier(secret) } @@ -137,8 +134,7 @@ where { /// Computes the nullifier that will be created when this PrivateImmutable is first initialized. unconstrained fn get_initialization_nullifier(self) -> Field { - let owner_npk_m = get_public_keys(self.owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(self.owner).npk_m_hash; let secret = get_nhk_app(owner_npk_m_hash); self.compute_initialization_nullifier(secret) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr index 81a61aade5d9..bcf186e894ea 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr @@ -12,10 +12,8 @@ use crate::{ }; use crate::protocol::{ - address::AztecAddress, - constants::DOM_SEP__INITIALIZATION_NULLIFIER, - hash::poseidon2_hash_with_separator, - traits::{Hash, Packable}, + address::AztecAddress, constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, + traits::Packable, }; mod test; @@ -104,8 +102,7 @@ where /// also be useful for contracts that need to check if a PrivateMutable has been initialized. /// fn get_initialization_nullifier(self) -> Field { - let owner_npk_m = get_public_keys(self.owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(self.owner).npk_m_hash; let secret = self.context.request_nhk_app(owner_npk_m_hash); self.compute_initialization_nullifier(secret) } @@ -311,8 +308,7 @@ where { /// Computes the nullifier that will be created when this PrivateMutable is first initialized. unconstrained fn get_initialization_nullifier(self) -> Field { - let owner_npk_m = get_public_keys(self.owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(self.owner).npk_m_hash; let secret = get_nhk_app(owner_npk_m_hash); self.compute_initialization_nullifier(secret) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr index 6ae7103ee469..9e822bb64cea 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_immutable.nr @@ -12,9 +12,7 @@ use crate::{ }; use crate::protocol::{ - constants::DOM_SEP__INITIALIZATION_NULLIFIER, - hash::poseidon2_hash_with_separator, - traits::{Hash, Packable}, + constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, traits::Packable, }; mod test; @@ -87,8 +85,7 @@ impl SinglePrivateImmutable { /// that need to check if a SinglePrivateImmutable has been initialized. fn get_initialization_nullifier(self) -> Field { let contract_address = self.context.this_address(); - let contract_npk_m = get_public_keys(contract_address).npk_m; - let contract_npk_m_hash = contract_npk_m.hash(); + let contract_npk_m_hash = get_public_keys(contract_address).npk_m_hash; let secret = self.context.request_nhk_app(contract_npk_m_hash); self.compute_initialization_nullifier(secret) } @@ -152,8 +149,7 @@ where /// Computes the nullifier that will be created when this SinglePrivateImmutable is first initialized. unconstrained fn get_initialization_nullifier(self) -> Field { let contract_address = self.context.this_address(); - let contract_npk_m = get_public_keys(contract_address).npk_m; - let contract_npk_m_hash = contract_npk_m.hash(); + let contract_npk_m_hash = get_public_keys(contract_address).npk_m_hash; let secret = get_nhk_app(contract_npk_m_hash); self.compute_initialization_nullifier(secret) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr index 14feab03af3c..04951b29263d 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_private_mutable.nr @@ -12,10 +12,8 @@ use crate::{ }; use crate::protocol::{ - address::AztecAddress, - constants::DOM_SEP__INITIALIZATION_NULLIFIER, - hash::poseidon2_hash_with_separator, - traits::{Hash, Packable}, + address::AztecAddress, constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, + traits::Packable, }; mod test; @@ -122,8 +120,7 @@ where /// also be useful for contracts that need to check if a SinglePrivateMutable has been initialized. fn get_initialization_nullifier(self) -> Field { let contract_address = self.context.this_address(); - let contract_npk_m = get_public_keys(contract_address).npk_m; - let contract_npk_m_hash = contract_npk_m.hash(); + let contract_npk_m_hash = get_public_keys(contract_address).npk_m_hash; let secret = self.context.request_nhk_app(contract_npk_m_hash); self.compute_initialization_nullifier(secret) } @@ -243,8 +240,7 @@ where /// Computes the nullifier that will be created when this SinglePrivateMutable is first initialized. unconstrained fn get_initialization_nullifier(self) -> Field { let contract_address = self.context.this_address(); - let contract_npk_m = get_public_keys(contract_address).npk_m; - let contract_npk_m_hash = contract_npk_m.hash(); + let contract_npk_m_hash = get_public_keys(contract_address).npk_m_hash; let secret = get_nhk_app(contract_npk_m_hash); self.compute_initialization_nullifier(secret) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr b/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr index a97301415b21..5da2abb76b9b 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/single_use_claim.nr @@ -1,6 +1,5 @@ use crate::protocol::{ address::AztecAddress, constants::DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, hash::poseidon2_hash_with_separator, - traits::Hash, }; use crate::{ @@ -104,7 +103,7 @@ impl SingleUseClaim<&mut PrivateContext> { /// The implementation of this function emits a nullifier derived from the `owner`'s nullifier hiding key and the /// storage slot of the underlying state variable. pub fn claim(self) { - let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m.hash()); + let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m_hash); self.context.push_nullifier_unsafe(self.compute_nullifier(owner_nhk_app)); } @@ -116,7 +115,7 @@ impl SingleUseClaim<&mut PrivateContext> { /// This function generates a kernel nullifier read request, so it can even assert the existence of pending claims, /// i.e. when [`SingleUseClaim::claim`] was called in the same transaction as [`SingleUseClaim::assert_claimed`]. pub fn assert_claimed(self) { - let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m.hash()); + let owner_nhk_app = self.context.request_nhk_app(get_public_keys(self.owner).npk_m_hash); let nullifier = self.compute_nullifier(owner_nhk_app); // Safety: `check_nullifier_exists` is an unconstrained function - we can constrain a true value @@ -136,7 +135,7 @@ impl SingleUseClaim<&mut PrivateContext> { impl SingleUseClaim { /// Returns `true` if an owner has claimed this single use claim. pub unconstrained fn has_claimed(self) -> bool { - let owner_nhk_app = get_nhk_app(get_public_keys(self.owner).npk_m.hash()); + let owner_nhk_app = get_nhk_app(get_public_keys(self.owner).npk_m_hash); check_nullifier_exists(self.compute_nullifier(owner_nhk_app)) } } diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/misc.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/misc.nr index 26ab11663952..d03347ea83f4 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/misc.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment/test/misc.nr @@ -60,8 +60,5 @@ unconstrained fn txe_oracle_version_is_checked_upon_env_creation() { let _env = TestEnvironment::new(); assert_eq(mock.times_called(), 1); - assert_eq( - mock.get_last_params::<(Field, Field)>(), - (TXE_ORACLE_VERSION_MAJOR, TXE_ORACLE_VERSION_MINOR), - ); + assert_eq(mock.get_last_params::<(Field, Field)>(), (TXE_ORACLE_VERSION_MAJOR, TXE_ORACLE_VERSION_MINOR)); } diff --git a/noir-projects/aztec-nr/aztec/src/utils/point.nr b/noir-projects/aztec-nr/aztec/src/utils/point.nr index ab5b90614ee8..7f2b3b54a7a0 100644 --- a/noir-projects/aztec-nr/aztec/src/utils/point.nr +++ b/noir-projects/aztec-nr/aztec/src/utils/point.nr @@ -1,11 +1,11 @@ -use crate::protocol::{point::Point, utils::field::sqrt}; +use crate::protocol::{point::EmbeddedCurvePoint, utils::field::sqrt}; // I am storing the modulus minus 1 divided by 2 here because full modulus would throw "String literal too large" error // Full modulus is 21888242871839275222246405745257275088548364400416034343698204186575808495617 global BN254_FR_MODULUS_DIV_2: Field = 10944121435919637611123202872628637544274182200208017171849102093287904247808; /// Returns: true if p.y <= MOD_DIV_2, else false. -pub fn get_sign_of_point(p: Point) -> bool { +pub fn get_sign_of_point(p: EmbeddedCurvePoint) -> bool { // We store only a "sign" of the y coordinate because the rest can be derived from the x coordinate. To get the // sign we check if the y coordinate is less or equal than the field's modulus minus 1 divided by 2. Ideally we'd // do `y <= MOD_DIV_2`, but there's no `lte` function, so instead we do `!(y > MOD_DIV_2)`, which is equivalent, @@ -13,18 +13,18 @@ pub fn get_sign_of_point(p: Point) -> bool { !BN254_FR_MODULUS_DIV_2.lt(p.y) } -/// Returns a `Point` in the Grumpkin curve given its x coordinate. +/// Returns an `EmbeddedCurvePoint` in the Grumpkin curve given its x coordinate. /// /// Because not all values in the field are valid x coordinates of points in the curve (i.e. there is no corresponding /// y value in the field that satisfies the curve equation), it may not be possible to reconstruct a `Point`. /// `Option::none()` is returned in such cases. -pub fn point_from_x_coord(x: Field) -> Option { +pub fn point_from_x_coord(x: Field) -> Option { // y ^ 2 = x ^ 3 - 17 let rhs = x * x * x - 17; - sqrt(rhs).map(|y| Point { x, y, is_infinite: false }) + sqrt(rhs).map(|y| EmbeddedCurvePoint { x, y }) } -/// Returns a `Point` in the Grumpkin curve given its x coordinate and sign for the y coordinate. +/// Returns an `EmbeddedCurvePoint` in the Grumpkin curve given its x coordinate and sign for the y coordinate. /// /// Because not all values in the field are valid x coordinates of points in the curve (i.e. there is no corresponding /// y value in the field that satisfies the curve equation), it may not be possible to reconstruct a `Point`. @@ -32,7 +32,7 @@ pub fn point_from_x_coord(x: Field) -> Option { /// /// @param x - The x coordinate of the point @param sign - The "sign" of the y coordinate - determines whether y <= /// (Fr.MODULUS - 1) / 2 -pub fn point_from_x_coord_and_sign(x: Field, sign: bool) -> Option { +pub fn point_from_x_coord_and_sign(x: Field, sign: bool) -> Option { // y ^ 2 = x ^ 3 - 17 let rhs = x * x * x - 17; @@ -40,12 +40,12 @@ pub fn point_from_x_coord_and_sign(x: Field, sign: bool) -> Option { // If there is a square root, we need to ensure it has the correct "sign" let y_is_positive = !BN254_FR_MODULUS_DIV_2.lt(y); let final_y = if y_is_positive == sign { y } else { -y }; - Point { x, y: final_y, is_infinite: false } + EmbeddedCurvePoint { x, y: final_y } }) } mod test { - use crate::protocol::point::Point; + use crate::protocol::point::EmbeddedCurvePoint; use crate::utils::point::{ BN254_FR_MODULUS_DIV_2, get_sign_of_point, point_from_x_coord, point_from_x_coord_and_sign, }; @@ -59,7 +59,7 @@ mod test { assert_eq(p.x, x); assert_eq(p.y, 0x07fc22c7f2c7057571f137fe46ea9c95114282bc95d37d71ec4bfb88de457d4a); - assert_eq(p.is_infinite, false); + assert_eq(p.is_infinite(), false); // Test negative y coordinate let x2 = 0x247371652e55dd74c9af8dbe9fb44931ba29a9229994384bd7077796c14ee2b5; @@ -68,7 +68,7 @@ mod test { assert_eq(p2.x, x2); assert_eq(p2.y, 0x26441aec112e1ae4cee374f42556932001507ad46e255ffb27369c7e3766e5c0); - assert_eq(p2.is_infinite, false); + assert_eq(p2.is_infinite(), false); } #[test] @@ -123,7 +123,7 @@ mod test { unconstrained fn test_get_sign_of_point() { // Derive a point from x = 8, then test both possible y values let point = point_from_x_coord(8).unwrap(); - let neg_point = Point { x: point.x, y: 0 - point.y, is_infinite: false }; + let neg_point = EmbeddedCurvePoint { x: point.x, y: 0 - point.y }; // One should be "positive" (y <= MOD_DIV_2) and one "negative" let sign1 = get_sign_of_point(point); @@ -131,15 +131,15 @@ mod test { assert(sign1 != sign2); // y = 0 should return true (0 <= MOD_DIV_2) - let zero_y_point = Point { x: 0, y: 0, is_infinite: false }; + let zero_y_point = EmbeddedCurvePoint { x: 0, y: 0 }; assert(get_sign_of_point(zero_y_point) == true); // y = MOD_DIV_2 should return true (exactly at boundary) - let boundary_point = Point { x: 0, y: BN254_FR_MODULUS_DIV_2, is_infinite: false }; + let boundary_point = EmbeddedCurvePoint { x: 0, y: BN254_FR_MODULUS_DIV_2 }; assert(get_sign_of_point(boundary_point) == true); // y = MOD_DIV_2 + 1 should return false (just over boundary) - let over_boundary_point = Point { x: 0, y: BN254_FR_MODULUS_DIV_2 + 1, is_infinite: false }; + let over_boundary_point = EmbeddedCurvePoint { x: 0, y: BN254_FR_MODULUS_DIV_2 + 1 }; assert(get_sign_of_point(over_boundary_point) == false); } diff --git a/noir-projects/aztec-nr/uint-note/src/uint_note.nr b/noir-projects/aztec-nr/uint-note/src/uint_note.nr index 00583d1e7d73..87fb76f7f4db 100644 --- a/noir-projects/aztec-nr/uint-note/src/uint_note.nr +++ b/noir-projects/aztec-nr/uint-note/src/uint_note.nr @@ -15,7 +15,7 @@ use aztec::{ DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, }, hash::{compute_log_tag, compute_siloed_nullifier, poseidon2_hash_with_separator}, - traits::{Deserialize, FromField, Hash, Packable, Serialize, ToField}, + traits::{Deserialize, FromField, Packable, Serialize, ToField}, }, }; @@ -64,8 +64,7 @@ impl NoteHash for UintNote { owner: AztecAddress, note_hash_for_nullification: Field, ) -> Field { - let owner_npk_m = get_public_keys(owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; let secret = context.request_nhk_app(owner_npk_m_hash); compute_note_nullifier(note_hash_for_nullification, [secret]) } @@ -76,8 +75,7 @@ impl NoteHash for UintNote { note_hash_for_nullification: Field, ) -> Option { try_get_public_keys(owner).map(|public_keys| { - let owner_npk_m = public_keys.npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = public_keys.npk_m_hash; let secret = get_nhk_app(owner_npk_m_hash); compute_note_nullifier(note_hash_for_nullification, [secret]) }) diff --git a/noir-projects/bootstrap.sh b/noir-projects/bootstrap.sh index 006f75495900..197e7cc8bbd3 100755 --- a/noir-projects/bootstrap.sh +++ b/noir-projects/bootstrap.sh @@ -10,9 +10,14 @@ function build { function prep { set -eu (cd noir-protocol-circuits && yarn && node ./scripts/generate_variants.js) - for dir in noir-contracts noir-protocol-circuits mock-protocol-circuits aztec-nr; do - (cd $dir && ../../noir/noir-repo/target/release/nargo fmt --check) - done + # nargo downloads its git dependencies (e.g. noir-lang/poseidon) on first use. + # Under heavy parallel CI load the VPC DNS resolver drops lookups + # ("Could not resolve host: github.com"), leaving a half-cloned dependency dir + # that then fails with "Cannot read file .../Nargo.toml". Retry the download, + # wiping the partial dependency cache after a failure so the next attempt + # re-clones cleanly. A warm cache is left intact on success. + local fmt_check='( set -e; for dir in noir-contracts noir-protocol-circuits mock-protocol-circuits aztec-nr; do (cd "$dir" && ../../noir/noir-repo/target/release/nargo fmt --check); done )' + RETRY_SLEEP=10 retry "$fmt_check || { rm -rf \"\$HOME/nargo\"; exit 1; }" } export -f prep diff --git a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr index 1886bf121746..104a9d2b6f88 100644 --- a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr +++ b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr @@ -9,7 +9,7 @@ use aztec::{ protocol::{ address::AztecAddress, constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - traits::{Deserialize, FromField, Hash, Packable, Serialize, ToField}, + traits::{Deserialize, FromField, Packable, Serialize, ToField}, }, state_vars::{Owned, PrivateSet, StateVariable}, }; @@ -181,7 +181,7 @@ impl Deck { global PACK_CARDS: u32 = 3; // Limited by number of write requests (max 4) pub fn get_pack_cards(seed: Field, owner: AztecAddress, context: &mut PrivateContext) -> [Card; PACK_CARDS] { - let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; // generate pseudo randomness deterministically from 'seed' and user secret let secret = context.request_nhk_app(owner_npk_m_hash); diff --git a/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr b/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr index 6f0e47db7085..183a85c618a3 100644 --- a/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr +++ b/noir-projects/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr @@ -15,7 +15,7 @@ use aztec::{ DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, }, hash::{compute_log_tag, poseidon2_hash_with_separator}, - traits::{Deserialize, Hash, Packable, Serialize, ToField}, + traits::{Deserialize, Packable, Serialize, ToField}, }, }; @@ -60,8 +60,7 @@ impl NoteHash for NFTNote { owner: AztecAddress, note_hash_for_nullification: Field, ) -> Field { - let owner_npk_m = get_public_keys(owner).npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; let secret = context.request_nhk_app(owner_npk_m_hash); compute_note_nullifier(note_hash_for_nullification, [secret]) } @@ -72,8 +71,7 @@ impl NoteHash for NFTNote { note_hash_for_nullification: Field, ) -> Option { try_get_public_keys(owner).map(|public_keys| { - let owner_npk_m = public_keys.npk_m; - let owner_npk_m_hash = owner_npk_m.hash(); + let owner_npk_m_hash = public_keys.npk_m_hash; let secret = get_nhk_app(owner_npk_m_hash); compute_note_nullifier(note_hash_for_nullification, [secret]) }) diff --git a/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr index af84b0e17cf0..ded38bc11126 100644 --- a/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr +++ b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr @@ -1,7 +1,7 @@ use aztec::{ keys::ecdh_shared_secret::compute_app_siloed_shared_secret, macros::notes::note, - protocol::{address::AztecAddress, point::Point, traits::{Deserialize, Packable, Serialize}}, + protocol::{address::AztecAddress, point::EmbeddedCurvePoint, traits::{Deserialize, Packable, Serialize}}, }; /// A record of a handshake established by the note's owner (the sender). @@ -20,11 +20,11 @@ pub struct HandshakeNote { recipient: AztecAddress, /// The raw ECDH shared-secret point `S = eph_sk * recipient_address_point`. Only this module can read it for /// siloing, and it is never returned by an external function. - secret: Point, + secret: EmbeddedCurvePoint, } impl HandshakeNote { - pub(crate) fn new(shared_secret: Point, handshake_type: u8, recipient: AztecAddress) -> Self { + pub(crate) fn new(shared_secret: EmbeddedCurvePoint, handshake_type: u8, recipient: AztecAddress) -> Self { Self { handshake_type, recipient, secret: shared_secret } } diff --git a/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr b/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr index e8f1e8c0bb4a..48dafc745fd9 100644 --- a/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr @@ -32,14 +32,16 @@ pub contract ContractInstanceRegistry { salt: Field, contract_class_id: ContractClassId, initialization_hash: Field, + immutables_hash: Field, public_keys: PublicKeys, deployer: AztecAddress, } - // Custom serialization is required because we don't want to waste one field for the `is_infinite` flag of public - // key points (public key points will never be the infinity point). + // Custom serialization is required because: + // - npk_m, ovpk_m, and tpk_m are exposed only as hashes so we serialize the hashes directly. + // - For ivpk_m we drop the `is_infinite` flag (we assume non-infinity). impl ContractInstancePublished { - fn serialize_non_standard(self) -> [Field; 15] { + fn serialize_non_standard(self) -> [Field; 13] { [ self.CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE, self.address.to_field(), @@ -47,14 +49,12 @@ pub contract ContractInstanceRegistry { self.salt, self.contract_class_id.to_field(), self.initialization_hash, - self.public_keys.npk_m.serialize()[0], - self.public_keys.npk_m.serialize()[1], - self.public_keys.ivpk_m.serialize()[0], - self.public_keys.ivpk_m.serialize()[1], - self.public_keys.ovpk_m.serialize()[0], - self.public_keys.ovpk_m.serialize()[1], - self.public_keys.tpk_m.serialize()[0], - self.public_keys.tpk_m.serialize()[1], + self.immutables_hash, + self.public_keys.npk_m_hash, + self.public_keys.ivpk_m.inner.x, + self.public_keys.ivpk_m.inner.y, + self.public_keys.ovpk_m_hash, + self.public_keys.tpk_m_hash, self.deployer.to_field(), ] } @@ -77,13 +77,15 @@ pub contract ContractInstanceRegistry { /// Publishes a new contract instance. /// - /// The caller provides deployment parameters (salt, class_id, init_hash, public_keys, universal_deploy). + /// The caller provides deployment parameters (salt, class_id, init_hash, immutables_hash, public_keys, + /// universal_deploy). /// The `universal_deploy` flag controls whether the deployer address is bound into the contract address: /// when true, deployer is zero (anyone can deploy the same instance); when false, deployer is the caller. /// /// This function: /// 1. Verifies the contract class is registered in ContractClassRegistry (nullifier existence check). - /// 2. Validates public key points are on the Grumpkin curve (preventing AVM DoS via invalid points). + /// 2. Validates `ivpk_m` is on the Grumpkin curve and not the point at infinity (preventing AVM DoS via an invalid + /// point). `npk_m`, `ovpk_m`, and `tpk_m` are exposed only as hashes and are not validated in-circuit. /// 3. Computes the deterministic contract address from the deployment parameters. /// 4. Emits the address as a nullifier (proving publication preventing duplicate deployment) /// --> this address nullifier is then checked to exist by the AVM upon public function execution (if it doesn't @@ -95,6 +97,7 @@ pub contract ContractInstanceRegistry { salt: Field, contract_class_id: ContractClassId, initialization_hash: Field, + immutables_hash: Field, public_keys: PublicKeys, universal_deploy: bool, ) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { @@ -103,7 +106,9 @@ pub contract ContractInstanceRegistry { // body, I have removed that check. assert_compatible_oracle_version(); - let serialized_params: [Field; 16] = [salt, contract_class_id.to_field(), initialization_hash] + // 4 prefix fields (salt, class_id, init_hash, immutables_hash) + 5 public-key fields + 1 + // universal_deploy flag = 10. + let serialized_params: [Field; 10] = [salt, contract_class_id.to_field(), initialization_hash, immutables_hash] .concat(public_keys.serialize()) .concat([universal_deploy.to_field()]); @@ -126,9 +131,17 @@ pub contract ContractInstanceRegistry { context.maybe_msg_sender().unwrap() }; - let partial_address = PartialAddress::compute(contract_class_id, salt, initialization_hash, deployer); + let partial_address = PartialAddress::compute( + contract_class_id, + salt, + initialization_hash, + deployer, + immutables_hash, + ); - // Validate public key points lie on the Grumpkin curve and are non-0 to prevent AVM DoS attacks. + // Validate `ivpk_m` is on the Grumpkin curve and is not the point at infinity (preventing AVM + // DoS attacks). The other three master keys are exposed as hashes and have no + // curve-point to validate here. public_keys.validate_on_curve(); public_keys.validate_non_infinity(); @@ -138,23 +151,24 @@ pub contract ContractInstanceRegistry { // We use no domain separators because these are the only nullifiers this contract uses. context.push_nullifier(address.to_field()); - // Broadcast deployment event. Uses non-standard serialization (2 fields per point, - // omitting is_infinite) for TypeScript SDK compatibility. + // Broadcast deployment event. Version 2 carries hashes for npk/ovpk/tpk and the affine + // coordinates of ivpk only; see `serialize_non_standard`. let event = ContractInstancePublished { CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE, contract_class_id, address, public_keys, initialization_hash, + immutables_hash, salt, deployer, - version: 1, + version: 2, }; let payload = event.serialize_non_standard(); debug_log_format("ContractInstancePublished: {}", payload); - // We pad the payload with [0] to match the length required by emit_private_log. Since the log is not + // We pad the payload with zeros to match the length required by emit_private_log. Since the log is not // encrypted, padding with zero rather than a random value is acceptable (we don't care about privacy here). - let padded_log = payload.concat([0]); + let padded_log = payload.concat([0, 0, 0]); let length = payload.len(); context.emit_private_log(padded_log, length); @@ -307,6 +321,7 @@ pub contract ContractInstanceRegistry { pub _salt: Field, pub _contract_class_id: ContractClassId, pub _initialization_hash: Field, + pub _immutables_hash: Field, pub _public_keys: PublicKeys, pub _universal_deploy: bool, } diff --git a/noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface/src/main.nr b/noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface/src/main.nr index d672c3b7bf5b..43af16745a71 100644 --- a/noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface/src/main.nr @@ -25,6 +25,7 @@ pub contract ContractInstanceRegistry { salt: Field, contract_class_id: ContractClassId, initialization_hash: Field, + immutables_hash: Field, public_keys: PublicKeys, universal_deploy: bool, ) {} diff --git a/noir-projects/noir-contracts/contracts/test/avm_test_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/test/avm_test_contract/Nargo.toml index 5745846cfdbf..b29c5154badf 100644 --- a/noir-projects/noir-contracts/contracts/test/avm_test_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/test/avm_test_contract/Nargo.toml @@ -10,6 +10,7 @@ compressed_string = { path = "../../../../aztec-nr/compressed-string" } sha256 = { tag = "v0.3.0", git = "https://github.com/noir-lang/sha256" } keccak256 = { tag = "v0.1.3", git = "https://github.com/noir-lang/keccak256" } poseidon = { tag= "v0.3.0", git = "https://github.com/noir-lang/poseidon" } +schnorr = { tag = "v0.4.0", git = "https://github.com/noir-lang/schnorr" } fee_juice = { path = "../../protocol_interface/fee_juice_interface" } auth_contract = { path = "../../protocol/auth_registry_contract" } instance_contract = { path = "../../protocol_interface/contract_instance_registry_interface" } diff --git a/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr index 91e52f588160..d868087802c2 100644 --- a/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr @@ -16,10 +16,10 @@ pub contract AvmTest { use aztec::macros::{functions::{external, view}, storage::storage}; use aztec::oracle::get_contract_instance::{ get_contract_instance_class_id_avm, get_contract_instance_deployer_avm, - get_contract_instance_initialization_hash_avm, + get_contract_instance_immutables_hash_avm, get_contract_instance_initialization_hash_avm, }; use aztec::protocol::abis::function_selector::FunctionSelector; - use aztec::protocol::{address::{AztecAddress, EthAddress}, point::Point, scalar::Scalar}; + use aztec::protocol::{address::{AztecAddress, EthAddress}, point::EmbeddedCurvePoint, scalar::Scalar}; use aztec::protocol::{ constants::{ CANONICAL_AUTH_REGISTRY_ADDRESS, CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, FEE_JUICE_ADDRESS, @@ -195,13 +195,13 @@ pub contract AvmTest { } #[external("public")] - fn elliptic_curve_add(lhs: Point, rhs: Point) -> Point { + fn elliptic_curve_add(lhs: EmbeddedCurvePoint, rhs: EmbeddedCurvePoint) -> EmbeddedCurvePoint { lhs + rhs } #[external("public")] - fn elliptic_curve_add_and_double() -> Point { - let g = Point { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y, is_infinite: false }; + fn elliptic_curve_add_and_double() -> EmbeddedCurvePoint { + let g = EmbeddedCurvePoint { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y }; let doubled = g + g; let added = g + doubled; @@ -209,20 +209,23 @@ pub contract AvmTest { } #[external("public")] - fn variable_base_msm(scalar_lo: Field, scalar_hi: Field, scalar2_lo: Field, scalar2_hi: Field) -> Point { - let g = Point { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y, is_infinite: false }; + fn variable_base_msm( + scalar_lo: Field, + scalar_hi: Field, + scalar2_lo: Field, + scalar2_hi: Field, + ) -> EmbeddedCurvePoint { + let g = EmbeddedCurvePoint { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y }; - let triple_g = multi_scalar_mul( - [g.to_embedded(), g.to_embedded()], + multi_scalar_mul( + [g, g], [Scalar { lo: scalar_lo, hi: scalar_hi }, Scalar { lo: scalar2_lo, hi: scalar2_hi }], - ); - triple_g.into() + ) } #[external("public")] - fn pedersen_commit(x: Field, y: Field) -> Point { - let commitment = ::std::hash::pedersen_commitment_with_separator([x, y], 20); - commitment.into() + fn pedersen_commit(x: Field, y: Field) -> EmbeddedCurvePoint { + std::hash::pedersen_commitment_with_separator([x, y], 20) } #[external("public")] @@ -280,6 +283,26 @@ pub contract AvmTest { input.to_le_bits() } + // Exercises Schnorr signature verification in public. The grumpkin-Poseidon2 variant + // (schnorr v0.4.0+) only relies on EC arithmetic and Poseidon2, both of which the public AVM + // supports. Inputs are parameters rather than constants; when bulk_testing routes them in + // from calldata, Noir can't constant-fold the verify away and MSM+Poseidon2 actually execute. + #[contract_library_method] + fn _schnorr_verify_signature( + pubkey_x: Field, + pubkey_y: Field, + sig_s_lo: Field, + sig_s_hi: Field, + sig_e_lo: Field, + sig_e_hi: Field, + message: Field, + ) -> bool { + let public_key = std::embedded_curve_ops::EmbeddedCurvePoint::new(pubkey_x, pubkey_y); + let sig_s = std::embedded_curve_ops::EmbeddedCurveScalar::new(sig_s_lo, sig_s_hi); + let sig_e = std::embedded_curve_ops::EmbeddedCurveScalar::new(sig_e_lo, sig_e_hi); + schnorr::verify_signature(public_key, (sig_s, sig_e), message) + } + // Helper functions to demonstrate an internal call stack in error messages #[contract_library_method] fn inner_helper_with_failed_assertion() { @@ -389,20 +412,24 @@ pub contract AvmTest { [4, 5, 6] // Should not get here. } + // This function is called from avm/avm_simulator.test.ts to test retrieval #[external("public")] fn test_get_contract_instance(address: AztecAddress) { let deployer = get_contract_instance_deployer_avm(address); let class_id = get_contract_instance_class_id_avm(address); let initialization_hash = get_contract_instance_initialization_hash_avm(address); + let immutables_hash = get_contract_instance_immutables_hash_avm(address); assert(deployer.is_some(), "Contract instance not found when getting DEPLOYER!"); assert(class_id.is_some(), "Contract instance not found when getting CLASS_ID!"); assert(initialization_hash.is_some(), "Contract instance not found when getting INIT_HASH!"); + assert(immutables_hash.is_some(), "Contract instance not found when getting IMMUTABLES_HASH!"); // The values here should match those in `avm_simulator.test.ts` assert(deployer.unwrap().eq(AztecAddress::from_field(0x456))); assert(class_id.unwrap().eq(ContractClassId::from_field(0x789))); assert(initialization_hash.unwrap() == 0x101112); + assert(immutables_hash.unwrap() == 0x202221); } #[external("public")] @@ -411,12 +438,14 @@ pub contract AvmTest { expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, + expected_immutables_hash: Field, ) { _test_get_contract_instance_matches( address, expected_deployer, expected_class_id, expected_initialization_hash, + expected_immutables_hash, ); } @@ -426,19 +455,23 @@ pub contract AvmTest { expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, + expected_immutables_hash: Field, ) { let deployer = get_contract_instance_deployer_avm(address); let class_id = get_contract_instance_class_id_avm(address); let initialization_hash = get_contract_instance_initialization_hash_avm(address); + let immutables_hash = get_contract_instance_immutables_hash_avm(address); assert(deployer.is_some(), "Contract instance not found when getting DEPLOYER!"); assert(class_id.is_some(), "Contract instance not found when getting CLASS_ID!"); assert(initialization_hash.is_some(), "Contract instance not found when getting INIT_HASH!"); + assert(immutables_hash.is_some(), "Contract instance not found when getting IMMUTABLES_HASH!"); // The values here should match those in `avm_simulator.test.ts` assert(deployer.unwrap().eq(expected_deployer)); assert(class_id.unwrap().eq(expected_class_id)); assert(initialization_hash.unwrap().eq(expected_initialization_hash)); + assert(immutables_hash.unwrap().eq(expected_immutables_hash)); // Get a Protocol Contract and it should exist aztec::oracle::logging::debug_log("Get Contract Instance Protocol Contract Instance"); @@ -842,6 +875,8 @@ pub contract AvmTest { expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, + expected_immutables_hash: Field, + schnorr_inputs: [Field; 7], skip_strictly_limited_side_effects: bool, ) { aztec::oracle::logging::debug_log("biwise_ops"); @@ -863,6 +898,17 @@ pub contract AvmTest { let _ = sha256::sha256_var(args_u8, args_u8.len()); aztec::oracle::logging::debug_log("poseidon2_hash"); let _ = poseidon::poseidon2::Poseidon2::hash(args_field, args_field.len()); + aztec::oracle::logging::debug_log("schnorr_verify_signature"); + let schnorr_ok = _schnorr_verify_signature( + schnorr_inputs[0], + schnorr_inputs[1], + schnorr_inputs[2], + schnorr_inputs[3], + schnorr_inputs[4], + schnorr_inputs[5], + schnorr_inputs[6], + ); + assert(schnorr_ok, "Schnorr signature should verify"); aztec::oracle::logging::debug_log("pedersen_hash"); let _ = std::hash::pedersen_hash(args_field); aztec::oracle::logging::debug_log("pedersen_hash_with_index"); @@ -877,6 +923,7 @@ pub contract AvmTest { expected_deployer, expected_class_id, expected_initialization_hash, + expected_immutables_hash, ); aztec::oracle::logging::debug_log("get_address"); let _ = _get_address(self.address); @@ -935,3 +982,28 @@ pub contract AvmTest { //let _ = nested_call_to_nothing_recovers(); } } + +mod test { + use std::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar}; + + // Pins the same vector as `_schnorr_verify_signature` in the contract above (mirroring the C++ + // pinned_test_vector_large) so a regression in the schnorr lib or noir submodule is caught at + // `nargo test` time rather than only when running the AVM end-to-end test. + #[test] + unconstrained fn schnorr_pinned_vector_verifies() { + let public_key = EmbeddedCurvePoint::new( + 0x065812e335a97c2108ea8cf4ccfe2f9dd6b117a0714f5e18461575be93f61da6, + 0x1a915003e8ec534f9a15d926a7ded478e178468ccc4f28e236e67450a55ac622, + ); + let sig_s = EmbeddedCurveScalar::new( + 0xf3bc3b7147acb9c621fd9f72dbf15ffa, + 0x08599f379f0301dfefdbd0272554454d, + ); + let sig_e = EmbeddedCurveScalar::new( + 0x97065383ebbbd76620398792bd259bc2, + 0x2ceaee87f45b7a417f0ffb05451a8c92, + ); + let message: Field = 0x0123456789abcdef0fedcba9876543210123456789abcdef0fedcba987654321; + assert(schnorr::verify_signature(public_key, (sig_s, sig_e), message)); + } +} diff --git a/noir-projects/noir-contracts/contracts/test/returning_tuple_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/returning_tuple_contract/src/main.nr index b5887569e14e..0b7dee4ec40d 100644 --- a/noir-projects/noir-contracts/contracts/test/returning_tuple_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/returning_tuple_contract/src/main.nr @@ -5,7 +5,7 @@ use aztec::macros::aztec; pub contract ReturningTuple { use aztec::{ macros::functions::{external, view}, - protocol::{address::AztecAddress, point::Point, traits::{Deserialize, FromField}}, + protocol::{address::AztecAddress, point::EmbeddedCurvePoint, traits::{Deserialize, FromField}}, }; #[external("private")] @@ -40,8 +40,8 @@ pub contract ReturningTuple { #[external("private")] #[view] - fn fn_that_returns_6() -> (Field, u128, bool, str<3>, AztecAddress, Point) { - (1, 2, false, "xyz", AztecAddress::from_field(1), Point::deserialize([1, 2, 0])) + fn fn_that_returns_6() -> (Field, u128, bool, str<3>, AztecAddress, EmbeddedCurvePoint) { + (1, 2, false, "xyz", AztecAddress::from_field(1), EmbeddedCurvePoint::deserialize([1, 2])) } #[external("public")] @@ -76,8 +76,8 @@ pub contract ReturningTuple { #[external("public")] #[view] - fn fn_that_returns_6_public() -> (Field, u128, bool, str<3>, AztecAddress, Point) { - (1, 2, false, "xyz", AztecAddress::from_field(1), Point::deserialize([1, 2, 0])) + fn fn_that_returns_6_public() -> (Field, u128, bool, str<3>, AztecAddress, EmbeddedCurvePoint) { + (1, 2, false, "xyz", AztecAddress::from_field(1), EmbeddedCurvePoint::deserialize([1, 2])) } } diff --git a/noir-projects/noir-contracts/contracts/test/scope_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/scope_test_contract/src/main.nr index 27dd883cfed8..53a41d35fdde 100644 --- a/noir-projects/noir-contracts/contracts/test/scope_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/scope_test_contract/src/main.nr @@ -9,7 +9,7 @@ pub contract ScopeTest { keys::getters::{get_nhk_app, get_public_keys}, macros::{functions::{external, initializer, view}, storage::storage}, messages::message_delivery::MessageDelivery, - protocol::{address::AztecAddress, traits::Hash}, + protocol::address::AztecAddress, state_vars::{Owned, PrivateImmutable}, }; @@ -52,7 +52,7 @@ pub contract ScopeTest { /// Will fail if the caller is not authorized to access the owner's keys. #[external("private")] fn get_nhk(owner: AztecAddress) -> Field { - let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; self.context.request_nhk_app(owner_npk_m_hash) } @@ -67,7 +67,7 @@ pub contract ScopeTest { /// Will fail if the caller is not authorized to access the owner's keys. #[external("utility")] unconstrained fn get_nhk_utility(owner: AztecAddress) -> Field { - let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m_hash; get_nhk_app(owner_npk_m_hash) } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-2/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-2/Prover.toml new file mode 100644 index 000000000000..ad9bdf3b8638 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-2/Prover.toml @@ -0,0 +1,4016 @@ +vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" +is_private_only = true +first_nullifier_hint = "0x22c8f916474c9e4fbc086a9476c89c93120e1b8f7e32f1167216e7c3cb2e3308" +revertible_counter_hint = "0x0000000000000000000000000000000000000000000000000000000000000005" + +[tx_request] +args_hash = "0x02486714bcf7b63435b8818a646f5124643019b4d7a09497d20cca8d58ae946d" +salt = "0x0151ac979fc0d39f599d2b839d8bc37405936ad2d0d39b60185aa75a6d0e7336" + + [tx_request.origin] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [tx_request.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[tx_request.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[tx_request.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[tx_request.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[tx_request.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [tx_request.function_data] + is_private = true + + [tx_request.function_data.selector] + inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" + +[[protocol_contracts.derived_addresses]] +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" + +[[protocol_contracts.derived_addresses]] +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" + +[[protocol_contracts.derived_addresses]] +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" + +[[protocol_contracts.derived_addresses]] +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" + +[[protocol_contracts.derived_addresses]] +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" + +[[protocol_contracts.derived_addresses]] +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[private_call_0.vk] +key = [ + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000b61", + "0x0000000000000000000000000000007b6222b3a18551d60b847957202de6c8f5", + "0x00000000000000000000000000000000001e26b96548b9f12369e9c3ec0eee85", + "0x000000000000000000000000000000025aac0bbaf1beff1c0500e3ec38d34c8a", + "0x00000000000000000000000000000000002c498aff2f95b25bb92e2c9360aff5", + "0x00000000000000000000000000000039d32590e9d6e0be118712b9402c606156", + "0x000000000000000000000000000000000026588627e22f203f6399975fb67258", + "0x000000000000000000000000000000097282335613efda63abaeaddc915f44db", + "0x000000000000000000000000000000000021b51f545ea031ad8c826962f52545", + "0x00000000000000000000000000000035a0536197418c2ba2c29a1830f709420c", + "0x000000000000000000000000000000000020f8cabd08dfc29e045e0b80eb42d3", + "0x00000000000000000000000000000099e53cda88a63b8e751a2bc253f7a689a7", + "0x0000000000000000000000000000000000231a514e7a4dd0e23c4faf8d567c77", + "0x0000000000000000000000000000002dac12ff4e48e530611ceb7a400c099e4a", + "0x00000000000000000000000000000000001ad1cb6dbbe8ea3dd6c4f44ffdce56", + "0x000000000000000000000000000000dfd19e74f4e4c641b3b3f623825ccd495f", + "0x00000000000000000000000000000000000ce4453cef94251418336baa54e582", + "0x0000000000000000000000000000007ad93fd648d3587168e2ba9ee66dbbf918", + "0x00000000000000000000000000000000000a7680894366d3b1755d14152e528e", + "0x00000000000000000000000000000008bf43eecffcec9e31d916289a212b8f88", + "0x0000000000000000000000000000000000216620e5bd7b177f3fa15ceeb2526e", + "0x00000000000000000000000000000021db86993540e76c420c850640a25f7d94", + "0x000000000000000000000000000000000017418ee5d4d58a54e7728b755757a8", + "0x0000000000000000000000000000000cf5f978296643872c59d00be3c23ad68d", + "0x000000000000000000000000000000000013e45088158c3bf8ac1f8e71eec154", + "0x000000000000000000000000000000768cc857ea136153788ffa81c07daddaf2", + "0x000000000000000000000000000000000014b992148ee6906cb3a1989f3c4bb1", + "0x0000000000000000000000000000000127e074cd6ea24f75f86f3ab119f9ae5d", + "0x00000000000000000000000000000000001719d1f7fc4645193b8036cf9a3d52", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x000000000000000000000000000000622ac3715a21583a169b4c635c162bdc13", + "0x000000000000000000000000000000000012374104ee9056dfafba40f457c0a8", + "0x000000000000000000000000000000f6c09b75f7561f7fbbd272af5d3efa974b", + "0x00000000000000000000000000000000000e0a7bd7a377bca3ff6c89d68a3e5e", + "0x0000000000000000000000000000009d165e9a47e021ab9760d27339570655e5", + "0x0000000000000000000000000000000000000b204b0dc1f11b52bb345fb52145", + "0x000000000000000000000000000000d4c558b53b27cb4c171f8a5eb0bd1e3a2c", + "0x00000000000000000000000000000000002f6870272192d541c1b8887b15a95a", + "0x0000000000000000000000000000008f4c64ade1e7b515b074c100d489415d4c", + "0x00000000000000000000000000000000000f9aca92beccde2e1b08c99ab92a6c", + "0x0000000000000000000000000000008be6976e9870523051d19531843262ce4c", + "0x0000000000000000000000000000000000277419877e0ba35217f219676b5656", + "0x00000000000000000000000000000051ec180d05026f2f62b1674ca2e1a2c142", + "0x000000000000000000000000000000000022264cbd2ea66b7766612864c5108c", + "0x000000000000000000000000000000f137ae2b224915db0c43de1611134011d0", + "0x000000000000000000000000000000000011877af1a2b9b35d6ac04c489fe3ba", + "0x000000000000000000000000000000935ae3a5a2c4a7aad8e94a7cf1c4bec70e", + "0x00000000000000000000000000000000002a56488e09fd406c14aca4acf2b4c3", + "0x000000000000000000000000000000e770a6c5c0093eb5de2e5aa8d173e9ef05", + "0x000000000000000000000000000000000005522908d6e06b02d6938a789bb5c9", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000b139df614924ddb845d70d642d94873569", + "0x00000000000000000000000000000000000084d02351f0d2b405f3af6092edc0", + "0x0000000000000000000000000000006c1123c8d14bdfbfa99f95d1fd0d9674f7", + "0x00000000000000000000000000000000002be519d31aea4dac51b16b3655b459", + "0x00000000000000000000000000000035b52a2f19454b2d02086d012cfc44cbdb", + "0x000000000000000000000000000000000027f3e1c4d5482e3b1ebcbc5e43d1d2", + "0x000000000000000000000000000000bc81f2a307249de2d56c3c8151aa3a4179", + "0x000000000000000000000000000000000014745d0c8957b03309ffd69c523944", + "0x000000000000000000000000000000d90966909da4a8611a68a5b2544044ee27", + "0x00000000000000000000000000000000002dda368cf4f8ae011ba33953ccdbdc", + "0x00000000000000000000000000000099fd8e2a4efaa0e979e53c6360f11a3520", + "0x000000000000000000000000000000000029023563407bf604b94f3d3b82e32c", + "0x00000000000000000000000000000095ced0bf10b79aec2651f808812961ce57", + "0x0000000000000000000000000000000000204601f003e0e59d1865597a5cdcd4", + "0x000000000000000000000000000000fd07b0a28f8510ae42eefbbd2d0136dc4f", + "0x00000000000000000000000000000000001e3aba113eb2b6e0d9a07cb16188c0", + "0x0000000000000000000000000000004496315acb001bd07077d5e61a5fd28f1b", + "0x00000000000000000000000000000000001a39ca40a2fdca943fd7c57ea59fc9", + "0x0000000000000000000000000000001a6e9238224f825fbe059c173514ee0fe7", + "0x000000000000000000000000000000000022f701f63bad50d3161322f8d104b3", + "0x000000000000000000000000000000e7cb0e4c388d5b2b1350a0c1b259d7c4aa", + "0x0000000000000000000000000000000000216c09ccaf44298565b3e593e3a7bd", + "0x000000000000000000000000000000d840ba780d73076cfaadb07a9a1a2cad8b", + "0x00000000000000000000000000000000002a887121806c1166b16f3aa9de6716", + "0x0000000000000000000000000000000e3b5cb0fc3e09ea8b4059e2a6109ff857", + "0x00000000000000000000000000000000001794754a1a61af4fa7976eefdac79e", + "0x000000000000000000000000000000dfef9deedb32693d7cc279f72cdc785d1e", + "0x00000000000000000000000000000000000e55622ad6ca63ffde7f64ed504b16", + "0x000000000000000000000000000000d08df7bdd8d57cb1d65728efccbbfcf607", + "0x000000000000000000000000000000000005f2689ecd1c3bf58c28357d95d48a", + "0x0000000000000000000000000000002d7d2927cc7e65b41792f5745ba169663e", + "0x00000000000000000000000000000000002b5f2432471d8c12ea391ac1a0bd12", + "0x000000000000000000000000000000773d8fd379e59dbcbab02af010d195c779", + "0x000000000000000000000000000000000008826f48f7b0250873af38fa8f7500", + "0x0000000000000000000000000000006165595d9a271241c16e0472c174fba8f8", + "0x00000000000000000000000000000000001c673e22bf04c83bddc2f02ebaae36", + "0x0000000000000000000000000000008d6afb067ac5198bb372113d34c56552fa", + "0x00000000000000000000000000000000001e08cbe1d21feee99c841191e54333", + "0x0000000000000000000000000000007646a1a3ca480b5d7322e5e4bb688049f7", + "0x0000000000000000000000000000000000269f2465562733cff2488fe75060fe", + "0x0000000000000000000000000000005524b80d26a1d910532fda24c2383f979b", + "0x000000000000000000000000000000000023bf14a9a6153ade3200bcc787ba79", + "0x00000000000000000000000000000038d56d2f4e530f74fb02bb70d781488b16", + "0x00000000000000000000000000000000001d1731444ac607cb0623133a479871", + "0x000000000000000000000000000000fe08dc45003f859a25494ba5135502e42f", + "0x00000000000000000000000000000000001e6d7c5b53a5e88d78640651a5c6a0", + "0x000000000000000000000000000000ddf4dedac0a43ba687e608b3e6081b8546", + "0x000000000000000000000000000000000004c2446dcf61c32ba4b038fe7365fb", + "0x0000000000000000000000000000004557b361ff0d6568e896319c496fbe24b8", + "0x00000000000000000000000000000000000668a26f50d3354953d4b2766e8020", + "0x000000000000000000000000000000ea507b90f982c43d39d3f699d22b1f7c4a", + "0x00000000000000000000000000000000001429723650e7543325ff8bef1c4ffd", + "0x00000000000000000000000000000049c19043bd4f1ef29d5413b1f118d0f722", + "0x00000000000000000000000000000000001d7ad7b3a27a9bc7992d806af0ebc9", + "0x000000000000000000000000000000f291d1109ea1f48586582a3767b0392cbe", + "0x0000000000000000000000000000000000026df82a517f9dabb3c389c07aebc7", + "0x0000000000000000000000000000000999c4e1d13eba177baf97921ee863ca58", + "0x000000000000000000000000000000000002f7f537a4f96f2ca4eb19a57f0b9f", + "0x000000000000000000000000000000dea34b6c529204f209cd1420a81a3102bb", + "0x00000000000000000000000000000000001c53a430fcbd4b95ffc23b6461fa15", + "0x0000000000000000000000000000005c0cab22cbb5bdccf85116184958790eb4", + "0x00000000000000000000000000000000001b715af5e709bb9f06822082ee3120", + "0x000000000000000000000000000000c77eaa3f49d17dfe395648540f4cd0abc6", + "0x000000000000000000000000000000000007df3cadf5a234989c3f0b92052395", + "0x0000000000000000000000000000009c11b61aaa7a95751ddef148053d00a6e7", + "0x00000000000000000000000000000000000f65d42148106db82a9e434cb19459", + "0x000000000000000000000000000000f99b662c4e3bcd3fdffb75cad5deb632e6", + "0x0000000000000000000000000000000000284f78ec2bc1c17ffa75e285ad4529", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000059a5cd5c1c2d2e7cac107aaf0123ae4f84", + "0x0000000000000000000000000000000000170ffa45422a2680cd492bad46789d", + "0x0000000000000000000000000000003c91ea4fe538abe3c344c3603398af1cbc", + "0x0000000000000000000000000000000000295e7a3f8df6111a6bd51041d5179b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x11197593d62d0e7554158b832253460bcc00da8b6551eb5d955ef72444d95a3f" + +[private_call_0.verification_key_hints] +contract_class_artifact_hash = "0x1d9e0e30582ed207c6ba761454f1f542d807eb0a2b35a50b23297a6db34e3680" +contract_class_public_bytecode_commitment = "0x0ce4c618c3ed7f3a20410e618c06bb701e150af7fe28a3e92f68e7733809f33e" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_0.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x2cc233639ce62adaea3ec034abce91a0b008ca3b50da04eb0789bf1f438162ea", + "0x0f60b735d348fd08a8da88fe4b04361698e2bca73fbebb6cc1fdcb86a4d03c89", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_0.verification_key_hints.public_keys] + npk_m_hash = "0x2f1c4d79837ad500ede908112d4cc2af5d3af9fe982b8628035ccc97f15ee24c" + ovpk_m_hash = "0x1378ed60b21b30e7ad5260606275cd3b580932cef2ed8e95dcc953334277d28f" + tpk_m_hash = "0x25aed22eebf640703b2a68bc209562e3f5c5dadd47925e0bdd41df5e2102fb98" + +[private_call_0.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x17e45034ac640fd73c526836d47063c3158695ecd39fe841bd338ad7acf9f238" +y = "0x2b6dff182f1d814024994bce38d73c4ac9f7587b5e90b8351b08d65e1ed2a7ea" +is_infinite = false + + [private_call_0.verification_key_hints.salted_initialization_hash] + inner = "0x2de7750983e40a640c1540354955cbda141ba8ababbbabb93b83843a4a5c9e18" + + [private_call_0.verification_key_hints.updated_class_id_witness] + leaf_index = "123" + sibling_path = [ + "0x2848a1d7320b3bfb616ba2ff5b175f3dbbe07753e40389d913e60089060bca9e", + "0x0575020764758ac1e237d111ad2129b58c276979d075a2617d047edf1fa0af80", + "0x28d9c1b19a6d32ba2f59b1371ff35722075ccc81c08c306c0b2412697e18a906", + "0x13981cd7447462f1010ec3a2725d09dd4fad76d010fbc2cb1e6eaaf93f680abc", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x02c691e1474ab605965337b84f97e9ac2a34e1214040cf86d9e229f08f4494d5", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_0.verification_key_hints.updated_class_id_leaf] + slot = "0x1f29d351ad8d747c09020ea47be7a38833dccaaf378b55d7d8e6e79f1892c1a3" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x2511fb7ac309f6693b0411aac44ee65c49b46b778d669ad0a19168cc49f93d57" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000082" + +[private_call_1.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000f", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000001ecf", + "0x0000000000000000000000000000004e5d53d6b0dcb727fb0a33d6f23326ba13", + "0x0000000000000000000000000000000000270b1029efbcacf2ba8156be926f36", + "0x0000000000000000000000000000007600c8bfba70975b81933fa1375cc49525", + "0x0000000000000000000000000000000000265b4f40ec4362ecaa6574a26fb9e7", + "0x00000000000000000000000000000002a42259f84697487cf0c806cff78d376b", + "0x00000000000000000000000000000000000a6da882cb12c7c9c8851044af46fd", + "0x0000000000000000000000000000000900fa9df2854c361a2b8ebb4204bc11e2", + "0x0000000000000000000000000000000000143a6867f9c677696dfc6145c0c2c2", + "0x0000000000000000000000000000005c613b43829a134f234301805866bff5c4", + "0x000000000000000000000000000000000013475408680fcccaf629834bd8e7ef", + "0x000000000000000000000000000000d41c74cb34c4413784a7fe1a3282b8ac71", + "0x0000000000000000000000000000000000208a8fea14e1035198fa205027c3aa", + "0x000000000000000000000000000000214caa5099e30bd4a4e7c1e951df172823", + "0x000000000000000000000000000000000010d4ddfb284638abb946bb5ea54ce8", + "0x000000000000000000000000000000b8eccfd963140d75ef69510d499e067c38", + "0x000000000000000000000000000000000022601a5ccbb6f31253dfb90449ea30", + "0x000000000000000000000000000000e62806cc11817d65af2ca51f43374683d9", + "0x0000000000000000000000000000000000217caebd3a47049f39f536f74363dd", + "0x0000000000000000000000000000008675da1f10d0a3ac0694740302e4c151d9", + "0x0000000000000000000000000000000000063c9ac7b0c51b14ea568b914ddb81", + "0x000000000000000000000000000000c849ad93ed5bb6e903001c8afc4d0839cf", + "0x00000000000000000000000000000000000a6b6070a20448dcdfa172b42f4ec2", + "0x000000000000000000000000000000d868ec79d642032bfcb95ae042b6f1ac2f", + "0x000000000000000000000000000000000020a1badffea327b0c2382295e2bf37", + "0x00000000000000000000000000000096a76c0e5d034f551c375f3e163cda5ba5", + "0x000000000000000000000000000000000004377ed9eb4ad9a1f79a2c5f294687", + "0x00000000000000000000000000000026c41b380a9fe2218f43552af149474957", + "0x00000000000000000000000000000000000615923fe00c15504bb1df8742dea4", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x00000000000000000000000000000009f6c6c04f9663d4a48f223d1249b2be6a", + "0x00000000000000000000000000000000002ff1eba1b37fdea02479c1e08d4d9a", + "0x00000000000000000000000000000048eacfade5f40fa7633579d12282f34788", + "0x00000000000000000000000000000000000c1d432a61ced2e150052be1bdcbdc", + "0x000000000000000000000000000000fbb81a2a7bfda945d91e8bbf67859e2558", + "0x00000000000000000000000000000000000c5cf53ad125e9e20a43f4ba1b49e3", + "0x000000000000000000000000000000253f23492f5e66c4a71242b6065814d6be", + "0x000000000000000000000000000000000023aed5cc445240ea7e33642f388c0f", + "0x0000000000000000000000000000004e7b1102cb6629ce1c142b72b28d4121ec", + "0x00000000000000000000000000000000000be005e3dd35052d36f1618a30871c", + "0x000000000000000000000000000000d90c80545e6168100c5b30f2cd3ed03619", + "0x000000000000000000000000000000000025a3812bfb861f4f004b772688f421", + "0x0000000000000000000000000000008e81605a5541040e1f2ec3750c9cc1ad91", + "0x000000000000000000000000000000000022e98685d97495dd44d59443a4ddf7", + "0x000000000000000000000000000000bc71506d95e3eb7ccfc3f274c99ff4b4a7", + "0x0000000000000000000000000000000000164b75e08b8d331120c23eadfca1e2", + "0x000000000000000000000000000000d4cdc90349d20a48a3e8ca44261cc4d5d9", + "0x00000000000000000000000000000000002ca5fac829cab6e119a24a7549cbdd", + "0x0000000000000000000000000000001887ff5bf46b7fefa8e7e305115c8ecb82", + "0x0000000000000000000000000000000000246f6db366525ceafcc2bd631bcdda", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000cd0ea7c07146a4f133bec5927e060bc57", + "0x000000000000000000000000000000000008366b1a0b90d771f72558197500b0", + "0x000000000000000000000000000000511886d35341446044afbc3f131db62ef7", + "0x000000000000000000000000000000000018ed754624197b0ade7b09f979f764", + "0x0000000000000000000000000000002ddab298f8f8f4e5601e3e5b2d0502f5b4", + "0x000000000000000000000000000000000019aaba272386a074151b33e7573b7a", + "0x000000000000000000000000000000526847ceeeeabd41693ed875f287c0172a", + "0x00000000000000000000000000000000000a6ab59df9f9f596112cc75e7ad0e1", + "0x000000000000000000000000000000c7dcabda3081bd36cd3728c290d35f049a", + "0x00000000000000000000000000000000002f5adb48cf156083022ff35b8dea57", + "0x000000000000000000000000000000100d5b11bbd6a432f89a7661ee462f4fd0", + "0x00000000000000000000000000000000000a6db230819796b38024f7ac3652af", + "0x000000000000000000000000000000faf8c3a8115abf040a7987e13562d25823", + "0x00000000000000000000000000000000000766baad18942e49b8513a2598f024", + "0x00000000000000000000000000000065343c030b950f495ef279c3ae6fa8cf8e", + "0x0000000000000000000000000000000000004195275abab416e6285e7fef5c42", + "0x000000000000000000000000000000a4d73493608bf60776185cb54569d37884", + "0x00000000000000000000000000000000000d2294694cde8c2b80f26954c9654c", + "0x0000000000000000000000000000002c883362a20769983f3001e037dadf85aa", + "0x0000000000000000000000000000000000305e619e436bc34d062dd828db185e", + "0x0000000000000000000000000000001a24b6aca234e5b59fee9c5f5799bca8c8", + "0x0000000000000000000000000000000000263d9ec2c0e4fd83010bcf422e073a", + "0x000000000000000000000000000000d5a18905211738ce550bd5df1e6f651e6b", + "0x000000000000000000000000000000000006849a1a5a4ae4bd50b85f57b79ff3", + "0x0000000000000000000000000000007085114bdad689e95391baa4e1199ceb32", + "0x000000000000000000000000000000000016d5d494b1c50f319e77e3be309979", + "0x000000000000000000000000000000258d56a0e151bf30b8744bb9401e8d8e8a", + "0x0000000000000000000000000000000000050dde6b5d9c72348fa2f2095e5ee8", + "0x000000000000000000000000000000676b88185357d24cb206fc939d7a7b13eb", + "0x0000000000000000000000000000000000242d174d168d7f057cc67a38cd4554", + "0x000000000000000000000000000000c9247a8333e75b895693b3a746f9c0fe63", + "0x000000000000000000000000000000000016f81cfda626001669e616e793146c", + "0x000000000000000000000000000000082e949fec7d6423b2c0fb406b2cee538e", + "0x0000000000000000000000000000000000089fd3f1823232561b1b9247fec27b", + "0x0000000000000000000000000000001b70523f6729991b2187b0c6fd61bac5a8", + "0x00000000000000000000000000000000001a1036f5381975fa25b6c7d78cd3d3", + "0x0000000000000000000000000000007b21e17d5b6e5851a9e14e08561b54647b", + "0x000000000000000000000000000000000013f459b5b6220fd49e4b86fa2cf759", + "0x0000000000000000000000000000000abe91579c6b726e246955c9d64a21109b", + "0x00000000000000000000000000000000001318f7e0b6149e80d854e0f175357e", + "0x0000000000000000000000000000004a33bf4661d63052dd2a8aba3a2ca31c6f", + "0x000000000000000000000000000000000018e73a3b131452a25fd8eba6d9bf11", + "0x000000000000000000000000000000b2f9e03f56e553b01741e7797773b63ae0", + "0x00000000000000000000000000000000000e0e1faf47f04536946ea7f4b9add9", + "0x000000000000000000000000000000d4801c1612d60931ff9acaf1c4e3da5f11", + "0x000000000000000000000000000000000024fdcc1a51fe3ff2087b655b20caf5", + "0x0000000000000000000000000000004cbf700c9e4dffe3436c402ef2763a9d82", + "0x00000000000000000000000000000000001ad39a65f5e94beb8f4aa4a4eb72e5", + "0x000000000000000000000000000000ae5f6f0773eea4e72673c43f98f59c77bc", + "0x000000000000000000000000000000000017e6d8fba023937a7c9dcc496f97cb", + "0x0000000000000000000000000000007de8ad390b0d705cd3935bd3b0ab7b4702", + "0x000000000000000000000000000000000020f6d9c94dfee2edb5ffdc6d73a9cb", + "0x00000000000000000000000000000009b9e999e33b4eefa6bf7f32ec014cf07d", + "0x00000000000000000000000000000000000b19c397850a390fae5e2aae8478b7", + "0x0000000000000000000000000000008018e7399b887105f9b220042a598cb537", + "0x00000000000000000000000000000000000dfc609597d01c19940874c4f45ea8", + "0x0000000000000000000000000000007b51a05d7a2c5523f0231f4b47d6602cb0", + "0x000000000000000000000000000000000012d37368bab765c45e538db3ba336b", + "0x0000000000000000000000000000003425dcfe2083a93586c7d4ab95ea10bfc5", + "0x00000000000000000000000000000000002c4225a6d08ba0bc43964a7b93a360", + "0x000000000000000000000000000000141e28a99bfffc1133051bda380a6a2492", + "0x00000000000000000000000000000000000a67f6456af27a15c4cc7bd3cfa3d3", + "0x00000000000000000000000000000078ef6f7fe4e465da00834b45dfdd49d921", + "0x00000000000000000000000000000000002ed6911e528e948d8e9dd33c411ad4", + "0x0000000000000000000000000000004021a31886522f571c4105a3493d4902f5", + "0x00000000000000000000000000000000002c5d54fd117985469cae7c46f00bd2", + "0x0000000000000000000000000000009f4db1d104e923ee0be0180b9481ad7353", + "0x00000000000000000000000000000000001d80d0ccf52aba1ca04d3d93b7465a", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000339b9ff46aac534bec7cbabf748cc261bb", + "0x00000000000000000000000000000000001a79a371ba6e290aae903c62d93d38", + "0x000000000000000000000000000000e8ba9f98cbba842d599752ff3bdb58a1dc", + "0x00000000000000000000000000000000002060d719336689061cd0e72794e35f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x103b5b395e745292eb788f93c2f8700433cdf9b3113e086984e70fd6df2b932b" + +[private_call_1.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_1.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x011238ee64b18828d55242673008fae81f12fc8d61617d35f910c8cb0683f665", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_1.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_1.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_1.verification_key_hints.salted_initialization_hash] + inner = "0x18f60f80bfefaaf0fae5a0505bc6ae3d0240a1bd010a0bc3fe55c20a05c924de" + + [private_call_1.verification_key_hints.updated_class_id_witness] + leaf_index = "134" + sibling_path = [ + "0x04faeb1fbcaba22bb78f190827a5dd614409f548340279badeb318d58f40c003", + "0x22f1b4d319f851468b77a99c6bde547499fc0dafc3676279d0724f0cff0186a2", + "0x02863b9ba1de6f80706d154369db20f4660240d04c2588e80259928737caa007", + "0x072c485f46fea63147c965f3bf2ae2a16a6cef7035c1a8140796c225f7b502b2", + "0x1d52af9cd9f69c1286e9a96fd498e736789a5bc463fceb1c176a4f9292f7cbe3", + "0x1ff1d5db01572c915915a22173c73d8073df9af4e4c57f6af29df5315da44419", + "0x070dcbac794fa663bc71b42d80775c0cea8c3ed7580207cfd30fd1285813ce07", + "0x23133cdd5344591bc2ab830355d7972651d536892416317c4f6ceef63e4eb068", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_1.verification_key_hints.updated_class_id_leaf] + slot = "0x00636bd5b0883a2a1830afcbc6b4b41d16f9639ece8274acc27154705f3b8276" + value = "0x0000000000000000000000000000000000000000000000000000000000000012" + next_slot = "0x01a19f390779d3a125f11b7c60ce770979b067defbc52b8f0f898bbbc3454c6f" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000080" + +[app_public_inputs_0] +args_hash = "0x02486714bcf7b63435b8818a646f5124643019b4d7a09497d20cca8d58ae946d" +returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000002" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" +is_fee_payer = true +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d77eb" + + [app_public_inputs_0.call_context] + is_static_call = false + + [app_public_inputs_0.call_context.msg_sender] + inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + + [app_public_inputs_0.call_context.contract_address] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" + + [app_public_inputs_0.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x2dd746d2f347ebd8d2f591aaf062159b2cceeadb449a919ada77febe9b940e78" +counter = "0x0000000000000000000000000000000000000000000000000000000000000003" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x20f721110cd2674df07fe76cb6f6d43b9704d876ec3a63e8213ccc98a791d3b9" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0603f2bc643a4bf06692b6ea01af9cc928ebf24c8b9f8f359afdc60db9d40e3c" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000000cca003a" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header] + sponge_blob_hash = "0x2f558adc653a6a683f54170a4e3dae8e0d4ba2c84cd9f344d503fe330cb35e31" + total_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + total_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" + + [app_public_inputs_0.anchor_block_header.last_archive] + root = "0x10be4ebc997dc24abc6485ffe1083eece538d2c803bdbbf84a57eb22b99f4e0d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + +[app_public_inputs_0.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" + +[app_public_inputs_0.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_0.anchor_block_header.state.partial.nullifier_tree] +root = "0x2dd3f55fc629452f3b9e9af072058cbb8cdac165fe9b362ccaed7a6ca31fc22e" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" + +[app_public_inputs_0.anchor_block_header.state.partial.public_data_tree] +root = "0x230f9d4acea01315bfa2dd1733846f3f5c6a2e24f73d2c502cac359cb4a64c05" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_0.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c266b" + + [app_public_inputs_0.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_0.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_0.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_0.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_0.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_0.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_0.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1] +args_hash = "0x20f721110cd2674df07fe76cb6f6d43b9704d876ec3a63e8213ccc98a791d3b9" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" +end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000007" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d77eb" + + [app_public_inputs_1.call_context] + is_static_call = false + + [app_public_inputs_1.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_1.call_context.contract_address] + inner = "0x0603f2bc643a4bf06692b6ea01af9cc928ebf24c8b9f8f359afdc60db9d40e3c" + + [app_public_inputs_1.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000000cca003a" + + [app_public_inputs_1.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x187e53c08c6177e7be8e18cd1511a7b02fac95d620a7349072f8c986b4aa193c" + counter = "0x0000000000000000000000000000000000000000000000000000000000000007" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000007" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x27f7908974fa11bc63765f7a1b114d07d9ad578813f4d0bd17d9813ca6b27d7e", + "0x2b4f001ce369a77d37023f59330365467ee04d275c895aedb8694611542d94d9", + "0x08ab102205d6d7cdc51b690d90dbaeae75deee6f290cfd0f16d4f5f76c6c107b", + "0x075fe0ac96f29e3c3fddb3ae675d0b61832a9312d86bc21d7ddd178f2fe7a18b", + "0x1a8d36da37286095e016128c77667d821885a35c428c2a5a8d3d7027613d63b2", + "0x0c2abcb09984b5ac2ff447fb27c9d44680d2d1a7f388309464fd86e54c12096e", + "0x021d186c82a2da8eda6c7dd59d9f5077f63945e66c22a6fdce79703ef90ed0e5", + "0x232182781c34950c9a3d0b394017d4656a64b90b58cf0e6b994573576180df46", + "0x132bd5a7c2d3ca8a3257057b54c8c37152ee21c6c1365b1b9710198ed5212f92", + "0x147ccd354ce72dda084dbb9dc934bc12df8e572aafd7d5ac5a4465bd7b9129eb", + "0x0f1fe8876cf409abae1e327fb730f9b5aa06290c89efb0e95d3eee9c30c8d6fe", + "0x011da20d31c9ab9a33f3c961f804ebfee1d16fb1fbacc4b5a6a84cdc9f976433", + "0x00504bd1efa46596911c37ebd9be8fb98c8061008af020d503b7cb145229aa0b", + "0x1dca533ae55a689ce6546d8e3bc1e37f1db389ddc02fc8819c1db3d2157891e7", + "0x0d7510b19f7d59fc1c93dd530a39b8c5d435c788f840e11d93a55ef03a281009", + "0x1961fbc5069d8d9c5da1d25951827876da2fa0e58de781dc30b3f5da5d9e6621" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000010" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header] + sponge_blob_hash = "0x2f558adc653a6a683f54170a4e3dae8e0d4ba2c84cd9f344d503fe330cb35e31" + total_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + total_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" + + [app_public_inputs_1.anchor_block_header.last_archive] + root = "0x10be4ebc997dc24abc6485ffe1083eece538d2c803bdbbf84a57eb22b99f4e0d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + +[app_public_inputs_1.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" + +[app_public_inputs_1.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_1.anchor_block_header.state.partial.nullifier_tree] +root = "0x2dd3f55fc629452f3b9e9af072058cbb8cdac165fe9b362ccaed7a6ca31fc22e" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" + +[app_public_inputs_1.anchor_block_header.state.partial.public_data_tree] +root = "0x230f9d4acea01315bfa2dd1733846f3f5c6a2e24f73d2c502cac359cb4a64c05" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_1.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c266b" + + [app_public_inputs_1.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_1.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_1.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_1.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_1.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_1.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_1.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-3/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-3/Prover.toml new file mode 100644 index 000000000000..19c3001432f0 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-3/Prover.toml @@ -0,0 +1,5989 @@ +vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" +is_private_only = true +first_nullifier_hint = "0x0376cca63c52eaa5f415738d2b371223600cabef83495b4c6a9e0c3c0a647a3d" +revertible_counter_hint = "0x0000000000000000000000000000000000000000000000000000000000000005" + +[tx_request] +args_hash = "0x0e4a049212502ddf801e6de7e638cc14cfa74a583afb5b0112958f1f263384b0" +salt = "0x1a2fd2df752551a143f27fc16a54deac89bfe6f0a31f8ccf68a1ca86369e72eb" + + [tx_request.origin] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [tx_request.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[tx_request.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[tx_request.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[tx_request.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" + +[tx_request.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [tx_request.function_data] + is_private = true + + [tx_request.function_data.selector] + inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" + +[[protocol_contracts.derived_addresses]] +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" + +[[protocol_contracts.derived_addresses]] +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" + +[[protocol_contracts.derived_addresses]] +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" + +[[protocol_contracts.derived_addresses]] +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" + +[[protocol_contracts.derived_addresses]] +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" + +[[protocol_contracts.derived_addresses]] +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[private_call_0.vk] +key = [ + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000b61", + "0x0000000000000000000000000000007b6222b3a18551d60b847957202de6c8f5", + "0x00000000000000000000000000000000001e26b96548b9f12369e9c3ec0eee85", + "0x000000000000000000000000000000025aac0bbaf1beff1c0500e3ec38d34c8a", + "0x00000000000000000000000000000000002c498aff2f95b25bb92e2c9360aff5", + "0x00000000000000000000000000000039d32590e9d6e0be118712b9402c606156", + "0x000000000000000000000000000000000026588627e22f203f6399975fb67258", + "0x000000000000000000000000000000097282335613efda63abaeaddc915f44db", + "0x000000000000000000000000000000000021b51f545ea031ad8c826962f52545", + "0x00000000000000000000000000000035a0536197418c2ba2c29a1830f709420c", + "0x000000000000000000000000000000000020f8cabd08dfc29e045e0b80eb42d3", + "0x00000000000000000000000000000099e53cda88a63b8e751a2bc253f7a689a7", + "0x0000000000000000000000000000000000231a514e7a4dd0e23c4faf8d567c77", + "0x0000000000000000000000000000002dac12ff4e48e530611ceb7a400c099e4a", + "0x00000000000000000000000000000000001ad1cb6dbbe8ea3dd6c4f44ffdce56", + "0x000000000000000000000000000000dfd19e74f4e4c641b3b3f623825ccd495f", + "0x00000000000000000000000000000000000ce4453cef94251418336baa54e582", + "0x0000000000000000000000000000007ad93fd648d3587168e2ba9ee66dbbf918", + "0x00000000000000000000000000000000000a7680894366d3b1755d14152e528e", + "0x00000000000000000000000000000008bf43eecffcec9e31d916289a212b8f88", + "0x0000000000000000000000000000000000216620e5bd7b177f3fa15ceeb2526e", + "0x00000000000000000000000000000021db86993540e76c420c850640a25f7d94", + "0x000000000000000000000000000000000017418ee5d4d58a54e7728b755757a8", + "0x0000000000000000000000000000000cf5f978296643872c59d00be3c23ad68d", + "0x000000000000000000000000000000000013e45088158c3bf8ac1f8e71eec154", + "0x000000000000000000000000000000768cc857ea136153788ffa81c07daddaf2", + "0x000000000000000000000000000000000014b992148ee6906cb3a1989f3c4bb1", + "0x0000000000000000000000000000000127e074cd6ea24f75f86f3ab119f9ae5d", + "0x00000000000000000000000000000000001719d1f7fc4645193b8036cf9a3d52", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x000000000000000000000000000000622ac3715a21583a169b4c635c162bdc13", + "0x000000000000000000000000000000000012374104ee9056dfafba40f457c0a8", + "0x000000000000000000000000000000f6c09b75f7561f7fbbd272af5d3efa974b", + "0x00000000000000000000000000000000000e0a7bd7a377bca3ff6c89d68a3e5e", + "0x0000000000000000000000000000009d165e9a47e021ab9760d27339570655e5", + "0x0000000000000000000000000000000000000b204b0dc1f11b52bb345fb52145", + "0x000000000000000000000000000000d4c558b53b27cb4c171f8a5eb0bd1e3a2c", + "0x00000000000000000000000000000000002f6870272192d541c1b8887b15a95a", + "0x0000000000000000000000000000008f4c64ade1e7b515b074c100d489415d4c", + "0x00000000000000000000000000000000000f9aca92beccde2e1b08c99ab92a6c", + "0x0000000000000000000000000000008be6976e9870523051d19531843262ce4c", + "0x0000000000000000000000000000000000277419877e0ba35217f219676b5656", + "0x00000000000000000000000000000051ec180d05026f2f62b1674ca2e1a2c142", + "0x000000000000000000000000000000000022264cbd2ea66b7766612864c5108c", + "0x000000000000000000000000000000f137ae2b224915db0c43de1611134011d0", + "0x000000000000000000000000000000000011877af1a2b9b35d6ac04c489fe3ba", + "0x000000000000000000000000000000935ae3a5a2c4a7aad8e94a7cf1c4bec70e", + "0x00000000000000000000000000000000002a56488e09fd406c14aca4acf2b4c3", + "0x000000000000000000000000000000e770a6c5c0093eb5de2e5aa8d173e9ef05", + "0x000000000000000000000000000000000005522908d6e06b02d6938a789bb5c9", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000b139df614924ddb845d70d642d94873569", + "0x00000000000000000000000000000000000084d02351f0d2b405f3af6092edc0", + "0x0000000000000000000000000000006c1123c8d14bdfbfa99f95d1fd0d9674f7", + "0x00000000000000000000000000000000002be519d31aea4dac51b16b3655b459", + "0x00000000000000000000000000000035b52a2f19454b2d02086d012cfc44cbdb", + "0x000000000000000000000000000000000027f3e1c4d5482e3b1ebcbc5e43d1d2", + "0x000000000000000000000000000000bc81f2a307249de2d56c3c8151aa3a4179", + "0x000000000000000000000000000000000014745d0c8957b03309ffd69c523944", + "0x000000000000000000000000000000d90966909da4a8611a68a5b2544044ee27", + "0x00000000000000000000000000000000002dda368cf4f8ae011ba33953ccdbdc", + "0x00000000000000000000000000000099fd8e2a4efaa0e979e53c6360f11a3520", + "0x000000000000000000000000000000000029023563407bf604b94f3d3b82e32c", + "0x00000000000000000000000000000095ced0bf10b79aec2651f808812961ce57", + "0x0000000000000000000000000000000000204601f003e0e59d1865597a5cdcd4", + "0x000000000000000000000000000000fd07b0a28f8510ae42eefbbd2d0136dc4f", + "0x00000000000000000000000000000000001e3aba113eb2b6e0d9a07cb16188c0", + "0x0000000000000000000000000000004496315acb001bd07077d5e61a5fd28f1b", + "0x00000000000000000000000000000000001a39ca40a2fdca943fd7c57ea59fc9", + "0x0000000000000000000000000000001a6e9238224f825fbe059c173514ee0fe7", + "0x000000000000000000000000000000000022f701f63bad50d3161322f8d104b3", + "0x000000000000000000000000000000e7cb0e4c388d5b2b1350a0c1b259d7c4aa", + "0x0000000000000000000000000000000000216c09ccaf44298565b3e593e3a7bd", + "0x000000000000000000000000000000d840ba780d73076cfaadb07a9a1a2cad8b", + "0x00000000000000000000000000000000002a887121806c1166b16f3aa9de6716", + "0x0000000000000000000000000000000e3b5cb0fc3e09ea8b4059e2a6109ff857", + "0x00000000000000000000000000000000001794754a1a61af4fa7976eefdac79e", + "0x000000000000000000000000000000dfef9deedb32693d7cc279f72cdc785d1e", + "0x00000000000000000000000000000000000e55622ad6ca63ffde7f64ed504b16", + "0x000000000000000000000000000000d08df7bdd8d57cb1d65728efccbbfcf607", + "0x000000000000000000000000000000000005f2689ecd1c3bf58c28357d95d48a", + "0x0000000000000000000000000000002d7d2927cc7e65b41792f5745ba169663e", + "0x00000000000000000000000000000000002b5f2432471d8c12ea391ac1a0bd12", + "0x000000000000000000000000000000773d8fd379e59dbcbab02af010d195c779", + "0x000000000000000000000000000000000008826f48f7b0250873af38fa8f7500", + "0x0000000000000000000000000000006165595d9a271241c16e0472c174fba8f8", + "0x00000000000000000000000000000000001c673e22bf04c83bddc2f02ebaae36", + "0x0000000000000000000000000000008d6afb067ac5198bb372113d34c56552fa", + "0x00000000000000000000000000000000001e08cbe1d21feee99c841191e54333", + "0x0000000000000000000000000000007646a1a3ca480b5d7322e5e4bb688049f7", + "0x0000000000000000000000000000000000269f2465562733cff2488fe75060fe", + "0x0000000000000000000000000000005524b80d26a1d910532fda24c2383f979b", + "0x000000000000000000000000000000000023bf14a9a6153ade3200bcc787ba79", + "0x00000000000000000000000000000038d56d2f4e530f74fb02bb70d781488b16", + "0x00000000000000000000000000000000001d1731444ac607cb0623133a479871", + "0x000000000000000000000000000000fe08dc45003f859a25494ba5135502e42f", + "0x00000000000000000000000000000000001e6d7c5b53a5e88d78640651a5c6a0", + "0x000000000000000000000000000000ddf4dedac0a43ba687e608b3e6081b8546", + "0x000000000000000000000000000000000004c2446dcf61c32ba4b038fe7365fb", + "0x0000000000000000000000000000004557b361ff0d6568e896319c496fbe24b8", + "0x00000000000000000000000000000000000668a26f50d3354953d4b2766e8020", + "0x000000000000000000000000000000ea507b90f982c43d39d3f699d22b1f7c4a", + "0x00000000000000000000000000000000001429723650e7543325ff8bef1c4ffd", + "0x00000000000000000000000000000049c19043bd4f1ef29d5413b1f118d0f722", + "0x00000000000000000000000000000000001d7ad7b3a27a9bc7992d806af0ebc9", + "0x000000000000000000000000000000f291d1109ea1f48586582a3767b0392cbe", + "0x0000000000000000000000000000000000026df82a517f9dabb3c389c07aebc7", + "0x0000000000000000000000000000000999c4e1d13eba177baf97921ee863ca58", + "0x000000000000000000000000000000000002f7f537a4f96f2ca4eb19a57f0b9f", + "0x000000000000000000000000000000dea34b6c529204f209cd1420a81a3102bb", + "0x00000000000000000000000000000000001c53a430fcbd4b95ffc23b6461fa15", + "0x0000000000000000000000000000005c0cab22cbb5bdccf85116184958790eb4", + "0x00000000000000000000000000000000001b715af5e709bb9f06822082ee3120", + "0x000000000000000000000000000000c77eaa3f49d17dfe395648540f4cd0abc6", + "0x000000000000000000000000000000000007df3cadf5a234989c3f0b92052395", + "0x0000000000000000000000000000009c11b61aaa7a95751ddef148053d00a6e7", + "0x00000000000000000000000000000000000f65d42148106db82a9e434cb19459", + "0x000000000000000000000000000000f99b662c4e3bcd3fdffb75cad5deb632e6", + "0x0000000000000000000000000000000000284f78ec2bc1c17ffa75e285ad4529", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000059a5cd5c1c2d2e7cac107aaf0123ae4f84", + "0x0000000000000000000000000000000000170ffa45422a2680cd492bad46789d", + "0x0000000000000000000000000000003c91ea4fe538abe3c344c3603398af1cbc", + "0x0000000000000000000000000000000000295e7a3f8df6111a6bd51041d5179b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x11197593d62d0e7554158b832253460bcc00da8b6551eb5d955ef72444d95a3f" + +[private_call_0.verification_key_hints] +contract_class_artifact_hash = "0x1d9e0e30582ed207c6ba761454f1f542d807eb0a2b35a50b23297a6db34e3680" +contract_class_public_bytecode_commitment = "0x0ce4c618c3ed7f3a20410e618c06bb701e150af7fe28a3e92f68e7733809f33e" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_0.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x2cc233639ce62adaea3ec034abce91a0b008ca3b50da04eb0789bf1f438162ea", + "0x0f60b735d348fd08a8da88fe4b04361698e2bca73fbebb6cc1fdcb86a4d03c89", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_0.verification_key_hints.public_keys] + npk_m_hash = "0x2f1c4d79837ad500ede908112d4cc2af5d3af9fe982b8628035ccc97f15ee24c" + ovpk_m_hash = "0x1378ed60b21b30e7ad5260606275cd3b580932cef2ed8e95dcc953334277d28f" + tpk_m_hash = "0x25aed22eebf640703b2a68bc209562e3f5c5dadd47925e0bdd41df5e2102fb98" + +[private_call_0.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x17e45034ac640fd73c526836d47063c3158695ecd39fe841bd338ad7acf9f238" +y = "0x2b6dff182f1d814024994bce38d73c4ac9f7587b5e90b8351b08d65e1ed2a7ea" +is_infinite = false + + [private_call_0.verification_key_hints.salted_initialization_hash] + inner = "0x2de7750983e40a640c1540354955cbda141ba8ababbbabb93b83843a4a5c9e18" + + [private_call_0.verification_key_hints.updated_class_id_witness] + leaf_index = "123" + sibling_path = [ + "0x2848a1d7320b3bfb616ba2ff5b175f3dbbe07753e40389d913e60089060bca9e", + "0x0575020764758ac1e237d111ad2129b58c276979d075a2617d047edf1fa0af80", + "0x197c46bd1868465bea0e1ca4eb0c791d4d43dcfa5ec01979117a2d968636c8f1", + "0x13981cd7447462f1010ec3a2725d09dd4fad76d010fbc2cb1e6eaaf93f680abc", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x02c691e1474ab605965337b84f97e9ac2a34e1214040cf86d9e229f08f4494d5", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_0.verification_key_hints.updated_class_id_leaf] + slot = "0x1f29d351ad8d747c09020ea47be7a38833dccaaf378b55d7d8e6e79f1892c1a3" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x2511fb7ac309f6693b0411aac44ee65c49b46b778d669ad0a19168cc49f93d57" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000082" + +[private_call_1.vk] +key = [ + "0x0000000000000000000000000000000000000000000000000000000000000012", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000d78842d18da378b75ea5ecba09e24ba714", + "0x00000000000000000000000000000000002614d3b3afd5c98cc271bb129aa4bb", + "0x000000000000000000000000000000dcb5d6e5f2dc6a6dafbac3d99e47a24119", + "0x0000000000000000000000000000000000175d55301ed1c5b1c62da959d3fc6f", + "0x0000000000000000000000000000009ee8ccc66f353c3e7bdcd350ac4998dc90", + "0x00000000000000000000000000000000001fa45e6bb1b43b70150d132ad729b3", + "0x000000000000000000000000000000d9f8955545361a6a22980bc0f7b651d7f1", + "0x0000000000000000000000000000000000274fa1311795d3fb681f38da2f4b5e", + "0x00000000000000000000000000000091be5017efe75c83eda91ec4bd1b42baf8", + "0x00000000000000000000000000000000001e1320cf89e65f8059750bd3e6b9de", + "0x000000000000000000000000000000b0e3421324eb3d1e8d315e02dd5e3bb069", + "0x000000000000000000000000000000000020b7707896a1118a547874cd3d80f6", + "0x0000000000000000000000000000005aef4684fb42d4e382c97c38cfd4b843e2", + "0x00000000000000000000000000000000002dc76f6be8447d41aeeb5f8fbe56ce", + "0x000000000000000000000000000000291eaf624ea58ac49bb2966a00767c1bee", + "0x0000000000000000000000000000000000061c5512bff8ca586035bc8c7ccb29", + "0x0000000000000000000000000000005a2c1a95ca457f8a3e52ef27330df96092", + "0x00000000000000000000000000000000001b500485cff873b5722090a4fd39bc", + "0x00000000000000000000000000000045cfcb9dba052df46fd0909a62c7f83a85", + "0x000000000000000000000000000000000013d8218b28b1cefe69df2445eee754", + "0x0000000000000000000000000000004256d472632ec7880e32b87785d837de9b", + "0x000000000000000000000000000000000024fcaff42d72e45ec189cc0b090c08", + "0x000000000000000000000000000000a5998134f404e813099347fbc65e520ffb", + "0x00000000000000000000000000000000002e84db533ec72a5aed8e08c5bb2e4c", + "0x0000000000000000000000000000002c8af6b50cb7b3a1b5c9f42321383ac95f", + "0x00000000000000000000000000000000001b77619171b002d76b7d7084c0c4a3", + "0x0000000000000000000000000000001f74c98dd4249922d3882988a92d23f0a2", + "0x00000000000000000000000000000000001c0b2de307a80de2addfd628a37371", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000009294bfa73402e7d7f181253c64739c4e57", + "0x000000000000000000000000000000000012eb8c51856dd3dac0290a2cf2f2ac", + "0x0000000000000000000000000000003652676c6f29515781b4f2e9107a3ad802", + "0x00000000000000000000000000000000002358ca9e65f12e25d9269a3daa3867", + "0x00000000000000000000000000000010132bea790e06b24ec62c94c9739bf7fc", + "0x00000000000000000000000000000000000b5413bcabe6b86f13aa5e58caefc8", + "0x000000000000000000000000000000f3237b868b577980a9e8c5bfe705c02b3f", + "0x00000000000000000000000000000000001713038b46367ec42e6e3f890c5c9c", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000235c9995c3bdb6ab05bfca8c4049d2c847", + "0x00000000000000000000000000000000000afc8fc26b080a90461cbe02e9a6d0", + "0x000000000000000000000000000000173de4469e782937b09e8dcd77b50d1704", + "0x00000000000000000000000000000000000720f74870fef7ce9c03a59b27c7c7", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000009be835eed95bf0cc42300a68f5358b9bb2", + "0x00000000000000000000000000000000001f34644d7229734b59b90f401278a6", + "0x000000000000000000000000000000e4bb4606126464c38ce411a355feefe834", + "0x0000000000000000000000000000000000090cff50304d6d56f40552fe8fbc43", + "0x000000000000000000000000000000878f9b15b540d6b97936ff6f7fcbc40369", + "0x00000000000000000000000000000000000107632f87301cfc69893652ebff38", + "0x0000000000000000000000000000008b441474e5363738eedbe070487f6777b9", + "0x00000000000000000000000000000000002797248ef1768570cf11bd6c3f2cd5", + "0x00000000000000000000000000000082ead96c117b51634c284d114f577257f4", + "0x0000000000000000000000000000000000147cc59c4e253f962c751eea2813a6", + "0x000000000000000000000000000000d456e249e3d9448cbdcdacd2a882671f52", + "0x00000000000000000000000000000000002981e0bdcc199c7d64806f20b36fa0", + "0x000000000000000000000000000000abfc90b4471135ca2ab8ba7c405edbc4e3", + "0x000000000000000000000000000000000023cfe401afd6bbfa4d35b6007170b4", + "0x000000000000000000000000000000c9ce5aded190329ae1a889665442ad7cd9", + "0x00000000000000000000000000000000000d708b930b128365c05717683bb86d", + "0x000000000000000000000000000000b823096a368099e4a5d6862151a7549148", + "0x00000000000000000000000000000000000d503250145a3efda57c6d32a4908a", + "0x000000000000000000000000000000f17e7bf93cfb998cd43bbd2ad3050125b9", + "0x00000000000000000000000000000000000930e7a51e277067f5271e46dc1252", + "0x00000000000000000000000000000038cfe8a840de63616a7362610bd3578168", + "0x00000000000000000000000000000000001c8141e7febc0876e0fe25d2579d62", + "0x000000000000000000000000000000152c755dee390a0c43ebf06a142061bd1e", + "0x00000000000000000000000000000000002c55e5fe44bef19e878f10b91e109d", + "0x000000000000000000000000000000ed38501369c52c2d563fdee920fa81afed", + "0x00000000000000000000000000000000002c0040967b7c6a962ddbb2773e40ac", + "0x0000000000000000000000000000008b720a162b659c1d6b99ff7f5ea1943bf0", + "0x00000000000000000000000000000000002037f64217f765367a73dc8809a402", + "0x000000000000000000000000000000333ce1795d12def27b282c7e9d940377d1", + "0x0000000000000000000000000000000000222e04a026255b1716e250489c02be", + "0x0000000000000000000000000000000fb2c89741afacaee5671840d555ee6200", + "0x00000000000000000000000000000000002b8b656e09e7a782aedb62ab07c4de", + "0x000000000000000000000000000000b8d83eee65d8da3867d44e479895cd3885", + "0x0000000000000000000000000000000000005290388f5c314efc8786ca753020", + "0x000000000000000000000000000000d962ca29ad326f0ca366e48b1094c90ba6", + "0x00000000000000000000000000000000002667dc84b31ddb50e7cbe8117469e1", + "0x000000000000000000000000000000edf193bc38e0bde8a4247cb94aac7c3453", + "0x0000000000000000000000000000000000130e46d1e5b5054183bbf59f75d5f1", + "0x000000000000000000000000000000d76ec7bf0b5b79acbcfa8fdcc4b7e1f43e", + "0x0000000000000000000000000000000000205b8db525acd7ad31210b279cf5aa", + "0x000000000000000000000000000000fa94df30aa6642a201c24b4ff9c513e7b4", + "0x000000000000000000000000000000000020ea9468339e4a650306e096fc7eb8", + "0x000000000000000000000000000000b67f58244f388df32f1c53d4e80d390c72", + "0x00000000000000000000000000000000001566a4116792031cf65c94bdfe703e", + "0x000000000000000000000000000000a6a0281f1c337f8b6e2c2ceb786ee11a82", + "0x00000000000000000000000000000000000921dbb00839427d1bbf18977b5e90", + "0x00000000000000000000000000000031e8e63905e4a45e4933e971d14318e6eb", + "0x00000000000000000000000000000000001e0193b93c681de90ee266c1c96ea9", + "0x0000000000000000000000000000002b5e19e56d15c9e6b6fe9067ee99196975", + "0x00000000000000000000000000000000002ad08af4cdb0b92223ccf588748fa6", + "0x0000000000000000000000000000003e5a1bd944e4c82fa00876f1dab8617c72", + "0x00000000000000000000000000000000001adc187328e0e2842fee7ba44727cc", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000a4bc612c9919e31850cacbdb2c0ebee136", + "0x00000000000000000000000000000000000a68940d7f098fcba91e5d2543efc5", + "0x000000000000000000000000000000c2036981811af6499bb28cf5780bff85a0", + "0x00000000000000000000000000000000001d7867c0364339f803e83b9073fe73", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x1531ed0e20d6d05f1aeb06f746c8c4b8f467174836d6edf915b0c45099b393ed" + +[private_call_1.verification_key_hints] +contract_class_artifact_hash = "0x23e12e098d940ef2795fc61735ed268fdd624134af96a39ec20efd4da8253a5a" +contract_class_public_bytecode_commitment = "0x0ce4c618c3ed7f3a20410e618c06bb701e150af7fe28a3e92f68e7733809f33e" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_1.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x0b63a53787021a4a962a452c2921b3663aff1ffd8d5510540f8e659e782956f1", + "0x1eeeb8fb2c3d5ed2bdeb4545deda4551d41e22e63ebfe4e47e98d83847870dc9", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_1.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_1.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_1.verification_key_hints.salted_initialization_hash] + inner = "0x28acc8124b398dcb4bfe1e23a886d244156df682b7bc2ee00132e80e21ade98d" + + [private_call_1.verification_key_hints.updated_class_id_witness] + leaf_index = "119" + sibling_path = [ + "0x0367624bc197266ce056aec8d19a5f089edceb4f0901727a0b128da357b67e1b", + "0x25e343ef927ea3980db5fdc788830d0b84a1dc80052cfac2dec9f5666716bfe9", + "0x2523970382de270c1acd87f98b4ed454353257f9c689dc608f7dc1b6ca23741a", + "0x06e7dff9596de301b2b1de0d823f50f5d5b7eec918ba502edd702a3b4351da32", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x02c691e1474ab605965337b84f97e9ac2a34e1214040cf86d9e229f08f4494d5", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_1.verification_key_hints.updated_class_id_leaf] + slot = "0x15d83fc6aef4d33787e8b2f45f47282217f56eedafe4c3456f98211053ee38af" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x18d8563211a45773494e257e92d4c8fdac1d0d7d4d533ac158523f4e37744230" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000083" + +[private_call_2.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000939ecc7e0238ba4538d07d06515106b715", + "0x000000000000000000000000000000000027f7faae22e35882db334002325b9a", + "0x0000000000000000000000000000005b7135656f7af02984fc29f460c2a39618", + "0x000000000000000000000000000000000015221e93ac7028e30bbf11170c8af7", + "0x000000000000000000000000000000d725982b5326885c8dbd7db7737acde886", + "0x0000000000000000000000000000000000096c86aff7dc8e83432bf71d155e54", + "0x000000000000000000000000000000b52a552f2377e7ad8de1275a5fab15b09c", + "0x00000000000000000000000000000000002921048ee5922f5021bf3414d233cb", + "0x000000000000000000000000000000c7cf0ad69cb6b47c7f5a005582eb4c0d5c", + "0x0000000000000000000000000000000000088d4215fd4cb39439928a35c36826", + "0x000000000000000000000000000000fa0549dd5c225f4523cd33dfdaa35a6d08", + "0x00000000000000000000000000000000001a5c6875705097231840579a7abe46", + "0x000000000000000000000000000000a53e503273acac0c370811e406798da8cb", + "0x0000000000000000000000000000000000263d9dd6253344f0b0f0d32aebd392", + "0x00000000000000000000000000000077fce21217a229537a0fe2347b7497c667", + "0x00000000000000000000000000000000002bc83252d459bcaa9a65d5f851ebc1", + "0x000000000000000000000000000000582db2c2b5419a8949d4a040faaae2d90c", + "0x0000000000000000000000000000000000272efacb35c7e6ef1b1c87b23b1986", + "0x000000000000000000000000000000c56053e996805d61c3087f426b76d05d91", + "0x00000000000000000000000000000000001a5dde0d931482170055089c35182d", + "0x0000000000000000000000000000005b20c5c214ec1bac8c86b04411d459ec25", + "0x0000000000000000000000000000000000059b95f533b5615af11b06773f3559", + "0x0000000000000000000000000000008ab521c6ee63c1f56d3e0e05cb23080a98", + "0x0000000000000000000000000000000000055c3afbbd2da250ac604a24bb2ef9", + "0x000000000000000000000000000000b02119ad4ce7d63abb9510f1ddff318823", + "0x000000000000000000000000000000000029a492a4d6587d8589814704f58870", + "0x000000000000000000000000000000e7c4b069553db68acdd0c13aec0d682052", + "0x00000000000000000000000000000000000fdedea57a1d5532c8074aa04fa4b1", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000c1324a637ac6aa9cce6d2f9458f6dfb351", + "0x0000000000000000000000000000000000091b6347806ddbaffc97bddc7a30dd", + "0x000000000000000000000000000000fe95016d73b67c279bba4e66e8d9703537", + "0x000000000000000000000000000000000005f0d9f14086df89040735f71fa7b7", + "0x00000000000000000000000000000005efa022dc2e8eb479b2b78d83c8765d5e", + "0x000000000000000000000000000000000018619d74d1bcaa0904107337bd012e", + "0x0000000000000000000000000000007546da679d2f3fa476de4b4caac4f8e720", + "0x0000000000000000000000000000000000022c0dbbf61f2b793f2d7e1a14f7ea", + "0x000000000000000000000000000000377837418627c78b9c5581cc090fa58e38", + "0x00000000000000000000000000000000001382a8f9f8f16c26c6fb5623a58a6e", + "0x0000000000000000000000000000000e6b1306d2ee4c0e782f794233e8cbef0e", + "0x000000000000000000000000000000000015b08ca4c24b72dce50f64314d5da9", + "0x0000000000000000000000000000008cb1ed0e54e2be1b693e7930db7cb80ab3", + "0x0000000000000000000000000000000000239d76e639d9cdf7dfabf6c51f899c", + "0x0000000000000000000000000000000ae1f82ad50cbd733f08e432946514a350", + "0x0000000000000000000000000000000000295d7b2a57a16c715033860938fd50", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e24abed3d841d011ef73411a094875efcb", + "0x0000000000000000000000000000000000214dda13d13241bacb5802308722ac", + "0x000000000000000000000000000000e199a3fb1785a3aec260f70f8e375a1a2b", + "0x0000000000000000000000000000000000069692a44d75d315feef84b77236e2", + "0x000000000000000000000000000000f14079d90bffc6fbec385022d0458981ad", + "0x0000000000000000000000000000000000061e4d15aea9c20c425c89f3f2fb4d", + "0x000000000000000000000000000000bc69945a1c97d6970f8069c46e47282b46", + "0x00000000000000000000000000000000002756f7fde3edd1c8f306f63df0237c", + "0x0000000000000000000000000000003697ab9c36685cc97805a81d7d2c9135b6", + "0x00000000000000000000000000000000002dfe72fbb64b8bf80041637521df7f", + "0x000000000000000000000000000000ba93cf80ee63038d9cbb53e8028c2171b2", + "0x00000000000000000000000000000000000d1cfd416d77e90cebf25b135b75c7", + "0x000000000000000000000000000000b8d64485c600b5bdc5aeaf70405edf46a8", + "0x0000000000000000000000000000000000211e94dafb97ac2bf1fc042e75e30e", + "0x0000000000000000000000000000007b3535533bf23ebc5e93f72f3178e40167", + "0x00000000000000000000000000000000000297f06e65bd27d0af59e48e282d13", + "0x000000000000000000000000000000e1575bec02ddb89a48eb03929177e08295", + "0x0000000000000000000000000000000000129d4383c4e0b52d70655b8f6dd3c1", + "0x000000000000000000000000000000c20bd4ea75f38d2e6b41161274a4a9bff9", + "0x00000000000000000000000000000000000d10237adc48d09824b74c0bf30af8", + "0x0000000000000000000000000000005bc3d742bc3521ee9bfd22eca4fe041d4f", + "0x00000000000000000000000000000000000dd34305439efd31d8f1069f2f1298", + "0x000000000000000000000000000000724a171fe6ee9412cdc4f2ff3d25849659", + "0x00000000000000000000000000000000001ae910663d2ca08ca35718d11c7ebf", + "0x00000000000000000000000000000075ffa7853e4e65151b0a07a653a4deff20", + "0x00000000000000000000000000000000002a899e407fe87d860ec446a9b9d50e", + "0x0000000000000000000000000000009f811b594a5ca4e03abfac98d71c4cad52", + "0x00000000000000000000000000000000002c4577b0ffa13c22944caeef4aeb7b", + "0x000000000000000000000000000000b22122da5120631c81ae7c090fab5c4eb4", + "0x000000000000000000000000000000000014ddbc63b8e87cf38d5f1bdedf8932", + "0x000000000000000000000000000000e79feec7013b1298f980ee48a3951c46ea", + "0x0000000000000000000000000000000000144a09988130e955b0f991671fc734", + "0x000000000000000000000000000000fccadf005dcf11dfae7e16251da139c64c", + "0x00000000000000000000000000000000000e2455a5b1f5bb6808f9c69e1b4b83", + "0x000000000000000000000000000000cad73f1e10fe30f6c3c6604462a9ad39e5", + "0x000000000000000000000000000000000023af407ebb2ebbb916b19f5e1806bd", + "0x000000000000000000000000000000358c8f99a29f2dcc8d936d1537bb16215f", + "0x00000000000000000000000000000000002f321ab6de1f6a2c179488e418d570", + "0x000000000000000000000000000000fc501808c7eeac2a8f1a94ba2d24be4281", + "0x00000000000000000000000000000000000abc0fe411716883c4a7cd5df8c5af", + "0x000000000000000000000000000000ea4b9a97a081f3d16f86c349dc23079367", + "0x00000000000000000000000000000000000a9606176049cae0de6c5847c80222", + "0x00000000000000000000000000000061d6ccdec76d72dc64ada1a81f788664c1", + "0x00000000000000000000000000000000000c0408321acfdf3367b63b83b33a9e", + "0x000000000000000000000000000000c570f10738530d83d30ed979bbc4acbf18", + "0x0000000000000000000000000000000000157eccb3d3c1c095eb8edbeec669b4", + "0x000000000000000000000000000000aab92fa5f685cbf4f8720464e2232dbe5e", + "0x00000000000000000000000000000000002c51b29180e84ca25a542c74b13be9", + "0x000000000000000000000000000000bf4ae6cdd940147e48440e3155e3e4d90b", + "0x00000000000000000000000000000000002068fd4b37ed9dc0f51780c6bbc319", + "0x00000000000000000000000000000010b17735f490af682367ecbaea8f46ede8", + "0x000000000000000000000000000000000023783618dae8e3dad244ee5b4fa5bf", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006cbfd45394e5c611c0c1ce272ee3cc6e47", + "0x0000000000000000000000000000000000224fe3dc1b6636cee421f29842b37a", + "0x0000000000000000000000000000003dae50a4473ffe62298a434d706481e6c8", + "0x00000000000000000000000000000000001c6855a0c6a537f41c9ed7a5c1b7e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x073f4bb2a667f5058abfb94949c5a8d5b1977df83de82a05390a90f8bb420751" + +[private_call_2.verification_key_hints] +contract_class_artifact_hash = "0x114be567f8aa3cadf98ceedfadbe6edb25681584cfdda8dd44acf0437b1ddc54" +contract_class_public_bytecode_commitment = "0x260735cf6645c6f07d2f0ebe2bfbd3062e95ddc820661329a5422bc239261bba" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_2.verification_key_hints.function_leaf_membership_witness] + leaf_index = "0" + sibling_path = [ + "0x0b63a53787021a4a962a452c2921b3663aff1ffd8d5510540f8e659e782956f1", + "0x1eeeb8fb2c3d5ed2bdeb4545deda4551d41e22e63ebfe4e47e98d83847870dc9", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_2.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_2.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_2.verification_key_hints.salted_initialization_hash] + inner = "0x0afe58e6645b396d31e0de341c28e73e0eee8c2d5fa7bd89a905a8c77cfc45b7" + + [private_call_2.verification_key_hints.updated_class_id_witness] + leaf_index = "134" + sibling_path = [ + "0x04faeb1fbcaba22bb78f190827a5dd614409f548340279badeb318d58f40c003", + "0x22f1b4d319f851468b77a99c6bde547499fc0dafc3676279d0724f0cff0186a2", + "0x02863b9ba1de6f80706d154369db20f4660240d04c2588e80259928737caa007", + "0x072c485f46fea63147c965f3bf2ae2a16a6cef7035c1a8140796c225f7b502b2", + "0x1d52af9cd9f69c1286e9a96fd498e736789a5bc463fceb1c176a4f9292f7cbe3", + "0x1ff1d5db01572c915915a22173c73d8073df9af4e4c57f6af29df5315da44419", + "0x070dcbac794fa663bc71b42d80775c0cea8c3ed7580207cfd30fd1285813ce07", + "0x1e40bcb76d2b688cff569abcc238c9f6bc9960fa9b07dd12652117fe819b1626", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_2.verification_key_hints.updated_class_id_leaf] + slot = "0x00636bd5b0883a2a1830afcbc6b4b41d16f9639ece8274acc27154705f3b8276" + value = "0x0000000000000000000000000000000000000000000000000000000000000012" + next_slot = "0x01a19f390779d3a125f11b7c60ce770979b067defbc52b8f0f898bbbc3454c6f" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000080" + +[app_public_inputs_0] +args_hash = "0x0e4a049212502ddf801e6de7e638cc14cfa74a583afb5b0112958f1f263384b0" +returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000002" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" +is_fee_payer = true +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d700b" + + [app_public_inputs_0.call_context] + is_static_call = false + + [app_public_inputs_0.call_context.msg_sender] + inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + + [app_public_inputs_0.call_context.contract_address] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" + + [app_public_inputs_0.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x2dd746d2f347ebd8d2f591aaf062159b2cceeadb449a919ada77febe9b940e78" +counter = "0x0000000000000000000000000000000000000000000000000000000000000003" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0ebd7eba73dc20bf082971c1d7211dc1ea94d1955f3f8bdfcb6ffe5555dfb502" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000006934ed0d" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0e251fbf263324b797960cb40a76612db073a017b0c373f8bcad29f31877b767" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000e" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x00000000000000000000000000000000000000000000000000000000a59b4137" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header] + sponge_blob_hash = "0x0536a4ab22763da9987147107b1502cd6c0f5100c5057af90cc913dfb7555a97" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" + + [app_public_inputs_0.anchor_block_header.last_archive] + root = "0x07b049e8df80c5fcaf98c5f5e83697da80766abb0aed71e3e8269717cdf0ce8d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" + +[app_public_inputs_0.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" + +[app_public_inputs_0.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" + +[app_public_inputs_0.anchor_block_header.state.partial.nullifier_tree] +root = "0x2b5af9d9cfd13b27d7e5971722fd8e4139011ea9f30375f3e2bd633d64e7293f" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_0.anchor_block_header.state.partial.public_data_tree] +root = "0x17494afd96414c3d5543c103ea394725d765efb8b615fcbb273725c82a6d2e68" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_0.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c1e8b" + + [app_public_inputs_0.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_0.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_0.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_0.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_0.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_0.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" + +[app_public_inputs_0.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1] +args_hash = "0x0ebd7eba73dc20bf082971c1d7211dc1ea94d1955f3f8bdfcb6ffe5555dfb502" +returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" +end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d700b" + + [app_public_inputs_1.call_context] + is_static_call = false + + [app_public_inputs_1.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_1.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [app_public_inputs_1.call_context.function_selector] + inner = "0x000000000000000000000000000000000000000000000000000000006934ed0d" + + [app_public_inputs_1.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000007" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + + [app_public_inputs_1.contract_class_logs_hashes.array.inner] + value = "0x242b9549d1e2c420a764a5aa2ba58d98b77e35fef8ffa5aa787f9b325f2b5005" + length = "0x0000000000000000000000000000000000000000000000000000000000000068" + + [app_public_inputs_1.anchor_block_header] + sponge_blob_hash = "0x0536a4ab22763da9987147107b1502cd6c0f5100c5057af90cc913dfb7555a97" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" + + [app_public_inputs_1.anchor_block_header.last_archive] + root = "0x07b049e8df80c5fcaf98c5f5e83697da80766abb0aed71e3e8269717cdf0ce8d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" + +[app_public_inputs_1.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" + +[app_public_inputs_1.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" + +[app_public_inputs_1.anchor_block_header.state.partial.nullifier_tree] +root = "0x2b5af9d9cfd13b27d7e5971722fd8e4139011ea9f30375f3e2bd633d64e7293f" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_1.anchor_block_header.state.partial.public_data_tree] +root = "0x17494afd96414c3d5543c103ea394725d765efb8b615fcbb273725c82a6d2e68" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_1.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c1e8b" + + [app_public_inputs_1.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_1.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_1.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_1.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_1.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_1.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" + +[app_public_inputs_1.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2] +args_hash = "0x0e251fbf263324b797960cb40a76612db073a017b0c373f8bcad29f31877b767" +returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000e" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d700b" + + [app_public_inputs_2.call_context] + is_static_call = false + + [app_public_inputs_2.call_context.msg_sender] + inner = "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d" + + [app_public_inputs_2.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [app_public_inputs_2.call_context.function_selector] + inner = "0x00000000000000000000000000000000000000000000000000000000a59b4137" + + [app_public_inputs_2.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15" +counter = "0x000000000000000000000000000000000000000000000000000000000000000b" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x000000000000000000000000000000000000000000000000000000000000000c" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0603f2bc643a4bf06692b6ea01af9cc928ebf24c8b9f8f359afdc60db9d40e3c" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x000000000000000000000000000000000000000000000000000000000000000d" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x174c6b3d0fd14728e4fc5e53f7b262ab943546a7e125e2ed5e9fde3cf0b3e22f", + "0x0603f2bc643a4bf06692b6ea01af9cc928ebf24c8b9f8f359afdc60db9d40e3c", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x1032ac682578d498c2288d1726fd4eafc40634ef1248e4a0218d27e98013091c", + "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", + "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", + "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", + "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", + "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", + "0x1a5bc640b9ee6b7cb908e6672e5678531c8f4cb21c956616e436eecad76a452d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x000000000000000000000000000000000000000000000000000000000000000d" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.anchor_block_header] + sponge_blob_hash = "0x0536a4ab22763da9987147107b1502cd6c0f5100c5057af90cc913dfb7555a97" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" + + [app_public_inputs_2.anchor_block_header.last_archive] + root = "0x07b049e8df80c5fcaf98c5f5e83697da80766abb0aed71e3e8269717cdf0ce8d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" + +[app_public_inputs_2.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" + +[app_public_inputs_2.anchor_block_header.state.partial.note_hash_tree] +root = "0x16c5b9c25398499f649c59f6d3e931edf963460b8761248e3b17bb1f5794f3db" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" + +[app_public_inputs_2.anchor_block_header.state.partial.nullifier_tree] +root = "0x2b5af9d9cfd13b27d7e5971722fd8e4139011ea9f30375f3e2bd633d64e7293f" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" + +[app_public_inputs_2.anchor_block_header.state.partial.public_data_tree] +root = "0x17494afd96414c3d5543c103ea394725d765efb8b615fcbb273725c82a6d2e68" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_2.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c1e8b" + + [app_public_inputs_2.anchor_block_header.global_variables.coinbase] + inner = "0x0000000000000000000000005ea83c9061394d0c643bd0df9d2d0c6d3102f6dc" + + [app_public_inputs_2.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + + [app_public_inputs_2.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000f81aedd1" + +[app_public_inputs_2.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_2.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_2.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" + +[app_public_inputs_2.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/Prover.toml index 11d2e8ee0b13..2c9c13b491fc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/Prover.toml @@ -1,18 +1,18 @@ -vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" +vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" is_private_only = false -first_nullifier_hint = "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef" +first_nullifier_hint = "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb" revertible_counter_hint = "0x0000000000000000000000000000000000000000000000000000000000000005" [tx_request] -args_hash = "0x2237e42a84e35fc9371ec568e04d6db13130f02f527e0cce6f78ebf038f70f5f" -salt = "0x0dcc552c9a204fa5c60481076f34e420fdd64d81a8c273ad1c336f00b6912f8c" +args_hash = "0x04a65dff28c7219e24a65785e4145db8afe036681c48c8348314e2eeba1c56d3" +salt = "0x2ebfaeadfb0e170b136b798638f54796e2ba938a2566a404a6ef114a7313194e" [tx_request.origin] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [tx_request.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [tx_request.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -37,22 +37,22 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" [[protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -73,152 +73,152 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key = [ "0x0000000000000000000000000000000000000000000000000000000000000010", "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000b81", - "0x000000000000000000000000000000323d5a3bacf46ff720167bfa82f1d3a470", - "0x00000000000000000000000000000000000109869e9ff89595121baa1badc56f", - "0x00000000000000000000000000000028564096270cb8849cc3552446a7787f44", - "0x00000000000000000000000000000000002c0182a1646ff1fe580199388a6e67", - "0x000000000000000000000000000000e207084f39d03f0b9d49d65a831a476bdc", - "0x00000000000000000000000000000000002aac72303765a3fadee7fa1db1be05", - "0x0000000000000000000000000000005e8598ff5e2c6cd7dc473187b18a60e56e", - "0x00000000000000000000000000000000002a412cc07438f09a0dd6201ad2c845", - "0x0000000000000000000000000000005946521ae9065d5a2f1e7016a837d41720", - "0x00000000000000000000000000000000000ea66d443ec8deb6a04dc4f974a8e0", - "0x0000000000000000000000000000006d72fbabcf2fb19129b47b1cea05b6fbea", - "0x0000000000000000000000000000000000093da4177e03b9ceffde6bfcba715b", - "0x00000000000000000000000000000073b9e515320060a26b76a2585026e35095", - "0x00000000000000000000000000000000001d0acd33c22a462a2f19a01731d7d1", - "0x000000000000000000000000000000ddce5c2135081e4f770a66abb583c2d173", - "0x0000000000000000000000000000000000157776c2b29efb55f9a8431e76ae1c", - "0x0000000000000000000000000000001bca989328d1c9116bb16813323cecba31", - "0x00000000000000000000000000000000001b5dc4ef90e0723fdc7945ef4c54ce", - "0x0000000000000000000000000000004e18c66149c3b7ac47179461f6e195cc80", - "0x00000000000000000000000000000000001281bbcfe7ef0f2fccf4cd92272414", - "0x0000000000000000000000000000003c8e508f2ffeb91e6f3f83c3f6c86d56ba", - "0x0000000000000000000000000000000000064d022b5e2c394f45dcd33af07326", - "0x00000000000000000000000000000002cafc1f9a92a5ee32f170622efede1b43", - "0x00000000000000000000000000000000000aceb2867aa9d36e777e91c8af94e4", - "0x0000000000000000000000000000009de7a9cc413e4291453c88d92591e15064", - "0x00000000000000000000000000000000002a99adc4aea9cf55b7adb21dc2d7b5", - "0x000000000000000000000000000000c5c063499d6beb3c15a568f0eb3b9accfb", - "0x0000000000000000000000000000000000085343e51f8e54f7e4b3bca5b8ccdb", - "0x0000000000000000000000000000004df9e2c11487e96cde4a354328c2322b7e", - "0x00000000000000000000000000000000001e71380507bf8f7a65f542a668967e", - "0x000000000000000000000000000000387a87e1fd5a4d755a72bf4223e72cf175", - "0x0000000000000000000000000000000000140d1d6145c78a4cd60b85534d174f", - "0x00000000000000000000000000000009dd5aa20682fbbc7e632f8a1db534e9b3", - "0x00000000000000000000000000000000000634427a3afc7faeb13b2d9dfb819f", - "0x000000000000000000000000000000b4197b6332dcded183750122f25b0a2519", - "0x000000000000000000000000000000000027607abc7388bbdbd2d7f96188fbb4", - "0x00000000000000000000000000000003d113f92b1cd5b3ff63420794e03ef685", - "0x0000000000000000000000000000000000207b2aef1ef8b28ace8c83aecf7e28", - "0x000000000000000000000000000000450f7e6b497cd2a96ae6b92be64fae5c6b", - "0x00000000000000000000000000000000002120f64101472951f06f632de5145f", - "0x000000000000000000000000000000debece59d8788da9e5f8d8dc220168c1d2", - "0x000000000000000000000000000000000015786f0aad65395b2bc4b537336ede", - "0x00000000000000000000000000000060a0d6c54c73c3690cecc86bddbfbcc42b", - "0x000000000000000000000000000000000000e01e5f4b5f9c61b6b572d6a489a8", - "0x00000000000000000000000000000051925bb85f77dc843e87768cad13898c66", - "0x00000000000000000000000000000000001d2e8c943486f2d8077ca3a545e58e", - "0x0000000000000000000000000000001eae3f40b556ff78fd87a9f0bf9835f121", - "0x000000000000000000000000000000000001a9ddb01e083df4fa7944b38b1d66", - "0x0000000000000000000000000000000a71144260f9510eea1b6b164635f58a85", - "0x00000000000000000000000000000000002450da73f6d16c22bbfee6979c1aa5", - "0x000000000000000000000000000000a05fce07c3de8206138c6fff56b0384a77", - "0x00000000000000000000000000000000001413ce1460c3807fa23afc23048488", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000fa598d6d181474b0f0bc69f2183b523e80", - "0x00000000000000000000000000000000000d8c40ab9e154226f73e321ea0aadd", - "0x000000000000000000000000000000d279bcf5f49b4e581e307f708085120acc", - "0x00000000000000000000000000000000000b7a923678250450f635555bd4cd46", - "0x000000000000000000000000000000cc727ba574f665e0eb1b68de979a694028", - "0x00000000000000000000000000000000000a6f019b23bb4dc91aa9fa1c549e8f", - "0x00000000000000000000000000000048e4410bd774618ebb93dddc7ad9cb3ea4", - "0x000000000000000000000000000000000023dd18195483e82d97eb518a8c3ba4", - "0x000000000000000000000000000000bb65ab115ceeb8fb08e90f292f09d0cef2", - "0x00000000000000000000000000000000000eb1879efc776a7cac9ccb88550a4f", - "0x0000000000000000000000000000001d331e0112dd2d8cd8ce94e7b32843751b", - "0x000000000000000000000000000000000011e69febc35e19e3d67d16f534ec53", - "0x000000000000000000000000000000919614fa3ba8ef2dacf8ea9a6805df8e9f", - "0x000000000000000000000000000000000021f21cdf5a4aa72e8ff57923e8543b", - "0x000000000000000000000000000000708a9164194ce14fac9d0386a3adcb4bc0", - "0x000000000000000000000000000000000028d7bc88df3ad73259787bf5d7d01a", - "0x0000000000000000000000000000002964cf46a5183cb04145d9a8b439a32df1", - "0x00000000000000000000000000000000001539ee0fec0781bc1760b30e479b1e", - "0x000000000000000000000000000000ba5f4a89c83775cb92fcc3ff4c358a7553", - "0x00000000000000000000000000000000002640734ef86775f76d689e95814fc3", - "0x0000000000000000000000000000009c2f263653c7e2af7401216151678eade5", - "0x000000000000000000000000000000000022cac24cb9b9c0bd20263c02178a74", - "0x0000000000000000000000000000009b91b2b9cd766ab9d54d4e0ce5b31b2df9", - "0x000000000000000000000000000000000021feeed9c2bbeaf1b31b97bd475898", - "0x000000000000000000000000000000b167db6919d49e56465b96227e40c83b61", - "0x00000000000000000000000000000000001382f4cd681ca5a3b409cc27c9622f", - "0x0000000000000000000000000000004459ed40f5cbfa7d6a37b8ea44d6cbd6dc", - "0x00000000000000000000000000000000001bd5f7d5688bb20ed13a7d6c96ef7a", - "0x000000000000000000000000000000ca992efecefafda29e202a7a347d81367e", - "0x00000000000000000000000000000000001db9c5d73ac26232863ae012269306", - "0x0000000000000000000000000000008ee5b3d7b16d5fe16702aa8885d4b96219", - "0x00000000000000000000000000000000000e59f4b3fd78b0fb4ac7e9c2172cb4", - "0x000000000000000000000000000000ae1a100ea1870b38b32d117cfddb7963f6", - "0x00000000000000000000000000000000002e373869e16038a011dcbd14cd4f01", - "0x0000000000000000000000000000005a5fe1304e6aeac934bddd72a03ebc626b", - "0x00000000000000000000000000000000002a21976f3e8487fb635ad21e9ffe2c", - "0x000000000000000000000000000000217dfe935e944ba7075acde9faa6cb5173", - "0x00000000000000000000000000000000000e5ad22ef54fc104806cd546d25b9a", - "0x000000000000000000000000000000d0760a836a218a69ae33c7172912f1d331", - "0x0000000000000000000000000000000000248701194b3dad90a302030dd3ed4c", - "0x00000000000000000000000000000015771863f13527395472cdbefc01ce7d50", - "0x000000000000000000000000000000000025b39680b4a83bfcbb03bbef9286d9", - "0x00000000000000000000000000000015172ac2d95099e3de8feae18d349ed077", - "0x00000000000000000000000000000000002f0e6eb33c7a8589eb4aa0a58e4948", - "0x000000000000000000000000000000bc4ffdb2d7a1280fc2ce31024a5f4028f8", - "0x00000000000000000000000000000000000f8b150ff8204297433768c07af62b", - "0x0000000000000000000000000000003b337a09da46d718fdbb452d16e1c3355f", - "0x0000000000000000000000000000000000209451e38476922aff2f5e89d9050c", - "0x0000000000000000000000000000003204c8b80470419acd48ab8cfc4ee4edcd", - "0x00000000000000000000000000000000000e6382ea5ec96629b90c530219c3cb", - "0x000000000000000000000000000000573110e5e30f83f2b1cdbf6021589f56d4", - "0x00000000000000000000000000000000002153342158e09047429d5ff0cf2814", - "0x0000000000000000000000000000000c87cc7ea9f19d895b531f173f10e1fb7a", - "0x000000000000000000000000000000000028ce104aa04c8883606e30145396ca", - "0x000000000000000000000000000000091bf18675b31c2ca35cd6d9c4c61980f6", - "0x00000000000000000000000000000000001e4a1ac80c95b28bd73997aa8be018", - "0x00000000000000000000000000000027ac5003261c40666193e97d00708290e6", - "0x0000000000000000000000000000000000155026062b8202477e26ea5692a700", - "0x000000000000000000000000000000cf95c483603fd34a07e7e0aaa6ddedf5aa", - "0x00000000000000000000000000000000001ed0d7dc69f72e8055cbe26bc2ce26", - "0x000000000000000000000000000000bd27f2a517da170087251aface1dbc9172", - "0x0000000000000000000000000000000000201a01367b862c45ba57aabe90a276", - "0x0000000000000000000000000000006242c06ca6844877f622da669895d8081a", - "0x000000000000000000000000000000000007e008d692476d4eb814fb8f610fba", - "0x00000000000000000000000000000013de6e7df5135ff688efa9d436ed802342", - "0x0000000000000000000000000000000000291c207e9ad4c322aa0711d30bde2f", - "0x000000000000000000000000000000dd165b3f058369e880294dc2d3f1548ffc", - "0x000000000000000000000000000000000017829ab7f82e60e0e4da95135e6e84", + "0x0000000000000000000000000000000000000000000000000000000000000b61", + "0x0000000000000000000000000000007b6222b3a18551d60b847957202de6c8f5", + "0x00000000000000000000000000000000001e26b96548b9f12369e9c3ec0eee85", + "0x000000000000000000000000000000025aac0bbaf1beff1c0500e3ec38d34c8a", + "0x00000000000000000000000000000000002c498aff2f95b25bb92e2c9360aff5", + "0x00000000000000000000000000000039d32590e9d6e0be118712b9402c606156", + "0x000000000000000000000000000000000026588627e22f203f6399975fb67258", + "0x000000000000000000000000000000097282335613efda63abaeaddc915f44db", + "0x000000000000000000000000000000000021b51f545ea031ad8c826962f52545", + "0x00000000000000000000000000000035a0536197418c2ba2c29a1830f709420c", + "0x000000000000000000000000000000000020f8cabd08dfc29e045e0b80eb42d3", + "0x00000000000000000000000000000099e53cda88a63b8e751a2bc253f7a689a7", + "0x0000000000000000000000000000000000231a514e7a4dd0e23c4faf8d567c77", + "0x0000000000000000000000000000002dac12ff4e48e530611ceb7a400c099e4a", + "0x00000000000000000000000000000000001ad1cb6dbbe8ea3dd6c4f44ffdce56", + "0x000000000000000000000000000000dfd19e74f4e4c641b3b3f623825ccd495f", + "0x00000000000000000000000000000000000ce4453cef94251418336baa54e582", + "0x0000000000000000000000000000007ad93fd648d3587168e2ba9ee66dbbf918", + "0x00000000000000000000000000000000000a7680894366d3b1755d14152e528e", + "0x00000000000000000000000000000008bf43eecffcec9e31d916289a212b8f88", + "0x0000000000000000000000000000000000216620e5bd7b177f3fa15ceeb2526e", + "0x00000000000000000000000000000021db86993540e76c420c850640a25f7d94", + "0x000000000000000000000000000000000017418ee5d4d58a54e7728b755757a8", + "0x0000000000000000000000000000000cf5f978296643872c59d00be3c23ad68d", + "0x000000000000000000000000000000000013e45088158c3bf8ac1f8e71eec154", + "0x000000000000000000000000000000768cc857ea136153788ffa81c07daddaf2", + "0x000000000000000000000000000000000014b992148ee6906cb3a1989f3c4bb1", + "0x0000000000000000000000000000000127e074cd6ea24f75f86f3ab119f9ae5d", + "0x00000000000000000000000000000000001719d1f7fc4645193b8036cf9a3d52", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x000000000000000000000000000000622ac3715a21583a169b4c635c162bdc13", + "0x000000000000000000000000000000000012374104ee9056dfafba40f457c0a8", + "0x000000000000000000000000000000f6c09b75f7561f7fbbd272af5d3efa974b", + "0x00000000000000000000000000000000000e0a7bd7a377bca3ff6c89d68a3e5e", + "0x0000000000000000000000000000009d165e9a47e021ab9760d27339570655e5", + "0x0000000000000000000000000000000000000b204b0dc1f11b52bb345fb52145", + "0x000000000000000000000000000000d4c558b53b27cb4c171f8a5eb0bd1e3a2c", + "0x00000000000000000000000000000000002f6870272192d541c1b8887b15a95a", + "0x0000000000000000000000000000008f4c64ade1e7b515b074c100d489415d4c", + "0x00000000000000000000000000000000000f9aca92beccde2e1b08c99ab92a6c", + "0x0000000000000000000000000000008be6976e9870523051d19531843262ce4c", + "0x0000000000000000000000000000000000277419877e0ba35217f219676b5656", + "0x00000000000000000000000000000051ec180d05026f2f62b1674ca2e1a2c142", + "0x000000000000000000000000000000000022264cbd2ea66b7766612864c5108c", + "0x000000000000000000000000000000f137ae2b224915db0c43de1611134011d0", + "0x000000000000000000000000000000000011877af1a2b9b35d6ac04c489fe3ba", + "0x000000000000000000000000000000935ae3a5a2c4a7aad8e94a7cf1c4bec70e", + "0x00000000000000000000000000000000002a56488e09fd406c14aca4acf2b4c3", + "0x000000000000000000000000000000e770a6c5c0093eb5de2e5aa8d173e9ef05", + "0x000000000000000000000000000000000005522908d6e06b02d6938a789bb5c9", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000b139df614924ddb845d70d642d94873569", + "0x00000000000000000000000000000000000084d02351f0d2b405f3af6092edc0", + "0x0000000000000000000000000000006c1123c8d14bdfbfa99f95d1fd0d9674f7", + "0x00000000000000000000000000000000002be519d31aea4dac51b16b3655b459", + "0x00000000000000000000000000000035b52a2f19454b2d02086d012cfc44cbdb", + "0x000000000000000000000000000000000027f3e1c4d5482e3b1ebcbc5e43d1d2", + "0x000000000000000000000000000000bc81f2a307249de2d56c3c8151aa3a4179", + "0x000000000000000000000000000000000014745d0c8957b03309ffd69c523944", + "0x000000000000000000000000000000d90966909da4a8611a68a5b2544044ee27", + "0x00000000000000000000000000000000002dda368cf4f8ae011ba33953ccdbdc", + "0x00000000000000000000000000000099fd8e2a4efaa0e979e53c6360f11a3520", + "0x000000000000000000000000000000000029023563407bf604b94f3d3b82e32c", + "0x00000000000000000000000000000095ced0bf10b79aec2651f808812961ce57", + "0x0000000000000000000000000000000000204601f003e0e59d1865597a5cdcd4", + "0x000000000000000000000000000000fd07b0a28f8510ae42eefbbd2d0136dc4f", + "0x00000000000000000000000000000000001e3aba113eb2b6e0d9a07cb16188c0", + "0x0000000000000000000000000000004496315acb001bd07077d5e61a5fd28f1b", + "0x00000000000000000000000000000000001a39ca40a2fdca943fd7c57ea59fc9", + "0x0000000000000000000000000000001a6e9238224f825fbe059c173514ee0fe7", + "0x000000000000000000000000000000000022f701f63bad50d3161322f8d104b3", + "0x000000000000000000000000000000e7cb0e4c388d5b2b1350a0c1b259d7c4aa", + "0x0000000000000000000000000000000000216c09ccaf44298565b3e593e3a7bd", + "0x000000000000000000000000000000d840ba780d73076cfaadb07a9a1a2cad8b", + "0x00000000000000000000000000000000002a887121806c1166b16f3aa9de6716", + "0x0000000000000000000000000000000e3b5cb0fc3e09ea8b4059e2a6109ff857", + "0x00000000000000000000000000000000001794754a1a61af4fa7976eefdac79e", + "0x000000000000000000000000000000dfef9deedb32693d7cc279f72cdc785d1e", + "0x00000000000000000000000000000000000e55622ad6ca63ffde7f64ed504b16", + "0x000000000000000000000000000000d08df7bdd8d57cb1d65728efccbbfcf607", + "0x000000000000000000000000000000000005f2689ecd1c3bf58c28357d95d48a", + "0x0000000000000000000000000000002d7d2927cc7e65b41792f5745ba169663e", + "0x00000000000000000000000000000000002b5f2432471d8c12ea391ac1a0bd12", + "0x000000000000000000000000000000773d8fd379e59dbcbab02af010d195c779", + "0x000000000000000000000000000000000008826f48f7b0250873af38fa8f7500", + "0x0000000000000000000000000000006165595d9a271241c16e0472c174fba8f8", + "0x00000000000000000000000000000000001c673e22bf04c83bddc2f02ebaae36", + "0x0000000000000000000000000000008d6afb067ac5198bb372113d34c56552fa", + "0x00000000000000000000000000000000001e08cbe1d21feee99c841191e54333", + "0x0000000000000000000000000000007646a1a3ca480b5d7322e5e4bb688049f7", + "0x0000000000000000000000000000000000269f2465562733cff2488fe75060fe", + "0x0000000000000000000000000000005524b80d26a1d910532fda24c2383f979b", + "0x000000000000000000000000000000000023bf14a9a6153ade3200bcc787ba79", + "0x00000000000000000000000000000038d56d2f4e530f74fb02bb70d781488b16", + "0x00000000000000000000000000000000001d1731444ac607cb0623133a479871", + "0x000000000000000000000000000000fe08dc45003f859a25494ba5135502e42f", + "0x00000000000000000000000000000000001e6d7c5b53a5e88d78640651a5c6a0", + "0x000000000000000000000000000000ddf4dedac0a43ba687e608b3e6081b8546", + "0x000000000000000000000000000000000004c2446dcf61c32ba4b038fe7365fb", + "0x0000000000000000000000000000004557b361ff0d6568e896319c496fbe24b8", + "0x00000000000000000000000000000000000668a26f50d3354953d4b2766e8020", + "0x000000000000000000000000000000ea507b90f982c43d39d3f699d22b1f7c4a", + "0x00000000000000000000000000000000001429723650e7543325ff8bef1c4ffd", + "0x00000000000000000000000000000049c19043bd4f1ef29d5413b1f118d0f722", + "0x00000000000000000000000000000000001d7ad7b3a27a9bc7992d806af0ebc9", + "0x000000000000000000000000000000f291d1109ea1f48586582a3767b0392cbe", + "0x0000000000000000000000000000000000026df82a517f9dabb3c389c07aebc7", + "0x0000000000000000000000000000000999c4e1d13eba177baf97921ee863ca58", + "0x000000000000000000000000000000000002f7f537a4f96f2ca4eb19a57f0b9f", + "0x000000000000000000000000000000dea34b6c529204f209cd1420a81a3102bb", + "0x00000000000000000000000000000000001c53a430fcbd4b95ffc23b6461fa15", + "0x0000000000000000000000000000005c0cab22cbb5bdccf85116184958790eb4", + "0x00000000000000000000000000000000001b715af5e709bb9f06822082ee3120", + "0x000000000000000000000000000000c77eaa3f49d17dfe395648540f4cd0abc6", + "0x000000000000000000000000000000000007df3cadf5a234989c3f0b92052395", + "0x0000000000000000000000000000009c11b61aaa7a95751ddef148053d00a6e7", + "0x00000000000000000000000000000000000f65d42148106db82a9e434cb19459", + "0x000000000000000000000000000000f99b662c4e3bcd3fdffb75cad5deb632e6", + "0x0000000000000000000000000000000000284f78ec2bc1c17ffa75e285ad4529", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000c5c5fddc6d03b2bb9af543e73695863c77", - "0x00000000000000000000000000000000002b03df11145d0fa2c23bdd7fb7066b", - "0x000000000000000000000000000000211136d196e61c110edd7e581be8645373", - "0x00000000000000000000000000000000000a2fb7ada300644cbf7b7d7f36de36", + "0x00000000000000000000000000000059a5cd5c1c2d2e7cac107aaf0123ae4f84", + "0x0000000000000000000000000000000000170ffa45422a2680cd492bad46789d", + "0x0000000000000000000000000000003c91ea4fe538abe3c344c3603398af1cbc", + "0x0000000000000000000000000000000000295e7a3f8df6111a6bd51041d5179b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000585fcdfa31b424adfe685b43435cdc567", - "0x00000000000000000000000000000000002717439949acf883c385bc7c246dc6", - "0x000000000000000000000000000000b97f0f863a1005a5c88ba628c1d8bb1740", - "0x000000000000000000000000000000000001f73676f90fa92e0bd9ce8716cfb9" + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" ] -hash = "0x103023eab6f953f6b7b9525f412e0bc1655bd72d5e4b46ded148c6137deb9006" +hash = "0x11197593d62d0e7554158b832253460bcc00da8b6551eb5d955ef72444d95a3f" [private_call.verification_key_hints] -contract_class_artifact_hash = "0x1d8791271c09cabf2ac9aaa6bd8095b473d90e367f72c6df771aa7a4ec960f9e" +contract_class_artifact_hash = "0x1d9e0e30582ed207c6ba761454f1f542d807eb0a2b35a50b23297a6db34e3680" contract_class_public_bytecode_commitment = "0x0ce4c618c3ed7f3a20410e618c06bb701e150af7fe28a3e92f68e7733809f33e" updated_class_id_delayed_public_mutable_values = [ "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -229,8 +229,8 @@ updated_class_id_delayed_public_mutable_values = [ [private_call.verification_key_hints.function_leaf_membership_witness] leaf_index = "0" sibling_path = [ - "0x238e2af83a65aa19075bf14aa7aeb0f681204a09f3756757b334f3061e238757", - "0x25ce89a823f16f35f08b6081a3ea3197c468941e46b7400ac6b33280b19cf251", + "0x2cc233639ce62adaea3ec034abce91a0b008ca3b50da04eb0789bf1f438162ea", + "0x0f60b735d348fd08a8da88fe4b04361698e2bca73fbebb6cc1fdcb86a4d03c89", "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", @@ -238,40 +238,30 @@ updated_class_id_delayed_public_mutable_values = [ "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" ] -[private_call.verification_key_hints.public_keys.npk_m.inner] -x = "0x025f9f657095ad240d89a28336e0f7be994c9f270d62c6a3228aa8bada12d01d" -y = "0x1a7e0782cbdd3ebc39b0bd4a33b5894cb3451bc52c2fadd70371ed8d81db479f" -is_infinite = false + [private_call.verification_key_hints.public_keys] + npk_m_hash = "0x00b1aa481847b00c84520d8703150e4ffcabef37bd6c690e2b2f0def0d234412" + ovpk_m_hash = "0x2f06e183807ba9785e51fc03048ad8578bc00a26557c98d6395da6d0a222ff05" + tpk_m_hash = "0x2a5642d242500c1704918b9a0b8273080ed77a05eb814254711ee48459fb417e" [private_call.verification_key_hints.public_keys.ivpk_m.inner] -x = "0x22f40cddddbd77c2aa6fead1b876909111a45ab1b5f69a48df1440764a7dcd90" -y = "0x1a6c5d7af83395c1e6c82ef8cb26ec6674f65cfb52521dae0b54130764bdf10d" -is_infinite = false - -[private_call.verification_key_hints.public_keys.ovpk_m.inner] -x = "0x2d41c74462094b1d13ed19ce294c4a39cdc7635080f32399494e5e796b663933" -y = "0x19944298156083d73fc78b3e628123fccead0fec542f0a55cfd319f2b77047ca" -is_infinite = false - -[private_call.verification_key_hints.public_keys.tpk_m.inner] -x = "0x2b8dc3a19be872d7c3b215f6b1716e586cdc99c79320ec3f5989233e0957fc39" -y = "0x13eec92e41aeeec0598539fbf7d94629cc58515f87507cb2638264f68be7c432" +x = "0x2c7112e002424a07f386ee65ea79eb477c96ca5b30a00a5a98360c0b9c33dafe" +y = "0x0459c95061c10cdb6d2e6a55872d820a1101881d8d07625d524cac97710a1373" is_infinite = false [private_call.verification_key_hints.salted_initialization_hash] - inner = "0x26ec6a326bed489e479823ab0ea1152729bcec7cbe15048c3e02a1e4309d4a68" + inner = "0x17a48cd849b95dbc8a26ff209bd1d3e80d011e9473beed095fa5a5d92def57fd" [private_call.verification_key_hints.updated_class_id_witness] - leaf_index = "132" + leaf_index = "118" sibling_path = [ - "0x10a274cd78b609bb9ff5960dfac7a0add8ccae279c81ec05441bbb8165d517dd", - "0x27047bd2479bc929cd5250e32e3b3e05f8cef863f7c8a349df77a9b2bf85588d", - "0x1d36a7e02b793d41e28f57b4480fe48b3f169b794f73d57683c7bfc4253da367", - "0x25c533089637cf9ecd3633dfcb0ee03be91faff3e02f51778cd5738264514c88", - "0x1d52af9cd9f69c1286e9a96fd498e736789a5bc463fceb1c176a4f9292f7cbe3", - "0x1ff1d5db01572c915915a22173c73d8073df9af4e4c57f6af29df5315da44419", - "0x070dcbac794fa663bc71b42d80775c0cea8c3ed7580207cfd30fd1285813ce07", - "0x2027713f7323f965c6751ce6c41f7759c9501fe781928b9507814d749cb86f25", + "0x013c095d61087adcef13cfdeb887287dba3806baf73093ee460023cfb7730f22", + "0x060b5c8a3d6c10c09c2c4ef7897592f838ac2433c4ca664adc73ae6bf507aff4", + "0x2523970382de270c1acd87f98b4ed454353257f9c689dc608f7dc1b6ca23741a", + "0x12bef12e0e192e65178ebf9707e29797e5afdace0a42a17d796d1c40e5b7501c", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x1ff2ba9f5f44162476e89f994a79debf4b9af550a887b5b484d18f5997553566", "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", @@ -307,13 +297,13 @@ is_infinite = false ] [private_call.verification_key_hints.updated_class_id_leaf] - slot = "0x1dbe81fde1f18bf3e8828a3595c65a1ee32397477e23d9c5c9e4c0386bbb4a2b" - value = "0x0055534400000000000000000000000000000000000000000000000000000000" - next_slot = "0x213a03911d28297ad85626532672b56d721f6e4af4e78d6f156cf1cb98482089" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000086" + slot = "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969" + value = "0x00000000000000000000000000000000000000000000021e01e389dbb1028c00" + next_slot = "0x07e3196f3e5be886c078da1e359a784f0451f3b454344a3c6482a090708f2547" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000087" [app_public_inputs] -args_hash = "0x2237e42a84e35fc9371ec568e04d6db13130f02f527e0cce6f78ebf038f70f5f" +args_hash = "0x04a65dff28c7219e24a65785e4145db8afe036681c48c8348314e2eeba1c56d3" returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000002" end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000007" @@ -321,7 +311,7 @@ expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000 expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" is_fee_payer = true -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff2940" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7f3f" [app_public_inputs.call_context] is_static_call = false @@ -330,7 +320,7 @@ expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000 inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" [app_public_inputs.call_context.contract_address] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [app_public_inputs.call_context.function_selector] inner = "0x000000000000000000000000000000000000000000000000000000009d57a239" @@ -340,7 +330,7 @@ expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000 [[app_public_inputs.note_hash_read_requests.array]] [app_public_inputs.note_hash_read_requests.array.inner] -inner = "0x29ecb485abf1e4a9963bb4dada6e8b67bda9c6bb09527ecb8d0c64a0d119e0fd" +inner = "0x302a86bd5883e95684cbcd46af941e62a60b0416ee605f00eae4a0189b8af2ee" counter = "0x0000000000000000000000000000000000000000000000000000000000000003" [app_public_inputs.note_hash_read_requests.array.contract_address] @@ -604,178 +594,114 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [app_public_inputs.note_hashes] length = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1113,13 +1039,13 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.public_call_requests.array.inner] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x00a5e40cab902df3efe088094577e83eb92103581c990f351edf1dfba3778905" [app_public_inputs.public_call_requests.array.inner.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [app_public_inputs.public_call_requests.array.inner.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x1be490a4b344f41827e94113f628fb311efc1abac19bc1e84b08fd578708964a" [[app_public_inputs.public_call_requests.array]] counter = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2055,50 +1981,50 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" length = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [app_public_inputs.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [app_public_inputs.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [app_public_inputs.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [app_public_inputs.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [app_public_inputs.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [app_public_inputs.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [app_public_inputs.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [app_public_inputs.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [app_public_inputs.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [app_public_inputs.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-2/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-2/Prover.toml new file mode 100644 index 000000000000..d52c721bb422 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-2/Prover.toml @@ -0,0 +1,10000 @@ +[previous_kernel.vk_data] +leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000041" +sibling_path = [ + "0x12c59c16ed84032f7c5273ff19d7a05e8e861c23959fb71cf4b2c6ac45d21f8c", + "0x225eef52a484280b0f1c6cb9f90a84dc301536c01bfa4d61bd6496b3eaf19052", + "0x0e084e8198288b2ff94eaf4d6f37fba06e430a879dd37c726a3b5a65416fe6b6", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x0e9cb07dc8495e2adab02c5db0e34a0dbe42e9b473e0462641c54f73a4a4fdd3" +] + + [previous_kernel.vk_data.vk] + key = [ + "0x0000000000000000000000000000000000000000000000000000000000000011", + "0x000000000000000000000000000000000000000000000000000000000000001a", + "0x0000000000000000000000000000000000000000000000000000000000000cbd", + "0x000000000000000000000000000000c4d62213b081c8e90e6c8f3587321997f5", + "0x00000000000000000000000000000000002236a0b9f0654f7cd634c9c34280f1", + "0x0000000000000000000000000000007cb00736872fd50e291ec99fb640f1f7d9", + "0x00000000000000000000000000000000002d1b1b74b74ddf7d6f964a7bdb2af3", + "0x000000000000000000000000000000f26bcf89c86dcbce68a4f1b5b73505dcec", + "0x000000000000000000000000000000000011a128ae6c7be3a962485534f27786", + "0x00000000000000000000000000000088278f8cce72a5f698601f11a1532a9dad", + "0x00000000000000000000000000000000000d9caeabde23d8c2a0bd2cdef54193", + "0x0000000000000000000000000000001cfb29930f6753e5cb6a60342c16fe5e4f", + "0x00000000000000000000000000000000001022a2847e12bdd43b96342e5b8e16", + "0x000000000000000000000000000000fefee7789c5b50b89ce3ac6155975c4319", + "0x000000000000000000000000000000000002e25d02799b225c89aba3a667d7e5", + "0x0000000000000000000000000000006e210889b06205312234c097f979fca3b5", + "0x00000000000000000000000000000000000566396dc1f8e15f3a1c3729bb3393", + "0x0000000000000000000000000000009790f776d7aaecbcaf977d3aad6070c4e4", + "0x00000000000000000000000000000000002dcdeaf93e01c780512d9950fbfd94", + "0x000000000000000000000000000000d2ef194a7b605db9c6df08b9576c97735e", + "0x00000000000000000000000000000000001ff98ab3818a3d5fdc538a7bbeb87e", + "0x000000000000000000000000000000be40a925ee773bfc3923df01da59a497d7", + "0x00000000000000000000000000000000001fb52b895f997b5a90ea722d9a4140", + "0x000000000000000000000000000000dd5a7d1074be39e4451795f983d45b5be3", + "0x00000000000000000000000000000000001cbfd5b0d763096343af10ed1f3496", + "0x0000000000000000000000000000007cc56b953bb8ef24745e9200896ee10ee1", + "0x000000000000000000000000000000000001ef96b3ae0b2677b21939012dcc17", + "0x0000000000000000000000000000004ba56f98fc7d6d956bd6302ef6941f9239", + "0x000000000000000000000000000000000010bf82473c11a65eb2ac193002bfe4", + "0x00000000000000000000000000000072739ba831885d7f767251b9cc444961e5", + "0x0000000000000000000000000000000000256ea7e1dc188341f8692fd52454cf", + "0x000000000000000000000000000000a284c1c0bd5602eb7242fda659dc49ff99", + "0x000000000000000000000000000000000002e5e663dd3bf5f961173646b8e7b3", + "0x000000000000000000000000000000194cc54081bb3ffba3c67547dcb2db4d37", + "0x00000000000000000000000000000000002377042c75bab3ceee3b186c40b8b6", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000f0af57d5589fc84e1f8897bb5a62ec0ea9", + "0x000000000000000000000000000000000016583df9856bef930ef0a81d3357f0", + "0x000000000000000000000000000000e0a92aecf729c58fa7672c82066409d090", + "0x000000000000000000000000000000000010085406672c105a10ddee00634540", + "0x00000000000000000000000000000036b650e61cb6e0ec6ff6b1aef12c8c81e3", + "0x00000000000000000000000000000000000049ced3703b6736736daa8d94d66c", + "0x00000000000000000000000000000024e41b443846d1b9d969a739fe9ec5544d", + "0x0000000000000000000000000000000000251ef94ce2811e61503920adc1a548", + "0x000000000000000000000000000000ab378c4d63d86a750348adbd4cbc2c6883", + "0x0000000000000000000000000000000000079aee0bbaec8a7e39acda8a2bfd44", + "0x000000000000000000000000000000c4996ccb316a1671fa17ac0ec536c08aee", + "0x00000000000000000000000000000000000087a93f4353d8c6e85d6c58c7af49", + "0x0000000000000000000000000000002754983ee3f30f64f3ef3d6a27f671032d", + "0x00000000000000000000000000000000001b77b7da696321894ac402dc70a471", + "0x00000000000000000000000000000065a8c950362ff55e55d6006254e4cb8f60", + "0x00000000000000000000000000000000000a0eb81f69be92cc51ba479d4d4b2d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003a6dc78277b2838aca18adc58385b4a7f0", + "0x0000000000000000000000000000000000132c99e752833cae9473e7dfe278d0", + "0x0000000000000000000000000000003ec707e1f4369d5f99a3bac8eaa16ec4ba", + "0x00000000000000000000000000000000001cd77155c0a5e65f942f719c8e73f5", + "0x00000000000000000000000000000084604af6454cd074b40340a0900f8e47cc", + "0x0000000000000000000000000000000000077d31bdfcd802cd5aa1a457b97f10", + "0x00000000000000000000000000000099c886edf1320d2f8eef9c059a2495598d", + "0x00000000000000000000000000000000001400c2b452cd839ce363493a76312b", + "0x00000000000000000000000000000090681337eb7720ddc934e8bcc81bd9ae2b", + "0x000000000000000000000000000000000006ab19688014b0f0cf860c615759af", + "0x0000000000000000000000000000007165a99470ed5af56e75a9636be648e93d", + "0x000000000000000000000000000000000009dbbccaa2350bd92c5ce19b5d290a", + "0x0000000000000000000000000000000e1e042ed81d839a9f0ead9d291b6a8f32", + "0x00000000000000000000000000000000001a205aec8c334db49f816f4b5dafcd", + "0x000000000000000000000000000000ebb4edb0db1dcdf348033a7901a3680b6a", + "0x000000000000000000000000000000000011aae86275b822ebd3fa82c7315eff", + "0x000000000000000000000000000000e97eee8ec09b50e69135709916aba933c6", + "0x000000000000000000000000000000000010e2e96f78a68fc25ba2e4dafd04cc", + "0x000000000000000000000000000000b214f0a5321e8817d78adb6e0c20d7319e", + "0x000000000000000000000000000000000025bc9ba17b749d567d90e8f13af9a2", + "0x00000000000000000000000000000066fba7ba25f999f6f2838e553a29901fa7", + "0x000000000000000000000000000000000020711b883c2eb028f9d2d3da010519", + "0x000000000000000000000000000000a140d481bdc261d13949520f9ec7371c20", + "0x0000000000000000000000000000000000020bfe682fa3abc7653ce6853b0112", + "0x0000000000000000000000000000001b2bf2cbcde5d02c025a94db3378725693", + "0x000000000000000000000000000000000023e613dfd6966df7487e58fd52480c", + "0x0000000000000000000000000000006e2eb63e8f0cbcbd7a88665a53e119e428", + "0x00000000000000000000000000000000002e70d3962ba79ea7ae10b168c1c7d9", + "0x00000000000000000000000000000030517d9ecfee899135ff976333894660c2", + "0x000000000000000000000000000000000007417244ffad99a470ba89eb0ff90e", + "0x0000000000000000000000000000009bac28f405d40e017edf00277102b49c3d", + "0x000000000000000000000000000000000006b41a5fb6e909b8be3ff0dd952728", + "0x0000000000000000000000000000006683ae1c70f7eb680544f4c342c93087f1", + "0x000000000000000000000000000000000025f0aabdb61ed9c3922c0edfb358ec", + "0x000000000000000000000000000000351b5aea3d5e9850880e66335bcae23e94", + "0x00000000000000000000000000000000000ee72d3f7aca6bbe97267028d6abf9", + "0x0000000000000000000000000000008928d9a8e7f72b161cbe49ae95aa21ae63", + "0x0000000000000000000000000000000000185c141dba0abcf1e6d7db09787ca1", + "0x0000000000000000000000000000003e245e17b3e7805608abb6a2350fa6a847", + "0x00000000000000000000000000000000000cf54864a0d0738294136903b96823", + "0x000000000000000000000000000000f11eab4aad68f934214988cc4f58d5a6a2", + "0x000000000000000000000000000000000022f67f7b7d5406007bb7ddae120884", + "0x000000000000000000000000000000c05dc37331557bb9a3f702d92cfe090666", + "0x0000000000000000000000000000000000264629b4e2c6c2614bd57046d2ac8b", + "0x00000000000000000000000000000017305f321100b05a42b9014b4b5f033fd9", + "0x00000000000000000000000000000000000300f05e18d0c58963b144d3d28da6", + "0x00000000000000000000000000000039e8490810fc737b4a353bb67d95baa83c", + "0x00000000000000000000000000000000001b8f101b87ef8f67f87224f50b4e86", + "0x00000000000000000000000000000048da15030eaa7e0cc01567e721d66ead43", + "0x0000000000000000000000000000000000126b3927169eb104827c842837f462", + "0x00000000000000000000000000000008b500094a5820c680fb1db8c125502e1e", + "0x000000000000000000000000000000000000660eef61b7d219f439ec4fbfff1b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000001115e1df83c7f85610477a243a350ad610", + "0x000000000000000000000000000000000016b525f879d97a8d50cab6d1a41d58", + "0x0000000000000000000000000000005545bbd9cc9de7a79986b650103736492e", + "0x00000000000000000000000000000000000aac06f3452ec0a5be2b5e3060f108", + "0x000000000000000000000000000000c6e13ef9aedec4af73a577a6dd72dda690", + "0x000000000000000000000000000000000016b603e70199deaa1eff742257259f", + "0x000000000000000000000000000000dd7902c16a885b205f012abf38e3f9f470", + "0x00000000000000000000000000000000002a45b4a48e9544c186e119184fd191", + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" +] + hash = "0x1e580df70c4374ef9942846936ab5fc2d7da61ca21bd0576f269746152a782c4" + +[previous_kernel_public_inputs] +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c1" +is_private_only = true +claimed_first_nullifier = "0x0f03b3ad77a1cb11c580c3ed7f69278d1374df07f295fbb4d71640819c7732cf" +claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" + + [previous_kernel_public_inputs.constants] + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + + [previous_kernel_public_inputs.constants.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [previous_kernel_public_inputs.constants.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x01d1d92b90682f39cf6b9ed768d21409cc7142c7b1dc75f647c0f3680bc71695" +counter = "0x0000000000000000000000000000000000000000000000000000000000000003" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers] +length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x04868546b55cd61db182599d47524c126a6cb4acc069435e1bac39c4920db227" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.contract_class_logs_hashes] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.contract_class_logs_hashes.array]] +[previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.contract_class_logs_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.public_call_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_call_stack] +length = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000d" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = true + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x023a62eaf4ce3a8f2752add0746950be81e1f647953b1c21f038c8c2f5d94f4a" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.fee_payer] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + +[private_call_0.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_0.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_0.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_0.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_0.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_0.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_0.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_0.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[private_call_1.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_1.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_1.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_1.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_1.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_1.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_1.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_1.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[app_public_inputs_0] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_0.call_context] + is_static_call = true + + [app_public_inputs_0.call_context.msg_sender] + inner = "0x023a62eaf4ce3a8f2752add0746950be81e1f647953b1c21f038c8c2f5d94f4a" + + [app_public_inputs_0.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_0.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_0.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_0.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_0.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_0.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_0.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_0.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_0.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_0.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_0.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_0.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_0.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_0.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_0.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_0.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000d" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000e" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_1.call_context] + is_static_call = false + + [app_public_inputs_1.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [app_public_inputs_1.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_1.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_1.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x000000000000000000000000000000000000000000000000000000000000000e" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_1.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_1.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_1.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_1.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_1.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_1.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_1.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_1.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_1.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_1.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_1.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_1.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_1.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-3/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-3/Prover.toml new file mode 100644 index 000000000000..e8ec43aaea12 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-3/Prover.toml @@ -0,0 +1,11973 @@ +[previous_kernel.vk_data] +leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000041" +sibling_path = [ + "0x12c59c16ed84032f7c5273ff19d7a05e8e861c23959fb71cf4b2c6ac45d21f8c", + "0x225eef52a484280b0f1c6cb9f90a84dc301536c01bfa4d61bd6496b3eaf19052", + "0x0e084e8198288b2ff94eaf4d6f37fba06e430a879dd37c726a3b5a65416fe6b6", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x0e9cb07dc8495e2adab02c5db0e34a0dbe42e9b473e0462641c54f73a4a4fdd3" +] + + [previous_kernel.vk_data.vk] + key = [ + "0x0000000000000000000000000000000000000000000000000000000000000011", + "0x000000000000000000000000000000000000000000000000000000000000001a", + "0x0000000000000000000000000000000000000000000000000000000000000cbd", + "0x000000000000000000000000000000c4d62213b081c8e90e6c8f3587321997f5", + "0x00000000000000000000000000000000002236a0b9f0654f7cd634c9c34280f1", + "0x0000000000000000000000000000007cb00736872fd50e291ec99fb640f1f7d9", + "0x00000000000000000000000000000000002d1b1b74b74ddf7d6f964a7bdb2af3", + "0x000000000000000000000000000000f26bcf89c86dcbce68a4f1b5b73505dcec", + "0x000000000000000000000000000000000011a128ae6c7be3a962485534f27786", + "0x00000000000000000000000000000088278f8cce72a5f698601f11a1532a9dad", + "0x00000000000000000000000000000000000d9caeabde23d8c2a0bd2cdef54193", + "0x0000000000000000000000000000001cfb29930f6753e5cb6a60342c16fe5e4f", + "0x00000000000000000000000000000000001022a2847e12bdd43b96342e5b8e16", + "0x000000000000000000000000000000fefee7789c5b50b89ce3ac6155975c4319", + "0x000000000000000000000000000000000002e25d02799b225c89aba3a667d7e5", + "0x0000000000000000000000000000006e210889b06205312234c097f979fca3b5", + "0x00000000000000000000000000000000000566396dc1f8e15f3a1c3729bb3393", + "0x0000000000000000000000000000009790f776d7aaecbcaf977d3aad6070c4e4", + "0x00000000000000000000000000000000002dcdeaf93e01c780512d9950fbfd94", + "0x000000000000000000000000000000d2ef194a7b605db9c6df08b9576c97735e", + "0x00000000000000000000000000000000001ff98ab3818a3d5fdc538a7bbeb87e", + "0x000000000000000000000000000000be40a925ee773bfc3923df01da59a497d7", + "0x00000000000000000000000000000000001fb52b895f997b5a90ea722d9a4140", + "0x000000000000000000000000000000dd5a7d1074be39e4451795f983d45b5be3", + "0x00000000000000000000000000000000001cbfd5b0d763096343af10ed1f3496", + "0x0000000000000000000000000000007cc56b953bb8ef24745e9200896ee10ee1", + "0x000000000000000000000000000000000001ef96b3ae0b2677b21939012dcc17", + "0x0000000000000000000000000000004ba56f98fc7d6d956bd6302ef6941f9239", + "0x000000000000000000000000000000000010bf82473c11a65eb2ac193002bfe4", + "0x00000000000000000000000000000072739ba831885d7f767251b9cc444961e5", + "0x0000000000000000000000000000000000256ea7e1dc188341f8692fd52454cf", + "0x000000000000000000000000000000a284c1c0bd5602eb7242fda659dc49ff99", + "0x000000000000000000000000000000000002e5e663dd3bf5f961173646b8e7b3", + "0x000000000000000000000000000000194cc54081bb3ffba3c67547dcb2db4d37", + "0x00000000000000000000000000000000002377042c75bab3ceee3b186c40b8b6", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000f0af57d5589fc84e1f8897bb5a62ec0ea9", + "0x000000000000000000000000000000000016583df9856bef930ef0a81d3357f0", + "0x000000000000000000000000000000e0a92aecf729c58fa7672c82066409d090", + "0x000000000000000000000000000000000010085406672c105a10ddee00634540", + "0x00000000000000000000000000000036b650e61cb6e0ec6ff6b1aef12c8c81e3", + "0x00000000000000000000000000000000000049ced3703b6736736daa8d94d66c", + "0x00000000000000000000000000000024e41b443846d1b9d969a739fe9ec5544d", + "0x0000000000000000000000000000000000251ef94ce2811e61503920adc1a548", + "0x000000000000000000000000000000ab378c4d63d86a750348adbd4cbc2c6883", + "0x0000000000000000000000000000000000079aee0bbaec8a7e39acda8a2bfd44", + "0x000000000000000000000000000000c4996ccb316a1671fa17ac0ec536c08aee", + "0x00000000000000000000000000000000000087a93f4353d8c6e85d6c58c7af49", + "0x0000000000000000000000000000002754983ee3f30f64f3ef3d6a27f671032d", + "0x00000000000000000000000000000000001b77b7da696321894ac402dc70a471", + "0x00000000000000000000000000000065a8c950362ff55e55d6006254e4cb8f60", + "0x00000000000000000000000000000000000a0eb81f69be92cc51ba479d4d4b2d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003a6dc78277b2838aca18adc58385b4a7f0", + "0x0000000000000000000000000000000000132c99e752833cae9473e7dfe278d0", + "0x0000000000000000000000000000003ec707e1f4369d5f99a3bac8eaa16ec4ba", + "0x00000000000000000000000000000000001cd77155c0a5e65f942f719c8e73f5", + "0x00000000000000000000000000000084604af6454cd074b40340a0900f8e47cc", + "0x0000000000000000000000000000000000077d31bdfcd802cd5aa1a457b97f10", + "0x00000000000000000000000000000099c886edf1320d2f8eef9c059a2495598d", + "0x00000000000000000000000000000000001400c2b452cd839ce363493a76312b", + "0x00000000000000000000000000000090681337eb7720ddc934e8bcc81bd9ae2b", + "0x000000000000000000000000000000000006ab19688014b0f0cf860c615759af", + "0x0000000000000000000000000000007165a99470ed5af56e75a9636be648e93d", + "0x000000000000000000000000000000000009dbbccaa2350bd92c5ce19b5d290a", + "0x0000000000000000000000000000000e1e042ed81d839a9f0ead9d291b6a8f32", + "0x00000000000000000000000000000000001a205aec8c334db49f816f4b5dafcd", + "0x000000000000000000000000000000ebb4edb0db1dcdf348033a7901a3680b6a", + "0x000000000000000000000000000000000011aae86275b822ebd3fa82c7315eff", + "0x000000000000000000000000000000e97eee8ec09b50e69135709916aba933c6", + "0x000000000000000000000000000000000010e2e96f78a68fc25ba2e4dafd04cc", + "0x000000000000000000000000000000b214f0a5321e8817d78adb6e0c20d7319e", + "0x000000000000000000000000000000000025bc9ba17b749d567d90e8f13af9a2", + "0x00000000000000000000000000000066fba7ba25f999f6f2838e553a29901fa7", + "0x000000000000000000000000000000000020711b883c2eb028f9d2d3da010519", + "0x000000000000000000000000000000a140d481bdc261d13949520f9ec7371c20", + "0x0000000000000000000000000000000000020bfe682fa3abc7653ce6853b0112", + "0x0000000000000000000000000000001b2bf2cbcde5d02c025a94db3378725693", + "0x000000000000000000000000000000000023e613dfd6966df7487e58fd52480c", + "0x0000000000000000000000000000006e2eb63e8f0cbcbd7a88665a53e119e428", + "0x00000000000000000000000000000000002e70d3962ba79ea7ae10b168c1c7d9", + "0x00000000000000000000000000000030517d9ecfee899135ff976333894660c2", + "0x000000000000000000000000000000000007417244ffad99a470ba89eb0ff90e", + "0x0000000000000000000000000000009bac28f405d40e017edf00277102b49c3d", + "0x000000000000000000000000000000000006b41a5fb6e909b8be3ff0dd952728", + "0x0000000000000000000000000000006683ae1c70f7eb680544f4c342c93087f1", + "0x000000000000000000000000000000000025f0aabdb61ed9c3922c0edfb358ec", + "0x000000000000000000000000000000351b5aea3d5e9850880e66335bcae23e94", + "0x00000000000000000000000000000000000ee72d3f7aca6bbe97267028d6abf9", + "0x0000000000000000000000000000008928d9a8e7f72b161cbe49ae95aa21ae63", + "0x0000000000000000000000000000000000185c141dba0abcf1e6d7db09787ca1", + "0x0000000000000000000000000000003e245e17b3e7805608abb6a2350fa6a847", + "0x00000000000000000000000000000000000cf54864a0d0738294136903b96823", + "0x000000000000000000000000000000f11eab4aad68f934214988cc4f58d5a6a2", + "0x000000000000000000000000000000000022f67f7b7d5406007bb7ddae120884", + "0x000000000000000000000000000000c05dc37331557bb9a3f702d92cfe090666", + "0x0000000000000000000000000000000000264629b4e2c6c2614bd57046d2ac8b", + "0x00000000000000000000000000000017305f321100b05a42b9014b4b5f033fd9", + "0x00000000000000000000000000000000000300f05e18d0c58963b144d3d28da6", + "0x00000000000000000000000000000039e8490810fc737b4a353bb67d95baa83c", + "0x00000000000000000000000000000000001b8f101b87ef8f67f87224f50b4e86", + "0x00000000000000000000000000000048da15030eaa7e0cc01567e721d66ead43", + "0x0000000000000000000000000000000000126b3927169eb104827c842837f462", + "0x00000000000000000000000000000008b500094a5820c680fb1db8c125502e1e", + "0x000000000000000000000000000000000000660eef61b7d219f439ec4fbfff1b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000001115e1df83c7f85610477a243a350ad610", + "0x000000000000000000000000000000000016b525f879d97a8d50cab6d1a41d58", + "0x0000000000000000000000000000005545bbd9cc9de7a79986b650103736492e", + "0x00000000000000000000000000000000000aac06f3452ec0a5be2b5e3060f108", + "0x000000000000000000000000000000c6e13ef9aedec4af73a577a6dd72dda690", + "0x000000000000000000000000000000000016b603e70199deaa1eff742257259f", + "0x000000000000000000000000000000dd7902c16a885b205f012abf38e3f9f470", + "0x00000000000000000000000000000000002a45b4a48e9544c186e119184fd191", + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" +] + hash = "0x1e580df70c4374ef9942846936ab5fc2d7da61ca21bd0576f269746152a782c4" + +[previous_kernel_public_inputs] +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c1" +is_private_only = true +claimed_first_nullifier = "0x2b17c43e24196724833491ef10cd2e263c2541b0a2ce69df8cb6f80afcaa89da" +claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" + + [previous_kernel_public_inputs.constants] + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + + [previous_kernel_public_inputs.constants.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [previous_kernel_public_inputs.constants.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[previous_kernel_public_inputs.constants.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x01d1d92b90682f39cf6b9ed768d21409cc7142c7b1dc75f647c0f3680bc71695" +counter = "0x0000000000000000000000000000000000000000000000000000000000000003" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array]] +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner] +key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.note_hashes.array]] +[previous_kernel_public_inputs.end.note_hashes.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.note_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers] +length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x1f2d325e53b36b047c5d53521b42951773c7b94e77d80b6c1a6ac3badfd68ccd" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.nullifiers.array]] +[previous_kernel_public_inputs.end.nullifiers.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.nullifiers.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.l2_to_l1_msgs.array]] +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.l2_to_l1_msgs.array.inner.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.l2_to_l1_msgs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_logs.array]] +[previous_kernel_public_inputs.end.private_logs.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_logs.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.contract_class_logs_hashes] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.contract_class_logs_hashes.array]] +[previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner] +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.contract_class_logs_hashes.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.public_call_requests] +length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[previous_kernel_public_inputs.end.private_call_stack] +length = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000010" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000012" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000d" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = true + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x023a62eaf4ce3a8f2752add0746950be81e1f647953b1c21f038c8c2f5d94f4a" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[previous_kernel_public_inputs.end.private_call_stack.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context] + is_static_call = false + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [previous_kernel_public_inputs.fee_payer] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + +[private_call_0.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_0.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_0.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_0.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_0.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_0.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_0.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_0.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[private_call_1.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_1.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_1.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_1.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_1.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_1.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_1.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_1.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[private_call_2.vk] +key = [ + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" +] +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" + +[private_call_2.verification_key_hints] +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" +updated_class_id_delayed_public_mutable_values = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + + [private_call_2.verification_key_hints.function_leaf_membership_witness] + leaf_index = "1" + sibling_path = [ + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", + "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", + "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", + "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" +] + + [private_call_2.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" + +[private_call_2.verification_key_hints.public_keys.ivpk_m.inner] +x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" +y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" +is_infinite = false + + [private_call_2.verification_key_hints.salted_initialization_hash] + inner = "0x16e38e91838134a964d7a5a42f03951c253f10dc548680d7d77a4a6ab193d8b3" + + [private_call_2.verification_key_hints.updated_class_id_witness] + leaf_index = "120" + sibling_path = [ + "0x03948d03e299b62ec468a36c5aaed9b2ec99de1ca6f891b5e35a38b224e0241e", + "0x26fa5749dc6bf5ae73016be4123dd8999a6f2f3b0c83000fb2957b91517a9a3f", + "0x159012fcfa91ebac3d7456369b7ef07c234cdc6450d29b3dfa36b3bfb255531d", + "0x23b7b4afca7eeb88b7d797b2fddc90b144e51b508e702e39ec4af07a6049f4a5", + "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", + "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", + "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", + "0x18ac27f81c0a8a78e77797c10cab4fbade9633a67765586f1bf66e2eb833a029", + "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", + "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", + "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", + "0x002b13fd827e0e0d6b4b44c63fdeaf75cfed5190728ff712530f5f0f6f92b1e4", + "0x1b61a4759569c7e380534b815a326c2f0614ce68188b3421b09db1a560349f4b", + "0x24faee168ea3e7ce5d9d22f24679594896a633ca5d12947fbcd2c28b1d27f94e", + "0x2c0e30deebb4fc9949601b0240d319424d3169290c5cd22c49c2f80b43491c24", + "0x1633b0cb253526da43ee63f3ec7a5ff4c9122f6f6ff53c5be3d6ee7e1daa7a4b", + "0x21a12dfd04d263a6a93feb45f10ae47f6142e9e0e29d66c20581bfa463983f43", + "0x0d02013ff44b6cc6cf983824fe5104671333c8243de05421c7a94033b02ef493", + "0x2f99a81e7faafb4d396d0cc32fe7e024c191325432ec3deb26878c8e69aa8a74", + "0x0f608351d05582fbead9c229631e4225305201e70d552a4c23915db3263507e3", + "0x1a85d719ace8c684b69950b47b17fb4b8a67b4454a5a8ff68bc33c2da4db4ce6", + "0x0ca806e767c92a5a84ae7fbc87886017fd616d5bb9944e76cb744051e30f8653", + "0x2dcebbd4d2afb62103883556c608e2ab29a0741ff744317f74d74ead537241db", + "0x0ceca69e0225bf70d28927ed19b793b034137ed87c901dd468a5c7d019b0c5a0", + "0x1983e65b490c4c4a2f0ba1bec5cf90a4cef0df719453e3c781d6310e7cdbcdd4", + "0x076cd8d40f992539f8034583bc6f2875f14eede666b8ddf12aac71fe90fd69ce", + "0x0caa288adc7dc74c3b3def6da3c6dcf8686ec1274eb35882437b2468ab598176", + "0x0179c92d038dd475c55c50689d306b24f0b7ff3622802b910be46b43ecef6596", + "0x1e60a8b88790824b178e6de4e2fa4f4623acd0a0bf100ba8fd9ccf95a7c9ca1c", + "0x0a0ce3ff3f93a8b62f857fb65f6e7db9330936e59b5ac6aa81a74c39aa5aeb1c", + "0x103f2e85701d4675ad6301fd100ffd649afc1f83a31ffbc7a71f12ba02625df5", + "0x1fb00a9227786ad2097c61cad83c201267d75841911691a9f554d8a02d3ecc90", + "0x19aedacdf53ccbe46ede5f653e3aa90872dd7184bf72b9a3763f750553a0fd9f", + "0x29c1557a25b705aa12decc723da5bc6ee57ff0d73dcd2eeeeeb8502d52bb80e2", + "0x1bfa49b22303484fb94e39d5e675fc3e71879d694b75e04eb521fdf7811997b8", + "0x15c54e05a78faa6df55608aa09cc2b4d94f9aecce72c64656ab2b1672a1acf35", + "0x1b5bf5d6a04a7fdc1f0ad8d5932c215ecd4d63c63d4c1af5b3d4947f66c9b194", + "0x0fdb0bd3ddf4531ca4f1de9e1a0d5d5997669c98f410e18e295cbc70e991f729", + "0x1e8e5a078bc01f2bfe12ffdf5cbd75109055869f0a6707b5c8eddbca3b9052ab", + "0x2995c91c614c3274568d97c6f8c70b9df77361434f18e77b48a19c390090c44c" +] + + [private_call_2.verification_key_hints.updated_class_id_leaf] + slot = "0x04aa829f7be68332750465e03b92ef63bc6e0fff7cfb1cf00ddc341e88632006" + value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" + next_slot = "0x077bb0f475657569d91f21509c7c928e0850ac34e02583083e1b0a901587c4c0" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000084" + +[app_public_inputs_0] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_0.call_context] + is_static_call = true + + [app_public_inputs_0.call_context.msg_sender] + inner = "0x023a62eaf4ce3a8f2752add0746950be81e1f647953b1c21f038c8c2f5d94f4a" + + [app_public_inputs_0.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_0.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_0.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hash_read_requests.array]] +[app_public_inputs_0.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifier_read_requests.array]] +[app_public_inputs_0.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_0.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_0.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_0.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_0.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_0.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_0.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_0.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_0.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_0.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_0.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_0.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_0.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_0.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_0.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_0.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_0.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_0.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000d" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000f" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000e" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_1.call_context] + is_static_call = false + + [app_public_inputs_1.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [app_public_inputs_1.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_1.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_1.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x000000000000000000000000000000000000000000000000000000000000000e" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hash_read_requests.array]] +[app_public_inputs_1.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifier_read_requests.array]] +[app_public_inputs_1.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_1.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_1.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_1.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_1.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_1.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_1.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_1.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_1.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_1.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_1.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_1.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_1.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_1.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_1.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_1.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_1.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_1.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2] +args_hash = "0x06a98a2a35aa4722fcc00b92195e61295f6b1c621792fcfe00191381a31178f8" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000010" +end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000012" +expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000011" +min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +is_fee_payer = false +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0d84c2" + + [app_public_inputs_2.call_context] + is_static_call = false + + [app_public_inputs_2.call_context.msg_sender] + inner = "0x1f3be138a5383c5ae6bfe93f200978857538b2100be1f25186f9da6e3e304d67" + + [app_public_inputs_2.call_context.contract_address] + inner = "0x023e27ffe99ffb57c23b47f77298a16e82b8166a3a052ce3217b06f27a693e8d" + + [app_public_inputs_2.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" + + [app_public_inputs_2.note_hash_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000001" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x158140e435824e3e5383ec9780da5083f41b9135df43fe241efc116fb988f802" +counter = "0x0000000000000000000000000000000000000000000000000000000000000011" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hash_read_requests.array]] +[app_public_inputs_2.note_hash_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.note_hash_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifier_read_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifier_read_requests.array]] +[app_public_inputs_2.nullifier_read_requests.array.inner] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[app_public_inputs_2.nullifier_read_requests.array.contract_address] +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.key_validation_requests_and_separators.array]] + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.note_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.note_hashes.array]] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.nullifiers.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.nullifiers.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_call_requests.array]] + args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context] + is_static_call = false + + [app_public_inputs_2.private_call_requests.array.call_context.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_call_requests.array.call_context.function_selector] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.public_call_requests.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_call_requests.array.inner.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request] + is_static_call = false + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request.msg_sender] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.public_teardown_call_request.contract_address] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.l2_to_l1_msgs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner] + content = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.l2_to_l1_msgs.array.inner.recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.private_logs.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner] + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.private_logs.array.inner.log] + fields = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.contract_class_logs_hashes] + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [[app_public_inputs_2.contract_class_logs_hashes.array]] + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.contract_class_logs_hashes.array.inner] + value = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.anchor_block_header] + sponge_blob_hash = "0x2a15dc7ec43b465bf99f54afeddf01deb1956bc1b168dca0dee3fd42651c066d" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" + + [app_public_inputs_2.anchor_block_header.last_archive] + root = "0x17bffe007799492e080dedbbd1c0537f2cf07c6da475964e6ba2ac1238ca18b4" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + +[app_public_inputs_2.anchor_block_header.state.l1_to_l2_message_tree] +root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + +[app_public_inputs_2.anchor_block_header.state.partial.note_hash_tree] +root = "0x0dc9959e45144b0bff03308b20445805d413ef104b8c1cffec0df82fa026ddac" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" + +[app_public_inputs_2.anchor_block_header.state.partial.nullifier_tree] +root = "0x0429ae2142380c233e3eaae7cb2139acb56e5f1655f0c0869a2c86b61945ac79" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" + +[app_public_inputs_2.anchor_block_header.state.partial.public_data_tree] +root = "0x2e98690a14fa5e0ac8d56a825563ca3e2331f9be07e1e2065af4aaeb5fe569d2" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" + + [app_public_inputs_2.anchor_block_header.global_variables] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c3342" + + [app_public_inputs_2.anchor_block_header.global_variables.coinbase] + inner = "0x000000000000000000000000aa302018c588f8a0cbf1c93ef6e17276cf33d1ef" + + [app_public_inputs_2.anchor_block_header.global_variables.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [app_public_inputs_2.anchor_block_header.global_variables.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + + [app_public_inputs_2.tx_context] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" + version = "0x00000000000000000000000000000000000000000000000000000000fb3702bd" + +[app_public_inputs_2.tx_context.gas_settings.gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" +l2_gas = "0x000000000000000000000000000000000000000000000000000000000063cae0" + +[app_public_inputs_2.tx_context.gas_settings.teardown_gas_limits] +da_gas = "0x0000000000000000000000000000000000000000000000000000000000018000" +l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" + +[app_public_inputs_2.tx_context.gas_settings.max_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" + +[app_public_inputs_2.tx_context.gas_settings.max_priority_fees_per_gas] +fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" +fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/Prover.toml index 91f33eeac7c0..8b18e90b3cd2 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/Prover.toml @@ -1,128 +1,128 @@ [previous_kernel.vk_data] -leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000041" sibling_path = [ - "0x0ddc610a21615b2984181082c3de07058b9f7d4be62806c4fd475161f8bd2be3", - "0x0f92d54d29bddf6ec768db2c0b4685fb325d248b3ad9a3c6adda76c6c5004224", - "0x0656bbf5e3f4cc4fa5e2fa46e7fd370db0bee05586a1849c37c77d05abe2d8a5", - "0x166399703d23a5c22febc6185f8eb93c72b65906eefef226e643c35fa0022adb", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x12c59c16ed84032f7c5273ff19d7a05e8e861c23959fb71cf4b2c6ac45d21f8c", + "0x225eef52a484280b0f1c6cb9f90a84dc301536c01bfa4d61bd6496b3eaf19052", + "0x0e084e8198288b2ff94eaf4d6f37fba06e430a879dd37c726a3b5a65416fe6b6", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x0e9cb07dc8495e2adab02c5db0e34a0dbe42e9b473e0462641c54f73a4a4fdd3" ] [previous_kernel.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000011", "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000c11", - "0x000000000000000000000000000000b56b478d39fe1ea8636ca1c5f7efe26465", - "0x00000000000000000000000000000000002ce8a9b4b8b40012f631f6a39b6121", - "0x000000000000000000000000000000e90605e79e3b491b4e35bed971ffe40f20", - "0x000000000000000000000000000000000014aac08af29b80ea5e82169bde9f1b", - "0x000000000000000000000000000000f23100dd9e774faa9da6adabb0a5e868d1", - "0x00000000000000000000000000000000000675d3fb2db13df5feb7837a996202", - "0x0000000000000000000000000000002d41a263946c21172989f16b6c3eabd14b", - "0x00000000000000000000000000000000002f76f5733e8a0b6e45ad715c844fa3", - "0x0000000000000000000000000000009906b77efd02f89dd64543cb41b2ee7dc0", - "0x000000000000000000000000000000000011990c3a05d603a15abfdd104b7f45", - "0x000000000000000000000000000000b68418cb6eb350097b81ceebf7216de49f", - "0x0000000000000000000000000000000000193b041e80721ea6304e3edc45a55a", - "0x0000000000000000000000000000007f41793e8f1a2fbe4047a8c9b3ea8a7eba", - "0x000000000000000000000000000000000004ad79eb6e09a672b49359e429d4b2", - "0x00000000000000000000000000000084b9e57a26da81e52f9d96f484a3d8a6ae", - "0x00000000000000000000000000000000001b4cff12b3ca2c242b1cb101ca1f62", - "0x00000000000000000000000000000051285e317a9d17f2180bf8ec1f3e31c266", - "0x00000000000000000000000000000000002f79f4597dc1cbdfe8060d1d92c7fc", - "0x000000000000000000000000000000bfdd478df770ff0d6a9f5d30c6380e3bb2", - "0x00000000000000000000000000000000000f6c52e2949dd6fa7eff016e2e5bb6", - "0x0000000000000000000000000000001cba707dc36043107ad882453ae5d8b129", - "0x0000000000000000000000000000000000059cc841348db66a31d2dfa33b89a0", - "0x0000000000000000000000000000000e2b2caaf1a1eda41d509cc5221c984b51", - "0x0000000000000000000000000000000000037cc127472715a44cac19993d448a", - "0x0000000000000000000000000000003cc6bfe8250e54d57ce7daedc9a7095bc8", - "0x00000000000000000000000000000000001c95108bb4f2494bfef842093c3b36", - "0x0000000000000000000000000000008313e6a820b2f5c2a7de8028cd31798633", - "0x000000000000000000000000000000000027be294c15550f339b0839d5860142", - "0x00000000000000000000000000000060338657a29bcf8c13a4b50294e337ef11", - "0x00000000000000000000000000000000001569de523f46c6226a398155490417", - "0x000000000000000000000000000000163a5d9281ca7ac774da33d1bd5e32dd54", - "0x00000000000000000000000000000000001cea3677784e36b40d3084060d7486", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000008a36ca53543c7bd871dd8974dda60ec04e", - "0x000000000000000000000000000000000028fcc75fb20c13fa73b0b5dd1a9df0", - "0x000000000000000000000000000000646eccdb4bcb213d9d9867f291bc4cc715", - "0x0000000000000000000000000000000000239e0bfd2fe8666da2541d2b7e9242", - "0x00000000000000000000000000000057b0434a909bdd123f328dd722f50de441", - "0x0000000000000000000000000000000000056e909ead4cc889ca4ae259618b9e", - "0x000000000000000000000000000000cce3583f4dbdf7f0ea96b8413114530b7f", - "0x0000000000000000000000000000000000029d93569d5fb4eccfe54516bbfc2c", - "0x0000000000000000000000000000000202259bdd735f5d0996b36a14296dd956", - "0x00000000000000000000000000000000001c9a81340c0ef1a3f8ab9378b45228", - "0x000000000000000000000000000000bb9541231ccc05d3210933db9b2cfd662a", - "0x00000000000000000000000000000000002e90121d7079020ef60bf83a167d82", - "0x0000000000000000000000000000008e531da6a57f645193723255cc3949f2a6", - "0x000000000000000000000000000000000023d3bfa481c11731a958ae003b7049", - "0x0000000000000000000000000000005d505cd2a7715559ab2fb8ffa94fac158b", - "0x0000000000000000000000000000000000283299e0b6841cadaef68c90af63b3", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a50e32219d22dc5bc0a2a3afa8d1c963bf", - "0x00000000000000000000000000000000001b05579d422ec3526b639fa813b3db", - "0x000000000000000000000000000000931e9ee47cc6828d015bfd807445f50921", - "0x000000000000000000000000000000000005283cabb6b55f9baa597d00d3f46f", - "0x000000000000000000000000000000f14ecdef3987001b29e5574b25db85e726", - "0x00000000000000000000000000000000002b26e84ba3e9db90b9b761fbd5ba48", - "0x00000000000000000000000000000054401c158e8bfa1eac201ac628df1458d3", - "0x000000000000000000000000000000000028b61261027652e8ca3b29fb567872", - "0x0000000000000000000000000000005ddf21ec29f762249f79a86d986723b259", - "0x000000000000000000000000000000000020d889a78eaaeeced668f7a5e6a155", - "0x000000000000000000000000000000fbf31736f1c118ed779b00b56effa82f84", - "0x00000000000000000000000000000000001c10198fa65839280c9a4df0d48c69", - "0x000000000000000000000000000000ae45bd31909c920cd302c1833dc9dac27c", - "0x00000000000000000000000000000000000b5e828a1794bb52b1ef28384f36c3", - "0x000000000000000000000000000000623a32eccef6d3f192c9090e2c8d211339", - "0x000000000000000000000000000000000017dbcb62b1ef67a30ab74432100e03", - "0x0000000000000000000000000000008e75c04775713fe2b95076a7a5e1036c46", - "0x0000000000000000000000000000000000070ea9b40827062280d6e3cc9609a6", - "0x000000000000000000000000000000c70577cdcada107c62a7732ef0d2bbc15f", - "0x00000000000000000000000000000000002e57c64ac76e0a1e1c5980782cb606", - "0x000000000000000000000000000000902c14297534b09b2a8072cd93a9489887", - "0x00000000000000000000000000000000000cb983d7cc09d74a951dbf12ad432b", - "0x00000000000000000000000000000012bff816b24bc7a97ad6b1549515d6b28e", - "0x00000000000000000000000000000000000467570dff77ca3a342e4fc4d1a66b", - "0x00000000000000000000000000000080a63925457f739d70103395ccb7dcd29d", - "0x00000000000000000000000000000000000249558e7e5b5d6473ec5a9a980688", - "0x0000000000000000000000000000006cd74958767b5d51a95549a316e285ab74", - "0x0000000000000000000000000000000000091261933d2e12b6818f72bdc3e0c2", - "0x000000000000000000000000000000f97e56f24f292a230cf6c8350df6989d74", - "0x0000000000000000000000000000000000191f5e720c5ae2ded820c5e22cf23f", - "0x000000000000000000000000000000d3659c79160cc300c1726cdfe0a093bc08", - "0x000000000000000000000000000000000028e8e8952512f8006336791f90f01d", - "0x0000000000000000000000000000007ee7b8782f98bb5d90cbdc6fe174a42009", - "0x00000000000000000000000000000000000ae0ee6c55535140057064aa3fc5f0", - "0x000000000000000000000000000000d2bb98513b84e1e6f4e0b606bc025f9c48", - "0x00000000000000000000000000000000000b21f9d209054956c0524fababf1e9", - "0x000000000000000000000000000000d81d8ac019f7fed05a6b57f7845f56e44f", - "0x00000000000000000000000000000000002971c35ad470594c9a15abfc0e25a6", - "0x000000000000000000000000000000415d3a9385f247cc4092e3aad3382acd35", - "0x000000000000000000000000000000000025f0852ecc99395598d1e68d0ca89f", - "0x0000000000000000000000000000004f32605fa17fb311a06f7fb843c15d558a", - "0x000000000000000000000000000000000005071f43d210d49c73d5f25a18a596", - "0x0000000000000000000000000000000a679653df2810b4ec4c7adcd1cd7c97c8", - "0x000000000000000000000000000000000013c145ee6755ca17c398dafb88a569", - "0x00000000000000000000000000000083bace0537b2947643af96ab4b4aa8c478", - "0x000000000000000000000000000000000011ae383aeafc332a329462493ac315", - "0x000000000000000000000000000000a18bcfba0739bc5f71bd74ec53b6837fea", - "0x00000000000000000000000000000000001c2a9a991c7dbcd75129f92ff372b1", - "0x0000000000000000000000000000002c80b406fa46ad088b2e8d4f5a5701d47c", - "0x00000000000000000000000000000000001879ed897e504955597f01336b1d86", - "0x000000000000000000000000000000655b7a8802d367044c042458a17a0aeab4", - "0x000000000000000000000000000000000021be3e235af1a949dbf105cbe725d0", + "0x0000000000000000000000000000000000000000000000000000000000000cbd", + "0x000000000000000000000000000000c4d62213b081c8e90e6c8f3587321997f5", + "0x00000000000000000000000000000000002236a0b9f0654f7cd634c9c34280f1", + "0x0000000000000000000000000000007cb00736872fd50e291ec99fb640f1f7d9", + "0x00000000000000000000000000000000002d1b1b74b74ddf7d6f964a7bdb2af3", + "0x000000000000000000000000000000f26bcf89c86dcbce68a4f1b5b73505dcec", + "0x000000000000000000000000000000000011a128ae6c7be3a962485534f27786", + "0x00000000000000000000000000000088278f8cce72a5f698601f11a1532a9dad", + "0x00000000000000000000000000000000000d9caeabde23d8c2a0bd2cdef54193", + "0x0000000000000000000000000000001cfb29930f6753e5cb6a60342c16fe5e4f", + "0x00000000000000000000000000000000001022a2847e12bdd43b96342e5b8e16", + "0x000000000000000000000000000000fefee7789c5b50b89ce3ac6155975c4319", + "0x000000000000000000000000000000000002e25d02799b225c89aba3a667d7e5", + "0x0000000000000000000000000000006e210889b06205312234c097f979fca3b5", + "0x00000000000000000000000000000000000566396dc1f8e15f3a1c3729bb3393", + "0x0000000000000000000000000000009790f776d7aaecbcaf977d3aad6070c4e4", + "0x00000000000000000000000000000000002dcdeaf93e01c780512d9950fbfd94", + "0x000000000000000000000000000000d2ef194a7b605db9c6df08b9576c97735e", + "0x00000000000000000000000000000000001ff98ab3818a3d5fdc538a7bbeb87e", + "0x000000000000000000000000000000be40a925ee773bfc3923df01da59a497d7", + "0x00000000000000000000000000000000001fb52b895f997b5a90ea722d9a4140", + "0x000000000000000000000000000000dd5a7d1074be39e4451795f983d45b5be3", + "0x00000000000000000000000000000000001cbfd5b0d763096343af10ed1f3496", + "0x0000000000000000000000000000007cc56b953bb8ef24745e9200896ee10ee1", + "0x000000000000000000000000000000000001ef96b3ae0b2677b21939012dcc17", + "0x0000000000000000000000000000004ba56f98fc7d6d956bd6302ef6941f9239", + "0x000000000000000000000000000000000010bf82473c11a65eb2ac193002bfe4", + "0x00000000000000000000000000000072739ba831885d7f767251b9cc444961e5", + "0x0000000000000000000000000000000000256ea7e1dc188341f8692fd52454cf", + "0x000000000000000000000000000000a284c1c0bd5602eb7242fda659dc49ff99", + "0x000000000000000000000000000000000002e5e663dd3bf5f961173646b8e7b3", + "0x000000000000000000000000000000194cc54081bb3ffba3c67547dcb2db4d37", + "0x00000000000000000000000000000000002377042c75bab3ceee3b186c40b8b6", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000f0af57d5589fc84e1f8897bb5a62ec0ea9", + "0x000000000000000000000000000000000016583df9856bef930ef0a81d3357f0", + "0x000000000000000000000000000000e0a92aecf729c58fa7672c82066409d090", + "0x000000000000000000000000000000000010085406672c105a10ddee00634540", + "0x00000000000000000000000000000036b650e61cb6e0ec6ff6b1aef12c8c81e3", + "0x00000000000000000000000000000000000049ced3703b6736736daa8d94d66c", + "0x00000000000000000000000000000024e41b443846d1b9d969a739fe9ec5544d", + "0x0000000000000000000000000000000000251ef94ce2811e61503920adc1a548", + "0x000000000000000000000000000000ab378c4d63d86a750348adbd4cbc2c6883", + "0x0000000000000000000000000000000000079aee0bbaec8a7e39acda8a2bfd44", + "0x000000000000000000000000000000c4996ccb316a1671fa17ac0ec536c08aee", + "0x00000000000000000000000000000000000087a93f4353d8c6e85d6c58c7af49", + "0x0000000000000000000000000000002754983ee3f30f64f3ef3d6a27f671032d", + "0x00000000000000000000000000000000001b77b7da696321894ac402dc70a471", + "0x00000000000000000000000000000065a8c950362ff55e55d6006254e4cb8f60", + "0x00000000000000000000000000000000000a0eb81f69be92cc51ba479d4d4b2d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003a6dc78277b2838aca18adc58385b4a7f0", + "0x0000000000000000000000000000000000132c99e752833cae9473e7dfe278d0", + "0x0000000000000000000000000000003ec707e1f4369d5f99a3bac8eaa16ec4ba", + "0x00000000000000000000000000000000001cd77155c0a5e65f942f719c8e73f5", + "0x00000000000000000000000000000084604af6454cd074b40340a0900f8e47cc", + "0x0000000000000000000000000000000000077d31bdfcd802cd5aa1a457b97f10", + "0x00000000000000000000000000000099c886edf1320d2f8eef9c059a2495598d", + "0x00000000000000000000000000000000001400c2b452cd839ce363493a76312b", + "0x00000000000000000000000000000090681337eb7720ddc934e8bcc81bd9ae2b", + "0x000000000000000000000000000000000006ab19688014b0f0cf860c615759af", + "0x0000000000000000000000000000007165a99470ed5af56e75a9636be648e93d", + "0x000000000000000000000000000000000009dbbccaa2350bd92c5ce19b5d290a", + "0x0000000000000000000000000000000e1e042ed81d839a9f0ead9d291b6a8f32", + "0x00000000000000000000000000000000001a205aec8c334db49f816f4b5dafcd", + "0x000000000000000000000000000000ebb4edb0db1dcdf348033a7901a3680b6a", + "0x000000000000000000000000000000000011aae86275b822ebd3fa82c7315eff", + "0x000000000000000000000000000000e97eee8ec09b50e69135709916aba933c6", + "0x000000000000000000000000000000000010e2e96f78a68fc25ba2e4dafd04cc", + "0x000000000000000000000000000000b214f0a5321e8817d78adb6e0c20d7319e", + "0x000000000000000000000000000000000025bc9ba17b749d567d90e8f13af9a2", + "0x00000000000000000000000000000066fba7ba25f999f6f2838e553a29901fa7", + "0x000000000000000000000000000000000020711b883c2eb028f9d2d3da010519", + "0x000000000000000000000000000000a140d481bdc261d13949520f9ec7371c20", + "0x0000000000000000000000000000000000020bfe682fa3abc7653ce6853b0112", + "0x0000000000000000000000000000001b2bf2cbcde5d02c025a94db3378725693", + "0x000000000000000000000000000000000023e613dfd6966df7487e58fd52480c", + "0x0000000000000000000000000000006e2eb63e8f0cbcbd7a88665a53e119e428", + "0x00000000000000000000000000000000002e70d3962ba79ea7ae10b168c1c7d9", + "0x00000000000000000000000000000030517d9ecfee899135ff976333894660c2", + "0x000000000000000000000000000000000007417244ffad99a470ba89eb0ff90e", + "0x0000000000000000000000000000009bac28f405d40e017edf00277102b49c3d", + "0x000000000000000000000000000000000006b41a5fb6e909b8be3ff0dd952728", + "0x0000000000000000000000000000006683ae1c70f7eb680544f4c342c93087f1", + "0x000000000000000000000000000000000025f0aabdb61ed9c3922c0edfb358ec", + "0x000000000000000000000000000000351b5aea3d5e9850880e66335bcae23e94", + "0x00000000000000000000000000000000000ee72d3f7aca6bbe97267028d6abf9", + "0x0000000000000000000000000000008928d9a8e7f72b161cbe49ae95aa21ae63", + "0x0000000000000000000000000000000000185c141dba0abcf1e6d7db09787ca1", + "0x0000000000000000000000000000003e245e17b3e7805608abb6a2350fa6a847", + "0x00000000000000000000000000000000000cf54864a0d0738294136903b96823", + "0x000000000000000000000000000000f11eab4aad68f934214988cc4f58d5a6a2", + "0x000000000000000000000000000000000022f67f7b7d5406007bb7ddae120884", + "0x000000000000000000000000000000c05dc37331557bb9a3f702d92cfe090666", + "0x0000000000000000000000000000000000264629b4e2c6c2614bd57046d2ac8b", + "0x00000000000000000000000000000017305f321100b05a42b9014b4b5f033fd9", + "0x00000000000000000000000000000000000300f05e18d0c58963b144d3d28da6", + "0x00000000000000000000000000000039e8490810fc737b4a353bb67d95baa83c", + "0x00000000000000000000000000000000001b8f101b87ef8f67f87224f50b4e86", + "0x00000000000000000000000000000048da15030eaa7e0cc01567e721d66ead43", + "0x0000000000000000000000000000000000126b3927169eb104827c842837f462", + "0x00000000000000000000000000000008b500094a5820c680fb1db8c125502e1e", + "0x000000000000000000000000000000000000660eef61b7d219f439ec4fbfff1b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -143,76 +143,76 @@ sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000006ab4e9fba1bb0c45d30796e0c19546192e", - "0x00000000000000000000000000000000000b1447f3413f687009608e1c55b192", - "0x000000000000000000000000000000567498365d293b6c0532b94c33d0e937a5", - "0x000000000000000000000000000000000006c4fabfa5194704563bcc508d234e", - "0x00000000000000000000000000000009835f11bc7b963372a60d92370980b183", - "0x00000000000000000000000000000000000d898f5e8487e3ed90a10fc50db186", - "0x000000000000000000000000000000b66ee3d15932d652c3b54801748e89da9f", - "0x000000000000000000000000000000000024899f4b6ba56af0e1128c4a431ba7", - "0x00000000000000000000000000000064dd7da7637cf2116a18531edc7fea829a", - "0x0000000000000000000000000000000000162e867465b02e01bbabb15c59b84d", - "0x00000000000000000000000000000071f09c1d3d2c8f9499c838fc966b04ada9", - "0x00000000000000000000000000000000000f4504ac6f302739e9f2c7aa824d12" + "0x0000000000000000000000000000001115e1df83c7f85610477a243a350ad610", + "0x000000000000000000000000000000000016b525f879d97a8d50cab6d1a41d58", + "0x0000000000000000000000000000005545bbd9cc9de7a79986b650103736492e", + "0x00000000000000000000000000000000000aac06f3452ec0a5be2b5e3060f108", + "0x000000000000000000000000000000c6e13ef9aedec4af73a577a6dd72dda690", + "0x000000000000000000000000000000000016b603e70199deaa1eff742257259f", + "0x000000000000000000000000000000dd7902c16a885b205f012abf38e3f9f470", + "0x00000000000000000000000000000000002a45b4a48e9544c186e119184fd191", + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" ] - hash = "0x051d17b4a7efa4af82e7c6b71f2a5cf71ee015e6d9edbcd39d326a5463aac1e6" + hash = "0x1e580df70c4374ef9942846936ab5fc2d7da61ca21bd0576f269746152a782c4" [previous_kernel_public_inputs] min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff293f" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7f3e" is_private_only = true -claimed_first_nullifier = "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c" +claimed_first_nullifier = "0x1b684937417a003a0e2c1602203b7630f3c2b65c422dfa2653acb1215dc0c852" claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" [previous_kernel_public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" [previous_kernel_public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [previous_kernel_public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -231,22 +231,22 @@ fee_per_da_gas = "0x000000000000000000000000000000000000000000000000000000000000 fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -268,7 +268,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] [previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] -inner = "0x29ecb485abf1e4a9963bb4dada6e8b67bda9c6bb09527ecb8d0c64a0d119e0fd" +inner = "0x302a86bd5883e95684cbcd46af941e62a60b0416ee605f00eae4a0189b8af2ee" counter = "0x0000000000000000000000000000000000000000000000000000000000000003" [previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] @@ -1301,13 +1301,9 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1316,13 +1312,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1331,13 +1323,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1346,13 +1334,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1361,13 +1345,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1376,13 +1356,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1391,13 +1367,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1406,13 +1378,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1421,13 +1389,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1436,13 +1400,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1451,13 +1411,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1466,13 +1422,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1481,13 +1433,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1496,13 +1444,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1511,13 +1455,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1526,13 +1466,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1541,13 +1477,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1556,13 +1488,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1571,13 +1499,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1586,13 +1510,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1601,13 +1521,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1616,13 +1532,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1631,13 +1543,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1646,13 +1554,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1661,13 +1565,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1676,13 +1576,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1691,13 +1587,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1706,13 +1598,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1721,13 +1609,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1736,13 +1620,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1751,13 +1631,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1766,13 +1642,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1781,13 +1653,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1796,13 +1664,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1811,13 +1675,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1826,13 +1686,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1841,13 +1697,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1856,13 +1708,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1871,13 +1719,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1886,13 +1730,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1901,13 +1741,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1916,13 +1752,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1931,13 +1763,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1946,13 +1774,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1961,13 +1785,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1976,13 +1796,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1991,13 +1807,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2006,13 +1818,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2021,13 +1829,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2036,13 +1840,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2051,13 +1851,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2066,13 +1862,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2081,13 +1873,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2096,13 +1884,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2111,13 +1895,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2126,13 +1906,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2141,13 +1917,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2156,13 +1928,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2171,13 +1939,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2186,13 +1950,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2201,13 +1961,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2216,13 +1972,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2231,13 +1983,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2246,13 +1994,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2779,7 +2523,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" counter = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x1f9942757ace032bb97eaa996ab3756544b55ccf805fdbf6f5093a5b8037e138" + value = "0x17479bfa3540b0edace48659f4f97a2f4dc9d4023b9c08bba4a1819e0ef21beb" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -6009,22 +5753,22 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.private_call_stack.array]] - args_hash = "0x00fdacb86277b5caac1f0395131955d3d7ddd5988f117d742d59ecdeef9db7a5" - returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" - end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000010" + args_hash = "0x05eabce2b553dfa52a6b3f33cd603318310b2f9f56a14d6eefbd3bbf640cb107" + returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" + start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" + end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" [previous_kernel_public_inputs.end.private_call_stack.array.call_context] - is_static_call = false + is_static_call = true [previous_kernel_public_inputs.end.private_call_stack.array.call_context.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x09d3e27b2b71e2140366b7b610129b819b841efe0dc06bf715e3eb5b68f65571" [previous_kernel_public_inputs.end.private_call_stack.array.call_context.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c" [previous_kernel_public_inputs.end.private_call_stack.array.call_context.function_selector] - inner = "0x00000000000000000000000000000000000000000000000000000000754fb767" + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" [[previous_kernel_public_inputs.end.private_call_stack.array]] args_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6307,121 +6051,121 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [private_call.vk] key = [ - "0x000000000000000000000000000000000000000000000000000000000000000f", + "0x000000000000000000000000000000000000000000000000000000000000000d", "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000367", - "0x00000000000000000000000000000077c298f63acd57d13cd760f1b09e733bc3", - "0x000000000000000000000000000000000026a287c4760845db19abbc695ff36a", - "0x00000000000000000000000000000069e321196774777d330d8c47b62018ee30", - "0x0000000000000000000000000000000000295262e94218827820d221f1a676f2", - "0x000000000000000000000000000000257dbf8aaa5e15520c24e9f783198f1cfe", - "0x0000000000000000000000000000000000190713b989ee2b0ecde498ce10b549", - "0x0000000000000000000000000000002295cabfb39afdc4509c3dd66e4c75da5e", - "0x000000000000000000000000000000000027507b50fee92f2d43690c874e86a2", - "0x000000000000000000000000000000aa13c08a3a7c1467715828adcb937c2043", - "0x00000000000000000000000000000000000f8a1543c6677019dc01eb2ce85dc8", - "0x0000000000000000000000000000001675deda7e3dafff4e33979da4ebd705c4", - "0x0000000000000000000000000000000000289905e8a6dc218db585b427eb056e", - "0x0000000000000000000000000000005ca36b42f5d503af3510645776a182509a", - "0x00000000000000000000000000000000002dd8eef985765f468fae90d96ba6fc", - "0x000000000000000000000000000000cea81c59bacc58df526b5e5f65fef5b74d", - "0x00000000000000000000000000000000001c6fb7347dc56d363c90b8d4488579", - "0x00000000000000000000000000000031fde8e713e9e8fc77842379f6745e401e", - "0x00000000000000000000000000000000002a4395c65a14e549b33900648d7960", - "0x0000000000000000000000000000005c83438275fadd9a66b48380362607b9ec", - "0x00000000000000000000000000000000001b2c0ed48bd9ac3b17f36ced09b85a", - "0x0000000000000000000000000000005a3fbe86fc074463d664ec1028991daf15", - "0x00000000000000000000000000000000001c2bca0518d0dc405eecc6c9b66511", - "0x00000000000000000000000000000058fb55a413b7865807590827cbb9007644", - "0x000000000000000000000000000000000009d6fc59acc8a61214589672dcea3d", - "0x00000000000000000000000000000006e868544e82268dc595a57ee6d88aaa33", - "0x00000000000000000000000000000000002de9cde4733c1f06fdb8ac10fda985", - "0x00000000000000000000000000000061bad33649e2767633ba30e687da7b70ac", - "0x00000000000000000000000000000000002c0b0343148e6beab80557d74f318e", - "0x0000000000000000000000000000004df9e2c11487e96cde4a354328c2322b7e", - "0x00000000000000000000000000000000001e71380507bf8f7a65f542a668967e", - "0x000000000000000000000000000000387a87e1fd5a4d755a72bf4223e72cf175", - "0x0000000000000000000000000000000000140d1d6145c78a4cd60b85534d174f", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000009ebab60fa5dc47e1914fda39298f7e6ac7", - "0x0000000000000000000000000000000000110e8c462632d85486fb2b573bb0ff", - "0x0000000000000000000000000000007d5067869e4f6c37bf78d104a880ad37e8", - "0x00000000000000000000000000000000001b8a3f8dbb8f2a3ecdd71594aca606", - "0x000000000000000000000000000000780fb7de9447ebdaf30ee24fbe3cba1300", - "0x0000000000000000000000000000000000084d032f1ae838a33a86164a6541df", - "0x000000000000000000000000000000c359ee0159370b1406940ba9db56dc4ff2", - "0x00000000000000000000000000000000001cfb12b15f63bd6b2c321b0a84f51f", - "0x00000000000000000000000000000073f32650074f87a7b77470996beeacdfe4", - "0x000000000000000000000000000000000005647aa1addd19b3136ec411e71431", - "0x000000000000000000000000000000258e47dcc86acc1d400247381ab87d4725", - "0x0000000000000000000000000000000000295e68d808cf3b272d91be2fd2ae37", - "0x0000000000000000000000000000003ba26fee14fb99c3515f5bbf524129e34f", - "0x00000000000000000000000000000000000466b9f8edd37c3fa3c7d06d1a7986", - "0x0000000000000000000000000000008318efe19eaaca4d497ad4912aa208ecee", - "0x0000000000000000000000000000000000013e5dc7040c7f8b74cec4df5572bd", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000708a99a1df6e2f08c37655b04da1516fb", - "0x0000000000000000000000000000000000200f93be3bb23204915ddf19a6102b", - "0x0000000000000000000000000000003ff62e27b5552bbe8742ef48a1ce956a38", - "0x00000000000000000000000000000000002eb0dfb213e5244c19612993acc338", - "0x0000000000000000000000000000000c97bab3896ad5ed1bdbc6811f35b52088", - "0x000000000000000000000000000000000024ed3a2bfaf9b9620f0cf2c2210117", - "0x00000000000000000000000000000010515c3eda29482356a09bc84a2f1455b6", - "0x00000000000000000000000000000000000a473218b2415232276d99ee32b8ee", - "0x000000000000000000000000000000caed4590a347c4d3079e1d47713f5b83e1", - "0x000000000000000000000000000000000017405dec66fa4028a4f662a5b3bc5e", - "0x0000000000000000000000000000000c1444e30937299c89f8208ffe290cc18c", - "0x00000000000000000000000000000000001ebb18f648670cdd53f595444360e2", - "0x00000000000000000000000000000080b476643287925a5f4195f56b06fdd3ed", - "0x00000000000000000000000000000000001ca4ac04e44de10be2048a9bebcc62", - "0x000000000000000000000000000000cc5c01a1dc52e751c01dd9ba1cb9b49cb7", - "0x000000000000000000000000000000000022a62f4ddacd5cff46b90a535daa0a", - "0x000000000000000000000000000000dad72ff673733fba291f0d57a41d942e0a", - "0x000000000000000000000000000000000021a56ad22274e1b58118768b538104", - "0x0000000000000000000000000000005a34af8d8c8aa47da41eb1e75a0dfb8fd0", - "0x000000000000000000000000000000000026707f18815730d1a64214fcbfcc1f", - "0x000000000000000000000000000000d646a8a65170a6b78d80190d8a21ea1dff", - "0x000000000000000000000000000000000014bb9f8b9321b456fd18feafe1e161", - "0x0000000000000000000000000000001d878bb4be89e69a6688949dcaf0ce7ea4", - "0x00000000000000000000000000000000000f536993bd0cba9f0585f1df277c57", - "0x000000000000000000000000000000748b419096289f75352c8d5d112f7fdae2", - "0x0000000000000000000000000000000000022790c5c22cbd4366b0ad6e2b4519", - "0x000000000000000000000000000000fbaaa9a8b489397bc3e4d7f1056574b2e2", - "0x00000000000000000000000000000000000fae47872873bb913289047ed5610c", - "0x000000000000000000000000000000d9609f0d20812e6577cf8f21f2625e3172", - "0x00000000000000000000000000000000001b995278cd324d1fb4ec16ad835993", - "0x00000000000000000000000000000048894f6e04feabafb53f7a7b67c9e4c0e5", - "0x000000000000000000000000000000000027ec0d2be1c42a0a90b0ea2af01861", - "0x00000000000000000000000000000003e5fa4bc70fe52643ca6985c073c70dc3", - "0x0000000000000000000000000000000000038e1e0276e2e6dfe9a9d8aa596b76", - "0x00000000000000000000000000000065526bfbb668d3f936d18df508e43bccb3", - "0x00000000000000000000000000000000001f65337846109ac55e93e42a9fa3cc", - "0x000000000000000000000000000000585161baf0203d961615740c9ba7c9e707", - "0x000000000000000000000000000000000005728984358785c066c4cd63845858", - "0x0000000000000000000000000000002ff9899e736c45e4f04a866d93f57c116b", - "0x00000000000000000000000000000000002c4d422fd03c9a5b2e329d93362757", - "0x0000000000000000000000000000002cf70e3a6f9fe963cc77d1520d5d4edee6", - "0x000000000000000000000000000000000005f00e31445a7a9cd4219d268a06d4", - "0x00000000000000000000000000000025a2bc22bef7d083c5f847e80f943c189d", - "0x00000000000000000000000000000000001239130781e0d914daca12578a2b41", - "0x000000000000000000000000000000f3696d80095221316a91e185aec90d4607", - "0x00000000000000000000000000000000001469812dd8efeca285ecc964c4e02c", - "0x000000000000000000000000000000b9583e757e383f8ac91620436cfd8b488b", - "0x0000000000000000000000000000000000086edbc84ee73808efb9a82a2f806e", - "0x000000000000000000000000000000d8b0ecd6e3cddb9c693c8bf1d32795968e", - "0x00000000000000000000000000000000002757dfd7d21719de99dd25b8fc095a", - "0x000000000000000000000000000000684a589b8e853856d7cffbbf4293bf3571", - "0x00000000000000000000000000000000001c280b47d50b66bc53b6b635dc9827", + "0x0000000000000000000000000000000000000000000000000000000000000347", + "0x000000000000000000000000000000865f30019df603aeaed1c1d8e3c5cfc175", + "0x000000000000000000000000000000000008662c67e18149c024a3bacb2df682", + "0x000000000000000000000000000000bceab00d2d8bdeccfcd00a84a861dbf39d", + "0x00000000000000000000000000000000001650219ec9e8be886bcb85c38d4717", + "0x000000000000000000000000000000a7cf43c352dad6bf77469b1404e60e06fa", + "0x00000000000000000000000000000000001e546982146e898c6328ed6d1371e1", + "0x0000000000000000000000000000001a06adaa7ecf9f08773589e813e35a54ff", + "0x00000000000000000000000000000000001c0ef1e79d844f4ab04f853ae8970b", + "0x0000000000000000000000000000008ea0bed66d661f737dae9432cd211a55e8", + "0x00000000000000000000000000000000000455426a9c3b08ca2e8043336f387c", + "0x000000000000000000000000000000ea82e69a42b2d1019e9d8f9451913ac042", + "0x00000000000000000000000000000000000b08dca1909630d4e2adfb1d5098ea", + "0x000000000000000000000000000000fe7390b3fc62d2904ab863c97613a9f3f4", + "0x000000000000000000000000000000000006adef037868832479f56eb00ae2f2", + "0x000000000000000000000000000000371199c3359a930d0544c57f5981a56353", + "0x00000000000000000000000000000000002529cfbf41f326259cc2e28d6add58", + "0x000000000000000000000000000000c19a28af19d8043033aa6812430cb850f3", + "0x000000000000000000000000000000000010657456725ca7293b6c6a68b9b3a1", + "0x0000000000000000000000000000008cdae9bdd9a5ac55371cd8bedc86674c6a", + "0x000000000000000000000000000000000003b620a70ee10a1a00426d2d81e5fb", + "0x0000000000000000000000000000002806b12269d372065ac3b1166be1033175", + "0x00000000000000000000000000000000000d1b9812f91483c4dc99dd47842f14", + "0x00000000000000000000000000000079bde04066ea11cbbbdbc610b17b7ea716", + "0x0000000000000000000000000000000000172ed63b113f0b9ed00943690c10db", + "0x0000000000000000000000000000003d2554e7d5b58b0dcb37e36b8db350e8ef", + "0x0000000000000000000000000000000000093de1b2590406402c4caa2b0d400d", + "0x000000000000000000000000000000632862715830705b58ea13d3626158f43f", + "0x0000000000000000000000000000000000291028929fad3a3b92603079664d39", + "0x0000000000000000000000000000001fc48b67fb4ec9714cfe69efa8469d2faa", + "0x00000000000000000000000000000000002800a5c6aa06adba0feb138f51b7c1", + "0x000000000000000000000000000000626607acd3cfe08cec8ccec45fc27222a0", + "0x00000000000000000000000000000000000bf5451f8e8805b3e83e17c778ac8f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043cc5bf77e079b00db695cb77a0c27a755", + "0x000000000000000000000000000000000007bb974c2dca9f3583a7be610d27bc", + "0x00000000000000000000000000000097720e9504d37f0a32805569a8ef675230", + "0x00000000000000000000000000000000001d16d8825fcdb521746bb4c658a29f", + "0x000000000000000000000000000000872162f7d2ba720e691b5387dda2393047", + "0x00000000000000000000000000000000001b2d2710296ae242e420846aca6d30", + "0x000000000000000000000000000000e7d1fce90f172eb4ab5489d9241a8919f4", + "0x00000000000000000000000000000000002477d0d688545e7884c3d0f4926e75", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e242c52613ef515743130929408b8395eb", + "0x00000000000000000000000000000000002f00c020f75dd48c87ed413a77180f", + "0x000000000000000000000000000000ea7902a077cb96eeabfc420359b9be6db3", + "0x000000000000000000000000000000000015628feadf61afbd89f5d0b872b2c3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ff3a4cd8afe4ac9de0176a552fc09c35", + "0x00000000000000000000000000000000002259e282b0d22c622181e3d68e4322", + "0x000000000000000000000000000000eb70dc3306d84c664e4b10cccd60a9899a", + "0x0000000000000000000000000000000000270322a73bd1df2dbc3114462eb34e", + "0x00000000000000000000000000000039f2a727db728fb54b63a5a2dc525fd924", + "0x00000000000000000000000000000000002db1e2eca29501192e304da4047a17", + "0x000000000000000000000000000000e748ef8209f555579c98c0f60d798fc768", + "0x00000000000000000000000000000000002cbaf388ead0bc80dba57d2b1e0a6b", + "0x000000000000000000000000000000431bd61e90ed225a41f3992f2ec05406f2", + "0x000000000000000000000000000000000018335cb5d014bd80d4454621cdfbc5", + "0x0000000000000000000000000000000617b8aab9cb8f83be590c7c713c67c2ff", + "0x000000000000000000000000000000000013228c3be2488a8b526ac67437dd1c", + "0x000000000000000000000000000000e3e6fb8594f3d96a4e3b90eab96051bfab", + "0x0000000000000000000000000000000000041115da2e46ed09c4904290ce2f28", + "0x0000000000000000000000000000008dc24ee445f72e75590d77c59c2502c325", + "0x0000000000000000000000000000000000278df9d0273f8abe29181cb2097566", + "0x000000000000000000000000000000d779f5665a6d8739e46b9dbaa1fbb1d861", + "0x000000000000000000000000000000000013ff6895fed419bcb47b05aab16230", + "0x000000000000000000000000000000d8e0764f92f389448cc165a0d6c4031ee5", + "0x0000000000000000000000000000000000262984e59a1b92af14b9a461b32ab6", + "0x00000000000000000000000000000063a63c160d8a803a0aaa1797164c10eba1", + "0x00000000000000000000000000000000000c0ac58d8af92cb4105a1e3b3e8859", + "0x000000000000000000000000000000a040bfc1e24982ef134ebf0f974cc16f63", + "0x00000000000000000000000000000000002fd203a2c6c8f3f7b65cf7dd2124de", + "0x000000000000000000000000000000af7bf5d17f14cb02d020a3338b5ac8185f", + "0x00000000000000000000000000000000001f1e62776c318cbeac47805ea72d38", + "0x00000000000000000000000000000027865898be950dc50fbf51a531deeb66d0", + "0x0000000000000000000000000000000000304e7951f51b85f00e58e95ad211f6", + "0x000000000000000000000000000000fe0779b92c0bcb7f02ee39a0aa8ac50741", + "0x000000000000000000000000000000000022f9764c1c492c3a5743c994e8c712", + "0x0000000000000000000000000000005cb8a0df70faf6225ba47ea58cc69931ee", + "0x00000000000000000000000000000000000458fd9ec786e9a8af6300297d33ac", + "0x000000000000000000000000000000621fc10d8a9e4658642abd6cf5e17172ed", + "0x00000000000000000000000000000000002c583db8d2e51e9a7e91a19f89448d", + "0x0000000000000000000000000000009db8a71852e36b1d16f89c6fa435764de7", + "0x000000000000000000000000000000000006f24d141ba33dcfd7be7353938779", + "0x000000000000000000000000000000e29b7681545a3aff6ca4c964fa138485b0", + "0x000000000000000000000000000000000001ad9a17d78c8c41e7a9333fac80a8", + "0x00000000000000000000000000000098a0fab1f65c3b55a29b3258e290692ff5", + "0x000000000000000000000000000000000007e2e68bdee42d0f878077d5380a29", + "0x000000000000000000000000000000105cec7ee17bd10a991deb8da3dec94834", + "0x00000000000000000000000000000000001edf9dbf6f0fa27c8382b88eeaa7ad", + "0x00000000000000000000000000000084bb0cbfba6eebc0a0492e0aa234700dfa", + "0x00000000000000000000000000000000001d5edc6e61f842ccc7d3ddb54e624d", + "0x000000000000000000000000000000defe1347096986ac6d98a339f30b4c79a4", + "0x000000000000000000000000000000000004d963817920de50753220dcfc0f39", + "0x000000000000000000000000000000136a1458f0c92ec89a5e9320fd1c6e898c", + "0x00000000000000000000000000000000002860427d9f6b7ce48fe90398d3ce14", + "0x000000000000000000000000000000ee77d7fb9e9d8be2914e33d3561c617025", + "0x00000000000000000000000000000000001ee9005f891b0f488bbc9d6b89c6b2", + "0x000000000000000000000000000000c070442f554a223e1dec049b9e101b1338", + "0x0000000000000000000000000000000000082c84c85011f35d945335ca2ba917", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -6442,24 +6186,24 @@ key = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000b91c3664d3270a60931c471928222bf6b", - "0x00000000000000000000000000000000001a702fa77522ea7356d9d6ed1c9b9e", - "0x00000000000000000000000000000032f9984b982de6753a3668f46872fee3db", - "0x00000000000000000000000000000000003036d9814a9753be22125d50c268e7", + "0x000000000000000000000000000000026c53007876d885d7cbb2375814e9947f", + "0x0000000000000000000000000000000000149684831934ae61b89fa614a91503", + "0x000000000000000000000000000000ff682c870fdd41c2a48b43f4042246343e", + "0x000000000000000000000000000000000004ad1447334cc38d8422f7c6c3b72e", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000585fcdfa31b424adfe685b43435cdc567", - "0x00000000000000000000000000000000002717439949acf883c385bc7c246dc6", - "0x000000000000000000000000000000b97f0f863a1005a5c88ba628c1d8bb1740", - "0x000000000000000000000000000000000001f73676f90fa92e0bd9ce8716cfb9" + "0x0000000000000000000000000000006c326bcc176f6bf7b61c67c607b538604e", + "0x00000000000000000000000000000000002e0df8ede24ac545f6f615607ae5a5", + "0x0000000000000000000000000000004810e97feaf203b539c161e31c09b9910d", + "0x00000000000000000000000000000000000e2612cea9f45e6238f1fcd8fe80e4" ] -hash = "0x147ef2802ee4a878790fc89ab3a742a3f9e794df4ba16a3c013856118e5e54d7" +hash = "0x02326db3f4292bc2483b97dc307b6d2f12920e3044ae9c04a1e662de1b5ea0d7" [private_call.verification_key_hints] -contract_class_artifact_hash = "0x17936c22a18e1310c8a71802414ad55bbea4d490023a55358f249edace43f2fb" -contract_class_public_bytecode_commitment = "0x1e88df4d0fb9c20b21bce0f5067f3f4c9a9da39101d2936741eb5b0cfcfc9a40" +contract_class_artifact_hash = "0x06c89aad50296e10a3cf790b9d73c854d096b136adb7cdde89447ef5591392f3" +contract_class_public_bytecode_commitment = "0x1d694c92cbd2f2f8a373c90582a93a2889a43d04c84a4a0147c606655ae98dc5" updated_class_id_delayed_public_mutable_values = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -6467,51 +6211,41 @@ updated_class_id_delayed_public_mutable_values = [ ] [private_call.verification_key_hints.function_leaf_membership_witness] - leaf_index = "3" + leaf_index = "1" sibling_path = [ - "0x1768f4ffe236f2d0d6f6e42ad30d7c9ace25c145ede7b699e3a551e0f90f65de", - "0x0a83a13c3704cbec2a1c8aeab69534367d70b291243f955cf1aea1caa6092382", - "0x04f1d72b0df1c0b8759643e6ae23442a5cdfe090978072dd559a8319c0811952", - "0x29e60d7288e9b28c0d1e6f4c7244c3b92efdd2de4e7042b85a1291c2ec910b1f", + "0x2a8a5b5b00b3298df0d362949857e44d9ab6dbe13517f17dae4d718eb429644b", + "0x29a39e8a923a570c2ff08365769dc6b9c551d550ee0e1a351eab6e04cd0df0a3", + "0x2974d8999d00928aa1378118756d6a4ba1368b1da89b2b1059c17fbb88ad21a8", + "0x2e6127fb2bcf542677ed9dfc6cd90a61a075142999aebccf345c816aff3a1d92", "0x267a9c24e849f51869c93086ded207858dfb130344e1879a9d15d35096464824", "0x1eb5f748aca7413c8875abf2789be0a1aec323884a365d9a59a1859aa2bce94e", "0x2402a100768c2e339831cdb0b63e5c272a6f3318323a37642bea76ab5ea1ed0c" ] -[private_call.verification_key_hints.public_keys.npk_m.inner] -x = "0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd" -y = "0x170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e344" -is_infinite = false + [private_call.verification_key_hints.public_keys] + npk_m_hash = "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26" + ovpk_m_hash = "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b" + tpk_m_hash = "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0" [private_call.verification_key_hints.public_keys.ivpk_m.inner] x = "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c" y = "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151" -is_infinite = false - -[private_call.verification_key_hints.public_keys.ovpk_m.inner] -x = "0x1b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287" -y = "0x080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833" -is_infinite = false - -[private_call.verification_key_hints.public_keys.tpk_m.inner] -x = "0x019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb" -y = "0x2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f" is_infinite = false [private_call.verification_key_hints.salted_initialization_hash] - inner = "0x283b87e95914a45f14ba1dbc2445f080d54b98ca600ca9c8a09bf4e6059b8e4b" + inner = "0x2c34a9418dab220d2f208289abd62de8f7eb8abca9e10988c48eccc4424221ac" [private_call.verification_key_hints.updated_class_id_witness] - leaf_index = "117" + leaf_index = "131" sibling_path = [ - "0x0371d4f7e5e7a3a1bc6eb35796ae80686c69151d345a495f9a6b43b11f13120c", - "0x015f1e689c2e78468161bdc9d10fabf2ce528bc217db9dc422ba929a70b5e860", - "0x2523970382de270c1acd87f98b4ed454353257f9c689dc608f7dc1b6ca23741a", - "0x2fa84a2c6fb5f1b544d9acb5620c87e8930bcc2f6411312fcc5d580ab4883a92", - "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", - "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", - "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", - "0x27c696ad87d2ae17e4005225c67d015eaca8a9c6e97dec181f97f15e2c1ff894", + "0x03a2485ed0c18f1f0b27f8cb762f330dc41f2fc280d4d3f073b4d72304ffe4fa", + "0x1d12604d1468fe48df2d32605da5dc60d5f557903d21f08ea292c9c4f0e5c939", + "0x1701fbabc2818af0649d35ba0bc29213fc7509835e081c1cab5501f63aae6757", + "0x2c82e75f6b16fa4ea9b4f7d46757ced7ac33905daa90ce61a6eea6a315fa79c8", + "0x1d52af9cd9f69c1286e9a96fd498e736789a5bc463fceb1c176a4f9292f7cbe3", + "0x1ff1d5db01572c915915a22173c73d8073df9af4e4c57f6af29df5315da44419", + "0x070dcbac794fa663bc71b42d80775c0cea8c3ed7580207cfd30fd1285813ce07", + "0x0202d252c8608f54b289d11e2ee5c49b48f809e3d008c80de0da1409f19d20a1", "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", @@ -6547,41 +6281,41 @@ is_infinite = false ] [private_call.verification_key_hints.updated_class_id_leaf] - slot = "0x00d9d7e98b29d1f3eadd6bcce14809b2ca27ba47b772ef0401455915ab91d062" - value = "0x00000000000000000000000000000000000000000000021e19e0c9bab2400000" - next_slot = "0x09667a49b892551e41d7ace7350264dab6567641a5096948a522f8e57069a8c0" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000076" + slot = "0x21217fba0620ad412df7954c1e33104958d3bd37f436672fdd7e0a42b47b29a4" + value = "0x05208323f49682fc3367ed42a0212854a797b5372b0cc6bc5493b00e96ff256d" + next_slot = "0x264534c4e6c3e98e04eb89dc84eac7e5a46ff6d391ab9eb97f44cc862bf0df7d" + next_index = "0x000000000000000000000000000000000000000000000000000000000000007d" [app_public_inputs] -args_hash = "0x00fdacb86277b5caac1f0395131955d3d7ddd5988f117d742d59ecdeef9db7a5" -returns_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" -start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000006" -end_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000010" +args_hash = "0x05eabce2b553dfa52a6b3f33cd603318310b2f9f56a14d6eefbd3bbf640cb107" +returns_hash = "0x20fd6cca0f81d2e3d2192b45a0208ef249e8032b9785fe9ecfed10beb1d36cb5" +start_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000008" +end_side_effect_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" expected_non_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" -expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000007" +expected_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000009" min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" is_fee_payer = false -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff2940" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7f3f" [app_public_inputs.call_context] - is_static_call = false + is_static_call = true [app_public_inputs.call_context.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x09d3e27b2b71e2140366b7b610129b819b841efe0dc06bf715e3eb5b68f65571" [app_public_inputs.call_context.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c" [app_public_inputs.call_context.function_selector] - inner = "0x00000000000000000000000000000000000000000000000000000000754fb767" + inner = "0x0000000000000000000000000000000000000000000000000000000080d3af36" [app_public_inputs.note_hash_read_requests] length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[app_public_inputs.note_hash_read_requests.array]] [app_public_inputs.note_hash_read_requests.array.inner] -inner = "0x14d24541deb5dd2fb77037cada005cc9755e7cdde176fafaa83d4038e6ffe551" -counter = "0x0000000000000000000000000000000000000000000000000000000000000008" +inner = "0x21c7e2027864f293ff502b26ca73419fb7de391a18467849bba3e7debd669312" +counter = "0x0000000000000000000000000000000000000000000000000000000000000009" [app_public_inputs.note_hash_read_requests.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6707,12 +6441,12 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifier_read_requests] - length = "0x0000000000000000000000000000000000000000000000000000000000000001" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.nullifier_read_requests.array]] [app_public_inputs.nullifier_read_requests.array.inner] -inner = "0x16c07a80d3d164d5d8082a5dda9fb5d5f0de35fc2bc4ac2fa36182ed91ce381f" -counter = "0x0000000000000000000000000000000000000000000000000000000000000007" +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifier_read_requests.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6838,194 +6572,130 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators] - length = "0x0000000000000000000000000000000000000000000000000000000000000001" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.key_validation_requests_and_separators.array]] - key_type_domain_separator = "0x000000000000000000000000000000000000000000000000000000000e6ebabc" + key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] - sk_app = "0x06676b93f3cec2a77597fadc4704afee9dc237873051a7e2638df02f77e35be9" - - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x025f9f657095ad240d89a28336e0f7be994c9f270d62c6a3228aa8bada12d01d" - y = "0x1a7e0782cbdd3ebc39b0bd4a33b5894cb3451bc52c2fadd70371ed8d81db479f" - is_infinite = false + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [[app_public_inputs.key_validation_requests_and_separators.array]] key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.key_validation_requests_and_separators.array.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [app_public_inputs.key_validation_requests_and_separators.array.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [app_public_inputs.note_hashes] - length = "0x0000000000000000000000000000000000000000000000000000000000000002" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.note_hashes.array]] - inner = "0x00def7bf22ad78b9b414af8c6b920730b29275a17b6c869a3e9ad3929c416c6f" - counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.note_hashes.array]] - inner = "0x1552be33f460bfea48702663acfd93ed46d02df9080308666dccf3eec187faa8" - counter = "0x000000000000000000000000000000000000000000000000000000000000000c" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.note_hashes.array]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -7084,20 +6754,20 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifiers] - length = "0x0000000000000000000000000000000000000000000000000000000000000002" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.nullifiers.array]] - counter = "0x0000000000000000000000000000000000000000000000000000000000000009" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifiers.array.inner] - value = "0x0c3f7479d44d8ec07d6aa92e715150ec4366e314b2fca5b309e6cb9e9948f56a" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.nullifiers.array]] - counter = "0x000000000000000000000000000000000000000000000000000000000000000e" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.nullifiers.array.inner] - value = "0x265ec541731007783d79c1154c1bf3c5a3a11617bf2d3bf679d939f52d140b8c" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.nullifiers.array]] @@ -7850,88 +7520,88 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs] - length = "0x0000000000000000000000000000000000000000000000000000000000000003" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.private_logs.array]] - counter = "0x000000000000000000000000000000000000000000000000000000000000000b" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner] - note_hash_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner.log] fields = [ - "0x0a19e21c4ab1897aa638eb354bb44aaccdb24a11525f3186595e2d2271248d15", - "0x10433733db106ed8336b9b799ec2debee9fe2da75f114f567eefde5abf9f74d3", - "0x17440c522b009a136c2207db86790b05464774690523c7fbf949ad381664d0ea", - "0x0a5e8928a4d74ad3256e8a697cfdf84b7baae32abad67b2de7c36ffd67acb665", - "0x0b1200621e156c6d79f463e17e81b96f11d18d716ca5222e7276e07d45845a26", - "0x04b2b64d09e487d10d557106046a94a97f2c40f4316e6667a2c2d9a99db05385", - "0x193da3d713c24b85e1c8f22dd8ef575e88d19c6732f8fd17e370cf64e65b3e04", - "0x08569203e8f3d028234ed200df77bca848c9b4b015ad8797c37669a5e5d1ee0c", - "0x13a9b2003409ad3d4f38caba797acc77092ddd431af25a955a83dc6f5b92cc93", - "0x16fece01bc0b0205bcbaca2904d5674d10573bfef038f94d3e5d526596da2ae9", - "0x0a438177a05071eaeb1862f154b187315de4dc804e275b0f2258baf4700c6d64", - "0x0959244a76e5e861ce5b8833101b91e19d758109d68cc174a6f9eec9c7afa008", - "0x03533d18a1c3ebcf22f820a243be161c9798ea59a506572e32e125c53b7aee7e", - "0x1e2b22ea302597bfcbcfdefcda48b60e35fce9c70f46c6cb90fa6db6e8d4dc6d", - "0x28fab93b8cd28d8d2a993badc3d1a080902feecfab019dc7c00af0ea9f6f403d", - "0x104c4c81c135af94af35a1eeb49b1262e5c53e25ee513731ddeb9f6496eea2ab" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.private_logs.array]] - counter = "0x000000000000000000000000000000000000000000000000000000000000000d" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner] - note_hash_counter = "0x000000000000000000000000000000000000000000000000000000000000000c" + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner.log] fields = [ - "0x009ca00e8f7d20a40d1266a37a186cd96c78b285a2506210cabc2fa353489be2", - "0x2320e89fb76918e7dc48b13861302dbf78af5ba8d5a20da77d19781ac32b9bc2", - "0x2a99619c0d4d380dbc3d53d03ed35011aa9c296a507fabcf712f43a0e5a10850", - "0x02e5d98e7dfbe7653dafb14afddd7e00f403b5a60816d7ab961823bd3cc4b628", - "0x223b37d6caffe87e91cddafdf65c4f641a609ff13350d02654b0fed1443088ab", - "0x2846b9aa4544f8f8851554f5d0c189c188756d734112e1eedd6840c8aeb0e66f", - "0x21cda3f228d55fb1b37f2b7c7a5d42066007143db17645669521ff58956fa7bf", - "0x1d8d79951d7389e5f9dfa963f93e399aebaa346e9ce3b3a5da1b45e4600a1553", - "0x15eabc8ed921f60621fa4fa35214748a7593f1c06a1e66b76092f789b4960bc5", - "0x16babb28d68725cb64d6d7558d49fb921c480359488fcdfb5292019239a50563", - "0x015e561b49da425d081b87bac01336defa1e29ee50d01b7be798ac28e05b24d6", - "0x04bf1a23807cb0711511a6140caf195df55fcf029842652243034ae2ca740648", - "0x2789cc422a86395739004c513cf6a15024e3adf5f2e238b18e1b4f1211a9383a", - "0x00c4e950cfe804e8a3623fe768c82b7340b0216f93c00351c53e2144364cfb51", - "0x2fd9827b4118b7ef401dff1727785e46fdd31947d2e733f4b39076f43652c18a", - "0x158ca7fba6e7fa7b3eb7c062751182d93b4e36b5c77d2e609e246b810650e59e" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.private_logs.array]] - counter = "0x000000000000000000000000000000000000000000000000000000000000000f" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner] note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.private_logs.array.inner.log] fields = [ - "0x145c6a232e670e3f0babf2a60ced437e3b543087bb24e9d398e05add3513dfa4", - "0x127157561e774918ba656738fb61ad37f92086431bd4f1e4842ab11928b0f8d2", - "0x2e5cf59c8f2eee7a06d14cdedb8fe58945357cb16f4c792094325909a12924b2", - "0x0e29376c31f2aa7a156c6ce6d1fc9529998251d8500604658f173ff86adffa98", - "0x20761b8be9a186cf6a1730b8a1e99049a07e45c005e66d27b6e0ef15a2833e2f", - "0x1adf679b2441cf3535241924a35164cf8309256721e3f9fcb860bc2acc462b46", - "0x06a613741497b7b7ee978a495bfed7d19bbf76c462d268cee17a3920b1b1abe0", - "0x10ade06e253c1cfd65f24246211fb703c157fd9b563ffaf6ab01b6fba4635155", - "0x2311c6b104555d4d9afc7d66be6b47a41f8aa96eb77f613a75fc952da5975ccf", - "0x08431c3838d7ad6198c1d33ff138953ace3520551bd95b69692609ee11ded216", - "0x1822c33cf8097138c896bb9f7aad7def909a6859d5e640919fd16ebcf153a0db", - "0x11203b31ef49d39fb85a5ea474116c334c156091ab468493a480f13ad1ec1849", - "0x207a4712bacadd2f631fe253cb62932a7acb586dd6dd1b10e0fbe733f61a8f11", - "0x2c862b0eb14b1325a0ca63dda4570f718541d998fb4aba96339b7913b80757c9", - "0x1bf17ee7d3cf2487dcf1eb7a3647b0920c9e68aacc0a33c9a424d4ee6601ded3", - "0x2c70c9b7da7d7df78fcae182d124d7041209070f76d920e5d5c2d7590c385ea1" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[app_public_inputs.private_logs.array]] counter = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -8295,50 +7965,50 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" length = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [app_public_inputs.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [app_public_inputs.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [app_public_inputs.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [app_public_inputs.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [app_public_inputs.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [app_public_inputs.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [app_public_inputs.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [app_public_inputs.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [app_public_inputs.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [app_public_inputs.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [app_public_inputs.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/key_validation_request_validator_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/key_validation_request_validator_tests.nr index 79cb6194f051..a637c416730a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/key_validation_request_validator_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/key_validation_request_validator_tests.nr @@ -12,7 +12,7 @@ fn clear_all_succeeds() { assert(propagated.array.is_empty()); } -#[test(should_fail_with = "Failed to derive matching master public key from the secret key")] +#[test(should_fail_with = "Failed to derive matching master public key hash from the secret key")] fn wrong_secret_key_hint_fails() { let mut builder = TestBuilder::new_clear_all(); @@ -45,12 +45,13 @@ fn amount_to_validate_smaller_than_hints_fails() { builder.validate_with_amount::(); } -#[test(should_fail_with = "Failed to derive matching master public key from the secret key")] +#[test(should_fail_with = "Derived master public key cannot be the point at infinity")] fn hints_fewer_than_requests_fails() { let mut builder = TestBuilder::empty(); builder.add_request_and_hint(11); - // Add an extra request without a hint. + // Add an extra request without a hint. The missing hint slot is implicitly sk_m = 0, which + // derives the point at infinity and is rejected by the kernel. builder.add_request(22); builder.validate(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/mod.nr index 1f5d66b0d683..d17e3e0d56f3 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/tests/mod.nr @@ -10,7 +10,8 @@ use types::{ abis::validation_requests::{KeyValidationRequest, KeyValidationRequestAndSeparator}, address::AztecAddress, hash::compute_app_siloed_secret_key, - point::Point, + point::EmbeddedCurvePoint, + public_keys::hash_public_key, scalar::Scalar, side_effect::Scoped, traits::{Empty, FromField}, @@ -73,14 +74,15 @@ impl TestBuilder { let contract_address = AztecAddress::from_field(456654); let sk_m = Scalar::from_field(sk); - let pk_m: Point = derive_public_key(sk_m).into(); + let pk_m = derive_public_key(sk_m); + let pk_m_hash = hash_public_key(pk_m); let key_type_domain_separator = 123321; let sk_app = compute_app_siloed_secret_key(sk_m, contract_address, key_type_domain_separator); let request = KeyValidationRequestAndSeparator { - request: KeyValidationRequest { pk_m, sk_app }, + request: KeyValidationRequest { pk_m_hash, sk_app }, key_type_domain_separator, } .scope(contract_address); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/validate_key_validation_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/validate_key_validation_request.nr index d8c0ff6f4abe..35063c20692f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/validate_key_validation_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/reset/key_validation_request/validate_key_validation_request.nr @@ -1,7 +1,8 @@ use std::embedded_curve_ops::fixed_base_scalar_mul as derive_public_key; use types::{ abis::validation_requests::KeyValidationRequestAndSeparator, - hash::compute_app_siloed_secret_key, point::Point, scalar::Scalar, side_effect::Scoped, + hash::compute_app_siloed_secret_key, point::EmbeddedCurvePoint, public_keys::hash_public_key, + scalar::Scalar, side_effect::Scoped, }; /// Validates a Key Validation Request that an app circuit has submitted to the kernel. @@ -16,22 +17,22 @@ use types::{ /// validation request" to the protocol's kernel circuits (which _are_ /// allowed to see certain master secret keys (sk_m)). /// -/// When a Key Validation Request tuple of (sk_app, Pk_m, app_address) is -/// submitted to the kernel, it will perform the following derivations -/// to validate the relationship between the claimed sk_app and the user's -/// Pk_m: +/// The app circuit only sees `pk_m_hash` (not the raw point). The kernel derives the +/// point from `sk_m`, hashes it, and asserts equality. When a Key Validation Request tuple of +/// (sk_app, pk_m_hash, app_address) is submitted to the kernel, it performs the following +/// derivations to validate the relationship between the claimed sk_app and the user's pk_m: /// -/// (sk_m) ----> * G ----> Pk_m -/// | | -/// v We use the kernel to prove this -/// h(sk_m, app_address) | sk_app-Pk_m relationship, because app -/// | circuits must not be trusted to see sk_m. -/// v | -/// sk_app - - - - - - - - - +/// (sk_m) ----> * G ----> pk_m ----> hash_public_key(pk_m) +/// | | +/// v | We use the kernel to prove this +/// h(sk_m, app_address) | sk_app-pk_m_hash relationship, because app +/// | | circuits must not be trusted to see sk_m. +/// v | +/// sk_app - - - - - - - - - - - - - - - - - - /// /// Where G is a hard-coded, protocol-defined generator for deriving user public keys. /// -/// The fact that the user is able to furnish a sk_m that derives both the Pk_m and +/// The fact that the user is able to furnish a sk_m that derives both the pk_m_hash and the /// sk_app of the key_validation_request proves that this sk_m is the correct one. /// If the wrong sk_m were used, then the assertions below would fail, and the user's /// tx would not contain a valid proof and so would not be includable in a block. @@ -44,7 +45,6 @@ use types::{ /// of a secret key). Key validation requests are slightly more efficient (although /// the overhead of managing arrays of key validation requests in the kernels might /// counter that claim). -/// pub fn validate_key_validation_request( scoped_request: Scoped, sk_m: Scalar, @@ -54,12 +54,20 @@ pub fn validate_key_validation_request( let request = request_and_separator.request; let key_type_domain_separator = request_and_separator.key_type_domain_separator; - // First we check that the derived public key matches the master public key from the request. - let pk_m: Point = derive_public_key(sk_m).into(); + // First we check that the hash of the derived public key matches the requested pk_m_hash. + let pk_m = derive_public_key(sk_m); + + // Safeguard against using a secret key equals to zero. + assert_eq( + pk_m.is_infinite(), + false, + "Derived master public key cannot be the point at infinity", + ); + assert_eq( - pk_m, - request.pk_m, - "Failed to derive matching master public key from the secret key", + hash_public_key(pk_m), + request.pk_m_hash, + "Failed to derive matching master public key hash from the secret key", ); // Then we check that siloing the master secret key with the contract address gives the app-siloed secret key. diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_init/private_call_data/validate_contract_address_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_init/private_call_data/validate_contract_address_tests.nr index 574ae4cceeef..ab3428dedccb 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_init/private_call_data/validate_contract_address_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_init/private_call_data/validate_contract_address_tests.nr @@ -89,7 +89,7 @@ fn incorrect_address_preimage() { let mut builder = TestBuilder::new_with_regular_contract(); builder.private_call.public_keys.ivpk_m.inner = - derive_public_key(EmbeddedCurveScalar::from_field(69)).into(); + derive_public_key(EmbeddedCurveScalar::from_field(69)); builder.execute_and_fail(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_inner/output_composition_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_inner/output_composition_tests.nr index 672ad79dbd3e..35086fd530f5 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_inner/output_composition_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_inner/output_composition_tests.nr @@ -13,7 +13,6 @@ use types::{ MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_LOGS_PER_CALL, MAX_PRIVATE_LOGS_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS, }, - point::Point, traits::{Empty, FromField}, utils::arrays::subarray, }; @@ -732,7 +731,7 @@ fn with_allowed_empty_values_from_private_call() { let _ = builder.private_call.add_nullifier_read_request(0); let empty_nullifier_read_request = builder.private_call.nullifier_read_requests.storage()[0]; - builder.private_call.add_request_for_key_validation(Point::empty(), 0, 0); + builder.private_call.add_request_for_key_validation(0, 0, 0); let empty_key_validation_request = builder.private_call.scoped_key_validation_requests_and_separators.storage()[0]; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/key_validation_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/key_validation_tests.nr index ec05925a20cf..6b6970ddc918 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/key_validation_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/key_validation_tests.nr @@ -28,7 +28,7 @@ fn validate_and_propagate_key_validation_requests() { ); } -#[test(should_fail_with = "Failed to derive matching master public key from the secret key")] +#[test(should_fail_with = "Failed to derive matching master public key hash from the secret key")] fn wrong_order_for_key_validation_request() { let mut builder = TestBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/mod.nr index 18b177e70e18..56a503ae2cc4 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_reset/mod.nr @@ -34,7 +34,8 @@ use types::{ merkle_tree::{ LeafPreimage, MembershipWitness, nullifier_merkle_hash, test_utils::SingleSubtreeMerkleTree, }, - point::Point, + point::EmbeddedCurvePoint, + public_keys::hash_public_key, side_effect::{Counted, Scoped}, traits::Empty, utils::arrays::find_first_index, @@ -199,14 +200,19 @@ impl TestBuilder { pub fn add_key_validation_request(&mut self, sk: Field) { let sk_m = EmbeddedCurveScalar::from_field(sk); - let pk_m: Point = derive_public_key(sk_m).into(); + let pk_m = derive_public_key(sk_m); + let pk_m_hash = hash_public_key(pk_m); let key_type_domain_separator = 123321; let contract_address = self.previous_kernel.contract_address; let sk_app = compute_app_siloed_secret_key(sk_m, contract_address, key_type_domain_separator); - self.previous_kernel.add_request_for_key_validation(pk_m, sk_app, key_type_domain_separator); + self.previous_kernel.add_request_for_key_validation( + pk_m_hash, + sk_app, + key_type_domain_separator, + ); } pub fn add_key_validation_request_and_hint(&mut self, sk: Field) { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail/previous_kernel_validation_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail/previous_kernel_validation_tests.nr index 2e33f970918f..8cf8526d0597 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail/previous_kernel_validation_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail/previous_kernel_validation_tests.nr @@ -5,7 +5,6 @@ use types::{ CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, DOM_SEP__IVSK_M, PRIVATE_KERNEL_TAIL_VK_INDEX, PRIVATE_LOG_SIZE_IN_FIELDS, }, - point::Point, side_effect::Scoped, traits::{Empty, FromField}, }; @@ -31,11 +30,7 @@ fn non_empty_nullifier_read_requests() { #[test(should_fail_with = "Non empty key validation requests")] fn non_empty_key_validations() { let mut builder = TestBuilder::new(); - builder.previous_kernel.add_request_for_key_validation( - Point { x: 1, y: 2, is_infinite: false }, - 27, - DOM_SEP__IVSK_M as Field, - ); + builder.previous_kernel.add_request_for_key_validation(12345, 27, DOM_SEP__IVSK_M as Field); let _ = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail_to_public/previous_kernel_validation_tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail_to_public/previous_kernel_validation_tests.nr index 88c70307d89d..9f8bb43390d6 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail_to_public/previous_kernel_validation_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_tail_to_public/previous_kernel_validation_tests.nr @@ -5,7 +5,6 @@ use types::{ CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, DOM_SEP__TSK_M, PRIVATE_KERNEL_TAIL_VK_INDEX, PRIVATE_LOG_SIZE_IN_FIELDS, }, - point::Point, side_effect::Scoped, traits::{Empty, FromField}, }; @@ -40,11 +39,7 @@ fn non_empty_nullifier_read_requests() { #[test(should_fail_with = "Non empty key validation requests")] fn non_empty_key_validations() { let mut builder = TestBuilder::new(); - builder.previous_kernel.add_request_for_key_validation( - Point { x: 1, y: 2, is_infinite: false }, - 27, - DOM_SEP__TSK_M as Field, - ); + builder.previous_kernel.add_request_for_key_validation(12345, 27, DOM_SEP__TSK_M as Field); let _ = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/Prover.toml index 2743b35323d1..b8e9f10ef706 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/Prover.toml @@ -1,128 +1,128 @@ [previous_kernel.vk_data] -leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000041" sibling_path = [ - "0x0ddc610a21615b2984181082c3de07058b9f7d4be62806c4fd475161f8bd2be3", - "0x0f92d54d29bddf6ec768db2c0b4685fb325d248b3ad9a3c6adda76c6c5004224", - "0x0656bbf5e3f4cc4fa5e2fa46e7fd370db0bee05586a1849c37c77d05abe2d8a5", - "0x166399703d23a5c22febc6185f8eb93c72b65906eefef226e643c35fa0022adb", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x12c59c16ed84032f7c5273ff19d7a05e8e861c23959fb71cf4b2c6ac45d21f8c", + "0x225eef52a484280b0f1c6cb9f90a84dc301536c01bfa4d61bd6496b3eaf19052", + "0x0e084e8198288b2ff94eaf4d6f37fba06e430a879dd37c726a3b5a65416fe6b6", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x0e9cb07dc8495e2adab02c5db0e34a0dbe42e9b473e0462641c54f73a4a4fdd3" ] [previous_kernel.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000011", "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000c11", - "0x000000000000000000000000000000b56b478d39fe1ea8636ca1c5f7efe26465", - "0x00000000000000000000000000000000002ce8a9b4b8b40012f631f6a39b6121", - "0x000000000000000000000000000000e90605e79e3b491b4e35bed971ffe40f20", - "0x000000000000000000000000000000000014aac08af29b80ea5e82169bde9f1b", - "0x000000000000000000000000000000f23100dd9e774faa9da6adabb0a5e868d1", - "0x00000000000000000000000000000000000675d3fb2db13df5feb7837a996202", - "0x0000000000000000000000000000002d41a263946c21172989f16b6c3eabd14b", - "0x00000000000000000000000000000000002f76f5733e8a0b6e45ad715c844fa3", - "0x0000000000000000000000000000009906b77efd02f89dd64543cb41b2ee7dc0", - "0x000000000000000000000000000000000011990c3a05d603a15abfdd104b7f45", - "0x000000000000000000000000000000b68418cb6eb350097b81ceebf7216de49f", - "0x0000000000000000000000000000000000193b041e80721ea6304e3edc45a55a", - "0x0000000000000000000000000000007f41793e8f1a2fbe4047a8c9b3ea8a7eba", - "0x000000000000000000000000000000000004ad79eb6e09a672b49359e429d4b2", - "0x00000000000000000000000000000084b9e57a26da81e52f9d96f484a3d8a6ae", - "0x00000000000000000000000000000000001b4cff12b3ca2c242b1cb101ca1f62", - "0x00000000000000000000000000000051285e317a9d17f2180bf8ec1f3e31c266", - "0x00000000000000000000000000000000002f79f4597dc1cbdfe8060d1d92c7fc", - "0x000000000000000000000000000000bfdd478df770ff0d6a9f5d30c6380e3bb2", - "0x00000000000000000000000000000000000f6c52e2949dd6fa7eff016e2e5bb6", - "0x0000000000000000000000000000001cba707dc36043107ad882453ae5d8b129", - "0x0000000000000000000000000000000000059cc841348db66a31d2dfa33b89a0", - "0x0000000000000000000000000000000e2b2caaf1a1eda41d509cc5221c984b51", - "0x0000000000000000000000000000000000037cc127472715a44cac19993d448a", - "0x0000000000000000000000000000003cc6bfe8250e54d57ce7daedc9a7095bc8", - "0x00000000000000000000000000000000001c95108bb4f2494bfef842093c3b36", - "0x0000000000000000000000000000008313e6a820b2f5c2a7de8028cd31798633", - "0x000000000000000000000000000000000027be294c15550f339b0839d5860142", - "0x00000000000000000000000000000060338657a29bcf8c13a4b50294e337ef11", - "0x00000000000000000000000000000000001569de523f46c6226a398155490417", - "0x000000000000000000000000000000163a5d9281ca7ac774da33d1bd5e32dd54", - "0x00000000000000000000000000000000001cea3677784e36b40d3084060d7486", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000008a36ca53543c7bd871dd8974dda60ec04e", - "0x000000000000000000000000000000000028fcc75fb20c13fa73b0b5dd1a9df0", - "0x000000000000000000000000000000646eccdb4bcb213d9d9867f291bc4cc715", - "0x0000000000000000000000000000000000239e0bfd2fe8666da2541d2b7e9242", - "0x00000000000000000000000000000057b0434a909bdd123f328dd722f50de441", - "0x0000000000000000000000000000000000056e909ead4cc889ca4ae259618b9e", - "0x000000000000000000000000000000cce3583f4dbdf7f0ea96b8413114530b7f", - "0x0000000000000000000000000000000000029d93569d5fb4eccfe54516bbfc2c", - "0x0000000000000000000000000000000202259bdd735f5d0996b36a14296dd956", - "0x00000000000000000000000000000000001c9a81340c0ef1a3f8ab9378b45228", - "0x000000000000000000000000000000bb9541231ccc05d3210933db9b2cfd662a", - "0x00000000000000000000000000000000002e90121d7079020ef60bf83a167d82", - "0x0000000000000000000000000000008e531da6a57f645193723255cc3949f2a6", - "0x000000000000000000000000000000000023d3bfa481c11731a958ae003b7049", - "0x0000000000000000000000000000005d505cd2a7715559ab2fb8ffa94fac158b", - "0x0000000000000000000000000000000000283299e0b6841cadaef68c90af63b3", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a50e32219d22dc5bc0a2a3afa8d1c963bf", - "0x00000000000000000000000000000000001b05579d422ec3526b639fa813b3db", - "0x000000000000000000000000000000931e9ee47cc6828d015bfd807445f50921", - "0x000000000000000000000000000000000005283cabb6b55f9baa597d00d3f46f", - "0x000000000000000000000000000000f14ecdef3987001b29e5574b25db85e726", - "0x00000000000000000000000000000000002b26e84ba3e9db90b9b761fbd5ba48", - "0x00000000000000000000000000000054401c158e8bfa1eac201ac628df1458d3", - "0x000000000000000000000000000000000028b61261027652e8ca3b29fb567872", - "0x0000000000000000000000000000005ddf21ec29f762249f79a86d986723b259", - "0x000000000000000000000000000000000020d889a78eaaeeced668f7a5e6a155", - "0x000000000000000000000000000000fbf31736f1c118ed779b00b56effa82f84", - "0x00000000000000000000000000000000001c10198fa65839280c9a4df0d48c69", - "0x000000000000000000000000000000ae45bd31909c920cd302c1833dc9dac27c", - "0x00000000000000000000000000000000000b5e828a1794bb52b1ef28384f36c3", - "0x000000000000000000000000000000623a32eccef6d3f192c9090e2c8d211339", - "0x000000000000000000000000000000000017dbcb62b1ef67a30ab74432100e03", - "0x0000000000000000000000000000008e75c04775713fe2b95076a7a5e1036c46", - "0x0000000000000000000000000000000000070ea9b40827062280d6e3cc9609a6", - "0x000000000000000000000000000000c70577cdcada107c62a7732ef0d2bbc15f", - "0x00000000000000000000000000000000002e57c64ac76e0a1e1c5980782cb606", - "0x000000000000000000000000000000902c14297534b09b2a8072cd93a9489887", - "0x00000000000000000000000000000000000cb983d7cc09d74a951dbf12ad432b", - "0x00000000000000000000000000000012bff816b24bc7a97ad6b1549515d6b28e", - "0x00000000000000000000000000000000000467570dff77ca3a342e4fc4d1a66b", - "0x00000000000000000000000000000080a63925457f739d70103395ccb7dcd29d", - "0x00000000000000000000000000000000000249558e7e5b5d6473ec5a9a980688", - "0x0000000000000000000000000000006cd74958767b5d51a95549a316e285ab74", - "0x0000000000000000000000000000000000091261933d2e12b6818f72bdc3e0c2", - "0x000000000000000000000000000000f97e56f24f292a230cf6c8350df6989d74", - "0x0000000000000000000000000000000000191f5e720c5ae2ded820c5e22cf23f", - "0x000000000000000000000000000000d3659c79160cc300c1726cdfe0a093bc08", - "0x000000000000000000000000000000000028e8e8952512f8006336791f90f01d", - "0x0000000000000000000000000000007ee7b8782f98bb5d90cbdc6fe174a42009", - "0x00000000000000000000000000000000000ae0ee6c55535140057064aa3fc5f0", - "0x000000000000000000000000000000d2bb98513b84e1e6f4e0b606bc025f9c48", - "0x00000000000000000000000000000000000b21f9d209054956c0524fababf1e9", - "0x000000000000000000000000000000d81d8ac019f7fed05a6b57f7845f56e44f", - "0x00000000000000000000000000000000002971c35ad470594c9a15abfc0e25a6", - "0x000000000000000000000000000000415d3a9385f247cc4092e3aad3382acd35", - "0x000000000000000000000000000000000025f0852ecc99395598d1e68d0ca89f", - "0x0000000000000000000000000000004f32605fa17fb311a06f7fb843c15d558a", - "0x000000000000000000000000000000000005071f43d210d49c73d5f25a18a596", - "0x0000000000000000000000000000000a679653df2810b4ec4c7adcd1cd7c97c8", - "0x000000000000000000000000000000000013c145ee6755ca17c398dafb88a569", - "0x00000000000000000000000000000083bace0537b2947643af96ab4b4aa8c478", - "0x000000000000000000000000000000000011ae383aeafc332a329462493ac315", - "0x000000000000000000000000000000a18bcfba0739bc5f71bd74ec53b6837fea", - "0x00000000000000000000000000000000001c2a9a991c7dbcd75129f92ff372b1", - "0x0000000000000000000000000000002c80b406fa46ad088b2e8d4f5a5701d47c", - "0x00000000000000000000000000000000001879ed897e504955597f01336b1d86", - "0x000000000000000000000000000000655b7a8802d367044c042458a17a0aeab4", - "0x000000000000000000000000000000000021be3e235af1a949dbf105cbe725d0", + "0x0000000000000000000000000000000000000000000000000000000000000cbd", + "0x000000000000000000000000000000c4d62213b081c8e90e6c8f3587321997f5", + "0x00000000000000000000000000000000002236a0b9f0654f7cd634c9c34280f1", + "0x0000000000000000000000000000007cb00736872fd50e291ec99fb640f1f7d9", + "0x00000000000000000000000000000000002d1b1b74b74ddf7d6f964a7bdb2af3", + "0x000000000000000000000000000000f26bcf89c86dcbce68a4f1b5b73505dcec", + "0x000000000000000000000000000000000011a128ae6c7be3a962485534f27786", + "0x00000000000000000000000000000088278f8cce72a5f698601f11a1532a9dad", + "0x00000000000000000000000000000000000d9caeabde23d8c2a0bd2cdef54193", + "0x0000000000000000000000000000001cfb29930f6753e5cb6a60342c16fe5e4f", + "0x00000000000000000000000000000000001022a2847e12bdd43b96342e5b8e16", + "0x000000000000000000000000000000fefee7789c5b50b89ce3ac6155975c4319", + "0x000000000000000000000000000000000002e25d02799b225c89aba3a667d7e5", + "0x0000000000000000000000000000006e210889b06205312234c097f979fca3b5", + "0x00000000000000000000000000000000000566396dc1f8e15f3a1c3729bb3393", + "0x0000000000000000000000000000009790f776d7aaecbcaf977d3aad6070c4e4", + "0x00000000000000000000000000000000002dcdeaf93e01c780512d9950fbfd94", + "0x000000000000000000000000000000d2ef194a7b605db9c6df08b9576c97735e", + "0x00000000000000000000000000000000001ff98ab3818a3d5fdc538a7bbeb87e", + "0x000000000000000000000000000000be40a925ee773bfc3923df01da59a497d7", + "0x00000000000000000000000000000000001fb52b895f997b5a90ea722d9a4140", + "0x000000000000000000000000000000dd5a7d1074be39e4451795f983d45b5be3", + "0x00000000000000000000000000000000001cbfd5b0d763096343af10ed1f3496", + "0x0000000000000000000000000000007cc56b953bb8ef24745e9200896ee10ee1", + "0x000000000000000000000000000000000001ef96b3ae0b2677b21939012dcc17", + "0x0000000000000000000000000000004ba56f98fc7d6d956bd6302ef6941f9239", + "0x000000000000000000000000000000000010bf82473c11a65eb2ac193002bfe4", + "0x00000000000000000000000000000072739ba831885d7f767251b9cc444961e5", + "0x0000000000000000000000000000000000256ea7e1dc188341f8692fd52454cf", + "0x000000000000000000000000000000a284c1c0bd5602eb7242fda659dc49ff99", + "0x000000000000000000000000000000000002e5e663dd3bf5f961173646b8e7b3", + "0x000000000000000000000000000000194cc54081bb3ffba3c67547dcb2db4d37", + "0x00000000000000000000000000000000002377042c75bab3ceee3b186c40b8b6", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000f0af57d5589fc84e1f8897bb5a62ec0ea9", + "0x000000000000000000000000000000000016583df9856bef930ef0a81d3357f0", + "0x000000000000000000000000000000e0a92aecf729c58fa7672c82066409d090", + "0x000000000000000000000000000000000010085406672c105a10ddee00634540", + "0x00000000000000000000000000000036b650e61cb6e0ec6ff6b1aef12c8c81e3", + "0x00000000000000000000000000000000000049ced3703b6736736daa8d94d66c", + "0x00000000000000000000000000000024e41b443846d1b9d969a739fe9ec5544d", + "0x0000000000000000000000000000000000251ef94ce2811e61503920adc1a548", + "0x000000000000000000000000000000ab378c4d63d86a750348adbd4cbc2c6883", + "0x0000000000000000000000000000000000079aee0bbaec8a7e39acda8a2bfd44", + "0x000000000000000000000000000000c4996ccb316a1671fa17ac0ec536c08aee", + "0x00000000000000000000000000000000000087a93f4353d8c6e85d6c58c7af49", + "0x0000000000000000000000000000002754983ee3f30f64f3ef3d6a27f671032d", + "0x00000000000000000000000000000000001b77b7da696321894ac402dc70a471", + "0x00000000000000000000000000000065a8c950362ff55e55d6006254e4cb8f60", + "0x00000000000000000000000000000000000a0eb81f69be92cc51ba479d4d4b2d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003a6dc78277b2838aca18adc58385b4a7f0", + "0x0000000000000000000000000000000000132c99e752833cae9473e7dfe278d0", + "0x0000000000000000000000000000003ec707e1f4369d5f99a3bac8eaa16ec4ba", + "0x00000000000000000000000000000000001cd77155c0a5e65f942f719c8e73f5", + "0x00000000000000000000000000000084604af6454cd074b40340a0900f8e47cc", + "0x0000000000000000000000000000000000077d31bdfcd802cd5aa1a457b97f10", + "0x00000000000000000000000000000099c886edf1320d2f8eef9c059a2495598d", + "0x00000000000000000000000000000000001400c2b452cd839ce363493a76312b", + "0x00000000000000000000000000000090681337eb7720ddc934e8bcc81bd9ae2b", + "0x000000000000000000000000000000000006ab19688014b0f0cf860c615759af", + "0x0000000000000000000000000000007165a99470ed5af56e75a9636be648e93d", + "0x000000000000000000000000000000000009dbbccaa2350bd92c5ce19b5d290a", + "0x0000000000000000000000000000000e1e042ed81d839a9f0ead9d291b6a8f32", + "0x00000000000000000000000000000000001a205aec8c334db49f816f4b5dafcd", + "0x000000000000000000000000000000ebb4edb0db1dcdf348033a7901a3680b6a", + "0x000000000000000000000000000000000011aae86275b822ebd3fa82c7315eff", + "0x000000000000000000000000000000e97eee8ec09b50e69135709916aba933c6", + "0x000000000000000000000000000000000010e2e96f78a68fc25ba2e4dafd04cc", + "0x000000000000000000000000000000b214f0a5321e8817d78adb6e0c20d7319e", + "0x000000000000000000000000000000000025bc9ba17b749d567d90e8f13af9a2", + "0x00000000000000000000000000000066fba7ba25f999f6f2838e553a29901fa7", + "0x000000000000000000000000000000000020711b883c2eb028f9d2d3da010519", + "0x000000000000000000000000000000a140d481bdc261d13949520f9ec7371c20", + "0x0000000000000000000000000000000000020bfe682fa3abc7653ce6853b0112", + "0x0000000000000000000000000000001b2bf2cbcde5d02c025a94db3378725693", + "0x000000000000000000000000000000000023e613dfd6966df7487e58fd52480c", + "0x0000000000000000000000000000006e2eb63e8f0cbcbd7a88665a53e119e428", + "0x00000000000000000000000000000000002e70d3962ba79ea7ae10b168c1c7d9", + "0x00000000000000000000000000000030517d9ecfee899135ff976333894660c2", + "0x000000000000000000000000000000000007417244ffad99a470ba89eb0ff90e", + "0x0000000000000000000000000000009bac28f405d40e017edf00277102b49c3d", + "0x000000000000000000000000000000000006b41a5fb6e909b8be3ff0dd952728", + "0x0000000000000000000000000000006683ae1c70f7eb680544f4c342c93087f1", + "0x000000000000000000000000000000000025f0aabdb61ed9c3922c0edfb358ec", + "0x000000000000000000000000000000351b5aea3d5e9850880e66335bcae23e94", + "0x00000000000000000000000000000000000ee72d3f7aca6bbe97267028d6abf9", + "0x0000000000000000000000000000008928d9a8e7f72b161cbe49ae95aa21ae63", + "0x0000000000000000000000000000000000185c141dba0abcf1e6d7db09787ca1", + "0x0000000000000000000000000000003e245e17b3e7805608abb6a2350fa6a847", + "0x00000000000000000000000000000000000cf54864a0d0738294136903b96823", + "0x000000000000000000000000000000f11eab4aad68f934214988cc4f58d5a6a2", + "0x000000000000000000000000000000000022f67f7b7d5406007bb7ddae120884", + "0x000000000000000000000000000000c05dc37331557bb9a3f702d92cfe090666", + "0x0000000000000000000000000000000000264629b4e2c6c2614bd57046d2ac8b", + "0x00000000000000000000000000000017305f321100b05a42b9014b4b5f033fd9", + "0x00000000000000000000000000000000000300f05e18d0c58963b144d3d28da6", + "0x00000000000000000000000000000039e8490810fc737b4a353bb67d95baa83c", + "0x00000000000000000000000000000000001b8f101b87ef8f67f87224f50b4e86", + "0x00000000000000000000000000000048da15030eaa7e0cc01567e721d66ead43", + "0x0000000000000000000000000000000000126b3927169eb104827c842837f462", + "0x00000000000000000000000000000008b500094a5820c680fb1db8c125502e1e", + "0x000000000000000000000000000000000000660eef61b7d219f439ec4fbfff1b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -143,65 +143,65 @@ sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000006ab4e9fba1bb0c45d30796e0c19546192e", - "0x00000000000000000000000000000000000b1447f3413f687009608e1c55b192", - "0x000000000000000000000000000000567498365d293b6c0532b94c33d0e937a5", - "0x000000000000000000000000000000000006c4fabfa5194704563bcc508d234e", - "0x00000000000000000000000000000009835f11bc7b963372a60d92370980b183", - "0x00000000000000000000000000000000000d898f5e8487e3ed90a10fc50db186", - "0x000000000000000000000000000000b66ee3d15932d652c3b54801748e89da9f", - "0x000000000000000000000000000000000024899f4b6ba56af0e1128c4a431ba7", - "0x00000000000000000000000000000064dd7da7637cf2116a18531edc7fea829a", - "0x0000000000000000000000000000000000162e867465b02e01bbabb15c59b84d", - "0x00000000000000000000000000000071f09c1d3d2c8f9499c838fc966b04ada9", - "0x00000000000000000000000000000000000f4504ac6f302739e9f2c7aa824d12" -] - hash = "0x051d17b4a7efa4af82e7c6b71f2a5cf71ee015e6d9edbcd39d326a5463aac1e6" + "0x0000000000000000000000000000001115e1df83c7f85610477a243a350ad610", + "0x000000000000000000000000000000000016b525f879d97a8d50cab6d1a41d58", + "0x0000000000000000000000000000005545bbd9cc9de7a79986b650103736492e", + "0x00000000000000000000000000000000000aac06f3452ec0a5be2b5e3060f108", + "0x000000000000000000000000000000c6e13ef9aedec4af73a577a6dd72dda690", + "0x000000000000000000000000000000000016b603e70199deaa1eff742257259f", + "0x000000000000000000000000000000dd7902c16a885b205f012abf38e3f9f470", + "0x00000000000000000000000000000000002a45b4a48e9544c186e119184fd191", + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" +] + hash = "0x1e580df70c4374ef9942846936ab5fc2d7da61ca21bd0576f269746152a782c4" [previous_kernel_public_inputs] min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff293f" -is_private_only = false -claimed_first_nullifier = "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7716" +is_private_only = true +claimed_first_nullifier = "0x1268b93c2a6a4d3780d6cb2b948cc3884e65336ef39eb7202b4de102b9cb3748" claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" [previous_kernel_public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" [previous_kernel_public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x1f8e9213a0888fe29bbbc5c39db80f4b9f1575e375c6a0932a13ca2b8e2fced2" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x1d706e11585e9d3ecfd4d2ead7a52c2a783a92adfbe3419e8671011fe5016491" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" [previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x0835e9ab1ea355f270408857dfd5647ca56d588ab4a7d573e67566f6324821d1" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1f860209ee462b9c30510a063670044f005084362ce71f528205a17ee048fc7d" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2597" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -212,7 +212,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [previous_kernel_public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -224,29 +224,29 @@ l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" [previous_kernel_public_inputs.constants.tx_context.gas_settings.max_fees_per_gas] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" -fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" [previous_kernel_public_inputs.constants.tx_context.gas_settings.max_priority_fees_per_gas] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -268,7 +268,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array]] [previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.inner] -inner = "0x29ecb485abf1e4a9963bb4dada6e8b67bda9c6bb09527ecb8d0c64a0d119e0fd" +inner = "0x302a86bd5883e95684cbcd46af941e62a60b0416ee605f00eae4a0189b8af2ee" counter = "0x0000000000000000000000000000000000000000000000000000000000000003" [previous_kernel_public_inputs.validation_requests.note_hash_read_requests.array.contract_address] @@ -779,15 +779,15 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.nullifier_read_requests] -length = "0x0000000000000000000000000000000000000000000000000000000000000000" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] [previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15" +counter = "0x000000000000000000000000000000000000000000000000000000000000000b" [previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" [[previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array]] [previous_kernel_public_inputs.validation_requests.nullifier_read_requests.array.inner] @@ -1301,13 +1301,9 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1316,13 +1312,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1331,13 +1323,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1346,13 +1334,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1361,13 +1345,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1376,13 +1356,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1391,13 +1367,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1406,13 +1378,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1421,13 +1389,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1436,13 +1400,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1451,13 +1411,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1466,13 +1422,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1481,13 +1433,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1496,13 +1444,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1511,13 +1455,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1526,13 +1466,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1541,13 +1477,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1556,13 +1488,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1571,13 +1499,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1586,13 +1510,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1601,13 +1521,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1616,13 +1532,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1631,13 +1543,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1646,13 +1554,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1661,13 +1565,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1676,13 +1576,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1691,13 +1587,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1706,13 +1598,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1721,13 +1609,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1736,13 +1620,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1751,13 +1631,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1766,13 +1642,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1781,13 +1653,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1796,13 +1664,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1811,13 +1675,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1826,13 +1686,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1841,13 +1697,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1856,13 +1708,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1871,13 +1719,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1886,13 +1730,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1901,13 +1741,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1916,13 +1752,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1931,13 +1763,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1946,13 +1774,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1961,13 +1785,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1976,13 +1796,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1991,13 +1807,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2006,13 +1818,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2021,13 +1829,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2036,13 +1840,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2051,13 +1851,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2066,13 +1862,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2081,13 +1873,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2096,13 +1884,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2111,13 +1895,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2126,13 +1906,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2141,13 +1917,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2156,13 +1928,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2171,13 +1939,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2186,13 +1950,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2201,13 +1961,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2216,13 +1972,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2231,13 +1983,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2246,13 +1994,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2772,14 +2516,14 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers] -length = "0x0000000000000000000000000000000000000000000000000000000000000001" +length = "0x0000000000000000000000000000000000000000000000000000000000000003" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] counter = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x023cfeab2c97a4c457a539c4b7c7c9d1fefa40027aacd687b5282ff01a46f27b" + value = "0x1d572b897a46622761043b29c51e639c89bda7b3a9f4111e8f1766a72bc194ec" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -2787,25 +2531,25 @@ inner = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000007" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x000000000000000000000000000000000000000000000000000000000000000c" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000002" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] @@ -3586,38 +3330,38 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs] -length = "0x0000000000000000000000000000000000000000000000000000000000000000" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x000000000000000000000000000000000000000000000000000000000000000d" [previous_kernel_public_inputs.end.private_logs.array.inner.inner] note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] fields = [ + "0x174c6b3d0fd14728e4fc5e53f7b262ab943546a7e125e2ed5e9fde3cf0b3e22f", + "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x1ca223fbc16e82cbb9bd22c108021ef47864791c258edbdd8eefa458c62ba8d2", + "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", + "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", + "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", + "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", + "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000000" + length = "0x000000000000000000000000000000000000000000000000000000000000000d" [previous_kernel_public_inputs.end.private_logs.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000002" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] @@ -5573,34 +5317,34 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.contract_class_logs_hashes] -length = "0x0000000000000000000000000000000000000000000000000000000000000000" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.contract_class_logs_hashes.array]] [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000008" [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner.inner] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" - length = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x242b9549d1e2c420a764a5aa2ba58d98b77e35fef8ffa5aa787f9b325f2b5005" + length = "0x0000000000000000000000000000000000000000000000000000000000000068" [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" [previous_kernel_public_inputs.end.public_call_requests] -length = "0x0000000000000000000000000000000000000000000000000000000000000001" +length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.public_call_requests.array]] - counter = "0x0000000000000000000000000000000000000000000000000000000000000006" + counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.public_call_requests.array.inner] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.public_call_requests.array]] counter = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6307,7 +6051,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [padded_side_effects] note_hashes = [ @@ -8311,9 +8055,9 @@ read_request_index = "0x00000000000000000000000000000000000000000000000000000000 "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", - "0x0951be8128e49814029387ac6bfbe43a1e43dadd05a6e50f78ef8265cd09b5a1", + "0x011493b3dc6ff7233e375206a6abca69781caccfbce08c0507c7ba581aa94b0b", "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", - "0x15f254a15d2db357812a7044082d84639b7c8adc2a909034fb01d4a6879296ab", + "0x2ed29e329b77e3cddc51479e8f2dd13802a7e1aa2ff1b447d6007fedf382717f", "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", @@ -8350,7 +8094,7 @@ read_request_index = "0x00000000000000000000000000000000000000000000000000000000 ] [hints.note_hash_read_request_hints.settled_read_hints.leaf_preimage] - value = "0x29ecb485abf1e4a9963bb4dada6e8b67bda9c6bb09527ecb8d0c64a0d119e0fd" + value = "0x302a86bd5883e95684cbcd46af941e62a60b0416ee605f00eae4a0189b8af2ee" [[hints.note_hash_read_request_hints.settled_read_hints]] read_request_index = "0x0000000000000000000000000000000000000000000000000000000000000040" @@ -11692,7 +11436,7 @@ read_request_index = "0x00000000000000000000000000000000000000000000000000000000 value = "0x0000000000000000000000000000000000000000000000000000000000000000" [[hints.nullifier_read_request_hints.read_request_actions]] -action = "0x0000000000000000000000000000000000000000000000000000000000000000" +action = "0x0000000000000000000000000000000000000000000000000000000000000001" hint_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[hints.nullifier_read_request_hints.read_request_actions]] @@ -11948,8 +11692,8 @@ action = "0x0000000000000000000000000000000000000000000000000000000000000000" hint_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[hints.nullifier_read_request_hints.pending_read_hints]] -read_request_index = "0x0000000000000000000000000000000000000000000000000000000000000040" -pending_value_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +read_request_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +pending_value_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [[hints.nullifier_read_request_hints.pending_read_hints]] read_request_index = "0x0000000000000000000000000000000000000000000000000000000000000040" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Prover.toml index 4a9ed54ae711..2875610b0af5 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Prover.toml @@ -1,130 +1,130 @@ -expiration_timestamp_upper_bound = "0x0000000000000000000000000000000000000000000000000000000069ff1b30" +expiration_timestamp_upper_bound = "0x000000000000000000000000000000000000000000000000000000006a0c712f" [previous_kernel.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000003d" sibling_path = [ - "0x1836f64afd38c3a05416bbcee658f4acce2576bbe554a445b33b8936297034e1", - "0x2c05a8ec2045319ea62b81134a53d4e0c1b021fed7877a3a8acc676cf26794f7", - "0x280ae800476659efd90f7ae6a3a2ae3958c1261ca9ae8ba3b2b8320fc9ef662d", - "0x1afa13b72352bab63bfdb391bbadee67783679a9b5ce7fbbcde44387ba5b0eae", - "0x2a99cb07c31aa5ee3a8af2c6db61485892e126a5eac56720fcbbbb002b19d015", - "0x0384c341c7892982bb9f5581098584a00bc572787bf4153d0a52532652ace783", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x0e5e5b81c76efb898b163faa6ee7d6855b64a79e56ac17ff7cf95a60a1125d58", + "0x1ed1f6ae3c2aba56858bdbb3c261d8f7700092a1a1f890d6a0a107e3712446e2", + "0x0ea9a4b61d0915de0514bdc6af213e5f1b338ed1afbef7f1e9fdcb042a751935", + "0x1998bd282e674d397ff88e6b98ed4c795f92263867aa8a0a0b73b1b5643128b5", + "0x084174c19225d48e9b905b49bd461775b745efe40c7f706e5df7e05b4d952d41", + "0x0ae4f3dc533a85154efaa40fbe95415d0544950a47ed66a57418e991f0f134a4", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [previous_kernel.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000011", "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000cad", - "0x0000000000000000000000000000002b2468b5f8f13bd482d710d25b291a02d4", - "0x000000000000000000000000000000000028799bf367c0778599b2b948882163", - "0x000000000000000000000000000000fe9b706fe16bc87d35001fd66356a746bc", - "0x000000000000000000000000000000000001ca485164bddf169d3fe6c29f62e7", - "0x00000000000000000000000000000075e09707371f536b6282e95e95cb185f37", - "0x000000000000000000000000000000000024009d9583c43b01bfe49bd946bf15", - "0x000000000000000000000000000000881a9c651f0a2aae2de99f5557fa22023f", - "0x00000000000000000000000000000000000068e5a5ca58bc35138b3847beeed4", - "0x000000000000000000000000000000f223a8c39d330da2a41cef98b4e091c9b7", - "0x0000000000000000000000000000000000211f7059c97618280acecd75745235", - "0x000000000000000000000000000000044e4a5f8a66993f61ec86dfb978efde9c", - "0x0000000000000000000000000000000000090682734b33c06cd65ba8824167f6", - "0x0000000000000000000000000000007add80ab4d0d02238831551a2844a9f730", - "0x00000000000000000000000000000000000bb45a300640a05ece5fe1ad9b9ee5", - "0x0000000000000000000000000000007da2be4190c8f0f38b37f33d411b427a1b", - "0x000000000000000000000000000000000026098dd8b73e82d335f5e784cbf652", - "0x0000000000000000000000000000007ab032555b3b13f26ed0788c300e54c30a", - "0x00000000000000000000000000000000002a8c9e9e15de7b8b11220f4055bf04", - "0x000000000000000000000000000000f4ce25385f14112552f1512e2f4e99d0e8", - "0x000000000000000000000000000000000015873846a6e7648a844f037a03f737", - "0x00000000000000000000000000000076dbac5187affde31d2adfb3b5064f5a77", - "0x000000000000000000000000000000000020ef23c172d94df80288571d7e3ca3", - "0x000000000000000000000000000000e69eb7802e5d99aa20bc39dee1f6b84b8f", - "0x00000000000000000000000000000000002b2c9af00759a128112ed819b8b1b0", - "0x000000000000000000000000000000f74bd0fb26a604548c9068fef410612fb9", - "0x00000000000000000000000000000000002ca283b09804c9b7d8ca32dc3a2c75", - "0x000000000000000000000000000000c90052c50c0497cddef7e3a71872d14596", - "0x0000000000000000000000000000000000231d65742b933d5aef1ad67db52143", - "0x000000000000000000000000000000b86b4223f0ebb39a8741b6ebba3a313095", - "0x00000000000000000000000000000000001f853f71eaa7368db93d05eefb5256", - "0x000000000000000000000000000000467ff45666661562c57d52de8c4f8f193c", - "0x00000000000000000000000000000000001fdb031a99c29b571b0a66a4140e8e", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000089d2777774ad5c33906740b3656fda53a0", - "0x0000000000000000000000000000000000133bedccd128dc4587817ae09af71b", - "0x000000000000000000000000000000641918e54723a119562889c1ff6239d13d", - "0x00000000000000000000000000000000002c14c2e4f17070e269f9903a383793", - "0x00000000000000000000000000000026c43cff4875a95471fe2c2008292fff78", - "0x00000000000000000000000000000000001224540abfac9c15d64e21d816b9dd", - "0x000000000000000000000000000000beb481b4d5d4eef75c1b133ca9b7efa690", - "0x000000000000000000000000000000000019b490637210bf2280a86ae0a1d7f7", - "0x000000000000000000000000000000e0b4e0795a8b1375e34eab2397b735ef03", - "0x00000000000000000000000000000000000effe6364fc31714fde11efcbe733c", - "0x0000000000000000000000000000005a1907824e164fc0fdd0f0e7c61f4d7398", - "0x00000000000000000000000000000000001cd6403b37da0361f243a3606ac383", - "0x0000000000000000000000000000006a48458b17770a4ad91f725dd01a8c486b", - "0x00000000000000000000000000000000000c395fd0e57de7d52c706e13918651", - "0x000000000000000000000000000000cde7b67f0a01ba051f06746ff7b56f59de", - "0x000000000000000000000000000000000020e0ab3fa354e260e0ac1855e128ca", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000654fe84b50aced8eb7212098af0880ed53", - "0x00000000000000000000000000000000002b2fcb6b0ee568a71f92d2a9bbfad3", - "0x0000000000000000000000000000005d9f4f1e59fac32314c435fb51e2a25ff0", - "0x000000000000000000000000000000000009734092d4e035b968ae8ee337464c", - "0x000000000000000000000000000000a28867ea56c5fbf4aca51fdbbf965e5dae", - "0x00000000000000000000000000000000002feaf04057ed002c072833048ce9e0", - "0x000000000000000000000000000000f9b70bdcd41a1c0bade216b9d5284af115", - "0x00000000000000000000000000000000001ece78d726aaf44e37d9053ebd1534", - "0x000000000000000000000000000000c4e55b000805b017402a109a6b29805245", - "0x00000000000000000000000000000000001d999b7c6ca8df0cca3c57ee4c8be8", - "0x0000000000000000000000000000008820aa820991933af75b5d02d44d0bf685", - "0x0000000000000000000000000000000000039880d1fbfc627ab3421788858e66", - "0x000000000000000000000000000000514dfa671906947f5f640255bfc583eedc", - "0x00000000000000000000000000000000000b0e0c990016a1fdf37d3d6daea7ae", - "0x00000000000000000000000000000040dbbc0f6d52ba0ce246acf816373fbbc1", - "0x0000000000000000000000000000000000035ba8d570a6b7efa251b206e85c82", - "0x0000000000000000000000000000003ebdd6ba8db24c72ad85e8d10fb1346027", - "0x0000000000000000000000000000000000035c795b4ad27e20c934ac5ae517b8", - "0x0000000000000000000000000000005369721308b3dda5dbbab39f83bffcf79a", - "0x0000000000000000000000000000000000241a6ba1547bf3c8eb2ded3454d897", - "0x0000000000000000000000000000009f97bcbba8db2f8bda79a78c0eaefacc5a", - "0x00000000000000000000000000000000002c960a56441f3a00b2f8b48f3b3563", - "0x000000000000000000000000000000ffe2ad855d3522d6b3f8b544681949c713", - "0x00000000000000000000000000000000000002f9753e605a6cbf6dbc604046a6", - "0x0000000000000000000000000000008cfee82227443d00335c9ef376137f6217", - "0x00000000000000000000000000000000001708d8cb04ad71f327107dd3e73cfb", - "0x0000000000000000000000000000007872392082ec4533c6b70f690660ee498f", - "0x0000000000000000000000000000000000122a83a98d1d526cb57355616bb850", - "0x0000000000000000000000000000000a95a3eeae99b98360d61166e89954845a", - "0x0000000000000000000000000000000000202c82d7bd85e9243e7ed0801ebe64", - "0x00000000000000000000000000000027acbc73301fe1b0c21888c2722dd75b7a", - "0x00000000000000000000000000000000002ae7d3ca125bd531826422c7d1acf7", - "0x000000000000000000000000000000d761bb670a9ff734cc38f0d30238a2b28c", - "0x000000000000000000000000000000000005aa3fab8a429258028c4a4287a0e6", - "0x0000000000000000000000000000007a80c32a515f441ce80a5d6cdb53d50866", - "0x000000000000000000000000000000000017f409fea3a1680e6df2a07e9eb3af", - "0x0000000000000000000000000000001a93444f40b0bc09418c7894fe797e2736", - "0x0000000000000000000000000000000000171474b32205fc141e14cfb847a8d3", - "0x000000000000000000000000000000081188cb41c2b23f91bef3a8237fb5fa5d", - "0x00000000000000000000000000000000001ed9b478e77d9f60e9614dfd6014ba", - "0x00000000000000000000000000000042f9a2c111e62ef204c3851affea6af0ef", - "0x0000000000000000000000000000000000108601bd973a835e50fc521d6ec1d9", - "0x000000000000000000000000000000f92be9d44c6688723f37065c3af9521bd6", - "0x000000000000000000000000000000000022ed90948b7d0f29ee1ed4349cab5a", - "0x000000000000000000000000000000bf6e68585d4cb32aeb39412d4a3e6cd968", - "0x00000000000000000000000000000000000c8df79002571c9aef12bb6d7f3bca", - "0x000000000000000000000000000000046577d9d6782e8214d846d3a16aa8ceb7", - "0x0000000000000000000000000000000000249e158a2e56acae4de64894bb2366", - "0x0000000000000000000000000000004b4ecd7a5a335425433b11e098157c3557", - "0x0000000000000000000000000000000000152c2ebca43c64a74ea10b830e9f62", - "0x0000000000000000000000000000006e65e30a946db2c5e16462e3a487d614eb", - "0x0000000000000000000000000000000000294d7279cdf2f3a5a0f47d5d830d40", + "0x0000000000000000000000000000000000000000000000000000000000000c2d", + "0x0000000000000000000000000000009746a298cc238fa9fc88119d64824cecd3", + "0x00000000000000000000000000000000000a622e89485dcc5a40545852372230", + "0x0000000000000000000000000000006809e41276c7672741eaf50c615e7aaf5f", + "0x000000000000000000000000000000000023ef3262cfcbaa1a38aa48f42b80a4", + "0x00000000000000000000000000000029b4a0a73660db847087b0ec0ff8ae7cc0", + "0x00000000000000000000000000000000000bbf015119fab668caabd4aac59b4a", + "0x0000000000000000000000000000003aceeaa5125630611ff88a1638c74b8bf8", + "0x00000000000000000000000000000000002954b4a5df3301bd05b4b33f4b1281", + "0x0000000000000000000000000000007d75fd1698bf937cad957054b4d802deac", + "0x00000000000000000000000000000000001eae87f9894a26c8d8685edcaa11f7", + "0x000000000000000000000000000000bec44c06c527d2c90cd142d22a575b64ad", + "0x00000000000000000000000000000000001ce6fd416b339978042baa3b29160b", + "0x000000000000000000000000000000601d1a36cbf2648b7a35e094aab2f78625", + "0x000000000000000000000000000000000013d19f319a00fc7417c1ad631d3286", + "0x000000000000000000000000000000cebe2c4b8938871fcd990b93f474835e2b", + "0x0000000000000000000000000000000000253ff4164f3a2cdd7a2118f953a472", + "0x000000000000000000000000000000633bff41528ff6e9648cabab45618cd3f8", + "0x00000000000000000000000000000000000a128ad23b420b11945de2c94bc8db", + "0x000000000000000000000000000000c2bdeaad6e1bb38c01807cbeb39eb01474", + "0x00000000000000000000000000000000001a87197d7cbb357c71e7475853a89a", + "0x000000000000000000000000000000d60d42e56b09250d5406827e9f63c5c507", + "0x00000000000000000000000000000000001c429c10ec7865314a9bb768fc77cb", + "0x000000000000000000000000000000874ae527782ea78b526a4069d5a5fffad6", + "0x00000000000000000000000000000000000cf6dd26f50b908aedf25ca7beb983", + "0x0000000000000000000000000000007dfb532ce535603daa17b40d4f20268fa6", + "0x00000000000000000000000000000000001aa8da80801279d91cd4386764d5b7", + "0x00000000000000000000000000000051498e1f98a404cce7b25f7487732af055", + "0x00000000000000000000000000000000002d5ce3870ecba8710b98522a635a24", + "0x0000000000000000000000000000003f1d7da491f2a68c39458177333aa62b8f", + "0x00000000000000000000000000000000001d1af6c81adf6a906f55b20aa99aa7", + "0x0000000000000000000000000000004398c4f4ff3f65cba6337e0a48437289b7", + "0x00000000000000000000000000000000002c90b326149002904e30310eed12dd", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ce520672cc9f4fba3288b2d696d69b60", + "0x0000000000000000000000000000000000240074838ef9434d6524883c8af328", + "0x000000000000000000000000000000cc5409001d9a1b6e499a55194c5cee623b", + "0x0000000000000000000000000000000000272e8cb04c7e831a06e0eff44b1633", + "0x00000000000000000000000000000029faeb6bccfe395b36c4dde26a9281cd51", + "0x0000000000000000000000000000000000079cd2f8b7f8d0ba574f06c074487c", + "0x000000000000000000000000000000467663df6ffc3082510ef243829669f9b2", + "0x0000000000000000000000000000000000154ba884593558e4fa1d35a08901c2", + "0x0000000000000000000000000000003b9367cb2541b5cae36cacba4a0e9565f2", + "0x00000000000000000000000000000000000e9c894d1634c38a1da7a18ff2a4d1", + "0x000000000000000000000000000000a44d578cb20654807e5da0fae4fb462540", + "0x00000000000000000000000000000000001583bdfc0f1f208b72177fd73a4e0e", + "0x0000000000000000000000000000005101bd383908b7e9563f9943ed5b6b9d5d", + "0x00000000000000000000000000000000001894ae59fb37a39ee483d90674a601", + "0x0000000000000000000000000000008eaa98f808cc4df6011d0467d94748bfef", + "0x000000000000000000000000000000000018728540c99b37787e0ec614d5d2c2", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000095b02b4b915ea97d2863c7de9364faf7c1", + "0x000000000000000000000000000000000024bf0c36515c471894eca07c722a6f", + "0x00000000000000000000000000000021b9c8dd0f3068ab110290ce8dde8ca475", + "0x0000000000000000000000000000000000033a64820c52027d57fb58ebb6c381", + "0x000000000000000000000000000000de86fb0a5a50dd02848572163142b8640e", + "0x000000000000000000000000000000000006104618e23a8bd65ba6678675ef30", + "0x0000000000000000000000000000007ecf243d0261b865862c9aa1c0fa854c03", + "0x00000000000000000000000000000000002b49777a506a0876586804d7265c91", + "0x000000000000000000000000000000b03490f3e92e51591fa83188e45ff33c1d", + "0x000000000000000000000000000000000020ca792b4db8d34742259c49a69680", + "0x000000000000000000000000000000bba53bf211eba5cfdc0655d659b54e5154", + "0x000000000000000000000000000000000025743fca2cf229c9e74f0b94b2a60c", + "0x00000000000000000000000000000039fa7ba046a2aa4d1e1b2e7caf7a8468b2", + "0x0000000000000000000000000000000000114565ee8a1a9f6c0765554f828b55", + "0x00000000000000000000000000000039f6f4a9450081d17e80431d7673b4e831", + "0x00000000000000000000000000000000001aeacf01182adb275721404acf94ec", + "0x000000000000000000000000000000b61eb26643a3330cf20693ce2863cd8df9", + "0x000000000000000000000000000000000001287624004468d7fdb961891f7657", + "0x0000000000000000000000000000008e93f0560ff5d7fc733764b1eb22480fef", + "0x0000000000000000000000000000000000122ec6ad7d326d49eb1ec1b6058f11", + "0x00000000000000000000000000000095ed3058c8b0990d267a70546ff583ee0f", + "0x000000000000000000000000000000000014b8a07a5bb9e756fca0fa2b309603", + "0x00000000000000000000000000000011c41e34d997fc68ea4bf83e558d0cc63c", + "0x00000000000000000000000000000000002d5aa2b07b478858f898b181d0ba8b", + "0x0000000000000000000000000000002181f534d66eac7d336c5a0615483614de", + "0x00000000000000000000000000000000001ddfc420c74fb84de1fc06e15cb736", + "0x000000000000000000000000000000221911551b028d679741b7201b0ecbec4c", + "0x00000000000000000000000000000000000dda073b8d6dff1f7820fd10608eac", + "0x000000000000000000000000000000f83c26a030132139738278422f03bf922a", + "0x0000000000000000000000000000000000090293167442d6241ef786787ad54a", + "0x00000000000000000000000000000081472fe64f8676d2c6ba66632be788181a", + "0x00000000000000000000000000000000002686bba5965dbeeace183975458ab6", + "0x000000000000000000000000000000afefc9d6f3b48945adcbfcfd1c96c9d317", + "0x000000000000000000000000000000000004230c01cef5000fc66eed900511c7", + "0x000000000000000000000000000000461b8ddba4875f5c0ee209e969c8cab5b5", + "0x000000000000000000000000000000000004f3c201bbca13be28a391550e3e15", + "0x0000000000000000000000000000008559177c932a1653672c242e7617b96ed7", + "0x0000000000000000000000000000000000171be06bb1a5c5e15ae25ea139e42a", + "0x000000000000000000000000000000ee99ac22da62f96c90ac540968ff4e0df5", + "0x00000000000000000000000000000000002a4b4f6cecfa52aeacb7c88e2ba547", + "0x00000000000000000000000000000075b8d277e2f2d2578c463156acd5f1475d", + "0x000000000000000000000000000000000013ad863e13e6edf10c859862b09f73", + "0x0000000000000000000000000000009f93998170f02cdbb3d8ab65ffc18aa878", + "0x000000000000000000000000000000000000b2bad4d1a7598557b09810779622", + "0x00000000000000000000000000000000d5a82f535d9f53a56ad2c90d651a6f07", + "0x000000000000000000000000000000000000e77d138f0fe1fb3334079b7a17b8", + "0x000000000000000000000000000000375d67be44557b3a7109eb34e19abe23bd", + "0x0000000000000000000000000000000000004374e342cf902621d2f067ee0dde", + "0x000000000000000000000000000000618d7aa8936861e2dfed7786fe06e14cbe", + "0x0000000000000000000000000000000000028eef3b42459371670ed47195575c", + "0x0000000000000000000000000000004185b847b001cc084cb5d9fc3c413c9447", + "0x00000000000000000000000000000000000f0cdae2ffe529626d71ad12c69406", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -145,76 +145,76 @@ sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000034620fc4f5dc2f120b5673912cf04226e9", - "0x000000000000000000000000000000000025a6078d74c0fd7d4dd9e328ad4c94", - "0x00000000000000000000000000000019d834f9bb59a8e973ed867f0477fc8121", - "0x00000000000000000000000000000000001fdeb0dc3db761477a1a9feb00c906", + "0x000000000000000000000000000000ae09bb7f78acfe7c9d9a2b944b789f8363", + "0x0000000000000000000000000000000000011fa902d1394869cea67da68c1718", + "0x000000000000000000000000000000655a4cb5f0e139646b6fe88fd680ee9c5d", + "0x0000000000000000000000000000000000019f3c976b53013b5041616ea60768", "0x00000000000000000000000000000076959cf0870e0ae93bb69edc64b0cacdac", "0x0000000000000000000000000000000000269679f8c1a1ad2aadccaf8ba3100e", "0x000000000000000000000000000000bb028a742987d54246ffc933f8240d70ef", "0x0000000000000000000000000000000000295f79977c6ae0d15cc2b68b7f0837", - "0x00000000000000000000000000000064dd7da7637cf2116a18531edc7fea829a", - "0x0000000000000000000000000000000000162e867465b02e01bbabb15c59b84d", - "0x00000000000000000000000000000071f09c1d3d2c8f9499c838fc966b04ada9", - "0x00000000000000000000000000000000000f4504ac6f302739e9f2c7aa824d12" + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" ] - hash = "0x297f9ac45dd6c9f333314227aacca93023e72710232e7120328d7e7c209ebc8f" + hash = "0x141adcbeacb22e8db98482647ab8bddc8bafc8d2c45ba62cefe4fabe03067018" [previous_kernel_public_inputs] min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff293f" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7f3e" is_private_only = false -claimed_first_nullifier = "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef" +claimed_first_nullifier = "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb" claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" [previous_kernel_public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" [previous_kernel_public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [previous_kernel_public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -233,22 +233,22 @@ fee_per_da_gas = "0x000000000000000000000000000000000000000000000000000000000000 fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1303,13 +1303,9 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1318,13 +1314,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1333,13 +1325,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1348,13 +1336,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1363,13 +1347,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1378,13 +1358,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1393,13 +1369,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1408,13 +1380,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1423,13 +1391,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1438,13 +1402,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1453,13 +1413,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1468,13 +1424,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1483,13 +1435,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1498,13 +1446,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1513,13 +1457,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1528,13 +1468,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1543,13 +1479,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1558,13 +1490,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1573,13 +1501,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1588,13 +1512,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1603,13 +1523,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1618,13 +1534,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1633,13 +1545,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1648,13 +1556,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1663,13 +1567,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1678,13 +1578,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1693,13 +1589,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1708,13 +1600,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1723,13 +1611,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1738,13 +1622,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1753,13 +1633,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1768,13 +1644,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1783,13 +1655,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1798,13 +1666,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1813,13 +1677,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1828,13 +1688,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1843,13 +1699,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1858,13 +1710,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1873,13 +1721,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1888,13 +1732,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1903,13 +1743,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1918,13 +1754,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1933,13 +1765,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1948,13 +1776,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1963,13 +1787,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1978,13 +1798,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1993,13 +1809,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2008,13 +1820,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2023,13 +1831,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2038,13 +1842,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2053,13 +1853,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2068,13 +1864,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2083,13 +1875,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2098,13 +1886,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2113,13 +1897,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2128,13 +1908,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2143,13 +1919,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2158,13 +1930,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2173,13 +1941,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2188,13 +1952,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2203,13 +1963,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2218,13 +1974,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2233,13 +1985,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2248,13 +1996,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2781,7 +2525,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" counter = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef" + value = "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -5596,13 +5340,13 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.public_call_requests.array.inner] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x00a5e40cab902df3efe088094577e83eb92103581c990f351edf1dfba3778905" [previous_kernel_public_inputs.end.public_call_requests.array.inner.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [previous_kernel_public_inputs.end.public_call_requests.array.inner.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x1be490a4b344f41827e94113f628fb311efc1abac19bc1e84b08fd578708964a" [[previous_kernel_public_inputs.end.public_call_requests.array]] counter = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6309,7 +6053,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [padded_side_effect_amounts] non_revertible_note_hashes = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/Prover.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/Prover.toml index e85826cf5411..908909bdd8d1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/Prover.toml @@ -1,130 +1,130 @@ -expiration_timestamp_upper_bound = "0x0000000000000000000000000000000000000000000000000000000069ff1b30" +expiration_timestamp_upper_bound = "0x000000000000000000000000000000000000000000000000000000006a0c6907" [previous_kernel.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000003d" sibling_path = [ - "0x1836f64afd38c3a05416bbcee658f4acce2576bbe554a445b33b8936297034e1", - "0x2c05a8ec2045319ea62b81134a53d4e0c1b021fed7877a3a8acc676cf26794f7", - "0x280ae800476659efd90f7ae6a3a2ae3958c1261ca9ae8ba3b2b8320fc9ef662d", - "0x1afa13b72352bab63bfdb391bbadee67783679a9b5ce7fbbcde44387ba5b0eae", - "0x2a99cb07c31aa5ee3a8af2c6db61485892e126a5eac56720fcbbbb002b19d015", - "0x0384c341c7892982bb9f5581098584a00bc572787bf4153d0a52532652ace783", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x0e5e5b81c76efb898b163faa6ee7d6855b64a79e56ac17ff7cf95a60a1125d58", + "0x1ed1f6ae3c2aba56858bdbb3c261d8f7700092a1a1f890d6a0a107e3712446e2", + "0x0ea9a4b61d0915de0514bdc6af213e5f1b338ed1afbef7f1e9fdcb042a751935", + "0x1998bd282e674d397ff88e6b98ed4c795f92263867aa8a0a0b73b1b5643128b5", + "0x084174c19225d48e9b905b49bd461775b745efe40c7f706e5df7e05b4d952d41", + "0x0ae4f3dc533a85154efaa40fbe95415d0544950a47ed66a57418e991f0f134a4", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [previous_kernel.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000011", "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000cad", - "0x0000000000000000000000000000002b2468b5f8f13bd482d710d25b291a02d4", - "0x000000000000000000000000000000000028799bf367c0778599b2b948882163", - "0x000000000000000000000000000000fe9b706fe16bc87d35001fd66356a746bc", - "0x000000000000000000000000000000000001ca485164bddf169d3fe6c29f62e7", - "0x00000000000000000000000000000075e09707371f536b6282e95e95cb185f37", - "0x000000000000000000000000000000000024009d9583c43b01bfe49bd946bf15", - "0x000000000000000000000000000000881a9c651f0a2aae2de99f5557fa22023f", - "0x00000000000000000000000000000000000068e5a5ca58bc35138b3847beeed4", - "0x000000000000000000000000000000f223a8c39d330da2a41cef98b4e091c9b7", - "0x0000000000000000000000000000000000211f7059c97618280acecd75745235", - "0x000000000000000000000000000000044e4a5f8a66993f61ec86dfb978efde9c", - "0x0000000000000000000000000000000000090682734b33c06cd65ba8824167f6", - "0x0000000000000000000000000000007add80ab4d0d02238831551a2844a9f730", - "0x00000000000000000000000000000000000bb45a300640a05ece5fe1ad9b9ee5", - "0x0000000000000000000000000000007da2be4190c8f0f38b37f33d411b427a1b", - "0x000000000000000000000000000000000026098dd8b73e82d335f5e784cbf652", - "0x0000000000000000000000000000007ab032555b3b13f26ed0788c300e54c30a", - "0x00000000000000000000000000000000002a8c9e9e15de7b8b11220f4055bf04", - "0x000000000000000000000000000000f4ce25385f14112552f1512e2f4e99d0e8", - "0x000000000000000000000000000000000015873846a6e7648a844f037a03f737", - "0x00000000000000000000000000000076dbac5187affde31d2adfb3b5064f5a77", - "0x000000000000000000000000000000000020ef23c172d94df80288571d7e3ca3", - "0x000000000000000000000000000000e69eb7802e5d99aa20bc39dee1f6b84b8f", - "0x00000000000000000000000000000000002b2c9af00759a128112ed819b8b1b0", - "0x000000000000000000000000000000f74bd0fb26a604548c9068fef410612fb9", - "0x00000000000000000000000000000000002ca283b09804c9b7d8ca32dc3a2c75", - "0x000000000000000000000000000000c90052c50c0497cddef7e3a71872d14596", - "0x0000000000000000000000000000000000231d65742b933d5aef1ad67db52143", - "0x000000000000000000000000000000b86b4223f0ebb39a8741b6ebba3a313095", - "0x00000000000000000000000000000000001f853f71eaa7368db93d05eefb5256", - "0x000000000000000000000000000000467ff45666661562c57d52de8c4f8f193c", - "0x00000000000000000000000000000000001fdb031a99c29b571b0a66a4140e8e", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000089d2777774ad5c33906740b3656fda53a0", - "0x0000000000000000000000000000000000133bedccd128dc4587817ae09af71b", - "0x000000000000000000000000000000641918e54723a119562889c1ff6239d13d", - "0x00000000000000000000000000000000002c14c2e4f17070e269f9903a383793", - "0x00000000000000000000000000000026c43cff4875a95471fe2c2008292fff78", - "0x00000000000000000000000000000000001224540abfac9c15d64e21d816b9dd", - "0x000000000000000000000000000000beb481b4d5d4eef75c1b133ca9b7efa690", - "0x000000000000000000000000000000000019b490637210bf2280a86ae0a1d7f7", - "0x000000000000000000000000000000e0b4e0795a8b1375e34eab2397b735ef03", - "0x00000000000000000000000000000000000effe6364fc31714fde11efcbe733c", - "0x0000000000000000000000000000005a1907824e164fc0fdd0f0e7c61f4d7398", - "0x00000000000000000000000000000000001cd6403b37da0361f243a3606ac383", - "0x0000000000000000000000000000006a48458b17770a4ad91f725dd01a8c486b", - "0x00000000000000000000000000000000000c395fd0e57de7d52c706e13918651", - "0x000000000000000000000000000000cde7b67f0a01ba051f06746ff7b56f59de", - "0x000000000000000000000000000000000020e0ab3fa354e260e0ac1855e128ca", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000654fe84b50aced8eb7212098af0880ed53", - "0x00000000000000000000000000000000002b2fcb6b0ee568a71f92d2a9bbfad3", - "0x0000000000000000000000000000005d9f4f1e59fac32314c435fb51e2a25ff0", - "0x000000000000000000000000000000000009734092d4e035b968ae8ee337464c", - "0x000000000000000000000000000000a28867ea56c5fbf4aca51fdbbf965e5dae", - "0x00000000000000000000000000000000002feaf04057ed002c072833048ce9e0", - "0x000000000000000000000000000000f9b70bdcd41a1c0bade216b9d5284af115", - "0x00000000000000000000000000000000001ece78d726aaf44e37d9053ebd1534", - "0x000000000000000000000000000000c4e55b000805b017402a109a6b29805245", - "0x00000000000000000000000000000000001d999b7c6ca8df0cca3c57ee4c8be8", - "0x0000000000000000000000000000008820aa820991933af75b5d02d44d0bf685", - "0x0000000000000000000000000000000000039880d1fbfc627ab3421788858e66", - "0x000000000000000000000000000000514dfa671906947f5f640255bfc583eedc", - "0x00000000000000000000000000000000000b0e0c990016a1fdf37d3d6daea7ae", - "0x00000000000000000000000000000040dbbc0f6d52ba0ce246acf816373fbbc1", - "0x0000000000000000000000000000000000035ba8d570a6b7efa251b206e85c82", - "0x0000000000000000000000000000003ebdd6ba8db24c72ad85e8d10fb1346027", - "0x0000000000000000000000000000000000035c795b4ad27e20c934ac5ae517b8", - "0x0000000000000000000000000000005369721308b3dda5dbbab39f83bffcf79a", - "0x0000000000000000000000000000000000241a6ba1547bf3c8eb2ded3454d897", - "0x0000000000000000000000000000009f97bcbba8db2f8bda79a78c0eaefacc5a", - "0x00000000000000000000000000000000002c960a56441f3a00b2f8b48f3b3563", - "0x000000000000000000000000000000ffe2ad855d3522d6b3f8b544681949c713", - "0x00000000000000000000000000000000000002f9753e605a6cbf6dbc604046a6", - "0x0000000000000000000000000000008cfee82227443d00335c9ef376137f6217", - "0x00000000000000000000000000000000001708d8cb04ad71f327107dd3e73cfb", - "0x0000000000000000000000000000007872392082ec4533c6b70f690660ee498f", - "0x0000000000000000000000000000000000122a83a98d1d526cb57355616bb850", - "0x0000000000000000000000000000000a95a3eeae99b98360d61166e89954845a", - "0x0000000000000000000000000000000000202c82d7bd85e9243e7ed0801ebe64", - "0x00000000000000000000000000000027acbc73301fe1b0c21888c2722dd75b7a", - "0x00000000000000000000000000000000002ae7d3ca125bd531826422c7d1acf7", - "0x000000000000000000000000000000d761bb670a9ff734cc38f0d30238a2b28c", - "0x000000000000000000000000000000000005aa3fab8a429258028c4a4287a0e6", - "0x0000000000000000000000000000007a80c32a515f441ce80a5d6cdb53d50866", - "0x000000000000000000000000000000000017f409fea3a1680e6df2a07e9eb3af", - "0x0000000000000000000000000000001a93444f40b0bc09418c7894fe797e2736", - "0x0000000000000000000000000000000000171474b32205fc141e14cfb847a8d3", - "0x000000000000000000000000000000081188cb41c2b23f91bef3a8237fb5fa5d", - "0x00000000000000000000000000000000001ed9b478e77d9f60e9614dfd6014ba", - "0x00000000000000000000000000000042f9a2c111e62ef204c3851affea6af0ef", - "0x0000000000000000000000000000000000108601bd973a835e50fc521d6ec1d9", - "0x000000000000000000000000000000f92be9d44c6688723f37065c3af9521bd6", - "0x000000000000000000000000000000000022ed90948b7d0f29ee1ed4349cab5a", - "0x000000000000000000000000000000bf6e68585d4cb32aeb39412d4a3e6cd968", - "0x00000000000000000000000000000000000c8df79002571c9aef12bb6d7f3bca", - "0x000000000000000000000000000000046577d9d6782e8214d846d3a16aa8ceb7", - "0x0000000000000000000000000000000000249e158a2e56acae4de64894bb2366", - "0x0000000000000000000000000000004b4ecd7a5a335425433b11e098157c3557", - "0x0000000000000000000000000000000000152c2ebca43c64a74ea10b830e9f62", - "0x0000000000000000000000000000006e65e30a946db2c5e16462e3a487d614eb", - "0x0000000000000000000000000000000000294d7279cdf2f3a5a0f47d5d830d40", + "0x0000000000000000000000000000000000000000000000000000000000000c2d", + "0x0000000000000000000000000000009746a298cc238fa9fc88119d64824cecd3", + "0x00000000000000000000000000000000000a622e89485dcc5a40545852372230", + "0x0000000000000000000000000000006809e41276c7672741eaf50c615e7aaf5f", + "0x000000000000000000000000000000000023ef3262cfcbaa1a38aa48f42b80a4", + "0x00000000000000000000000000000029b4a0a73660db847087b0ec0ff8ae7cc0", + "0x00000000000000000000000000000000000bbf015119fab668caabd4aac59b4a", + "0x0000000000000000000000000000003aceeaa5125630611ff88a1638c74b8bf8", + "0x00000000000000000000000000000000002954b4a5df3301bd05b4b33f4b1281", + "0x0000000000000000000000000000007d75fd1698bf937cad957054b4d802deac", + "0x00000000000000000000000000000000001eae87f9894a26c8d8685edcaa11f7", + "0x000000000000000000000000000000bec44c06c527d2c90cd142d22a575b64ad", + "0x00000000000000000000000000000000001ce6fd416b339978042baa3b29160b", + "0x000000000000000000000000000000601d1a36cbf2648b7a35e094aab2f78625", + "0x000000000000000000000000000000000013d19f319a00fc7417c1ad631d3286", + "0x000000000000000000000000000000cebe2c4b8938871fcd990b93f474835e2b", + "0x0000000000000000000000000000000000253ff4164f3a2cdd7a2118f953a472", + "0x000000000000000000000000000000633bff41528ff6e9648cabab45618cd3f8", + "0x00000000000000000000000000000000000a128ad23b420b11945de2c94bc8db", + "0x000000000000000000000000000000c2bdeaad6e1bb38c01807cbeb39eb01474", + "0x00000000000000000000000000000000001a87197d7cbb357c71e7475853a89a", + "0x000000000000000000000000000000d60d42e56b09250d5406827e9f63c5c507", + "0x00000000000000000000000000000000001c429c10ec7865314a9bb768fc77cb", + "0x000000000000000000000000000000874ae527782ea78b526a4069d5a5fffad6", + "0x00000000000000000000000000000000000cf6dd26f50b908aedf25ca7beb983", + "0x0000000000000000000000000000007dfb532ce535603daa17b40d4f20268fa6", + "0x00000000000000000000000000000000001aa8da80801279d91cd4386764d5b7", + "0x00000000000000000000000000000051498e1f98a404cce7b25f7487732af055", + "0x00000000000000000000000000000000002d5ce3870ecba8710b98522a635a24", + "0x0000000000000000000000000000003f1d7da491f2a68c39458177333aa62b8f", + "0x00000000000000000000000000000000001d1af6c81adf6a906f55b20aa99aa7", + "0x0000000000000000000000000000004398c4f4ff3f65cba6337e0a48437289b7", + "0x00000000000000000000000000000000002c90b326149002904e30310eed12dd", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000e6ce520672cc9f4fba3288b2d696d69b60", + "0x0000000000000000000000000000000000240074838ef9434d6524883c8af328", + "0x000000000000000000000000000000cc5409001d9a1b6e499a55194c5cee623b", + "0x0000000000000000000000000000000000272e8cb04c7e831a06e0eff44b1633", + "0x00000000000000000000000000000029faeb6bccfe395b36c4dde26a9281cd51", + "0x0000000000000000000000000000000000079cd2f8b7f8d0ba574f06c074487c", + "0x000000000000000000000000000000467663df6ffc3082510ef243829669f9b2", + "0x0000000000000000000000000000000000154ba884593558e4fa1d35a08901c2", + "0x0000000000000000000000000000003b9367cb2541b5cae36cacba4a0e9565f2", + "0x00000000000000000000000000000000000e9c894d1634c38a1da7a18ff2a4d1", + "0x000000000000000000000000000000a44d578cb20654807e5da0fae4fb462540", + "0x00000000000000000000000000000000001583bdfc0f1f208b72177fd73a4e0e", + "0x0000000000000000000000000000005101bd383908b7e9563f9943ed5b6b9d5d", + "0x00000000000000000000000000000000001894ae59fb37a39ee483d90674a601", + "0x0000000000000000000000000000008eaa98f808cc4df6011d0467d94748bfef", + "0x000000000000000000000000000000000018728540c99b37787e0ec614d5d2c2", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000095b02b4b915ea97d2863c7de9364faf7c1", + "0x000000000000000000000000000000000024bf0c36515c471894eca07c722a6f", + "0x00000000000000000000000000000021b9c8dd0f3068ab110290ce8dde8ca475", + "0x0000000000000000000000000000000000033a64820c52027d57fb58ebb6c381", + "0x000000000000000000000000000000de86fb0a5a50dd02848572163142b8640e", + "0x000000000000000000000000000000000006104618e23a8bd65ba6678675ef30", + "0x0000000000000000000000000000007ecf243d0261b865862c9aa1c0fa854c03", + "0x00000000000000000000000000000000002b49777a506a0876586804d7265c91", + "0x000000000000000000000000000000b03490f3e92e51591fa83188e45ff33c1d", + "0x000000000000000000000000000000000020ca792b4db8d34742259c49a69680", + "0x000000000000000000000000000000bba53bf211eba5cfdc0655d659b54e5154", + "0x000000000000000000000000000000000025743fca2cf229c9e74f0b94b2a60c", + "0x00000000000000000000000000000039fa7ba046a2aa4d1e1b2e7caf7a8468b2", + "0x0000000000000000000000000000000000114565ee8a1a9f6c0765554f828b55", + "0x00000000000000000000000000000039f6f4a9450081d17e80431d7673b4e831", + "0x00000000000000000000000000000000001aeacf01182adb275721404acf94ec", + "0x000000000000000000000000000000b61eb26643a3330cf20693ce2863cd8df9", + "0x000000000000000000000000000000000001287624004468d7fdb961891f7657", + "0x0000000000000000000000000000008e93f0560ff5d7fc733764b1eb22480fef", + "0x0000000000000000000000000000000000122ec6ad7d326d49eb1ec1b6058f11", + "0x00000000000000000000000000000095ed3058c8b0990d267a70546ff583ee0f", + "0x000000000000000000000000000000000014b8a07a5bb9e756fca0fa2b309603", + "0x00000000000000000000000000000011c41e34d997fc68ea4bf83e558d0cc63c", + "0x00000000000000000000000000000000002d5aa2b07b478858f898b181d0ba8b", + "0x0000000000000000000000000000002181f534d66eac7d336c5a0615483614de", + "0x00000000000000000000000000000000001ddfc420c74fb84de1fc06e15cb736", + "0x000000000000000000000000000000221911551b028d679741b7201b0ecbec4c", + "0x00000000000000000000000000000000000dda073b8d6dff1f7820fd10608eac", + "0x000000000000000000000000000000f83c26a030132139738278422f03bf922a", + "0x0000000000000000000000000000000000090293167442d6241ef786787ad54a", + "0x00000000000000000000000000000081472fe64f8676d2c6ba66632be788181a", + "0x00000000000000000000000000000000002686bba5965dbeeace183975458ab6", + "0x000000000000000000000000000000afefc9d6f3b48945adcbfcfd1c96c9d317", + "0x000000000000000000000000000000000004230c01cef5000fc66eed900511c7", + "0x000000000000000000000000000000461b8ddba4875f5c0ee209e969c8cab5b5", + "0x000000000000000000000000000000000004f3c201bbca13be28a391550e3e15", + "0x0000000000000000000000000000008559177c932a1653672c242e7617b96ed7", + "0x0000000000000000000000000000000000171be06bb1a5c5e15ae25ea139e42a", + "0x000000000000000000000000000000ee99ac22da62f96c90ac540968ff4e0df5", + "0x00000000000000000000000000000000002a4b4f6cecfa52aeacb7c88e2ba547", + "0x00000000000000000000000000000075b8d277e2f2d2578c463156acd5f1475d", + "0x000000000000000000000000000000000013ad863e13e6edf10c859862b09f73", + "0x0000000000000000000000000000009f93998170f02cdbb3d8ab65ffc18aa878", + "0x000000000000000000000000000000000000b2bad4d1a7598557b09810779622", + "0x00000000000000000000000000000000d5a82f535d9f53a56ad2c90d651a6f07", + "0x000000000000000000000000000000000000e77d138f0fe1fb3334079b7a17b8", + "0x000000000000000000000000000000375d67be44557b3a7109eb34e19abe23bd", + "0x0000000000000000000000000000000000004374e342cf902621d2f067ee0dde", + "0x000000000000000000000000000000618d7aa8936861e2dfed7786fe06e14cbe", + "0x0000000000000000000000000000000000028eef3b42459371670ed47195575c", + "0x0000000000000000000000000000004185b847b001cc084cb5d9fc3c413c9447", + "0x00000000000000000000000000000000000f0cdae2ffe529626d71ad12c69406", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -145,65 +145,65 @@ sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000034620fc4f5dc2f120b5673912cf04226e9", - "0x000000000000000000000000000000000025a6078d74c0fd7d4dd9e328ad4c94", - "0x00000000000000000000000000000019d834f9bb59a8e973ed867f0477fc8121", - "0x00000000000000000000000000000000001fdeb0dc3db761477a1a9feb00c906", + "0x000000000000000000000000000000ae09bb7f78acfe7c9d9a2b944b789f8363", + "0x0000000000000000000000000000000000011fa902d1394869cea67da68c1718", + "0x000000000000000000000000000000655a4cb5f0e139646b6fe88fd680ee9c5d", + "0x0000000000000000000000000000000000019f3c976b53013b5041616ea60768", "0x00000000000000000000000000000076959cf0870e0ae93bb69edc64b0cacdac", "0x0000000000000000000000000000000000269679f8c1a1ad2aadccaf8ba3100e", "0x000000000000000000000000000000bb028a742987d54246ffc933f8240d70ef", "0x0000000000000000000000000000000000295f79977c6ae0d15cc2b68b7f0837", - "0x00000000000000000000000000000064dd7da7637cf2116a18531edc7fea829a", - "0x0000000000000000000000000000000000162e867465b02e01bbabb15c59b84d", - "0x00000000000000000000000000000071f09c1d3d2c8f9499c838fc966b04ada9", - "0x00000000000000000000000000000000000f4504ac6f302739e9f2c7aa824d12" + "0x000000000000000000000000000000882d0b700868900a984b8a8f100e96bc7c", + "0x00000000000000000000000000000000000abfe4989e01ac99945d20ac56ed24", + "0x000000000000000000000000000000ceb31f078b322681c311c51b7684078b7e", + "0x0000000000000000000000000000000000041b07ce00654c923848301f5fbbd8" ] - hash = "0x297f9ac45dd6c9f333314227aacca93023e72710232e7120328d7e7c209ebc8f" + hash = "0x141adcbeacb22e8db98482647ab8bddc8bafc8d2c45ba62cefe4fabe03067018" [previous_kernel_public_inputs] min_revertible_side_effect_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" -expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff293f" +expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c7716" is_private_only = true -claimed_first_nullifier = "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c" +claimed_first_nullifier = "0x1268b93c2a6a4d3780d6cb2b948cc3884e65336ef39eb7202b4de102b9cb3748" claimed_revertible_counter = "0x0000000000000000000000000000000000000000000000000000000000000005" [previous_kernel_public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" [previous_kernel_public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x1f8e9213a0888fe29bbbc5c39db80f4b9f1575e375c6a0932a13ca2b8e2fced2" + total_fees = "0x00000000000000000000000000000000000000000000000002c5b2a32761f680" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a8282" [previous_kernel_public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x1d706e11585e9d3ecfd4d2ead7a52c2a783a92adfbe3419e8671011fe5016491" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" [previous_kernel_public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x0835e9ab1ea355f270408857dfd5647ca56d588ab4a7d573e67566f6324821d1" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [previous_kernel_public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1f860209ee462b9c30510a063670044f005084362ce71f528205a17ee048fc7d" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000006" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2597" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [previous_kernel_public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -214,7 +214,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [previous_kernel_public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [previous_kernel_public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -226,29 +226,29 @@ l2_gas = "0x00000000000000000000000000000000000000000000000000000000000c795c" [previous_kernel_public_inputs.constants.tx_context.gas_settings.max_fees_per_gas] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" -fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000336bfe2ba6" +fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000001cc0d810418" [previous_kernel_public_inputs.constants.tx_context.gas_settings.max_priority_fees_per_gas] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[previous_kernel_public_inputs.constants.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1303,13 +1303,9 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1318,13 +1314,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1333,13 +1325,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1348,13 +1336,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1363,13 +1347,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1378,13 +1358,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1393,13 +1369,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1408,13 +1380,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1423,13 +1391,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1438,13 +1402,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1453,13 +1413,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1468,13 +1424,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1483,13 +1435,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1498,13 +1446,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1513,13 +1457,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1528,13 +1468,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1543,13 +1479,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1558,13 +1490,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1573,13 +1501,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1588,13 +1512,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1603,13 +1523,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1618,13 +1534,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1633,13 +1545,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1648,13 +1556,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1663,13 +1567,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1678,13 +1578,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1693,13 +1589,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1708,13 +1600,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1723,13 +1611,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1738,13 +1622,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1753,13 +1633,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1768,13 +1644,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1783,13 +1655,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1798,13 +1666,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1813,13 +1677,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1828,13 +1688,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1843,13 +1699,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1858,13 +1710,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1873,13 +1721,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1888,13 +1732,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1903,13 +1743,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1918,13 +1754,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1933,13 +1765,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1948,13 +1776,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1963,13 +1787,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1978,13 +1798,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1993,13 +1809,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2008,13 +1820,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2023,13 +1831,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2038,13 +1842,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2053,13 +1853,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2068,13 +1864,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2083,13 +1875,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2098,13 +1886,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2113,13 +1897,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2128,13 +1908,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2143,13 +1919,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2158,13 +1930,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2173,13 +1941,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2188,13 +1952,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2203,13 +1963,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2218,13 +1974,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2233,13 +1985,9 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2248,31 +1996,27 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" key_type_domain_separator = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request] + pk_m_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" sk_app = "0x0000000000000000000000000000000000000000000000000000000000000000" - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.inner.request.pk_m] - x = "0x0000000000000000000000000000000000000000000000000000000000000000" - y = "0x0000000000000000000000000000000000000000000000000000000000000000" - is_infinite = false - [previous_kernel_public_inputs.validation_requests.scoped_key_validation_requests_and_separators.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.note_hashes] -length = "0x0000000000000000000000000000000000000000000000000000000000000002" +length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.note_hashes.array]] [previous_kernel_public_inputs.end.note_hashes.array.inner] -inner = "0x2295fa9f079bf362a4f01c3b07d9f912f9b484e5ee527ad7a528025a165b9352" -counter = "0x000000000000000000000000000000000000000000000000000000000000000a" +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.note_hashes.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.note_hashes.array]] [previous_kernel_public_inputs.end.note_hashes.array.inner] -inner = "0x27f0738f58cf7f88e6845175913245e6f82475f464578de70619eceaff66402e" -counter = "0x000000000000000000000000000000000000000000000000000000000000000c" +inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.note_hashes.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2781,7 +2525,7 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000003" counter = "0x0000000000000000000000000000000000000000000000000000000000000001" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c" + value = "0x1268b93c2a6a4d3780d6cb2b948cc3884e65336ef39eb7202b4de102b9cb3748" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -2789,10 +2533,10 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000009" +counter = "0x0000000000000000000000000000000000000000000000000000000000000007" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x1567c8c1ff81dda9727361df23c92849c46772567aa0bf3723db03c3751e9d2e" + value = "0x091de02133d9012fa28a3a5e8e913d5587b6baff1f4dc765b3bf31aa60c8924f" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -2800,10 +2544,10 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.nullifiers.array]] [previous_kernel_public_inputs.end.nullifiers.array.inner] -counter = "0x000000000000000000000000000000000000000000000000000000000000000e" +counter = "0x000000000000000000000000000000000000000000000000000000000000000c" [previous_kernel_public_inputs.end.nullifiers.array.inner.inner] - value = "0x1cb96ed0bfe97ed05e23f013062425e5ce6599fb6430b162e69edfc317d5bf82" + value = "0x23b82c3f4fd6976adb96ec88b22c4c5d876bd55be4810759e4e9ed9ec26d3eb0" note_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.nullifiers.array.contract_address] @@ -3588,97 +3332,97 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs] -length = "0x0000000000000000000000000000000000000000000000000000000000000003" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] -counter = "0x000000000000000000000000000000000000000000000000000000000000000b" +counter = "0x000000000000000000000000000000000000000000000000000000000000000d" [previous_kernel_public_inputs.end.private_logs.array.inner.inner] - note_hash_counter = "0x000000000000000000000000000000000000000000000000000000000000000a" + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] fields = [ - "0x2c3715409dc4762ec9a9a602d199ea9932d61edd3fd32c9891fe5ea5a722acde", - "0x10433733db106ed8336b9b799ec2debee9fe2da75f114f567eefde5abf9f74d3", - "0x17440c522b009a136c2207db86790b05464774690523c7fbf949ad381664d0ea", - "0x0a5e8928a4d74ad3256e8a697cfdf84b7baae32abad67b2de7c36ffd67acb665", - "0x0b1200621e156c6d79f463e17e81b96f11d18d716ca5222e7276e07d45845a26", - "0x04b2b64d09e487d10d557106046a94a97f2c40f4316e6667a2c2d9a99db05385", - "0x193da3d713c24b85e1c8f22dd8ef575e88d19c6732f8fd17e370cf64e65b3e04", - "0x08569203e8f3d028234ed200df77bca848c9b4b015ad8797c37669a5e5d1ee0c", - "0x13a9b2003409ad3d4f38caba797acc77092ddd431af25a955a83dc6f5b92cc93", - "0x16fece01bc0b0205bcbaca2904d5674d10573bfef038f94d3e5d526596da2ae9", - "0x0a438177a05071eaeb1862f154b187315de4dc804e275b0f2258baf4700c6d64", - "0x0959244a76e5e861ce5b8833101b91e19d758109d68cc174a6f9eec9c7afa008", - "0x03533d18a1c3ebcf22f820a243be161c9798ea59a506572e32e125c53b7aee7e", - "0x1e2b22ea302597bfcbcfdefcda48b60e35fce9c70f46c6cb90fa6db6e8d4dc6d", - "0x28fab93b8cd28d8d2a993badc3d1a080902feecfab019dc7c00af0ea9f6f403d", - "0x104c4c81c135af94af35a1eeb49b1262e5c53e25ee513731ddeb9f6496eea2ab" + "0x1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a8", + "0x0d0a8ccb98f956b37ac2b18ac43c84cf4e36fc01b0b08126241827575a48200c", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x1ca223fbc16e82cbb9bd22c108021ef47864791c258edbdd8eefa458c62ba8d2", + "0x30405a0693eed61f76d3d7c18614b8d3286aa2ad3039533e2658766de9ab4e15", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", + "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", + "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", + "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", + "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x000000000000000000000000000000000000000000000000000000000000000d" [previous_kernel_public_inputs.end.private_logs.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] -counter = "0x000000000000000000000000000000000000000000000000000000000000000d" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner] - note_hash_counter = "0x000000000000000000000000000000000000000000000000000000000000000c" + note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] fields = [ - "0x1b7f52b7a346b47077bab6835a0810e5d75e977fc3f3fbb0436055bcdaa167ee", - "0x2320e89fb76918e7dc48b13861302dbf78af5ba8d5a20da77d19781ac32b9bc2", - "0x2a99619c0d4d380dbc3d53d03ed35011aa9c296a507fabcf712f43a0e5a10850", - "0x02e5d98e7dfbe7653dafb14afddd7e00f403b5a60816d7ab961823bd3cc4b628", - "0x223b37d6caffe87e91cddafdf65c4f641a609ff13350d02654b0fed1443088ab", - "0x2846b9aa4544f8f8851554f5d0c189c188756d734112e1eedd6840c8aeb0e66f", - "0x21cda3f228d55fb1b37f2b7c7a5d42066007143db17645669521ff58956fa7bf", - "0x1d8d79951d7389e5f9dfa963f93e399aebaa346e9ce3b3a5da1b45e4600a1553", - "0x15eabc8ed921f60621fa4fa35214748a7593f1c06a1e66b76092f789b4960bc5", - "0x16babb28d68725cb64d6d7558d49fb921c480359488fcdfb5292019239a50563", - "0x015e561b49da425d081b87bac01336defa1e29ee50d01b7be798ac28e05b24d6", - "0x04bf1a23807cb0711511a6140caf195df55fcf029842652243034ae2ca740648", - "0x2789cc422a86395739004c513cf6a15024e3adf5f2e238b18e1b4f1211a9383a", - "0x00c4e950cfe804e8a3623fe768c82b7340b0216f93c00351c53e2144364cfb51", - "0x2fd9827b4118b7ef401dff1727785e46fdd31947d2e733f4b39076f43652c18a", - "0x158ca7fba6e7fa7b3eb7c062751182d93b4e36b5c77d2e609e246b810650e59e" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[previous_kernel_public_inputs.end.private_logs.array]] [previous_kernel_public_inputs.end.private_logs.array.inner] -counter = "0x000000000000000000000000000000000000000000000000000000000000000f" +counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner] note_hash_counter = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.inner.inner.log] fields = [ - "0x07d20bd951900d3094f2894e3c76c117114e3150dc3197e9e325e42b4487c6e2", - "0x127157561e774918ba656738fb61ad37f92086431bd4f1e4842ab11928b0f8d2", - "0x2e5cf59c8f2eee7a06d14cdedb8fe58945357cb16f4c792094325909a12924b2", - "0x0e29376c31f2aa7a156c6ce6d1fc9529998251d8500604658f173ff86adffa98", - "0x20761b8be9a186cf6a1730b8a1e99049a07e45c005e66d27b6e0ef15a2833e2f", - "0x1adf679b2441cf3535241924a35164cf8309256721e3f9fcb860bc2acc462b46", - "0x06a613741497b7b7ee978a495bfed7d19bbf76c462d268cee17a3920b1b1abe0", - "0x10ade06e253c1cfd65f24246211fb703c157fd9b563ffaf6ab01b6fba4635155", - "0x2311c6b104555d4d9afc7d66be6b47a41f8aa96eb77f613a75fc952da5975ccf", - "0x08431c3838d7ad6198c1d33ff138953ace3520551bd95b69692609ee11ded216", - "0x1822c33cf8097138c896bb9f7aad7def909a6859d5e640919fd16ebcf153a0db", - "0x11203b31ef49d39fb85a5ea474116c334c156091ab468493a480f13ad1ec1849", - "0x207a4712bacadd2f631fe253cb62932a7acb586dd6dd1b10e0fbe733f61a8f11", - "0x2c862b0eb14b1325a0ca63dda4570f718541d998fb4aba96339b7913b80757c9", - "0x1bf17ee7d3cf2487dcf1eb7a3647b0920c9e68aacc0a33c9a424d4ee6601ded3", - "0x2c70c9b7da7d7df78fcae182d124d7041209070f76d920e5d5c2d7590c385ea1" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.private_logs.array.contract_address] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -5575,18 +5319,18 @@ counter = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.end.contract_class_logs_hashes] -length = "0x0000000000000000000000000000000000000000000000000000000000000000" +length = "0x0000000000000000000000000000000000000000000000000000000000000001" [[previous_kernel_public_inputs.end.contract_class_logs_hashes.array]] [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner] -counter = "0x0000000000000000000000000000000000000000000000000000000000000000" +counter = "0x0000000000000000000000000000000000000000000000000000000000000008" [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.inner.inner] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" - length = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x242b9549d1e2c420a764a5aa2ba58d98b77e35fef8ffa5aa787f9b325f2b5005" + length = "0x0000000000000000000000000000000000000000000000000000000000000068" [previous_kernel_public_inputs.end.contract_class_logs_hashes.array.contract_address] -inner = "0x0000000000000000000000000000000000000000000000000000000000000000" +inner = "0x0000000000000000000000000000000000000000000000000000000000000003" [previous_kernel_public_inputs.end.public_call_requests] length = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6309,4 +6053,4 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [previous_kernel_public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" diff --git a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixture_builder.nr index 9721be95d429..83ec51b19263 100644 --- a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixture_builder.nr @@ -80,7 +80,6 @@ use types::{ }, merkle_tree::membership::MembershipWitness, messaging::l2_to_l1_message::L2ToL1Message, - point::Point, proof::{verification_key::{MegaVerificationKey, VerificationKey}, vk_data::VkData}, public_keys::PublicKeys, side_effect::{Counted, Ordered, Scoped}, @@ -965,11 +964,11 @@ impl FixtureBuilder { pub fn add_request_for_key_validation( &mut self, - pk_m: Point, + pk_m_hash: Field, sk_app: Field, key_type_domain_separator: Field, ) { - let request = KeyValidationRequest { pk_m, sk_app }; + let request = KeyValidationRequest { pk_m_hash, sk_app }; let request_and_separator = KeyValidationRequestAndSeparator { request, key_type_domain_separator }; let scoped_key_validation_request_and_generator = @@ -1258,10 +1257,7 @@ impl FixtureBuilder { fn mock_key_validation_request(self, index: u32) -> KeyValidationRequestAndSeparator { let value_offset = 3030 + self.value_offset + index as Field; - let request = KeyValidationRequest { - pk_m: Point { x: value_offset, y: 1 + value_offset, is_infinite: false }, - sk_app: 2 + value_offset, - }; + let request = KeyValidationRequest { pk_m_hash: value_offset, sk_app: 2 + value_offset }; KeyValidationRequestAndSeparator { request, key_type_domain_separator: 3 + value_offset } } diff --git a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/contracts.nr b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/contracts.nr index de6692fde7f3..41e15d836783 100644 --- a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/contracts.nr +++ b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/contracts.nr @@ -27,17 +27,17 @@ pub global default_contract: ContractData = ContractData { public_bytecode_commitment: 0x256abef672381d551191d5bbecf2dec6ac9cc2a81189f886ac22e29e5c58c49c, private_functions_root: 0x2653ec1bf2be3a13fa9b645cec2557f2b543286fc39168ec42b705835a301bb6, address: AztecAddress { - inner: 0x136422d2d758eb9181240eee44720fa9bc433d3a16bc13163699dc4f47540b0d, + inner: 0x1599beafce80b22c56446667e1627d865bb87ea94b8f1bdc757979f78a596042, }, partial_address: PartialAddress { - inner: 0x1676695fc9a4f3bc8816e4dc82a8856b2ae565d4872691a6e944cc3ce8897e72, + inner: 0x13bf689e2b04d5a75694270c1872e74b0c998c3f7f2f3a0a95648f9f41600808, }, contract_class_id: ContractClassId { inner: 0x2888d24c26f34b139f0f1d30278df8f9007d06da3b63cfe6eeb9a710d51f4f4a, }, public_keys: PublicKeys::default(), salted_initialization_hash: SaltedInitializationHash { - inner: 0x1d83f43991ef3c393247a1796b194020c559aaf129e515adc6eace265f726452, + inner: 0x20b8accdca7010cfebfcc932f55e3acf5136dfe57ba51d386dac8e9d110d9567, }, deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000, @@ -52,17 +52,17 @@ pub global parent_contract: ContractData = ContractData { public_bytecode_commitment: 0x1cfb8e870870be1d102249b47923b63c2d54f33ca81e3028d74a06d8dd5944ca, private_functions_root: 0x03cca4d59a01776df283eb2c8915cb144ad3f40a0b0ba06e9c24c532c59e3c43, address: AztecAddress { - inner: 0x2e90a78904fdb353ddf6eda97aedcfc2b8bf5a942f10f57a1e85373b740e7eca, + inner: 0x1ea25c8d3d0223005170fc2cc0a0e8e3593e322bfcdebc817cc2a02cc95fca9c, }, partial_address: PartialAddress { - inner: 0x2cfac19f0c29a86d17b4c60b205376bbd4c8e45d1dfd02dcd33820638d1d6d1e, + inner: 0x09dba9fffbfd68d6828334a178433b7bfae9d07c3c6f424ee4afa0304655c5d3, }, contract_class_id: ContractClassId { inner: 0x2998b9cf4a582f068a01b43c141dbcc5fd8f5cd17a797484b5a5db2386cf7574, }, public_keys: PublicKeys::default(), salted_initialization_hash: SaltedInitializationHash { - inner: 0x2bfefc4cfdd56352f0d6cf62ae70abe702d7d948f5ccff4eeb51f9aefaece295, + inner: 0x1384ae0b0212cbeb6cd53d6c8d9dfc6334318553dd6f33fdaa97b5dae4ab9dbb, }, deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000, @@ -77,17 +77,17 @@ pub global updated_contract: ContractData = ContractData { public_bytecode_commitment: 0x225d884cfeaddc5292dadbf921e7699632336876c65a33459d3b2ad9b5ec0da3, private_functions_root: 0x2b26caef823c6be4c41ef1980dace9b61825f8e6a16792c765a2cd8cb2121e75, address: AztecAddress { - inner: 0x1a56e3cef400d47addbbf65a95ea505b8f628a2d65a096d0e4d46a8cc9bd72c3, + inner: 0x144f3aaae816b99f40fbea5b9f80fe4683bf68a14876e7379c4171c871a1ef09, }, partial_address: PartialAddress { - inner: 0x04a4ed87aa4cff86962b974fe3f79d76e4bf3f034d4e2bde2bb50765927fad40, + inner: 0x12b89345d5d63f8bf9f73f5890d5caa0c5f023c61d313b1abeea40e300a83755, }, contract_class_id: ContractClassId { inner: 0x07a63b1343bb8515d1115202c71cdc95f9bcda9c2237bdfc25435b89ffa06b46, }, public_keys: PublicKeys::default(), salted_initialization_hash: SaltedInitializationHash { - inner: 0x0bbf968b28a0a1fa3a90ceb4c7104d63e7a8dc845a9c885781d74018d1579e59, + inner: 0x1f121db378dbceaf871eed1b9f0b20efcdca988e76f8abeaa11b2cdc80474189, }, deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml index f9937c534a5b..98750fce6576 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml @@ -484,7 +484,7 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x22e5411ababf49ccdacb44202da8507dcac351bce3fab350c18dd0655abcf9c0" + block_headers_hash = "0x07d6c206790cf70b15b8243736ee089cda60cf2c3e85d131fa3ec16d1f5bdd36" in_hash = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" out_hash = "0x0018febbd74d861e38064a4ff9d3b5ed7a39b398576ef75e104848700819a700" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -493,8 +493,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -513,7 +513,7 @@ proof = [ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x0edef98680cbea2855c4f0f152a0ecd69358e68b10da7b7e301f35ce709c13fa" + root = "0x27b365d73aa1b8ac1eb39c75262e2b87a238d041cc98fcb795f4c597c620ce64" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -576,10 +576,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" ] state = [ - "0x08cdf544ec44d694936ed6a5aa580afb2a3b1a4b087ba80870d4d01c79cb5772", - "0x192972b72a1776fa9d30c1202807fca4f9272b156c9e1eafa5f93e94a13c439b", - "0x23ace986d5ee172559ce2153d8a166075599a4403288cbe1a150bda49415fae6", - "0x0f3ccb179877769f2d268206c1b45ab9af36d5e7e005de27ede90c1a29450039" + "0x13ec9d9b37f0599c5765a81513125e07305454198fecae73a69e7d41dfb27215", + "0x24fe963f8f4139d84f904228cfe1e10256e9106331e614b72ed86be8903e4259", + "0x114cba9fee3fa49ffd5f440aa162c6ce6e8410138a592e587337646bb8b04ca7", + "0x10325219e420881603ba4ea16613cf66fa1c43ff98bceb97acaaab599e3326b5" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -587,134 +587,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" sibling_path = [ - "0x23d78e0b464510ddf15e00aafb3d9a34c4300cb431a0343efa8acc7ac7174e1f", - "0x24ebbcfd36a0a9ea7467ed78450dd4914d8c54a1434a5dfd9757f4f88c51b867", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x1276688c1c8f1024c963d35957328b73153c55580532254f0676c26e2ad55993", + "0x177b04fc814d3ca71e4c26c7a32c0c913574feaf5567348e99c5cc65f0f9ddfe", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000015", "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x000000000000000000000000000000e4ecee2341c2499228c4d2c83a9520cae8", - "0x000000000000000000000000000000000028d32ba99192667c15e398069c3240", - "0x0000000000000000000000000000006fb00058cacfb1b276d32fa36447360c8c", - "0x000000000000000000000000000000000001a8699458060a98552c6907a085e7", - "0x00000000000000000000000000000035e6b6b068c96f12086377d88703f3e07e", - "0x000000000000000000000000000000000015477ce75a652da3c7317382f97441", - "0x0000000000000000000000000000006b648f1adda6e61b44e9867b5f8e3b4f79", - "0x0000000000000000000000000000000000284a9d333412f98641932adc241a55", - "0x000000000000000000000000000000e4a1e119917387b63453afe2152f923081", - "0x000000000000000000000000000000000016f3a12e54e2b76aa8a0c2350c5b03", - "0x000000000000000000000000000000e6a6952f1b80d571443fb3a9782f7ba03a", - "0x0000000000000000000000000000000000115314dec35ce22a37e5e08838dd90", - "0x000000000000000000000000000000608fa42518b2ed1d41d26a56c4e7fd1cd0", - "0x00000000000000000000000000000000000e864b9635bc3ab6a2e8a63311af9a", - "0x000000000000000000000000000000089e6633599c12307e5d2315b0559fa3ff", - "0x0000000000000000000000000000000000188c6476388f9b0875dea7de1bc491", - "0x000000000000000000000000000000abca067961d5609684ecd2136ba688b8d5", - "0x000000000000000000000000000000000003650b02580ae03fa6c488d150619a", - "0x000000000000000000000000000000a7a66d3882208ec15d795f73ff135448cb", - "0x00000000000000000000000000000000000eda3b802a8c57b6007532ac4d3c73", - "0x0000000000000000000000000000001a0f5ebabaa07f627ed7025287560ef87d", - "0x0000000000000000000000000000000000081f627ebc9b282e50d5101f2fdc0b", - "0x000000000000000000000000000000af44c7ddc6ed98861741ef7d79b45171ab", - "0x0000000000000000000000000000000000189091a7b840d8a84827cc8270560e", - "0x000000000000000000000000000000c10049e49d4cd16c33bbc1e8eb3238ea26", - "0x00000000000000000000000000000000002578443465dd684c74b9c635f2c33e", - "0x000000000000000000000000000000770092209b5122c863dacecd7406bb2d48", - "0x00000000000000000000000000000000000f3fee6266059403a65308d4c5d7eb", - "0x000000000000000000000000000000533f8b9f4c4a0d43ef35dab7d27c1ea8da", - "0x00000000000000000000000000000000001adf8c6f547a4381844323d92940ac", - "0x0000000000000000000000000000003c366da2e86813e08788a4a283cff05948", - "0x000000000000000000000000000000000009d343f03cc09faee9ca1d918d51aa", - "0x0000000000000000000000000000004eff2a8415f5ebcbbb774b024c7cca829a", - "0x00000000000000000000000000000000001bdd73863935251e91860c886a55b1", - "0x0000000000000000000000000000003df888a4b79151f5f34eed566c6d247e55", - "0x00000000000000000000000000000000002d996ddc7dcf55af0fecfbe916441d", - "0x00000000000000000000000000000035a1c8de7d282962a240a6704a18d9aa9d", - "0x000000000000000000000000000000000022c5a65fc79d84f800459e76bd6ddc", - "0x000000000000000000000000000000f694c211bf5e8247c2ed4c9772d66b5320", - "0x00000000000000000000000000000000002254e08116deb9d889a0143317b65f", - "0x00000000000000000000000000000048358b74356aff020c99bcfffc97f02b91", - "0x00000000000000000000000000000000001d9bb0f7098bb21c970677fb97a3de", - "0x0000000000000000000000000000003fd980235a24687982d5bc1e10572d41bc", - "0x00000000000000000000000000000000002ad88fe0270c96dbf63278dd32b0eb", - "0x0000000000000000000000000000002aa721427068275b015588487a6dd9da77", - "0x000000000000000000000000000000000010ed5178cf97b67466833bb3e294fc", - "0x000000000000000000000000000000fc9b469311b99d851b65fb621b17172be3", - "0x0000000000000000000000000000000000058b714d3d803f8cea308e60246a25", - "0x000000000000000000000000000000ab189fd5ba15e2bc3843c70e4b6ccc5874", - "0x00000000000000000000000000000000001f0042de0aeed97be6e8b8e93e5484", - "0x000000000000000000000000000000990cfdb6f4a3699f168f757c1a663e2792", - "0x000000000000000000000000000000000029d9940fe4dfdae5c2cc1ebfdba6d8", - "0x00000000000000000000000000000006147c05564229442b8f35ada3f0f58754", - "0x00000000000000000000000000000000001ea24fc9d78495240f0fc072c3d6e9", - "0x0000000000000000000000000000008333bf707667d3ac3960826883a0d26107", - "0x00000000000000000000000000000000000e7f2da7e4a8b4ee0bca717b98686d", - "0x000000000000000000000000000000f80529b50987783f12df2e1ee9f91fdccc", - "0x00000000000000000000000000000000002fbee99a2fa069d2da029ad5a86c40", - "0x000000000000000000000000000000ea3704a764aeda63475f07b984b2297f60", - "0x00000000000000000000000000000000002cf75af466282247648425172dd45b", - "0x00000000000000000000000000000068754ac413cc462e8a87396033bafe80fc", - "0x0000000000000000000000000000000000138b5a95236c3755c228128437cb81", - "0x0000000000000000000000000000007c551a7f9f585f152f2899cd5c73cdf658", - "0x00000000000000000000000000000000001601277332a9e90e2af9bb57340356", - "0x0000000000000000000000000000007543dc89bcca355d7e34573dff53f933e2", - "0x0000000000000000000000000000000000170cb4ff2fe573d8a4f20d7e7b64ef", - "0x000000000000000000000000000000a32270e25bda22ff0b953eb2ccdd937551", - "0x00000000000000000000000000000000000b5603a198907b41d522094f42cad2", - "0x000000000000000000000000000000d0ff37f21975e21ddcaafdd3dd783ad7d6", - "0x00000000000000000000000000000000002d0a2f4c7e56c0c56b889f47c622c6", - "0x0000000000000000000000000000009472ecb153285dccdc60cf91dde517845e", - "0x000000000000000000000000000000000015e573aca14b7c5fd370bcfc540b27", - "0x000000000000000000000000000000c303cfdc251b35fff418176773aa2776e4", - "0x000000000000000000000000000000000026e160cb0be92aa253d24a3ef4762e", - "0x000000000000000000000000000000caa9c67bcb76b860aeb9f0f4b012671fbb", - "0x00000000000000000000000000000000001386aeb173c2f13bc20ed2b78147c1", - "0x0000000000000000000000000000002b385a5dfd8c9a7ffc125cfd6fa7f8fd45", - "0x00000000000000000000000000000000001597a3dd423660dbd9daa02d14e187", - "0x000000000000000000000000000000d563bdfaa101f554e342f7fe227dc29f16", - "0x0000000000000000000000000000000000090a2f765e614082aa702ded80dffe", - "0x0000000000000000000000000000002c13af1d7029f509b59a9d7902023a0783", - "0x000000000000000000000000000000000015f5fbf1568f18d113c76d8125b4c9", - "0x000000000000000000000000000000832350cc0d3066c6a9d8d4e59c38966d94", - "0x00000000000000000000000000000000002c0a8c5e6b3ad7b65677d02e3af4ca", - "0x0000000000000000000000000000004581bf4848fb500439bee9e9db80d8dce2", - "0x00000000000000000000000000000000001a7ae19bf5ba02728391e18925e760", - "0x000000000000000000000000000000d9b2acde6149cf8e6f308444a49c333a30", - "0x0000000000000000000000000000000000192e53bff5334c0fd6d7f110fc3552", - "0x00000000000000000000000000000095b5d8b7b4a63b05df652b0d10ef146d26", - "0x0000000000000000000000000000000000099e3bd5a0a00ab7fe18040105b9b3", - "0x0000000000000000000000000000002129af3a637f5a622a32440f860d1e2a7f", - "0x00000000000000000000000000000000000015b8d2515d76e2ccec99dcd19459", - "0x000000000000000000000000000000222b888108dc25d1aa450e0b4bc212c37e", - "0x00000000000000000000000000000000001b917517920bad3d8bc01c9595092a", - "0x000000000000000000000000000000482141c7ebe42000a1d58ccb74381f6d19", - "0x0000000000000000000000000000000000305e8992b148eedb22e6e992077a84", - "0x0000000000000000000000000000007c86847618681dc29d8a9363ab7c40e1c3", - "0x000000000000000000000000000000000016465a5ccbb550cd2c63bd58116fe4", - "0x000000000000000000000000000000439973ac12d7ca796d6fe98ca40e6ca6b7", - "0x00000000000000000000000000000000002e24d420fbf9508ed31de692db477b", - "0x00000000000000000000000000000028edd1a7e46c840d9c943fdf45521c64ce", - "0x0000000000000000000000000000000000043d063b130adfb37342af45d0155a", - "0x0000000000000000000000000000009330952ae74c573d1686d9cb4a00733854", - "0x0000000000000000000000000000000000261522c4089330646aff9673619494", - "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000ea6e74a6fa43b4810edc310e2d2b66dab4", + "0x000000000000000000000000000000000015c12f6f69bff32654e403b8e9a2b8", + "0x00000000000000000000000000000010f1d77dfb1e9178bab79124490d92915a", + "0x00000000000000000000000000000000000a9b89b1676b31989664a34260314d", + "0x000000000000000000000000000000a2d8941fda778834590a006f995557ff4c", + "0x00000000000000000000000000000000002dadd9e8063bfbee06194004949394", + "0x0000000000000000000000000000002036fe67ff22643d06461e1c8edcbc2dc9", + "0x000000000000000000000000000000000021c85b69f65f83d6cf1854a9563213", + "0x000000000000000000000000000000b19756d6156d0300b3ecb9be77605be1a8", + "0x0000000000000000000000000000000000014a4064a3b551e9b75fa13659629b", + "0x0000000000000000000000000000003491c66acf5693a16ec1f7241609c18f45", + "0x000000000000000000000000000000000023b0ed5030538c865d72cb8908352a", + "0x000000000000000000000000000000efedf593c1cfc28146ff68d9dcb1070ca7", + "0x00000000000000000000000000000000002a8174a5153b946abe57e2ed06d454", + "0x0000000000000000000000000000009c3212d084550b683558797af1477ceb8f", + "0x00000000000000000000000000000000002c32c65b02e59d9aae5b8a57ec27e4", + "0x0000000000000000000000000000007b88e113308893f906561837b9edc3baa5", + "0x00000000000000000000000000000000001a45b642b5e649f033eca82a810b8b", + "0x00000000000000000000000000000068591e612a0127878f63e7923f17854d2a", + "0x00000000000000000000000000000000001d50690ef0dd775e7f4fc0f17281bf", + "0x000000000000000000000000000000eece658386d09783fcc2d61a622eb6b121", + "0x00000000000000000000000000000000001d5b3af11c73d93414e18accc31071", + "0x0000000000000000000000000000007b1ee7fea7dfabee7dad1a5e3e816c2a2e", + "0x00000000000000000000000000000000000a5f02160bfa014a46b329f3618dc8", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000043bda12a99877a984942e29d821cd37870", + "0x000000000000000000000000000000000020b1906b429f07ca51070221399472", + "0x000000000000000000000000000000c185af02499653794e9d4c7fa1a6c5751c", + "0x00000000000000000000000000000000002927f8b050e657021afb2f572e0f84", + "0x000000000000000000000000000000ceda688bdd2aea1e5253ea0d86743abebd", + "0x00000000000000000000000000000000000072f93e3607e4ac8c369fb92fe33a", + "0x000000000000000000000000000000eaff91f9cc05f03c6d8546358d580ef17a", + "0x0000000000000000000000000000000000225d5df5771e53084f6e364ad8e3da", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000002218617f23e467fecd2e3c938179a2b578", + "0x00000000000000000000000000000000002497b7dd7eec4e260f8ca521f1109e", + "0x000000000000000000000000000000914e208f9621734ce56985cdd29d01a78b", + "0x00000000000000000000000000000000001092e497a21b124b279b86e029a993", + "0x0000000000000000000000000000002ef4ddf310bee1f74f655cbb0ceb9315d0", + "0x0000000000000000000000000000000000270b81bec5e6b0f455065b02f68a0f", + "0x000000000000000000000000000000ef21188ec62b59040e4f1b89dfa23be48e", + "0x000000000000000000000000000000000009ced6e0108e8e67b299d9e3bad9a9", + "0x000000000000000000000000000000f61d5b8425740d0df669b875491e615449", + "0x0000000000000000000000000000000000064a6a9bbcefc6ad4b2d4e1e03985f", + "0x000000000000000000000000000000d004ad7846785bcb0db2672f6e5292f7c2", + "0x00000000000000000000000000000000002114c1fc4a3c39cbc96baf3ba693af", + "0x0000000000000000000000000000005cc5465cd9391ce8e7799e91bf9aac8039", + "0x00000000000000000000000000000000001c59b40d18b5d06d88617f2ed5c568", + "0x0000000000000000000000000000008134581657d125ca542477d684313ad999", + "0x0000000000000000000000000000000000259435f2950ead4bad62f0635944d8", + "0x0000000000000000000000000000008e3beb4333afb6a1db12c0889130b8f7f7", + "0x00000000000000000000000000000000002d022d695e566dd0ddfd15b59ad6f6", + "0x00000000000000000000000000000019ac6e38521a0144c3d1abe706030d643e", + "0x00000000000000000000000000000000000961e2643f9317a4d6144abb77cae4", + "0x000000000000000000000000000000827e5482f658cec2661f8cf88c4558800d", + "0x00000000000000000000000000000000002bcc1992b1410cdd05f32c2148a800", + "0x000000000000000000000000000000049c1604c9e61fe1eb1a4e6c0044a88607", + "0x00000000000000000000000000000000001a50aafae1419fae00770a64d75a52", + "0x0000000000000000000000000000003a404091304c1a4935267fb66a90af706f", + "0x0000000000000000000000000000000000175f69e34efe02635c0450ff14d814", + "0x00000000000000000000000000000056a7488e33d23f5a7e31e8c24c4d32feb9", + "0x0000000000000000000000000000000000152b125831f20c0046084a92a3a01d", + "0x0000000000000000000000000000001bd75185387ebcf04a2d1541b418c93962", + "0x000000000000000000000000000000000007d44e382095a4ddb6c84d676f975b", + "0x000000000000000000000000000000e37e00ccdd16f0cfb118365311a964e475", + "0x00000000000000000000000000000000001c3ba17a670cdeca7019e1d2c17e93", + "0x000000000000000000000000000000ef2f893fc357863e53675b8dfdace77275", + "0x000000000000000000000000000000000013a4df076b371985ff93656b8e4483", + "0x0000000000000000000000000000007adddc444f0c602af7efaa9c977e9ab80f", + "0x0000000000000000000000000000000000138e76ae51938924778a06f02de461", + "0x000000000000000000000000000000f63ec082d951768fe05e6d3bc9d50bc72d", + "0x00000000000000000000000000000000002ac3a11527579ccbe6c1966976f6ad", + "0x00000000000000000000000000000066d0ea63d8dd4511ec55e666f7bf6d6c3d", + "0x00000000000000000000000000000000001fe7a9cb68d795240eaec0b6efe451", + "0x0000000000000000000000000000005309c6e2db27d4be273a758a178e1af682", + "0x00000000000000000000000000000000000962316a08cadc097d50603d1606c4", + "0x000000000000000000000000000000ab5c17e93d31a1c79c62d8597447920f36", + "0x000000000000000000000000000000000019ede1992f131cdd105f8afcde56a5", + "0x000000000000000000000000000000b03aa7f0563671be6a98678d8dac3ed963", + "0x00000000000000000000000000000000002c9acda51c7b3e6e04e82aaf0bbe35", + "0x000000000000000000000000000000b7eceb60b962a8108199e7506d967bf042", + "0x00000000000000000000000000000000000ab8ec69e3b26d13207351e2be7d7d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000019988ebb1316d375d71e97a8545a3c71a1", - "0x0000000000000000000000000000000000223ffc44e0e98747d5be232098b76c", - "0x00000000000000000000000000000039f06fcc03eb0ffcc95a6e4ffb19181791", - "0x00000000000000000000000000000000000d49dfcd43c5d2f7fd6edd6a818e5c" + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x000000000000000000000000000000ab626198b0ffe754ee7a00134867d6524b", + "0x0000000000000000000000000000000000016d89d36083b0f55dba4523be0aff", + "0x00000000000000000000000000000081d7c7a641b523d79569cb352fd7652081", + "0x000000000000000000000000000000000023fdf5ec3df2b078ebe39feac15b55" ] - hash = "0x05ce98498d8e3590661695e0243b58df2e19f9b0e7229b9ef88ee6fb20c40442" + hash = "0x1cd81d6249bfece0299cdfaff8344081684997c787276db4fb5cdb25a0d6822d" [[inputs.previous_rollups]] proof = [ @@ -1202,7 +1202,7 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x026f28b344918f22933d91a736c98c3d8f45258367baa5703621c045f634f02b" + block_headers_hash = "0x1953e1bdf126cbbbf44f73a3952cfe3ac37b665859467480ae6846d2539b6f7b" in_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" out_hash = "0x00abb50b8989a7f19fd4526d43e15a1ab5d2a43af413cc8ca91e82a3c8828625" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1211,8 +1211,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -1227,11 +1227,11 @@ proof = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x0edef98680cbea2855c4f0f152a0ecd69358e68b10da7b7e301f35ce709c13fa" + root = "0x27b365d73aa1b8ac1eb39c75262e2b87a238d041cc98fcb795f4c597c620ce64" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x0d5581ddb590b1f2e972ae3399ac1639129b04a4b4282a219285a5dba6553cdf" + root = "0x10abfc1e58ab5ed471d9c7fedcf2b291ad533ac85d136968ea047db10d73d599" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -1276,10 +1276,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" ] state = [ - "0x08cdf544ec44d694936ed6a5aa580afb2a3b1a4b087ba80870d4d01c79cb5772", - "0x192972b72a1776fa9d30c1202807fca4f9272b156c9e1eafa5f93e94a13c439b", - "0x23ace986d5ee172559ce2153d8a166075599a4403288cbe1a150bda49415fae6", - "0x0f3ccb179877769f2d268206c1b45ab9af36d5e7e005de27ede90c1a29450039" + "0x13ec9d9b37f0599c5765a81513125e07305454198fecae73a69e7d41dfb27215", + "0x24fe963f8f4139d84f904228cfe1e10256e9106331e614b72ed86be8903e4259", + "0x114cba9fee3fa49ffd5f440aa162c6ce6e8410138a592e587337646bb8b04ca7", + "0x10325219e420881603ba4ea16613cf66fa1c43ff98bceb97acaaab599e3326b5" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -1294,10 +1294,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" ] state = [ - "0x186114d0d063d6e6ddee6515e508484b364b20eeca9ca340f8566e398b71b198", - "0x114fbdb8bc7b843c83778ba1c8780534af4f59451f33adcb6a437c245d4bed64", - "0x2808ea7e05edca8293485bb1dfde34257ab644659366d516601dd5beba26639c", - "0x0ba75ded1f1125dbe2d4e7a5b18a7b2e2c238a70c72ed529163eb34be09a36d2" + "0x06b7a09d376432aa2b0a7411a06aaad2d07f77fe65a5401eea06ab9d30b77ceb", + "0x06b7ab96aca0b2e842d7692f25a662728d09309529ca41b0e61eb20e19a7f38a", + "0x0b211453e69b20a81d2247120eae55ca5f80139276d8d9a7bb790996624e335d", + "0x1af797fb95b1713b94475070546774ffc67e4d61c261abb49048a7834cc7e665" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1305,131 +1305,131 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000e" sibling_path = [ - "0x0d000c0ce80da2c814b0f1508b74728e2eb05f4fdfb0396e1e6939106be41f29", - "0x02e6f22eee7e3e5aa6291ccac5ee76b8a2f1e338a74bf57530740f36d19c9b2b", - "0x14c22836312c6ac50d8aae1289b45c06410355406e5af5ecf43bf59432dcdd17", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x2781192850bee4946aa72958703bc69fec3ab04ecffc00c34abcb81befd3c88f", + "0x2a4b8973bfb7d252bd970f41d74702d12b8bc7f63b15188bc79d78bda4a9413d", + "0x07a849e820943807a1c5531526528e89be50a06725dee96179285d8108e565c9", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000002fb0b1381b4486fbd49fa9fdb4d74afed8", - "0x00000000000000000000000000000000001b03700ad9942abf5144e1bd7393d2", - "0x0000000000000000000000000000007f3e184921857992c24753b966424214c6", - "0x0000000000000000000000000000000000283119b961cda64e529c68e135fa17", - "0x000000000000000000000000000000c251b282c34c8a6d712e6c12903362497c", - "0x00000000000000000000000000000000002c89e5571ae0b09fa870346cbd5cee", - "0x0000000000000000000000000000008eb0fcf7af2d945fd3266cd7b0b449e8d3", - "0x000000000000000000000000000000000021d78ef089716338837787911d13b0", - "0x0000000000000000000000000000007f691d58aee9d65248c5eecbbaddc13a98", - "0x0000000000000000000000000000000000098627646fa61b9928d6dc11c96e13", - "0x0000000000000000000000000000002c58cf39b7f2b04d82c4338ef8958a7473", - "0x00000000000000000000000000000000001aef806cf0aba5af2f1f8978cd56d8", - "0x00000000000000000000000000000082bb268c0e10a8bf5c0ef242f9906e4892", - "0x00000000000000000000000000000000000c90d93936cc598061c4d29f0b25a4", - "0x0000000000000000000000000000004d114fbbc4055f5761b7f8840f0da32908", - "0x00000000000000000000000000000000002957bebd162ed2169df723dde18c97", - "0x000000000000000000000000000000e9eea3e81c31b1aa9400fa13197b7393fb", - "0x0000000000000000000000000000000000218c3140bfb6edddbcb2d4cbc126bb", - "0x000000000000000000000000000000c0ff9e22fab79999e9ed7d78e138d2987d", - "0x000000000000000000000000000000000028bcfd13128cabc46955265a1e05dd", - "0x00000000000000000000000000000023a74d6f1a3fabe39ff7f0f6150be9ec00", - "0x00000000000000000000000000000000002e2507d7bf2a01aec6fd026fa0a409", - "0x0000000000000000000000000000000a0acda35b6f3d1a438d5fcf5783a50797", - "0x000000000000000000000000000000000021e1c9a570c3d0417707daa478fa20", - "0x000000000000000000000000000000c10049e49d4cd16c33bbc1e8eb3238ea26", - "0x00000000000000000000000000000000002578443465dd684c74b9c635f2c33e", - "0x000000000000000000000000000000770092209b5122c863dacecd7406bb2d48", - "0x00000000000000000000000000000000000f3fee6266059403a65308d4c5d7eb", - "0x00000000000000000000000000000093ed6cb8d6a2d5363b2c995ec9f930a714", - "0x0000000000000000000000000000000000276fea1e0f63f52d1e7564b9a81494", - "0x0000000000000000000000000000000389f3a2b3a8f8cc2f5f5d1cd72a8d196d", - "0x000000000000000000000000000000000013bcbd1229609722bcecd1798d4a4b", - "0x000000000000000000000000000000fe9ce7b1fd6536624c2fa96787f74d7bb0", - "0x00000000000000000000000000000000000c3c6d07104e24ea5acc68c3423208", - "0x000000000000000000000000000000b8da6eb9140a2d5588a8710a2d6d6318a2", - "0x00000000000000000000000000000000001b1f1fa538a3b66f72c15c53cca715", - "0x0000000000000000000000000000004730a9529ef0eb509d55e1379829c016c4", - "0x00000000000000000000000000000000001ce37c2c228f312b7c1e64bcca1dfd", - "0x000000000000000000000000000000a378c68d165ba8929cf5e20f479ed90e1d", - "0x000000000000000000000000000000000023024fd5c636e9ead7d63e4eac96d9", - "0x00000000000000000000000000000082a25f4e5374c7548fa507be32b596f423", - "0x000000000000000000000000000000000018ca6faa15b5b52e1ae8b15cb8b83f", - "0x000000000000000000000000000000091c75d9a46e8a66235f387c882bb14df2", - "0x000000000000000000000000000000000018f3db0dcead736435b7467239e00b", - "0x000000000000000000000000000000b87fb21960e7763dfd42205c459fdc41fa", - "0x00000000000000000000000000000000000267a4a344f85d00b6b0040d1c2150", - "0x0000000000000000000000000000000bd1017af78a6260c7d0f6eccb3a8d3890", - "0x000000000000000000000000000000000002641016e4e2bf5752b1e9472dde95", - "0x0000000000000000000000000000004697a8a794f990510a018a5b2c50f35b76", - "0x00000000000000000000000000000000000de0ab75e8b485639fe023a368024c", - "0x000000000000000000000000000000be33c35449966234d9bdf48ba396a57c4f", - "0x00000000000000000000000000000000000df556c20deb7a8ab0ee850f970c51", - "0x0000000000000000000000000000007e5366f459b2b033ca3664ff8f4a641d18", - "0x0000000000000000000000000000000000192f68a938c5a9ea9a5cc9f2181675", - "0x0000000000000000000000000000003a6f876985d4d54592c5b5c16ab8b16750", - "0x00000000000000000000000000000000002da0d2ee45300969c52f5ae43c7402", - "0x000000000000000000000000000000c0f7aa427b2ea5fe4f0e45dcb2eec42f83", - "0x000000000000000000000000000000000009739dbd1003e81acae3f329654c42", - "0x0000000000000000000000000000009191ff080e493eb7d3eb33ec9823178f09", - "0x00000000000000000000000000000000002c951c03d7dadfa04fdc92a298ea8f", - "0x000000000000000000000000000000245cbb1c8e9f243b94d55edca314c340d7", - "0x00000000000000000000000000000000000de0f174fce3433422830fdb869c6e", - "0x0000000000000000000000000000005348fbfc2bff27c23db0f849baac752835", - "0x00000000000000000000000000000000000fa0fe8cbbf06318ad99adc23d2e0c", - "0x000000000000000000000000000000b37df3b0cfe3793620f5315db38c0dcd29", - "0x0000000000000000000000000000000000011ef80549887e786cea0d08c13608", - "0x000000000000000000000000000000e085aac6fe78f6a3574c61f888eb0ace80", - "0x000000000000000000000000000000000015ea74a6e14e77ffea0611ecc18015", - "0x000000000000000000000000000000635cc32ee452dd83211c337fd3423850ff", - "0x000000000000000000000000000000000030399e012ea636c746005ba35a4536", - "0x000000000000000000000000000000c6c09fdb5d8cbc0266b956e5539ad94b8f", - "0x00000000000000000000000000000000000728658d282bb922ecff1634645aff", - "0x0000000000000000000000000000008fc753267c4b4393209eabc80d1c4fcac8", - "0x00000000000000000000000000000000001add24bab07f36d9d6e11beabf5bb8", - "0x0000000000000000000000000000001a38a11d04a6dc1d788b1cc4da1d171341", - "0x000000000000000000000000000000000004eadc7d1bcf2320272a6d96972ae7", - "0x0000000000000000000000000000004749834da45ee7f8ffc427cf41f3b715e3", - "0x000000000000000000000000000000000005e4285178878dbecdfd0c6eba227a", - "0x000000000000000000000000000000182e1a0661bfd39a43bcbbb18e3691b327", - "0x0000000000000000000000000000000000262b3f8b46fac1d385cc0f3bc24ee0", - "0x000000000000000000000000000000434d5dbebbf6fbc03531f25d963f155b9a", - "0x0000000000000000000000000000000000082a0f4d55eb1206313a4955f41f03", - "0x000000000000000000000000000000034001bbce1dcce343e80ff7a821fc3444", - "0x000000000000000000000000000000000013176cdf2f7fb58e75a4954f0bfd28", - "0x000000000000000000000000000000acb6987d4aafb95942bc208f40df86f426", - "0x00000000000000000000000000000000000e52fac6880e3f51e7641ab893e82a", - "0x0000000000000000000000000000002377224018803fe8e8922c797432d2d985", - "0x00000000000000000000000000000000000b3d671707c2cdc4842e4e8ffefc09", - "0x00000000000000000000000000000095b5d8b7b4a63b05df652b0d10ef146d26", - "0x0000000000000000000000000000000000099e3bd5a0a00ab7fe18040105b9b3", - "0x0000000000000000000000000000002129af3a637f5a622a32440f860d1e2a7f", - "0x00000000000000000000000000000000000015b8d2515d76e2ccec99dcd19459", - "0x000000000000000000000000000000222b888108dc25d1aa450e0b4bc212c37e", - "0x00000000000000000000000000000000001b917517920bad3d8bc01c9595092a", - "0x000000000000000000000000000000482141c7ebe42000a1d58ccb74381f6d19", - "0x0000000000000000000000000000000000305e8992b148eedb22e6e992077a84", - "0x0000000000000000000000000000007c86847618681dc29d8a9363ab7c40e1c3", - "0x000000000000000000000000000000000016465a5ccbb550cd2c63bd58116fe4", - "0x000000000000000000000000000000439973ac12d7ca796d6fe98ca40e6ca6b7", - "0x00000000000000000000000000000000002e24d420fbf9508ed31de692db477b", - "0x00000000000000000000000000000028edd1a7e46c840d9c943fdf45521c64ce", - "0x0000000000000000000000000000000000043d063b130adfb37342af45d0155a", - "0x0000000000000000000000000000009330952ae74c573d1686d9cb4a00733854", - "0x0000000000000000000000000000000000261522c4089330646aff9673619494", - "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000161e5bb10fa2b7c7380009239b649b4734", + "0x00000000000000000000000000000000000badbf533a087faffe865010dc5b37", + "0x000000000000000000000000000000381bfa95df551e67c494b29f07bfc5149c", + "0x00000000000000000000000000000000001bf4738c48442b6d952222d821547f", + "0x000000000000000000000000000000cdf67a2562ab96b4917ea73217efafd3b3", + "0x00000000000000000000000000000000001b0666d4bc44552a2ffc0223345a23", + "0x00000000000000000000000000000052e280645ffe873ef1e2cce244d3b23265", + "0x000000000000000000000000000000000029365e95dc11f595f23b37d9c475db", + "0x000000000000000000000000000000e0546cf49094bcd8d9e4a0e2f0b0d21d73", + "0x00000000000000000000000000000000001dd314bca6a6ded1a4a64266a516ce", + "0x000000000000000000000000000000c529043942840056e63f2fcffad4221afd", + "0x000000000000000000000000000000000011c2731f6fe0cb9f3c7d88d710950d", + "0x0000000000000000000000000000000dccca0374b5478a2414205ee24ca83668", + "0x000000000000000000000000000000000007e95f7cd90c21519b280c7c007fcc", + "0x00000000000000000000000000000004de3a9f180f0a4f01dab186eba8530269", + "0x00000000000000000000000000000000001372faf74b763ba502d7cc0845a54c", + "0x0000000000000000000000000000008aa4681b00633c2a5a63702641a6d36041", + "0x00000000000000000000000000000000002dc7f4ccd6922fc4b6654e175f2a80", + "0x000000000000000000000000000000d0d4f6ecbd8ee863fa3160211931061e33", + "0x0000000000000000000000000000000000263cb61cd13a131bdb313fa1159c3c", + "0x000000000000000000000000000000739ca3af1ec76a87a037f25bca5447ee69", + "0x0000000000000000000000000000000000065132cc73a764a9958eaf16937aac", + "0x0000000000000000000000000000004f397550e79074d0c4d3108fe675be5a4e", + "0x000000000000000000000000000000000012a58f58ab7bd421ca8f0fdf7990ed", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000dbe8bffec86d9a9c4e194450aafe44569a", + "0x00000000000000000000000000000000001ad711549791cb4bfb26753da71976", + "0x000000000000000000000000000000eef413cdd499365c5aff81234c29a8e9c8", + "0x00000000000000000000000000000000001c1a2f7052492deb0bf3831f1d659f", + "0x000000000000000000000000000000a430987c325c792662db95707eeb73bcda", + "0x00000000000000000000000000000000001fc6620d5b4b91a2bb7e967e4ca0a0", + "0x000000000000000000000000000000d3010833f9a0a6df8b842d2e94c7443271", + "0x00000000000000000000000000000000002b34c8b03764d6438d76005e33f136", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000090eb905a6ce8fdcfb3ad69b20f37b471a0", + "0x000000000000000000000000000000000015411f1068f3c41c0f03f763abc15a", + "0x000000000000000000000000000000afca164bedcee548eecb0590ec5abf1127", + "0x0000000000000000000000000000000000145ea9d00e643079977aa78cd2c109", + "0x000000000000000000000000000000854f1c53b1fafeaae64bc08161c77048b7", + "0x00000000000000000000000000000000001e235518c5c034960eec5fc45a716e", + "0x00000000000000000000000000000035145365e610d44ef42fa8ea613a9df4aa", + "0x00000000000000000000000000000000000f949d81fe0404cba9da3dbe012bd7", + "0x000000000000000000000000000000c5f55c78208dcda151683ee8cf95e8bc47", + "0x000000000000000000000000000000000012b17b8f64a8606a7817da004b71c1", + "0x0000000000000000000000000000007359e5ac4a48e1c4cf0e5665c6c059d99b", + "0x00000000000000000000000000000000001d7a0474a2bb254bf932f10146b961", + "0x00000000000000000000000000000024e0b7c596516bb0b5a2e8d6cb248b56a2", + "0x000000000000000000000000000000000012e9c9b3e8143abd574124134a05c8", + "0x000000000000000000000000000000dbc92535cff5ca03ba09ca111642d39fda", + "0x00000000000000000000000000000000002043571f43cad61de3a5e4328a4aee", + "0x00000000000000000000000000000079d599186f46e769fcc207b0cd6cbdc01e", + "0x00000000000000000000000000000000000c5c2f9466df09ea80f0ec14870034", + "0x0000000000000000000000000000005f94f587b12643ff51063a28353833f770", + "0x00000000000000000000000000000000000cf56aa28ed4b4beb7ff157d7da3ef", + "0x000000000000000000000000000000de4b43f87ff9317c8e9d9c4588fc2eef2d", + "0x000000000000000000000000000000000012d0aa842859d2ee838f5510f9bc22", + "0x0000000000000000000000000000006f2fdb4213da0129f8365bc86a01f6164d", + "0x00000000000000000000000000000000000bdc73bc5280a4afc7e65947531e51", + "0x000000000000000000000000000000f14874ba0df22c460d8352ca030bd9a861", + "0x00000000000000000000000000000000000885382903e5ffbd837b5e0e4bbf06", + "0x00000000000000000000000000000066e80b7e34ebe3899a4d07dea4f62cc7df", + "0x000000000000000000000000000000000013f829d0878ad53de418679f370067", + "0x0000000000000000000000000000002980ae9f85fad098e5a76ca9e6bdac5779", + "0x00000000000000000000000000000000001a774ae589e96cfbefb418dddcdaa2", + "0x000000000000000000000000000000327c44b0ed90d01976c32c94f04ef2cea8", + "0x0000000000000000000000000000000000225d757cb4f2bfbf6d13b8114d7b16", + "0x000000000000000000000000000000bdc629840f4a9d071f9fb1384008254135", + "0x000000000000000000000000000000000004e75cee70f3e11a2402faef92a73b", + "0x000000000000000000000000000000f40c508a906897027558980610fc4df4f2", + "0x00000000000000000000000000000000001f959d41e40d111d021ab23b4ef843", + "0x000000000000000000000000000000587fcafd86184e71ec3d650b3ba85f03fa", + "0x00000000000000000000000000000000000610c97af06081281e7404f44aee4b", + "0x0000000000000000000000000000007b029cc296434696323f9c37b5e4c9cf55", + "0x00000000000000000000000000000000000614733fbf8d375012614cce5e4aa0", + "0x000000000000000000000000000000bc102f5fba012ade36bbf671474a9afae2", + "0x00000000000000000000000000000000000d2b78d31298fc946624e482d61850", + "0x000000000000000000000000000000c1c26c3fbdd4fb7de13c6af78b90063442", + "0x00000000000000000000000000000000002da9dd34c453f3d5a99691ba052769", + "0x000000000000000000000000000000a788520d601038b7bcb1ef241547ddc5e1", + "0x00000000000000000000000000000000002a280445997573df993f3eaa9cc9bd", + "0x000000000000000000000000000000ec4d9274437dc457e7da9ee9f5d57b0825", + "0x000000000000000000000000000000000029454eff7f180c04c3dccd1d762531", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000005d656b6df65180c7833e41dc3231ba543d", - "0x000000000000000000000000000000000011345e9011207695e22c16713acdb8", - "0x0000000000000000000000000000007d63cb71b503d4b9abe5d31e76ac70ff93", - "0x000000000000000000000000000000000026b61287fe7afce1e989dc0d30a961" + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000007cf4b5713ad71efb2e02fe45bb7fc9507f", + "0x000000000000000000000000000000000026cf1fe248bb52d3e86b9f64b3c2d3", + "0x0000000000000000000000000000000e590349a07b67f041c3c615e4f436aeab", + "0x000000000000000000000000000000000015a097ca4d6bfa82e4dd755b3ebb59" ] - hash = "0x15602bffd51fabacf870d678a216f360ee85085e4b283f99086a716d2be141c1" + hash = "0x0b292d3b888b2793be2b844d85cf1ee4c10e4646758de66819a7d9483c294c05" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml index b55f7bf5c86f..c82902e1d32e 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml @@ -478,140 +478,140 @@ new_archive_sibling_path = [ [inputs.parity_root.public_inputs] sha_root = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" converted_root = "0x2f7247450c6d856804ef9fade0d5af92e4b87b1576f07ec88359012bf4c21abf" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.parity_root.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" sibling_path = [ - "0x259832d81ade32c589e6ab56f6c2bc4acf0b711b10e539b4ee38d8bacefbdcc3", - "0x00a28019e6ca588777548cd5e154dbf4f567f886cc8a01a812b4d3122f308cb7", - "0x03762ae9136a49df4624f45517c27d99c8b81a305e36011a211dda34608a3daa", - "0x2740690820f0df46bcbf149ccb51f228fb81a46173ad1793687319f77d32d49f", - "0x026fbe21cffb22c458f7e07b206bdaf767d39af34024eefe88e3d8b56eb9f695", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x26cc9e64527e3b22ec4559bc77cf5a17da79641f2be800e6ecdcd1956333e85f", + "0x2ba2de2d2cb820a66a273f2ba930d43a4469119ad58fe01eaed0e0d615ffb426", + "0x18f1abfe1a07005f35a20c06b468f7a4d3b68ecc2c025c88271b6550a827d41b", + "0x2370b2e567b79fe42809d72237ad8694479d864b90033ecbded55e041404191e", + "0x2c420960f09a97665929b2c1b4c167142f9e188be47609019306d64a45249c19", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.parity_root.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000016", - "0x000000000000000000000000000000000000000000000000000000000000000b", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x00000000000000000000000000000078b17daee7ce0a5fb9f5a84a2842c3b468", - "0x00000000000000000000000000000000001e4a85b98d71b0d69292687e2c5e94", - "0x00000000000000000000000000000000c3c7c53f8d6f387d02cbd30b373f624a", - "0x0000000000000000000000000000000000027492d891507b7fb721f827ec2125", - "0x000000000000000000000000000000448da0795e65c2acddb6a180b618ca4500", - "0x000000000000000000000000000000000026376b31e8ce3bb070bfed46801c3c", - "0x000000000000000000000000000000a8b4423143eb061d06dcf70a9b88d96cc0", - "0x0000000000000000000000000000000000140986c98f877b30ce48cb90461312", - "0x000000000000000000000000000000dc3228da5397acec91842e0564247a3281", - "0x00000000000000000000000000000000002c26f116c4120584e7c05868b9e034", - "0x000000000000000000000000000000f5ebf083289c311ee2d289dc034b0031b5", - "0x000000000000000000000000000000000027e5ca168fcf7984917277bd63aeb3", - "0x000000000000000000000000000000087667ff676cfafa2db57dd50364cfe79c", - "0x00000000000000000000000000000000002bb973ea83e8487c41459600a6ef16", - "0x00000000000000000000000000000000a38ca13acac1410f3d7ca6db34fa63f0", - "0x00000000000000000000000000000000002068ffd126a125d99af872b91155ff", - "0x000000000000000000000000000000fdc1eeb335429c34b4488e1ce565edd0be", - "0x00000000000000000000000000000000001279bb6460b4bdefc838d4cb235155", - "0x0000000000000000000000000000005ef93e2a85a22e47a3b3eabb4e229dfb95", - "0x000000000000000000000000000000000002085147ee68b313f39acde522a5b1", - "0x0000000000000000000000000000003601a6e8eaee36ae589e4f3efd39aacdd0", - "0x000000000000000000000000000000000015b26c9be4890cbf333c9d18e023f8", - "0x0000000000000000000000000000002597739e1725777058acf8c41ece5bc230", - "0x0000000000000000000000000000000000127f2d8950de2d351261de15ad3692", - "0x000000000000000000000000000000f0707fa498b915bb84481f22c68f82f852", - "0x0000000000000000000000000000000000026e1e4979e0d760c48aba45674641", - "0x000000000000000000000000000000ea45d31bd10dd18ccc02388e6f8b291dcc", - "0x000000000000000000000000000000000023e937480766000ba36ae295ec1e48", - "0x00000000000000000000000000000031baaf67d48e00f988f210e567ddd2b45d", - "0x00000000000000000000000000000000002715a3d431eafcba537d10c3033057", - "0x000000000000000000000000000000bbb3120089d0de7b11c4a1f29199f88181", - "0x00000000000000000000000000000000000367ef60efb55665d6d840fa949717", - "0x000000000000000000000000000000ed04c2879b84b210376953f58ce48eba0e", - "0x00000000000000000000000000000000000b092c857d4a2e5520dfaafb203c03", - "0x0000000000000000000000000000005da6cf732c008d8d037ca34a818312a024", - "0x000000000000000000000000000000000029f868f7234099b8361cb3510e7d8a", - "0x000000000000000000000000000000a0843902e624f3adccde6cf44e08311d4b", - "0x00000000000000000000000000000000000373ffc7fce598489f487b9c8c0ebd", - "0x000000000000000000000000000000a7314c6ed61312feaff048ba4b49842b7e", - "0x000000000000000000000000000000000028ef66d9ba57db55d9037eee6292af", - "0x000000000000000000000000000000d6a3a1c9a17835658d11e6a5d0fe9cf907", - "0x00000000000000000000000000000000001716bd0d35f792b5b5d1b3d57bceeb", - "0x0000000000000000000000000000008997c4ec5fabfd7e709a9e39a9ade4f7bf", - "0x00000000000000000000000000000000000f0a6f177b950ddd7b7eb33d04db21", - "0x00000000000000000000000000000039501b07dae9c6fb88b4c42448be3cb384", - "0x00000000000000000000000000000000001eaf14768ccbf9c57b217dec1e31d8", - "0x000000000000000000000000000000dc531c7d21f7b45ffbca2717ec44b041e8", - "0x0000000000000000000000000000000000279bdd1d3a8e15802c608c6b4708e1", - "0x000000000000000000000000000000b37783542b31dce0d8c31c0852e1d763c3", - "0x00000000000000000000000000000000002f467244c882fabc33838b10b7eb2a", - "0x000000000000000000000000000000ca408d8763a614b172e9b946a7dbb2e74b", - "0x0000000000000000000000000000000000262b64694fd389afba33f2989accea", - "0x000000000000000000000000000000b61193261fec588db146c2170e4d2b0a0e", - "0x00000000000000000000000000000000002f32c65a1fe400d17787690e55d2c8", - "0x00000000000000000000000000000007fbc70d900496b6366e965b79a2113b36", - "0x00000000000000000000000000000000002be977d4f13c3e45b8aa682458f534", - "0x00000000000000000000000000000019ec1befb0c5f1cddfebc885efc6265f95", - "0x000000000000000000000000000000000005d3ab687eed8f108bc3a75ec3b8e1", - "0x00000000000000000000000000000051bb7f4b08721f57f545ebc0e07d3eebf6", - "0x00000000000000000000000000000000000d9503879b9bd744448b6eb9fb2f7a", - "0x0000000000000000000000000000005a02ba394e9d2d3e77bcccd895c10694fc", - "0x000000000000000000000000000000000027e25fdc49dc55b63ef3d1ca90b5b2", - "0x00000000000000000000000000000091db8035e2aaa8610742df1503300087f9", - "0x0000000000000000000000000000000000021dc3eaf7990b12e4468c2e28bab0", - "0x000000000000000000000000000000e846d69b700fdd8b078052da8b91c352d7", - "0x00000000000000000000000000000000000c951fe8e7eb4a6298b14be6382f93", - "0x000000000000000000000000000000ec89072912c27066e932cf77f821994c90", - "0x0000000000000000000000000000000000182e68039cceed32fdac710403b7da", - "0x0000000000000000000000000000008debe6230106974006084e7308b4b5feca", - "0x00000000000000000000000000000000001ebd658ddc30d75e5e721359395120", - "0x0000000000000000000000000000006d3b5839b70a5b60de45166b9c2a4be3f5", - "0x00000000000000000000000000000000002ecf96badf1253c40c1486fabbfcad", - "0x00000000000000000000000000000098213252fb5d3b6c5a9747469ebcf0dcd9", - "0x00000000000000000000000000000000002d869db2f87c96d3e31e66aa911dda", - "0x000000000000000000000000000000555c7af1975654730348730a11775c9759", - "0x00000000000000000000000000000000002b8d102334de6b8cbc22090f9dda68", - "0x000000000000000000000000000000d34433dab85ff5064014d6b58f60d67c25", - "0x0000000000000000000000000000000000139da62905bcf796f7101bbc76122c", - "0x0000000000000000000000000000003840706e6d07460c44d74cba5c2b34358d", - "0x00000000000000000000000000000000000aa2f8b6291279bea275b7c9913258", - "0x000000000000000000000000000000019eaa3b842224650e76c5cb0e94484c6d", - "0x000000000000000000000000000000000006c9f637fbb6502a38f91b85ace5f5", - "0x000000000000000000000000000000efc01f95fe550a9a9f1476758824a74301", - "0x000000000000000000000000000000000003eaa2fbce3122916d12c78b219b9b", - "0x000000000000000000000000000000a6eda6357e83ebf12fcf13845427e4a057", - "0x0000000000000000000000000000000000255208b91373b2dede462b7e8b0b52", - "0x0000000000000000000000000000006d2aecad4cd09ada8fea8abb2ebbf070f5", - "0x000000000000000000000000000000000012bfb11d7a805c6e591f874ae3637a", - "0x000000000000000000000000000000f4a6c6ffdf80a72db78762e237d58cd5f6", - "0x000000000000000000000000000000000026814a59803555635a3b6dfd056d19", - "0x000000000000000000000000000000f45b8d96069231f48e0d0c34d57593a6a6", - "0x00000000000000000000000000000000000b9dc32399025796005b2f68c15991", - "0x000000000000000000000000000000750e1b5cb997a3adf8540bf55bb9264ec4", - "0x00000000000000000000000000000000001f6cd5b6d43f67798ae4655c016f37", - "0x000000000000000000000000000000596cc6183848f32c60ec74fe2bcd76b20f", - "0x00000000000000000000000000000000000ed62d10b019355f008b46412d0e2d", - "0x0000000000000000000000000000002020dfdab8c9db8335bca3c8284b1585b2", - "0x000000000000000000000000000000000023a2906d03204aa4f79b5b80b92eaa", - "0x0000000000000000000000000000009116c4d15f7c9a51f17c3830fe7c1e3b42", - "0x000000000000000000000000000000000024aecae332db48e03b97fc645a7f05", - "0x000000000000000000000000000000834c5e938cf9e8bd4bd5847e2408407276", - "0x000000000000000000000000000000000008524b40cf87b668119022f691cfac", - "0x000000000000000000000000000000e699df860731437ec57f9890fe4b3a4205", - "0x00000000000000000000000000000000000e1e9d4327e635f547da67aef57e86", - "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x000000000000000000000000000000000000000000000000000000000000000c", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x0000000000000000000000000000004f85c893bf8b1e843f2dffc48dc074f196", + "0x0000000000000000000000000000000000215339c99786f23abf06aa628e2bb5", + "0x00000000000000000000000000000021f56f1fd166b444f6945fef45a4260c98", + "0x000000000000000000000000000000000029832f088b0a8c0ed5fb1876da60ee", + "0x000000000000000000000000000000683bd852b0d5317d3104e00d57a7ff12fe", + "0x00000000000000000000000000000000000d2eb234e163af0321005edbadf074", + "0x00000000000000000000000000000043d1d78f4556dca95ed3ae27b1bb967956", + "0x00000000000000000000000000000000002406ce5529e27d341a34d8c9a819d2", + "0x000000000000000000000000000000d2bb936edd0bcb9cf33e24855aa3095d1e", + "0x000000000000000000000000000000000016629d2674b560633c3db0a21598ea", + "0x00000000000000000000000000000092c8bd15ab345a54468aba584a6f16e2b5", + "0x00000000000000000000000000000000001fbbe74a5bb8bad495a22f4a0384dd", + "0x000000000000000000000000000000d7dbc1eca647580a4a952821d02d282259", + "0x00000000000000000000000000000000002d68b4713f14d3be50ddb099e2b736", + "0x000000000000000000000000000000d4dfc475729d110ffc01eac27a1bb07187", + "0x000000000000000000000000000000000015026e1e1768366175d180725092cd", + "0x000000000000000000000000000000d799d0753526bf23193f9ab8f73c1c7307", + "0x0000000000000000000000000000000000052dcf1d1d89071ecfbfe34de96dff", + "0x0000000000000000000000000000008a7f1c8955fef499a04d57fa057c30e66a", + "0x00000000000000000000000000000000001fedcb5a5fb32238adaca91e2be32f", + "0x00000000000000000000000000000047c5bb126a6e6c788dec340b858f577f7d", + "0x000000000000000000000000000000000013e3b742ca471a245262fb2ecee07a", + "0x000000000000000000000000000000b6284febc7d58cc5491fee7334064865ef", + "0x00000000000000000000000000000000000038ae53da7215a286ebd0649136a1", + "0x0000000000000000000000000000006eed465622852dce8a0702c5327cff0583", + "0x000000000000000000000000000000000022b0941f412859d1cc37a757ca4375", + "0x0000000000000000000000000000008bef872c634b8c03bfe7ff37c00a727192", + "0x000000000000000000000000000000000004906c8767a040a562b166a360c43b", + "0x0000000000000000000000000000001770bcd5e95d6ed8c6299af5208e594351", + "0x00000000000000000000000000000000001170f991d5a8c2cece25a2eec45ac2", + "0x000000000000000000000000000000dd2567c65087f4413c4a68442f7838d361", + "0x00000000000000000000000000000000002b2e2b9fa7017ed5b534b950976cfb", + "0x00000000000000000000000000000060445810cd95870d181367a860937116e0", + "0x00000000000000000000000000000000000171fcd0debd9f9966aa439dafa69c", + "0x00000000000000000000000000000036d276aef0f30fea87630c34381ff63a36", + "0x000000000000000000000000000000000029a01a7f04aa1c5fc36c458ab5f806", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000e402279945a076c945901fca356628c525", - "0x000000000000000000000000000000000012fedcb7313f77c3006a35e9fb9f8d", - "0x00000000000000000000000000000084a3a7ab7d80d65ae1cf14ed89c99c143a", - "0x00000000000000000000000000000000002ece2d07ef9c9b1afa02b75b16e861" + "0x000000000000000000000000000000441c338c655b7e22f91724c986ec2a7d0a", + "0x00000000000000000000000000000000000988f7c276931907f533dfa99ae0ad", + "0x000000000000000000000000000000555d1bf8e49259a2b77c8e0caae5b13feb", + "0x00000000000000000000000000000000000716aa5a6148a8455d44f8759f22f5", + "0x0000000000000000000000000000006400f037f61c707f2729c70c5d912ce9d3", + "0x0000000000000000000000000000000000116682196031717f5d1cc4d903aafe", + "0x0000000000000000000000000000006459e7ac42c142260295108e744e33a0c1", + "0x000000000000000000000000000000000009228de1a4fbd3de4d757390f162da", + "0x00000000000000000000000000000067656846b7e2309e7c18c1cce38675bb00", + "0x000000000000000000000000000000000029e7406191ce46a9babc6ac5ff12cf", + "0x00000000000000000000000000000032e79eca379410f7ec358f9da21bac9fa9", + "0x00000000000000000000000000000000002c817548c195702d46fafe6ccd4faf", + "0x0000000000000000000000000000004fbb48b68f274f27d30cdcb82ee7cac9b2", + "0x0000000000000000000000000000000000068f9a71089873a24f8351d1e70d97", + "0x000000000000000000000000000000795c4af1416754d9625f084be947a93c64", + "0x000000000000000000000000000000000024e4ffd72d451203c5bc7d04a27116", + "0x0000000000000000000000000000008ca18e089457f9cceb58c823a944b03f26", + "0x00000000000000000000000000000000000422b4f22af36e628698a6865ddecd", + "0x000000000000000000000000000000fb52c4f612125db4012ed8a2e84e1d2c6c", + "0x000000000000000000000000000000000019dc534f8dd81d19f72590c6e1fb8e", + "0x000000000000000000000000000000fa01f84fdc11a5d03b14bee3a99a680c37", + "0x000000000000000000000000000000000022dad727328995272891d530216d61", + "0x000000000000000000000000000000b5f4bf23591d8b2447d60d61737c2c36bf", + "0x000000000000000000000000000000000002e2a075eaa9f4dd89c257af6cbab0", + "0x0000000000000000000000000000003561668a93cb72e95a340771ddc66e9c1a", + "0x00000000000000000000000000000000000026940a62997474ab260b2841eafb", + "0x00000000000000000000000000000075c66b2eeb9c27b8611335bafd53ed5e6b", + "0x000000000000000000000000000000000020720351df147e866486a5db6e8bf9", + "0x000000000000000000000000000000fa65c2574867f702f76ee91bf9721891f4", + "0x00000000000000000000000000000000000550d2b73072fe8ebb458db32bc272", + "0x0000000000000000000000000000005e45bf32b04d43d7d9e082552a7c6e3aab", + "0x0000000000000000000000000000000000156b9320b1c02a5ae4d5245079ef93", + "0x0000000000000000000000000000007dd31f38bd2d2529ea3d3537bddc4c2d8d", + "0x00000000000000000000000000000000001460b51e2428e23b3d5f0e0623a2a5", + "0x0000000000000000000000000000009973429339ccb353bf51ed2d258ab0c734", + "0x00000000000000000000000000000000002675f20f2783781dae8b8ceee4b947", + "0x000000000000000000000000000000f19f97ae0fa6b47d95ce8c99deff02825f", + "0x000000000000000000000000000000000008ac106283f7faa2a9523d6d3b6a65", + "0x000000000000000000000000000000ece35a6af0338418a01080dc9e20d76e8c", + "0x0000000000000000000000000000000000223186953dd9de4ffdf175c62fe17b", + "0x0000000000000000000000000000002cdb64ca6e6e3ae04f48e894d029463405", + "0x00000000000000000000000000000000002934e04d3c42257882836e1cd3c909", + "0x00000000000000000000000000000010928865f0c2b283d43e700debac484ce4", + "0x00000000000000000000000000000000001267fc086b1485e85ea3a8d0cd75de", + "0x000000000000000000000000000000f9cdf1ac824371f6761a75f1208a9ddfad", + "0x00000000000000000000000000000000000e0fdaaebe67864d0d5e9eadb9efc5", + "0x00000000000000000000000000000017a6567e4f95497a889a7d72f19789b322", + "0x0000000000000000000000000000000000288f112dfaacee642430e19b6959db", + "0x000000000000000000000000000000a16e293e7727181d85a1c007ac038f36fb", + "0x00000000000000000000000000000000000dd700294b3714e9f7b0e14b5d532b", + "0x0000000000000000000000000000008ac20e1e987aa4c40027fd4f9efd59fa05", + "0x0000000000000000000000000000000000154ef731c875ef2164785e8ff31c30", + "0x0000000000000000000000000000001911ff084795513c823a4fda7a38335e8c", + "0x0000000000000000000000000000000000302c54e62b85bc435230433f081725", + "0x000000000000000000000000000000c4779e7986fcf2ef065416576329f1c47c", + "0x00000000000000000000000000000000001ebeffb4dbaac41852670eeb9ede9d", + "0x000000000000000000000000000000f030e0b5c911d86aef1ef86fff6c540d91", + "0x00000000000000000000000000000000000bae7a5c23fa083c7231387cf8d78a", + "0x0000000000000000000000000000001942fc1702b7a2afec85c9a8473d44c487", + "0x000000000000000000000000000000000000210966c79a864b7f987cf31ab127", + "0x000000000000000000000000000000f77fcafc38ec30e711c06c5755d04144d6", + "0x00000000000000000000000000000000002db7460ea7c5e17383e5d1b8affeb4", + "0x0000000000000000000000000000007f430ccebae1fa38c07b989cb9ac4ccb2d", + "0x00000000000000000000000000000000001d815d190889cb37cacc2ccf4cfc96", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003ef880305f8c4beb28f1f80f7cc0e7d3f2", + "0x00000000000000000000000000000000000483fb33808b70b4a034dca390e659", + "0x0000000000000000000000000000003d66a145da1b03e8dc9914efd105dac5e6", + "0x00000000000000000000000000000000002a25301cc6f9e024e87f0b58047b1e" ] - hash = "0x260bc49f0702223b7f21b3aa27a20c75348991d78be9041f06bde5d2b51a3fc3" + hash = "0x17df297aed2208dd702c20c31bd85e54e0984ff5f2e4c2032f507c647b261849" [inputs.previous_archive] root = "0x21d6f855045a944864d3132e6d985947abedb3c639bcfb1b67a0fd240dff64b1" @@ -636,8 +636,8 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml index b60a27ba98d5..91d7ad39a447 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml @@ -28,10 +28,10 @@ new_l1_to_l2_message_subtree_root_sibling_path = [ "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" ] new_archive_sibling_path = [ - "0x08c303b52910eab1e07d04de401bcbe8d8f36ca377c5168e795f7f5f4156bcd5", - "0x1cfdc3f191fd4278971f73de8ee4302bd29051bb0c93c1ba7a8a7feaa4e59846", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x08ead7d93a6e0ab74b47c029605a16640557a4c3e830a2f6294aea4559e5325d", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -477,19 +477,19 @@ new_archive_sibling_path = [ [inputs.parity_root.public_inputs] sha_root = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" converted_root = "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.parity_root.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" sibling_path = [ - "0x03c2794698e7be6401d02011dc2296136a6aeb5a9ea3e6d244ece148cf45e1d0", + "0x1fd3c3c6e02265cacc9ce121274750908e476487f11894bf5fecd63e8782786e", "0x2ba2de2d2cb820a66a273f2ba930d43a4469119ad58fe01eaed0e0d615ffb426", "0x18f1abfe1a07005f35a20c06b468f7a4d3b68ecc2c025c88271b6550a827d41b", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.parity_root.vk_data.vk] @@ -1099,62 +1099,62 @@ new_archive_sibling_path = [ [inputs.previous_rollup.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x0000000000000000000000000000000000000000000000000022e452ad469ea0" - accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + accumulated_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" [inputs.previous_rollup.public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollup.public_inputs.constants.last_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" + root = "0x2d7278322ae3f2f02196f7b5eb323c037067b5a8bb27bb36e5936e01618b922e" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" [inputs.previous_rollup.public_inputs.constants.l1_to_l2_tree_snapshot] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" [inputs.previous_rollup.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000b" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000043" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde108" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2d77" [inputs.previous_rollup.public_inputs.constants.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.previous_rollup.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000003699e8ba0" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" [inputs.previous_rollup.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" [inputs.previous_rollup.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x0c877a1bf89b9eae6a04511e6f74bfaa71157ae9e20aa265ec7fb092914f6726" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [inputs.previous_rollup.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x21c0735ecdd66391ddb7fff9448a7973f1b8b4399648b1a150afb92d3a0d0ff5" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [inputs.previous_rollup.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" +root = "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.previous_rollup.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1175,128 +1175,128 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollup.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x000000000000000000000000000000000000000000000000000000000000000a" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000083" [inputs.previous_rollup.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000021e00afaeb15ed67ca0", - "0x0000000000000000000000000000000000000000000000000000000000000af0", - "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3" + "0x000a00000b020b0c000a090c2400000c00000c1027010504012300000c3d2d00", + "0x0003052600000000000000000000000000000000000000000000000000000000", + "0x000100000304092d00030a2d00050b2300000c222d010a082d04080b00000a02" ] state = [ - "0x11cc4dd8716179a3121aa6820cf8805b0e65d61d2b958fe317a1ec807c461a21", - "0x0027ae2792755b030071ea296ff933c1fbc939538b5565420ed3e94832815961", - "0x20fa0000aefa41fd803dab187b732d999bc74c8fbd1093faea082ec34b9a2976", - "0x15a69510721f899245edece9d54fb2ab846e01ef0c7480c8a80c649d69839cbd" + "0x1136161b0a665262c6670f13fc5040fb92cb9e9d8788a3e9007001bdc43cee76", + "0x18aa9fc3a56d70689da90c5f45ccd7f24947674af768221cd37158e6464e7ea6", + "0x1a30cbb374bc6cbdf6fb5b69ab449abd42245f063d346c7e6ebf9a110a83325f", + "0x056dec8ddd7e8e484e5fc378ab54c3ef2c1b70c644fa27f94fe44506d0feec0e" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false [inputs.previous_rollup.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" sibling_path = [ - "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", - "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", - "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", - "0x099ef6a9a40aaf85e056bda90684adf858addbb90af303d82f8157b86b705b92", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x1ef80142d10a45fb61f3a4192d352f1d813530777b10ca6db9613ccf5d025640", + "0x0a2d5d1c88992fa153310bc96af4c750c81353526f8c7dfe2b069ed57136e696", + "0x1c3b50ab3c647b6d36f1830308d4542ce50afddf32694ad04eb0cd74c3745ac8", + "0x09ef85eaa102507d30f8dd98ca7ac4118e672d857aa409ddcbfcd5ead95566f9", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollup.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x0000000000000000000000000000000000000000000000000000000000000016", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000008a8843c678d444ced3a35d87626e56ed9f", - "0x0000000000000000000000000000000000060403e4feb303ebae0081cbad4e96", - "0x000000000000000000000000000000f0fe138760bd40aadc43c77ad160555212", - "0x0000000000000000000000000000000000154e802ee66f7a511a469adb8153e5", - "0x00000000000000000000000000000012b75e2667d243bc4bb7b0cde3bdc5eefc", - "0x000000000000000000000000000000000013e94fa83017e580a2e280e4f8c376", - "0x000000000000000000000000000000fb8b3161040e7a5502bf277aec7b82cb6b", - "0x000000000000000000000000000000000014e7113349a6d4f2b0d3c9bde42075", - "0x0000000000000000000000000000006bc15064df220ad5d2fea722296bf72c99", - "0x00000000000000000000000000000000002039216ff43d16e0a63e542794decf", - "0x000000000000000000000000000000f0d3e00b510ae4272fbba83d787c7e6b6e", - "0x000000000000000000000000000000000022f73b00c62c39fc49fbffa96081da", - "0x0000000000000000000000000000000ff9f67bc7c9b90987dbed3fadf40bacc4", - "0x00000000000000000000000000000000001dc87bb292ea49bdb5bb87509c9781", - "0x00000000000000000000000000000025239c23a65572724acdd6663984afc224", - "0x000000000000000000000000000000000005e345da6870bd306f04558f601b45", - "0x000000000000000000000000000000cb380ac3dc3f8788bab24fcb5d9eedc949", - "0x000000000000000000000000000000000017714c1fab296b76d2f78ed675c1ce", - "0x00000000000000000000000000000095bca1a9f9a186f7ec34e43c479e5d1b2f", - "0x000000000000000000000000000000000018d292be64529b7e9ec24c76e561d9", - "0x0000000000000000000000000000006f1bd711730ae2aaf83227b9d9f46daa43", - "0x00000000000000000000000000000000002df0b894f5971084c0a65839178a66", - "0x000000000000000000000000000000909f2efe0bffa95e984d456089f568f59b", - "0x00000000000000000000000000000000002908f2c7ddf9573df347d6c9f22fde", + "0x0000000000000000000000000000003f557273f3723ac427671e7e0241709f42", + "0x00000000000000000000000000000000001a4c7c79f45cd9c3b2730b1014fb2c", + "0x000000000000000000000000000000a0758982a879da262fb5d4a283eb0b2fbd", + "0x00000000000000000000000000000000001cd980c7d658817fc07f56422786c8", + "0x0000000000000000000000000000001116c0ef394a159d7d04035e2d2b1df210", + "0x00000000000000000000000000000000001fc719cba8f7ef0eec1facb64807b8", + "0x00000000000000000000000000000030ae5b7a71f6a3350eb91e843430327027", + "0x000000000000000000000000000000000010623eeba8739fad768943b6a32cd7", + "0x00000000000000000000000000000075f511068970271dc3805b753a601ff6bf", + "0x0000000000000000000000000000000000087d083bd0a030d3e8d20a44cac510", + "0x0000000000000000000000000000008a1d365a7e9c0cdce156eefc77f82c324b", + "0x00000000000000000000000000000000000caa3c2fe3eec6d3abba790f3fdb0f", + "0x000000000000000000000000000000226b13400df89aa52dc04c9ba11ec76d0b", + "0x00000000000000000000000000000000000f98a2766e0e9bfae8946b711ef013", + "0x0000000000000000000000000000003795e58e429596f55168217c1397f38a8a", + "0x00000000000000000000000000000000002e1f8ca27b32c2497816dd49c983e2", + "0x00000000000000000000000000000024169a17177b075798734095f9cc8daf09", + "0x0000000000000000000000000000000000221931eec1149ebc68293392b42121", + "0x000000000000000000000000000000ba47588390fa3d72b699d8b0917b7e3406", + "0x00000000000000000000000000000000000e598a4916409aaf3745b4c6185f93", + "0x000000000000000000000000000000b749616c0462fced8081f284a03518d1a8", + "0x0000000000000000000000000000000000241ceb3abe3289083ce8c8c8bc28d0", + "0x0000000000000000000000000000001d9bd025c3e2e26266d41ff2e384400b47", + "0x00000000000000000000000000000000001e259846a94808bed66227cf262eff", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", - "0x000000000000000000000000000000d2c67f3c526e05aa6d25558ae65cf0e3ac", - "0x000000000000000000000000000000000006cc97b785475ed3429d939fa00e96", - "0x000000000000000000000000000000c5240a725c016a35037b37f73c37b68de9", - "0x000000000000000000000000000000000015e6206f121de2aafe259c32889a4b", - "0x0000000000000000000000000000004cba3ce39736c272ff963bdbdfcb67c2ef", - "0x0000000000000000000000000000000000243b3786310485c3234295957c5222", - "0x0000000000000000000000000000002c3672eaf01e849995fc3f6dc99dcd1d60", - "0x00000000000000000000000000000000001449e8673b109f980a1542f1ddd670", - "0x000000000000000000000000000000f077af86375782052dfc713a0c67f9a08b", - "0x0000000000000000000000000000000000124108d868884e76f5ceeb60b2bdae", - "0x00000000000000000000000000000029c3fd985c5dd5867bd8fed36ad940e02d", - "0x0000000000000000000000000000000000146fedc34ca9246ab0df070f31ee14", - "0x000000000000000000000000000000706a32f5a8f5fa44205bb08662e0ef1396", - "0x000000000000000000000000000000000016ded7f7f0b72d3ecf256f5c2ee613", - "0x0000000000000000000000000000002eaf856304cdbbb4d0b926d9c9211028c0", - "0x000000000000000000000000000000000004696250db37878179b548105ff54e", - "0x000000000000000000000000000000047767298e4177562ddcbcae03c7ec6ccc", - "0x00000000000000000000000000000000001f29f52f5f45f28e462390b0f914f9", - "0x00000000000000000000000000000004e950f9459bf160429275bc6a733319ea", - "0x0000000000000000000000000000000000175f23657f8f899b10b84c1ffe432c", - "0x0000000000000000000000000000006e522620788963bd42d9ab48810f89afe4", - "0x00000000000000000000000000000000002243c76dbde36a37e42b92bae3eb16", - "0x0000000000000000000000000000005641fbcbddd5abb62d653fd7f1ed10ed7e", - "0x000000000000000000000000000000000007d25e6a46da918fdb902e1a78efb4", - "0x00000000000000000000000000000065f7509bb551cb061c5fd1e92bc85a4974", - "0x00000000000000000000000000000000002efbc0dd9b88baa9675d95ae595e68", - "0x00000000000000000000000000000046bdd1d7603fdb2ee53f8966b3069082a5", - "0x0000000000000000000000000000000000161d3346daa3f83e4416d59e8135b6", - "0x000000000000000000000000000000ec124a53466d06b5e0df3e77f9f6a6ae15", - "0x0000000000000000000000000000000000128b36a77e814ffa503da6fd061fc3", - "0x0000000000000000000000000000002cfa5f8d00fe2bbdd85db6b0179a4c7346", - "0x00000000000000000000000000000000002b7ce5f45710c4b113f7ca6b3291b0", - "0x00000000000000000000000000000054409cb824bb2028eb6a501f9585b13eda", - "0x000000000000000000000000000000000026412333aa334f56e0761374f0c38b", - "0x0000000000000000000000000000002a23ae58cbd13760028a699488d5a4300f", - "0x0000000000000000000000000000000000225067a42bdcd7d9eec23d250acc92", - "0x0000000000000000000000000000006e28e63b7d6bc65c15c009f5dd9304f8fd", - "0x00000000000000000000000000000000002648ab0c9cfefbb147853e364bef8d", - "0x000000000000000000000000000000f00a9e6c1594965b7c14b2310b489b52f9", - "0x00000000000000000000000000000000000a03f4283d5d64b7245827349741ee", - "0x00000000000000000000000000000073f3c5531dc194b7332ef4e765192e3962", - "0x0000000000000000000000000000000000088b01c6cab84d827c1d8eae1ebbbd", - "0x000000000000000000000000000000e197f3a024045bec491c28fc4b7594347b", - "0x000000000000000000000000000000000025bf29aee6c0dd8976574600dfacea", - "0x00000000000000000000000000000023cebfa19e1e206b1d71359821037c31b7", - "0x00000000000000000000000000000000000c2354b63a0bcd72350e606c3fa0e7", - "0x000000000000000000000000000000fcf564b220543fd0aea7b28c05df85fe3a", - "0x00000000000000000000000000000000000c2f035d78985f2c0e4ab138790e69", - "0x0000000000000000000000000000005129d16313e897118223bd963067e22700", - "0x000000000000000000000000000000000004c87b337be4b82e809af637daef82", - "0x000000000000000000000000000000279941b3633c9a8e9fc6e68ef4be5633f4", - "0x00000000000000000000000000000000002a9334f2cfa791a9bbc88cc234a5d2", - "0x000000000000000000000000000000ab1a8db808cb2b1b90ba26085c23154102", - "0x00000000000000000000000000000000002c04e8fdbd1f2154a1b42961e3b6b5", - "0x0000000000000000000000000000005729f9b6dcfc45fa934c44ad8800e2b7c6", - "0x00000000000000000000000000000000002c584d4df5aaa602e46e5033408d64", - "0x0000000000000000000000000000004daf206a533411e7b39ab99acaf3287ca2", - "0x000000000000000000000000000000000020d85db8daa0dd9c83ceda296cbe73", - "0x000000000000000000000000000000ab6d868729c089d55819b59b1df10e26ce", - "0x000000000000000000000000000000000004b5421430befd61f014813d315ade", + "0x0000000000000000000000000000005eab99fc5c34cd0a9cf32bc53d04beea68", + "0x00000000000000000000000000000000002eea4190ba69ef934f8be916a217a9", + "0x0000000000000000000000000000005429ed84e5768b172fc483197bcfb786df", + "0x00000000000000000000000000000000000387e378a43d625a53900bde3ff4ad", + "0x0000000000000000000000000000006073a1bf82ba61c51ce96d6cb7030a22b4", + "0x00000000000000000000000000000000001ebaecf236ff2932e24e68d8e1be3b", + "0x00000000000000000000000000000006abf6369ec441190fb054e33c764fb032", + "0x00000000000000000000000000000000001bdbd38b557395b30427017524ba12", + "0x0000000000000000000000000000001d7bb00201b0efb3035f5048c3df84c772", + "0x000000000000000000000000000000000024548bcd56a9ef16c14feae610f806", + "0x000000000000000000000000000000e5655012ed18fcd1d8e339226dd0ba4078", + "0x0000000000000000000000000000000000227c2110109edbbc3955d0465bbc22", + "0x0000000000000000000000000000007bf8464ca9aa703f1e8a25d6e20221d3e9", + "0x000000000000000000000000000000000024963361ceb6d7756c3c2c42a845fe", + "0x00000000000000000000000000000048c96ec4485788f3ccdc37c4ae2a71f1a4", + "0x0000000000000000000000000000000000262b455b6cd2796327e461304e18f7", + "0x000000000000000000000000000000f750d5b7b2337529d40ced8d774f0283e6", + "0x0000000000000000000000000000000000120ef244fda086bafa6f4eccaf97fd", + "0x000000000000000000000000000000fc90ae3789baa78d1d13220b4f34c98f4e", + "0x00000000000000000000000000000000000d60e7b02c8af3cfd72fe199d6a8f6", + "0x0000000000000000000000000000000b9c9b15d9b55b4a49d449b2cd9dbf2dc2", + "0x0000000000000000000000000000000000129d1259178a85eee0f4d95edf2756", + "0x000000000000000000000000000000e8f0abccd4a45c69a68832f6ef8851f04a", + "0x00000000000000000000000000000000000b977396722d8361fecf325e0e32bc", + "0x000000000000000000000000000000645575d035dbf0dc7a5012097524a972d3", + "0x00000000000000000000000000000000001b4b534173d70982fcd6c9544d725d", + "0x0000000000000000000000000000000410cceb82ec7354128465ac80a1ffa862", + "0x00000000000000000000000000000000002acddfed4a484b2d862b4ca275b4d7", + "0x00000000000000000000000000000022d1618e485430a15465e219a117d3edfe", + "0x000000000000000000000000000000000007b06e6eb92e0b7a34acf20a1369f8", + "0x000000000000000000000000000000e856ca1b174973f3af5310a7e38cb305e6", + "0x000000000000000000000000000000000010be0fec1c7598a1c63ec216db4681", + "0x000000000000000000000000000000f0639c87f66ace434ddb4fe65ab243bfde", + "0x00000000000000000000000000000000000c3c99921dee4f0506f5127627f327", + "0x000000000000000000000000000000aa1c283b5ed1b8b43addafd2bb63ecf30d", + "0x00000000000000000000000000000000002b9dc475b4a10275550d8b8d8fbe3b", + "0x00000000000000000000000000000032af5ee654ac1bb41937bb3add8e38ba3e", + "0x00000000000000000000000000000000001491fed9838cf1fe30a73db7421ab1", + "0x0000000000000000000000000000007c9bcd4ba41aac07ea382a61e7b79bc6dd", + "0x0000000000000000000000000000000000064fbc9678a0191e9974927405e063", + "0x000000000000000000000000000000cf990fc7f643af435bd552d6c21f4f12d9", + "0x0000000000000000000000000000000000170bb10fc59004dae5b55d43a9f478", + "0x00000000000000000000000000000019a1d0ed8d637f1c2afba5fdd385d5fcd2", + "0x00000000000000000000000000000000001aeb885acef6da1ab84b4be20c558c", + "0x000000000000000000000000000000a11da3a0f3c7903c1b8119a3727c1d92a6", + "0x0000000000000000000000000000000000054448cc8cc704196f0ee4b52a9d63", + "0x0000000000000000000000000000000e44ab863c917d81428b86f84af8cd1a25", + "0x000000000000000000000000000000000024d7a2087fcd46a69fd94e824dfff2", + "0x0000000000000000000000000000009f11cf3ef8d440c8e83a8eacfe48155eaf", + "0x0000000000000000000000000000000000255afe02ffbc3178db86e228039ff5", + "0x0000000000000000000000000000004a9ad3947e4b5066ad0b4a731d994fa3a4", + "0x0000000000000000000000000000000000092b00146ab98c77c752c32098468c", + "0x000000000000000000000000000000165a72693efa48c7ecebf3f1fea42db4a6", + "0x00000000000000000000000000000000002e108deabceced2338790d19ba16b2", + "0x0000000000000000000000000000001722f48e7ed1f6f73faaf4007e165811f2", + "0x00000000000000000000000000000000002d43d6af66193fced48fd6f89e74f8", + "0x000000000000000000000000000000ac5108d90de1d0e6ce3d6186c769e8b2aa", + "0x00000000000000000000000000000000000de8c8ad0bfcca457220d03c5eb698", + "0x000000000000000000000000000000ab4c7dff5c06e3ad269e8e48dcb13f0a20", + "0x0000000000000000000000000000000000139a57f59fdf3ec29554b9179adc03", "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", @@ -1317,13 +1317,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000bd9c096acdaa162e6c7ee9b718f7fbf759", - "0x00000000000000000000000000000000002c70947eefbeb3fcbc1953b2ccb88f", - "0x00000000000000000000000000000045e09e50b539ce6228369e4b4cb8530ce0", - "0x0000000000000000000000000000000000062cf2c7d023a38df32e6c8c04a8c1" + "0x00000000000000000000000000000027dd7a7146d1c4ff9332e930ec54b6ea2e", + "0x0000000000000000000000000000000000251eb2367a907e55626a07bbea7e2b", + "0x000000000000000000000000000000ed074fc7f9cd09872a83d8c368c93a0725", + "0x00000000000000000000000000000000002621701db780a70b161ef185f06af9" ] - hash = "0x208d8b1ad2d688325416c8a23881e8b14753352851d7740b339ea2ebd455cdcc" + hash = "0x0a7fb889325f39bec13ee8f853c529ad8458c39c703cf4277c5b066d8d2eee15" [inputs.previous_l1_to_l2] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001c00" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml index 969d8532627b..c6438c29451a 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml @@ -28,10 +28,10 @@ new_l1_to_l2_message_subtree_root_sibling_path = [ "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" ] new_archive_sibling_path = [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x1cfdc3f191fd4278971f73de8ee4302bd29051bb0c93c1ba7a8a7feaa4e59846", + "0x02963c966fa7ce35d09c6efedc0319a95890e2e43d65e589e1554b9297826ced", + "0x171c3c9d071c144fac4784c5f2ccea6e9164bf047088712fc7b8e4d5a68cf235", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x08ead7d93a6e0ab74b47c029605a16640557a4c3e830a2f6294aea4559e5325d", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -477,19 +477,19 @@ new_archive_sibling_path = [ [inputs.parity_root.public_inputs] sha_root = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" converted_root = "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.parity_root.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" sibling_path = [ - "0x03c2794698e7be6401d02011dc2296136a6aeb5a9ea3e6d244ece148cf45e1d0", + "0x1fd3c3c6e02265cacc9ce121274750908e476487f11894bf5fecd63e8782786e", "0x2ba2de2d2cb820a66a273f2ba930d43a4469119ad58fe01eaed0e0d615ffb426", "0x18f1abfe1a07005f35a20c06b468f7a4d3b68ecc2c025c88271b6550a827d41b", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.parity_root.vk_data.vk] @@ -1099,31 +1099,31 @@ new_archive_sibling_path = [ [inputs.previous_rollups.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000002" out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x00000000000000000000000000000000000000000000000000885bb87af2ece0" - accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000001210e5" + accumulated_fees = "0x0000000000000000000000000000000000000000000000000083c454635e0920" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000011752b" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" + next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" [inputs.previous_rollups.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000a" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000042" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde0c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x000000000000000000000000000000000000000000000000000000000000000b" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000025" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2e4f" [inputs.previous_rollups.public_inputs.constants.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.previous_rollups.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1133,28 +1133,28 @@ new_archive_sibling_path = [ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x11ea69a14ea9c12bed3f481dd61addfb2d90d96aa40b626c4d2e47b3466e7b88" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" +root = "0x2d172b57477efffd52c4725031d5f351fe4b85137ca4a7121c486b7a6354f637" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x10e14d1e03084d8016d8018077d4e629cb58cbf3139897cdd78db40c002a04d7" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x0a8a1e4bcc4ca37ba1c0e2fcb5e41bc311a5e6b619df6801f0c66240b9614b22" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x1410b6658243b878037c23a953c69c3a138fdf38373efa0662a549111364b310" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x2d36c4289f1a8a4595fd6c28fc83a76c3ebe1112a192448aa6b8400c8d1bc260" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x26fd6ffebb711b7b1d916a895bb8bf3c6b5fc915b1e5a22db0fb801072027d80" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x082091a51b72ed76964eecd0505df5c335ce81a43e8f39055f31498364687c7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x2cef7e5e25fb54c99feb0d6fbc5bb44eb98d00d3022f4baf5e3f6025a7320293" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x2ee93e7bf272c4871c6ea3459ba1e3cfb0a00ee0432439a6095280b78ed82244" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollups.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1175,33 +1175,33 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000047" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000045" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x2a44787960631c708a6c54319236e2733f5bf18956a780d4f076e06d46e8c52f", - "0x21c2f9acd4cfd49d3570c4429b45c6dcf5658ac7592091682403c9468c8fbfc5", - "0x089c49b97c1e121fc3d9c0d7f3793cdd886de1fb26e735edbdae3790abaedd66" + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", + "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969", + "0x00000000000000000000000000000000000000000000021e012495ef5cfd1660" ] state = [ - "0x0b196378726e6d2cbd4d793963bdda8cc494c766409365f6a0f3b9f8e2e2c277", - "0x29906675cd547621ba2ccf000d609acec4b304b7b4d929f9e586687d92c311a9", - "0x17ecd8ac459a19c262c431de5d01f6726a3b03485399398d69165cc195454006", - "0x254280886c6baee6bfedb4dae9055f680574d4b1bb6a4245fb1f24c70eedaa76" + "0x22ea2f893e011e4e7eee01b158986dc9992f64040159170bcb324eae3e034b97", + "0x06a52127441effdec8d468b67c99f1845277ff28156fa7e2abc426c475b77e5a", + "0x27ce40389262fdebb78d0324fb312c0cbf88401e5c7b144c75ba81aaced2ec9c", + "0x0e692e75fdd9a570ffb576fd43504909483cbe4ee5d110f8d2d63bb4478a30dd" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" sibling_path = [ - "0x208d8b1ad2d688325416c8a23881e8b14753352851d7740b339ea2ebd455cdcc", + "0x25f3ed562872c5e18abd2b9c6d87543b21886af47c7a714c99e78776bae18397", "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", - "0x099ef6a9a40aaf85e056bda90684adf858addbb90af303d82f8157b86b705b92", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x24cead94db344ae1716301e94784822099e114c4deaddb78f16e8724ee376aaa", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] @@ -1811,31 +1811,31 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x000000000000000000000000000000000000000000000000004894bc72b69ca0" - accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000099dbf" + accumulated_fees = "0x000000000000000000000000000000000000000000000000004d2c208a4b8060" + accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" + next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" [inputs.previous_rollups.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000a" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000042" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde0c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x000000000000000000000000000000000000000000000000000000000000000b" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000025" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2e4f" [inputs.previous_rollups.public_inputs.constants.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.previous_rollups.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1845,45 +1845,45 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x26fd6ffebb711b7b1d916a895bb8bf3c6b5fc915b1e5a22db0fb801072027d80" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x082091a51b72ed76964eecd0505df5c335ce81a43e8f39055f31498364687c7a" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x2cef7e5e25fb54c99feb0d6fbc5bb44eb98d00d3022f4baf5e3f6025a7320293" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x2ee93e7bf272c4871c6ea3459ba1e3cfb0a00ee0432439a6095280b78ed82244" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x1cfed5fd7ef032befae488393236dfabcdca928fd71b5775b02eeeca5952b149" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" +root = "0x17809078aea757181529cc251693b3402311164785b07da22da983ca02d24ffa" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000047" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000045" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x2a44787960631c708a6c54319236e2733f5bf18956a780d4f076e06d46e8c52f", - "0x21c2f9acd4cfd49d3570c4429b45c6dcf5658ac7592091682403c9468c8fbfc5", - "0x089c49b97c1e121fc3d9c0d7f3793cdd886de1fb26e735edbdae3790abaedd66" + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", + "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969", + "0x00000000000000000000000000000000000000000000021e012495ef5cfd1660" ] state = [ - "0x0b196378726e6d2cbd4d793963bdda8cc494c766409365f6a0f3b9f8e2e2c277", - "0x29906675cd547621ba2ccf000d609acec4b304b7b4d929f9e586687d92c311a9", - "0x17ecd8ac459a19c262c431de5d01f6726a3b03485399398d69165cc195454006", - "0x254280886c6baee6bfedb4dae9055f680574d4b1bb6a4245fb1f24c70eedaa76" + "0x22ea2f893e011e4e7eee01b158986dc9992f64040159170bcb324eae3e034b97", + "0x06a52127441effdec8d468b67c99f1845277ff28156fa7e2abc426c475b77e5a", + "0x27ce40389262fdebb78d0324fb312c0cbf88401e5c7b144c75ba81aaced2ec9c", + "0x0e692e75fdd9a570ffb576fd43504909483cbe4ee5d110f8d2d63bb4478a30dd" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] @@ -1891,15 +1891,15 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000021e00d293040c1d1b40", - "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec", - "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3" + "0x00000000000000000000000000000000000000000000021e00d769ced2b19600", + "0x00000000000000000000000000000000000000000000000000000000000003e8", + "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969" ] state = [ - "0x046ca01947e306f5aad217a20c357e8720e466bf48af683e5dc034abe73721f0", - "0x14686ac6e82fd9bd26ab09d349ce45506d9c0d1dee28a4967817015ea73b887b", - "0x0b7d5bc95988dfda6650240e060e449c0ec3d312f8da80bd59a897a3ce57c1ee", - "0x1ea8a35effe09689490c7037df5f38ebfc4f6641047f2e4bcab5542979b4667c" + "0x1bc609f7dcef364685bb5064b63088b4b176e64477bcb8a59d1c5d75ecf2daa8", + "0x034e84257006a2e620593aa7b0d53b07c9241554a3c0758e9e8d3dd4dbb7fb69", + "0x0ea57cf50569254eb0b5e0a6bc854a45fd90dc63bbfc989ac9aab7b658b90219", + "0x09602775b5f377f951b58721d32a2e6596705625a417c0dbf308d84edb29d9df" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false @@ -1910,10 +1910,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", - "0x099ef6a9a40aaf85e056bda90684adf858addbb90af303d82f8157b86b705b92", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x24cead94db344ae1716301e94784822099e114c4deaddb78f16e8724ee376aaa", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] @@ -1921,94 +1921,94 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000008a8843c678d444ced3a35d87626e56ed9f", - "0x0000000000000000000000000000000000060403e4feb303ebae0081cbad4e96", - "0x000000000000000000000000000000f0fe138760bd40aadc43c77ad160555212", - "0x0000000000000000000000000000000000154e802ee66f7a511a469adb8153e5", - "0x00000000000000000000000000000012b75e2667d243bc4bb7b0cde3bdc5eefc", - "0x000000000000000000000000000000000013e94fa83017e580a2e280e4f8c376", - "0x000000000000000000000000000000fb8b3161040e7a5502bf277aec7b82cb6b", - "0x000000000000000000000000000000000014e7113349a6d4f2b0d3c9bde42075", - "0x0000000000000000000000000000006bc15064df220ad5d2fea722296bf72c99", - "0x00000000000000000000000000000000002039216ff43d16e0a63e542794decf", - "0x000000000000000000000000000000f0d3e00b510ae4272fbba83d787c7e6b6e", - "0x000000000000000000000000000000000022f73b00c62c39fc49fbffa96081da", - "0x0000000000000000000000000000000ff9f67bc7c9b90987dbed3fadf40bacc4", - "0x00000000000000000000000000000000001dc87bb292ea49bdb5bb87509c9781", - "0x00000000000000000000000000000025239c23a65572724acdd6663984afc224", - "0x000000000000000000000000000000000005e345da6870bd306f04558f601b45", - "0x000000000000000000000000000000cb380ac3dc3f8788bab24fcb5d9eedc949", - "0x000000000000000000000000000000000017714c1fab296b76d2f78ed675c1ce", - "0x00000000000000000000000000000095bca1a9f9a186f7ec34e43c479e5d1b2f", - "0x000000000000000000000000000000000018d292be64529b7e9ec24c76e561d9", - "0x0000000000000000000000000000006f1bd711730ae2aaf83227b9d9f46daa43", - "0x00000000000000000000000000000000002df0b894f5971084c0a65839178a66", - "0x000000000000000000000000000000909f2efe0bffa95e984d456089f568f59b", - "0x00000000000000000000000000000000002908f2c7ddf9573df347d6c9f22fde", + "0x000000000000000000000000000000b545d833a3cc9654dc3778c8fc7ba02260", + "0x00000000000000000000000000000000001b66ea392ccb7834c732bf86004463", + "0x00000000000000000000000000000085d1593162873215b0b41c64cb7cb0f3dd", + "0x0000000000000000000000000000000000137f2cf2c8141ddf32dc7895df5a91", + "0x00000000000000000000000000000015bd11a0a68a9fa3cb97d7b377340600a0", + "0x00000000000000000000000000000000001c98939c525c07b9dc35242a7c7552", + "0x000000000000000000000000000000cc31fdbc0ca878839693b87eee464d9f98", + "0x00000000000000000000000000000000002ba8d519b16b09c6af76887171a8bf", + "0x0000000000000000000000000000009a381e1beac98b23aeaee28a9046ac5ad9", + "0x00000000000000000000000000000000000aef8131f15aa3d0ba42d130678428", + "0x0000000000000000000000000000005f188d32071b43a3bd819e75c138f643e0", + "0x00000000000000000000000000000000002f02065d3e3a5ef4fdd72b9e71a6db", + "0x0000000000000000000000000000000562756bd3ba24529dde902ebf387674a2", + "0x00000000000000000000000000000000000d69752978cb2604a8f5976fa5b2aa", + "0x0000000000000000000000000000002d4785d1c39f767ca2489e57956e264037", + "0x00000000000000000000000000000000000eb3abc7015aef51cad0792c015bfb", + "0x000000000000000000000000000000feb4eee7085cf9c45105254a02f9265e10", + "0x00000000000000000000000000000000000beb9239680b506079e5cda03a9cdf", + "0x000000000000000000000000000000f6d0ed07f67728bfc43ac279ee33b4f6a5", + "0x0000000000000000000000000000000000130de3209e04190412baf56475a662", + "0x0000000000000000000000000000005ba14f0dd0b7766fb3855b36587341a777", + "0x000000000000000000000000000000000008d2a5bc2cebd4e7b9696c3aaee35d", + "0x0000000000000000000000000000000d8ca8b57e8aefe0252ffd103e1d3a2b94", + "0x0000000000000000000000000000000000084daf23a4d3af94ab98db652895c2", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", - "0x000000000000000000000000000000d2c67f3c526e05aa6d25558ae65cf0e3ac", - "0x000000000000000000000000000000000006cc97b785475ed3429d939fa00e96", - "0x000000000000000000000000000000c5240a725c016a35037b37f73c37b68de9", - "0x000000000000000000000000000000000015e6206f121de2aafe259c32889a4b", - "0x0000000000000000000000000000004cba3ce39736c272ff963bdbdfcb67c2ef", - "0x0000000000000000000000000000000000243b3786310485c3234295957c5222", - "0x0000000000000000000000000000002c3672eaf01e849995fc3f6dc99dcd1d60", - "0x00000000000000000000000000000000001449e8673b109f980a1542f1ddd670", - "0x000000000000000000000000000000f077af86375782052dfc713a0c67f9a08b", - "0x0000000000000000000000000000000000124108d868884e76f5ceeb60b2bdae", - "0x00000000000000000000000000000029c3fd985c5dd5867bd8fed36ad940e02d", - "0x0000000000000000000000000000000000146fedc34ca9246ab0df070f31ee14", - "0x000000000000000000000000000000706a32f5a8f5fa44205bb08662e0ef1396", - "0x000000000000000000000000000000000016ded7f7f0b72d3ecf256f5c2ee613", - "0x0000000000000000000000000000002eaf856304cdbbb4d0b926d9c9211028c0", - "0x000000000000000000000000000000000004696250db37878179b548105ff54e", - "0x000000000000000000000000000000047767298e4177562ddcbcae03c7ec6ccc", - "0x00000000000000000000000000000000001f29f52f5f45f28e462390b0f914f9", - "0x00000000000000000000000000000004e950f9459bf160429275bc6a733319ea", - "0x0000000000000000000000000000000000175f23657f8f899b10b84c1ffe432c", - "0x0000000000000000000000000000006e522620788963bd42d9ab48810f89afe4", - "0x00000000000000000000000000000000002243c76dbde36a37e42b92bae3eb16", - "0x0000000000000000000000000000005641fbcbddd5abb62d653fd7f1ed10ed7e", - "0x000000000000000000000000000000000007d25e6a46da918fdb902e1a78efb4", - "0x00000000000000000000000000000065f7509bb551cb061c5fd1e92bc85a4974", - "0x00000000000000000000000000000000002efbc0dd9b88baa9675d95ae595e68", - "0x00000000000000000000000000000046bdd1d7603fdb2ee53f8966b3069082a5", - "0x0000000000000000000000000000000000161d3346daa3f83e4416d59e8135b6", - "0x000000000000000000000000000000ec124a53466d06b5e0df3e77f9f6a6ae15", - "0x0000000000000000000000000000000000128b36a77e814ffa503da6fd061fc3", - "0x0000000000000000000000000000002cfa5f8d00fe2bbdd85db6b0179a4c7346", - "0x00000000000000000000000000000000002b7ce5f45710c4b113f7ca6b3291b0", - "0x00000000000000000000000000000054409cb824bb2028eb6a501f9585b13eda", - "0x000000000000000000000000000000000026412333aa334f56e0761374f0c38b", - "0x0000000000000000000000000000002a23ae58cbd13760028a699488d5a4300f", - "0x0000000000000000000000000000000000225067a42bdcd7d9eec23d250acc92", - "0x0000000000000000000000000000006e28e63b7d6bc65c15c009f5dd9304f8fd", - "0x00000000000000000000000000000000002648ab0c9cfefbb147853e364bef8d", - "0x000000000000000000000000000000f00a9e6c1594965b7c14b2310b489b52f9", - "0x00000000000000000000000000000000000a03f4283d5d64b7245827349741ee", - "0x00000000000000000000000000000073f3c5531dc194b7332ef4e765192e3962", - "0x0000000000000000000000000000000000088b01c6cab84d827c1d8eae1ebbbd", - "0x000000000000000000000000000000e197f3a024045bec491c28fc4b7594347b", - "0x000000000000000000000000000000000025bf29aee6c0dd8976574600dfacea", - "0x00000000000000000000000000000023cebfa19e1e206b1d71359821037c31b7", - "0x00000000000000000000000000000000000c2354b63a0bcd72350e606c3fa0e7", - "0x000000000000000000000000000000fcf564b220543fd0aea7b28c05df85fe3a", - "0x00000000000000000000000000000000000c2f035d78985f2c0e4ab138790e69", - "0x0000000000000000000000000000005129d16313e897118223bd963067e22700", - "0x000000000000000000000000000000000004c87b337be4b82e809af637daef82", - "0x000000000000000000000000000000279941b3633c9a8e9fc6e68ef4be5633f4", - "0x00000000000000000000000000000000002a9334f2cfa791a9bbc88cc234a5d2", - "0x000000000000000000000000000000ab1a8db808cb2b1b90ba26085c23154102", - "0x00000000000000000000000000000000002c04e8fdbd1f2154a1b42961e3b6b5", - "0x0000000000000000000000000000005729f9b6dcfc45fa934c44ad8800e2b7c6", - "0x00000000000000000000000000000000002c584d4df5aaa602e46e5033408d64", - "0x0000000000000000000000000000004daf206a533411e7b39ab99acaf3287ca2", - "0x000000000000000000000000000000000020d85db8daa0dd9c83ceda296cbe73", - "0x000000000000000000000000000000ab6d868729c089d55819b59b1df10e26ce", - "0x000000000000000000000000000000000004b5421430befd61f014813d315ade", + "0x0000000000000000000000000000000c6fdc12f114b3dff18c32b6639206626d", + "0x000000000000000000000000000000000029ea8e59560238dd94abed35cb70c8", + "0x000000000000000000000000000000798b53b0eca893b352181071c60c1697a3", + "0x0000000000000000000000000000000000143bc71afee8cde0cf0923214ba969", + "0x00000000000000000000000000000085734dbd3f00d833c7f16d28c7c161a6e6", + "0x00000000000000000000000000000000001dc1695bb379cc1fe09ce6224bbd76", + "0x00000000000000000000000000000076510156d9bbb6e8916f5df3484dbe501a", + "0x000000000000000000000000000000000002f88711cc50540166aaf0ed7563ce", + "0x0000000000000000000000000000004e92767827fb29389f5eecfe92604eab79", + "0x000000000000000000000000000000000015e003572014e30792cc42dd76f703", + "0x000000000000000000000000000000e9101815687b2b199e9813ab45410c58a0", + "0x00000000000000000000000000000000000bdf464606fd075764ebd13de85d18", + "0x000000000000000000000000000000a4765d6f5df947831e3f85a1bd0bc7628a", + "0x00000000000000000000000000000000000c553b386599253dcca9bcad704ca3", + "0x000000000000000000000000000000832463786e94b008b4014e652a0a06d7a8", + "0x000000000000000000000000000000000011ff61570f0bf2e97760512082e6f3", + "0x00000000000000000000000000000044e15aaa95424af2ca33a24f73d87a9fed", + "0x0000000000000000000000000000000000265a6e89432e27fe25605d534fefff", + "0x000000000000000000000000000000e50b139f7dcefba4c36067e75084866789", + "0x00000000000000000000000000000000001f7c7a9bcf4d3731b120fdb685be9a", + "0x000000000000000000000000000000c61155084507edfd2780b6595d0383e3d3", + "0x000000000000000000000000000000000024732fdee72acfeb9fcd7ecd03f17b", + "0x000000000000000000000000000000e3eba5ed351243e1b88baf42d6e3c3497f", + "0x00000000000000000000000000000000001ac8ebfb4b65882179207743191dab", + "0x000000000000000000000000000000d5ab1236a0b5298b47f9d147a330a0d1a6", + "0x000000000000000000000000000000000004bf74c81b93344ee6eb639f9b27f5", + "0x000000000000000000000000000000f54856ecc2104aaa4a8b1412198b8f19a0", + "0x000000000000000000000000000000000009657c61abf1cefe29851881f04171", + "0x0000000000000000000000000000000671c904145c28b987a2097d7e0a44bed7", + "0x000000000000000000000000000000000014a3beb99844cce00bf4bf29835019", + "0x000000000000000000000000000000bb586be39659e96f6200416f882ea6791a", + "0x00000000000000000000000000000000000ec0d3c4d4d09bf02f60b610ca417c", + "0x000000000000000000000000000000a27b8cc202048319ee3216614fe0b2bc78", + "0x0000000000000000000000000000000000259f13400b5ca91f037e522892f1d0", + "0x0000000000000000000000000000005afa7274e86f2e4544d9bc2995a4b59eb6", + "0x000000000000000000000000000000000013d4650df900f0413b1d29aa9ba528", + "0x000000000000000000000000000000a0230f28d66f5d56c9ff831a471d3c5f9b", + "0x00000000000000000000000000000000002b59c41dfcccc1692e67253054b1e5", + "0x000000000000000000000000000000cb139be520f9594c3b3265adf3c829a0be", + "0x00000000000000000000000000000000001a03e4be32cf715c13caa3b09031f2", + "0x000000000000000000000000000000acd2e4f92b6605e95986f1cffa82304b50", + "0x0000000000000000000000000000000000259fb01c767e7769e772eb56ce8193", + "0x000000000000000000000000000000282782aa36fde06ed1c6dd811c75864c98", + "0x00000000000000000000000000000000001369a47591ca24aab36f32a1f92922", + "0x0000000000000000000000000000001c17cb9d98dae6214548afa20c9f1c4f7c", + "0x000000000000000000000000000000000008b8f3d446e6f4e097bd6841e421b5", + "0x00000000000000000000000000000039e4c093b585f6a6fcb22f99bd8c342b7e", + "0x00000000000000000000000000000000003041bf4ef4eb97be85a8fdc7c9479e", + "0x000000000000000000000000000000da48e82a3d5d7897cb678ff5610a5cf1ff", + "0x000000000000000000000000000000000003acb814504ffac1f2ed4a14fc9bd3", + "0x0000000000000000000000000000009dca7075e3e05e41559f28912a82971ea0", + "0x0000000000000000000000000000000000235b08870fcb646e907b4d3d736174", + "0x00000000000000000000000000000088b105b378f5f68086a26e45ce7db625c5", + "0x00000000000000000000000000000000001d5e5ec54b2dc9f683c10f467d96ac", + "0x00000000000000000000000000000077d8cfd48ba52a9cdd346b1cf45f0d718e", + "0x00000000000000000000000000000000001d96ca59605ed27e2028cb8af363e0", + "0x0000000000000000000000000000006b206e2ff7e814240e93358f1c3ca92a89", + "0x00000000000000000000000000000000000f68e0a1401d250cc41f4478d6e0c3", + "0x0000000000000000000000000000003563a2722147fff76720456302877e3e2c", + "0x0000000000000000000000000000000000000ccf9ca6c5707774553f9e9a96f5", "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", @@ -2029,13 +2029,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000bd9c096acdaa162e6c7ee9b718f7fbf759", - "0x00000000000000000000000000000000002c70947eefbeb3fcbc1953b2ccb88f", - "0x00000000000000000000000000000045e09e50b539ce6228369e4b4cb8530ce0", - "0x0000000000000000000000000000000000062cf2c7d023a38df32e6c8c04a8c1" + "0x000000000000000000000000000000b0d85375aa0d40d56afab87a4500a0ee93", + "0x00000000000000000000000000000000002ff36f19431aa225aa3f1788d0c736", + "0x0000000000000000000000000000008395fb5b5962fc53092baed85b90f142e4", + "0x0000000000000000000000000000000000236be094b70d84fe3007f69d527f24" ] - hash = "0x208d8b1ad2d688325416c8a23881e8b14753352851d7740b339ea2ebd455cdcc" + hash = "0x25f3ed562872c5e18abd2b9c6d87543b21886af47c7a714c99e78776bae18397" [inputs.previous_l1_to_l2] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml index 9e681460ac92..4041bc024fee 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml @@ -1,7 +1,7 @@ [inputs] new_archive_sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x300378810ae25edf6021ba94b4ba9ad6eafaf9caec8c6504ba8ef81f3240f780", + "0x21decddb0e57243b3ec2d7320d3979efb6efebd4352375c223cf4f8efd1dbef3", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", @@ -523,12 +523,12 @@ new_archive_sibling_path = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.last_archive] - root = "0x0edef98680cbea2855c4f0f152a0ecd69358e68b10da7b7e301f35ce709c13fa" + root = "0x27b365d73aa1b8ac1eb39c75262e2b87a238d041cc98fcb795f4c597c620ce64" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollup.public_inputs.constants.l1_to_l2_tree_snapshot] @@ -586,10 +586,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" ] state = [ - "0x08cdf544ec44d694936ed6a5aa580afb2a3b1a4b087ba80870d4d01c79cb5772", - "0x192972b72a1776fa9d30c1202807fca4f9272b156c9e1eafa5f93e94a13c439b", - "0x23ace986d5ee172559ce2153d8a166075599a4403288cbe1a150bda49415fae6", - "0x0f3ccb179877769f2d268206c1b45ab9af36d5e7e005de27ede90c1a29450039" + "0x13ec9d9b37f0599c5765a81513125e07305454198fecae73a69e7d41dfb27215", + "0x24fe963f8f4139d84f904228cfe1e10256e9106331e614b72ed86be8903e4259", + "0x114cba9fee3fa49ffd5f440aa162c6ce6e8410138a592e587337646bb8b04ca7", + "0x10325219e420881603ba4ea16613cf66fa1c43ff98bceb97acaaab599e3326b5" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -604,10 +604,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x1b111ef987a8412d74666407b504b312064231fbf5c26a46f410fa863d95c877", - "0x1be482b447910939727d105aa8f4722d4300002a9481483a5a47b5be0d458a69", - "0x0918650d25d3222c18bf60663bf62753764ad8b75fc3ce5e74c3fa9c9470b1b8", - "0x1eba072dced35bc1bb87f4b50410109a790c58dd87ad9eebd46f50a25112d9b4" + "0x02a5b53c7efb068bc743feca8874f269cfe88163e97fef0ae200aa662ada3895", + "0x17a9dc2d3bc5a2ba2f0435e36c8441f5a18e087f04a9812a1261c97a3988bed6", + "0x1848e27196daf1ad40d8564e8b84be69d789d47c42ba2035af49d5c522d4cd43", + "0x29c59fa7664efcf9d55dd4bfdecbc4a442e78f6a405b6b5846d6c0ba49f78ca7" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -615,131 +615,131 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollup.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollup.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000008580b9a8c85e4a3c1e7b1089bd79f3bc28", - "0x000000000000000000000000000000000022dc01e3ed0e1b10bdcff9d093431a", - "0x00000000000000000000000000000054f9950035e8ffae852707e9d1a9032e59", - "0x0000000000000000000000000000000000276c56cb94e0545b3bfd85919a8ce8", - "0x0000000000000000000000000000009352ff9d82645804416a2b338260fa235d", - "0x000000000000000000000000000000000010a253776d2bdcb7129acfa2e91ac5", - "0x00000000000000000000000000000095babbbc4a6d5a9b68707c3a8e1e9508e2", - "0x000000000000000000000000000000000030157ca77e90f7ee9155c1009b06a1", - "0x000000000000000000000000000000068047e82e283284235befaa9cc7a1838d", - "0x00000000000000000000000000000000000bcd70cc5042e81e440b1ea5ef3c3f", - "0x0000000000000000000000000000007702a95c1bf5e2923ca69f26cc2d7efe0f", - "0x00000000000000000000000000000000000adeb0e8b1074c68de2b2172f21c5e", - "0x000000000000000000000000000000520354133ccbbccfc69be0c01b92abdf0f", - "0x00000000000000000000000000000000002dea248e3c2fe054c698a861bf4c27", - "0x000000000000000000000000000000f93b6112b7de5c27298a81c68d502b7beb", - "0x00000000000000000000000000000000002be3a33fc9502b0cc8b9427fcfe50f", - "0x000000000000000000000000000000168f01ff83f4a014a90db19e5d882a0a0a", - "0x000000000000000000000000000000000008876edc3cc7e3825dc194e21cb011", - "0x0000000000000000000000000000006d1df389f06e514e1829af3744dc64294a", - "0x000000000000000000000000000000000022e86ef68622bd107e5080cc062a4f", - "0x000000000000000000000000000000d137fc89e86049cb1b141b67b3361b6298", - "0x00000000000000000000000000000000001d7ad7d0634dc08d7d9816b5b6814c", - "0x000000000000000000000000000000defd2454e2c3a75ec8e0730bd3640b9408", - "0x00000000000000000000000000000000000b189f6ee9395b1ca5771c361501d7", - "0x00000000000000000000000000000001fccf755f5b30a7d544b2f78ce075cb5d", - "0x000000000000000000000000000000000026f5423942948047e155a519b195e8", - "0x000000000000000000000000000000a9efc76daffb8dfe2a39570b2d5d046767", - "0x000000000000000000000000000000000026e7dd89fe96952a4603c2b5555538", - "0x00000000000000000000000000000008262b430328dcaab242dd8acc504e8ac9", - "0x000000000000000000000000000000000015f3ab1410f0e5dd3e00f03b9f563b", - "0x0000000000000000000000000000008fca5ff8ed9a5d41fe9b451f02502dd1c9", - "0x0000000000000000000000000000000000266aa6e4947434ef18adeba3700713", - "0x000000000000000000000000000000d93cecd04341f5da304f3c92f0670afc43", - "0x000000000000000000000000000000000020165b3fd2bfb72a4de3dc68f66eed", - "0x000000000000000000000000000000094a6d376eb3cc1ba94b4da00dea583eac", - "0x00000000000000000000000000000000001caf7742d251b04f3517f0f1e5a625", - "0x0000000000000000000000000000003be5647cd472ad0b06a48f632997e3eea2", - "0x000000000000000000000000000000000015fb4d9ecb8125b3243cee37698c48", - "0x0000000000000000000000000000000854a3ab5bcbca1e86d4949b1b7c5f4b0e", - "0x000000000000000000000000000000000015450314fbf315448dc3379dc82214", - "0x0000000000000000000000000000009c2c55d2ea5bdf5fc5e28f1a78b1d29625", - "0x000000000000000000000000000000000020b36a8406ec64352600587cf04194", - "0x000000000000000000000000000000f14d08d9dab6a54412d741166146188ae6", - "0x00000000000000000000000000000000001b5a34ccd7eaf5cd09ab920011552f", - "0x00000000000000000000000000000074b7827a59faf701f7f41df26e5476c40c", - "0x00000000000000000000000000000000002decbab1c87b933da1625951860793", - "0x000000000000000000000000000000751aab48a0e01094128242ea0aaab63ff7", - "0x00000000000000000000000000000000001a2a334289adf8d23d4d52caf4cfe6", - "0x000000000000000000000000000000f6a41261290460b25e1e7d7bf69b564ae6", - "0x00000000000000000000000000000000000296925feaed4585bb03319f126d96", - "0x00000000000000000000000000000055b70d653ebd7df04f720951e76a27369b", - "0x000000000000000000000000000000000019744937a687edc9f46fb8323a46d9", - "0x00000000000000000000000000000047978fda5b64d8fc4571f09da3e8ccc7de", - "0x0000000000000000000000000000000000139de6a387109f47ecbacc74e03742", - "0x0000000000000000000000000000007f5afdfcb7bcd85aa293676e18e899a03e", - "0x000000000000000000000000000000000006a2971c1c947f4cadb07ebc9bc980", - "0x0000000000000000000000000000006cdb69a57b7f7a25b99e18fc0f83c1bc70", - "0x000000000000000000000000000000000028f2a76a01dc3cc927cdba29383e9b", - "0x0000000000000000000000000000001bbc4d6033de44907975ce473bc0f4f148", - "0x00000000000000000000000000000000002642f26fc1850c4b9b7fc4cd860ab9", - "0x000000000000000000000000000000ac996074e35eb268f6ebbe99e9c7d26c47", - "0x00000000000000000000000000000000002262620617978a01f75646f1909969", - "0x000000000000000000000000000000e63aa32bcc098428f407b5e07d9cb26118", - "0x000000000000000000000000000000000022b294b6a7dc4c17319f9a91a1b443", - "0x000000000000000000000000000000649d9ce9147431632893f55d3c6bbc158e", - "0x000000000000000000000000000000000020698c9b0787f14aa66a57bc232ec1", - "0x000000000000000000000000000000b4fde29f9bde909609d70bf9862dd65cf1", - "0x000000000000000000000000000000000005fcac9b75cac50d87ca827678c070", - "0x00000000000000000000000000000071e27b0a0dd0e2180985072f4a949f0c1d", - "0x000000000000000000000000000000000025d2d1388eddcf016213f1cadc763f", - "0x000000000000000000000000000000b216bad715cdfa7c382d30d7a368cc1346", - "0x0000000000000000000000000000000000302dbbf78b13a6d71d1978b5607145", - "0x00000000000000000000000000000002ebdec49969d2ff9220240bbcb8730617", - "0x000000000000000000000000000000000027f41cad8540e47008c1da90340ef6", - "0x000000000000000000000000000000e8259148321315cc34166a206fe910c6cb", - "0x000000000000000000000000000000000013444efc30c7688d961f36de252af6", - "0x0000000000000000000000000000005b7c7ad432291e9dff1dfad51159e50dbf", - "0x0000000000000000000000000000000000205ec973a0d1c898c1def7852353b3", - "0x0000000000000000000000000000007940a7e88fe5ce47af688975c92be1b62a", - "0x000000000000000000000000000000000015bdab44fe41eec6ee62ed58f55ff5", - "0x0000000000000000000000000000003693b90aedcd664eede665df6f376cf526", - "0x0000000000000000000000000000000000207c38fd6851d1568fe18a83585f31", - "0x000000000000000000000000000000f1a8a60975b9b092aab1421166be08c2f5", - "0x000000000000000000000000000000000015450d2e8ea17db209302582b886f1", - "0x000000000000000000000000000000526e857040a344bd434bfdbf94d3a49196", - "0x00000000000000000000000000000000000d0112b922a852c4754ab3929d6d02", - "0x000000000000000000000000000000d88041fa28c8118a58ceacbcc8780844b5", - "0x00000000000000000000000000000000002584170ebef150b71c5e6aa93e2fbb", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a2c4fbcbebac01e208127093cbf44780d4", - "0x00000000000000000000000000000000001ca34545a074b1cb689aa0b343402d", - "0x000000000000000000000000000000a58c28598055d8818a6dbadd0018904386", - "0x0000000000000000000000000000000000152154cbc213630f5c7ec1ee37751b" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000f944590031f1d3b251c3dc90ea2821c71d", + "0x00000000000000000000000000000000000d31fd1a4942efade625e012c77df1", + "0x0000000000000000000000000000001e9acd89b92c18e3d89b881b26312bb12b", + "0x000000000000000000000000000000000000736f00a23cbea07da614d8b767e4", + "0x00000000000000000000000000000012167fb1f0d3b9afea7d534404e3b36b53", + "0x0000000000000000000000000000000000021e6d056d0d40c720927abd39c872", + "0x0000000000000000000000000000004ea3f0c21ee1056b3e2ad9c082242e5a2e", + "0x00000000000000000000000000000000000c574204fd079871ae599e192d72c8", + "0x0000000000000000000000000000002654c5b2b175f95fdb2ab405dcc4220545", + "0x00000000000000000000000000000000001fd13a35df71290c2354c6c5f610de", + "0x000000000000000000000000000000d5e3b3464d67c82f035b33016912264b04", + "0x000000000000000000000000000000000009fcdab45c12d2f313f95b94a1dcb8", + "0x000000000000000000000000000000768c5a9d8ca0081f67ff3171a7ffe3ba49", + "0x00000000000000000000000000000000001cd676b8d32bb0bb898d83a9f49a2b", + "0x00000000000000000000000000000028650bc3473de217fbfec1e9fb10e4e999", + "0x0000000000000000000000000000000000260c000ea0ebc3db3ba672328007a5", + "0x000000000000000000000000000000f1948fbf68599bf0628f118156de61f57f", + "0x00000000000000000000000000000000000033e796d200425f6a499de18dbfeb", + "0x00000000000000000000000000000016a35cf8fc5f017037adf860723e6346e5", + "0x0000000000000000000000000000000000088cf6d72197800bb1300677f734a7", + "0x00000000000000000000000000000047169c153b6cc24bbac1e4126410779ccb", + "0x000000000000000000000000000000000022b70bfb92e8c7944ae65a49b7effa", + "0x000000000000000000000000000000425c661c37104ad33c2054f3cfde9954d0", + "0x000000000000000000000000000000000000c36b8ecc5963bef022dea4dfadcc", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", + "0x000000000000000000000000000000862e0c485b99696417d296ecc2b2bac316", + "0x00000000000000000000000000000000000ae46fcce211297d2d7fcab27fc041", + "0x000000000000000000000000000000551700c158e12cb40d8ea4ef2563b6fb43", + "0x00000000000000000000000000000000000b515d88939b250a4a4758e4e2ea53", + "0x000000000000000000000000000000f4bae0ad0baeb9d42c7fe2ae3d18c98fad", + "0x00000000000000000000000000000000002a20d66bd435a17fdf1eaf345d5933", + "0x000000000000000000000000000000ed8a8ba528c7088b1ae4730572e1ec32c8", + "0x000000000000000000000000000000000009506de430d6b9f9863e6f10cd35fb", + "0x000000000000000000000000000000682b627744ce0319f4d9191675057282fb", + "0x000000000000000000000000000000000017de059961f8c12752abd299396f86", + "0x000000000000000000000000000000b975958ec262178729e94350c0e7543fb0", + "0x0000000000000000000000000000000000220ce50e394560e53f025e094d17aa", + "0x0000000000000000000000000000001fca3a68a28d438e85e9dc955856752779", + "0x000000000000000000000000000000000028f8f3400bb3b9d19b02ec709e2ee4", + "0x0000000000000000000000000000004e35d073460b0634ebe216d49a3dca9b36", + "0x00000000000000000000000000000000000cb0f5827b08075c405353f10ba632", + "0x0000000000000000000000000000001ece860550ce14fae74eda0123ded56a74", + "0x00000000000000000000000000000000000a34b258bd3daaf8f9edd201c25ed3", + "0x0000000000000000000000000000008cb28ae85d58a75302229585a9ad114c2b", + "0x000000000000000000000000000000000014aac1da344ad32659c3036510fcc1", + "0x000000000000000000000000000000822b45036d5c2befa8a20df910513570c4", + "0x000000000000000000000000000000000011244b388e709fbcb7f54658cfac43", + "0x000000000000000000000000000000389de9951eb8fad7e25e4ad0a9229d2275", + "0x0000000000000000000000000000000000136e6eb0ee251f9b12336cb7bb46ee", + "0x00000000000000000000000000000088f21d9f6c7c54ce4e9a4c103a91b54a58", + "0x0000000000000000000000000000000000187f2beab9a05ca29d2137ee7cbc19", + "0x0000000000000000000000000000009c703a5eb43dcef0686e08fa57ef452f68", + "0x000000000000000000000000000000000012caebb183f1490d3e4f2a2c583ab6", + "0x0000000000000000000000000000009dab4a0aa8d4954a8e1761db3da148a746", + "0x0000000000000000000000000000000000230a08da3b62fd6479b4230760b686", + "0x00000000000000000000000000000081a00a1e38bbd5212603f18ef982a5189d", + "0x000000000000000000000000000000000021ae0f9df38f1e70fa3c26867f4ee8", + "0x0000000000000000000000000000001a722dbd34f841b4823cd055149fce642f", + "0x000000000000000000000000000000000002df2693a9b134670cfe72bf29b363", + "0x00000000000000000000000000000007c906c328630b844b0797e34cedccd1ec", + "0x00000000000000000000000000000000002ab2ae39dd9c0259f7dfb1dda47e81", + "0x000000000000000000000000000000ac6642a4923aa2df07a00a9d3e462b0ed1", + "0x000000000000000000000000000000000015afb7af6c0fc23a24457aa887df9c", + "0x0000000000000000000000000000004d916ec23ef29c0b6134f208e3535671d4", + "0x00000000000000000000000000000000000d37c6c25852903d79475133d414e8", + "0x00000000000000000000000000000029ad212431ba1972de7ee0ba9f12113be3", + "0x000000000000000000000000000000000005c2393db23155844d4f71bead84d0", + "0x000000000000000000000000000000c69074efa82a4910eaf8ab8689d7aafcad", + "0x000000000000000000000000000000000029f3d77437006a0eacf1a149c4b8a0", + "0x00000000000000000000000000000030926853da69d4016eca2f1f0df5e5316f", + "0x000000000000000000000000000000000014841d3291aecd45ea0e05657dbed2", + "0x00000000000000000000000000000052fdb060fe666a3f686088f1f6996a1cf9", + "0x00000000000000000000000000000000002be878eb09939603b391aa9ee0393a", + "0x000000000000000000000000000000d99de3b49476e64c0138037838cfc63803", + "0x0000000000000000000000000000000000260874b43f32c373783efe7ef200a2", + "0x0000000000000000000000000000004951edbb25e9c6b65d446e3418b2b3f16e", + "0x00000000000000000000000000000000002300fac13ab48d40a91114d1ff9627", + "0x00000000000000000000000000000090b8d216da73861ee276dddb17428d8c09", + "0x000000000000000000000000000000000028f906106984e5fa78812869cc1aee", + "0x000000000000000000000000000000ce2aff6eda49d5b8be6ee42104d2aa21e0", + "0x000000000000000000000000000000000002833f671993d2b772b5dec0e12056", + "0x0000000000000000000000000000008be4e7cfb1fdf317a33b7bc3530625e6b8", + "0x000000000000000000000000000000000023404bed8e224a350755410e5c96b2", + "0x000000000000000000000000000000cd9a812fad3fe3a89983e416b70529445b", + "0x00000000000000000000000000000000000b66296ff191a2cf6dbe6ca03dcd0c", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003e895e3756deb16393c59a6a9d3669ce0f", + "0x0000000000000000000000000000000000262d7f27b9058ca9bd2e0620f9a3d3", + "0x000000000000000000000000000000b98c4ce00d755cb57daf4bc1b860536fc3", + "0x0000000000000000000000000000000000017137ecc6753555f49859a34eeb62" ] - hash = "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6" + hash = "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml index 4536a33189ef..110c6d4f6505 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml @@ -523,8 +523,8 @@ new_archive_sibling_path = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] @@ -604,10 +604,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x095ff6c475ee1af84257c77b73b727e6ebf0cc7015e0318ea5ceb14044e637a8", - "0x28810b36811d26c3700f0c7867fc191986df3ef57ea3a195b396ae8e1516b1a7", - "0x0d0d075374c48ade348ced65280060db0bfe6c16752688a5d65a07afc55cf16c", - "0x0b29f6eee3031f85d7f5ce02982c80e8fc06b552319a441c5b0fc3521d9c801c" + "0x019c8b37514a1a54433fb4ee411ccaf6da8c99234b4e5d11cc5f6b95c3989bb5", + "0x026875d420939d38c5495ee684f0a31efd5cab908193ae929d1c426d68bb9409", + "0x1a8c7e8add3b6e5ee547b84164a1d59756426ff82c71128c0627a7c01c830220", + "0x081d1fadf8d9a49f296a172486009b0c5f64d52de31142cfc01bc2b08387210a" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -615,134 +615,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" sibling_path = [ - "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000015", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x000000000000000000000000000000cd83c7ffbb8a401156e168f37116ffb187", - "0x000000000000000000000000000000000004c9803d25f3aa3d87971ec69e9a09", - "0x0000000000000000000000000000002b8e3b59ff58ee5825f04add8396938ab7", - "0x00000000000000000000000000000000000ca92b3e71dca284819687b09058a5", - "0x000000000000000000000000000000f13a4c94014267f0fb20df8d4745321157", - "0x0000000000000000000000000000000000228ccf8e5e66edf617fe9cdffaa9f3", - "0x0000000000000000000000000000008bedbc082dc889634e668f035d885cb110", - "0x000000000000000000000000000000000000d1506f1dee82696f1132266cd876", - "0x000000000000000000000000000000eed1511734ae738d49eddd8c477030de23", - "0x0000000000000000000000000000000000185f94db8b977ecb674f578da3d454", - "0x00000000000000000000000000000052efb8157e56280d78c004328b104e22ee", - "0x00000000000000000000000000000000001e61e2eda64fdcef0aa3f7086d25ae", - "0x000000000000000000000000000000a7ba8e154b7cb9b052f03b722d1fada3ab", - "0x00000000000000000000000000000000001b74f30f877fcb688c4d7942a512ea", - "0x000000000000000000000000000000a64cc9925a82d55b5c8ed69024e76a1002", - "0x0000000000000000000000000000000000051a307beab7624f895eac2d7b107e", - "0x000000000000000000000000000000b71a10e4cb199c53f8ab26f4b5750e6ff1", - "0x000000000000000000000000000000000026ae3964368b4d1a78b494281305a6", - "0x00000000000000000000000000000070e6d26eeb2ae247b554ade309575fc966", - "0x00000000000000000000000000000000001b72f55e4403556e86319b26bac156", - "0x0000000000000000000000000000008d27b4ec306af3043276b465679e8bd42f", - "0x0000000000000000000000000000000000235c5f58ac9d6dca390a516970b4b2", - "0x000000000000000000000000000000f9cc90e3b5b8897ba1b69b74148d74cfc5", - "0x00000000000000000000000000000000002b2e95de9addf042a25f2539a53d1e", - "0x0000000000000000000000000000004288fb745aa3b78da694bc2f3c28178b53", - "0x0000000000000000000000000000000000029292ff399aa7b20eb1f743696c46", - "0x0000000000000000000000000000003582186b8e684671a476f80b8d0e114d5d", - "0x00000000000000000000000000000000001b3109c18b36e49b5ef30578b4bc60", - "0x00000000000000000000000000000083d976f2c2c90d81da35771e3f1822b38f", - "0x000000000000000000000000000000000004e8a3defd811d412647bd93ce9086", - "0x000000000000000000000000000000c2c94de698986ec3786d6f5b13b0a476b4", - "0x000000000000000000000000000000000004d6d12b482b85c51eb055c92d5560", - "0x000000000000000000000000000000d9fb425aa4b440ae16c1b17731a6529ec7", - "0x0000000000000000000000000000000000009388e6b80710c3afdbff80db6e84", - "0x0000000000000000000000000000002775ccd14fc93fee7d75f048054b1cbcd7", - "0x000000000000000000000000000000000000142a9e45b6b4b0b28a54737e0901", - "0x000000000000000000000000000000d88146894fb0088baf74ad347a6fa92dde", - "0x0000000000000000000000000000000000019df6a3b49d4de18dbe387aac8372", - "0x0000000000000000000000000000001775a3327c99e192a79ee17db4e2c514e2", - "0x0000000000000000000000000000000000062b76de133a235165e878faa5619f", - "0x000000000000000000000000000000c8383897bcdda98939560cf15dfefd9c0b", - "0x00000000000000000000000000000000001b84d621bc2ee73d81ad2bd595f2a8", - "0x00000000000000000000000000000093ec3803f444457ef388287856eaccad0b", - "0x0000000000000000000000000000000000103b731d15612e1b8ac234c501b92d", - "0x000000000000000000000000000000d83455ed5536ab998435ffd929486967f5", - "0x00000000000000000000000000000000000870e19f1fc3e0921179828f3dd48b", - "0x0000000000000000000000000000008a0b19fe136076435faa22c077837f88bb", - "0x00000000000000000000000000000000000039184f52378de1cbba4a757335f4", - "0x00000000000000000000000000000019bba41ff000f1c9a2800dff26a0ba56ce", - "0x000000000000000000000000000000000012a445925f8b47a193556076199e49", - "0x0000000000000000000000000000005ba24d7fb287fc15134264f129609a2bd8", - "0x000000000000000000000000000000000007076816a94acb232f9ce3c1ae86f4", - "0x000000000000000000000000000000f85d9c960786d5542ee7fb2b2413a6d377", - "0x00000000000000000000000000000000001501ca79d9e60002f03f2b2b7b650a", - "0x000000000000000000000000000000af9fa7ef32ca1cb5f5abfbcc106009b7d9", - "0x00000000000000000000000000000000000a3631ac245c1bcbc41500fbe90c39", - "0x000000000000000000000000000000c20fa79072822cd75c97c5b81e20ca8378", - "0x00000000000000000000000000000000001c6e3d83b0c29f88cf55cb349764c7", - "0x00000000000000000000000000000094269c5b70a400d545ff6927eb4ff34d94", - "0x0000000000000000000000000000000000179a075c118abe5e19ec509b92c329", - "0x000000000000000000000000000000f7bf1c1f7d4dd3e707966c05f1d2cf0efa", - "0x00000000000000000000000000000000002dfb152b58a74c48565f0dba30108d", - "0x000000000000000000000000000000cc8f8c54c07a2909a5e4dd79a7fee3e9f9", - "0x0000000000000000000000000000000000111875cd09b6d83b8c85d81902de1d", - "0x00000000000000000000000000000067879f62b49d4ec18a05fc15c67e61c1f0", - "0x000000000000000000000000000000000007d113480afafd29d13ea18ad95bc2", - "0x000000000000000000000000000000ff6cd4cc6b0f04ecadac8b0370831197bc", - "0x00000000000000000000000000000000002cf71926c179ee1544ddcdef962d3b", - "0x00000000000000000000000000000011dac3e4f0a624a359d0577b6ad0c6a9ea", - "0x0000000000000000000000000000000000021c6d473c1f38d00361a916aa5c57", - "0x00000000000000000000000000000003b3480a0434d1d1f33e1c9f1a7d0cb25d", - "0x00000000000000000000000000000000002c5c8e4157e553f3188d193d1b9569", - "0x00000000000000000000000000000019b738d9ea76f9cb03a4bcdb7533944a36", - "0x00000000000000000000000000000000001c8f2968fe3967d675bdc3dd95ae45", - "0x00000000000000000000000000000081ead652a5562e48d2271eb63e0b53f517", - "0x00000000000000000000000000000000000252e44fb0d2cd6daafe79b8a7ce1f", - "0x0000000000000000000000000000008fa4d0b6af4adecb0c882b3550bf708e3a", - "0x0000000000000000000000000000000000026f63ebffc62201b820a594862e6c", - "0x000000000000000000000000000000a9e22eecb21492cfdd0820eddc2392ecad", - "0x0000000000000000000000000000000000100eff1372735728c7d857bbe751cd", - "0x00000000000000000000000000000098c24dca66ff39798ffef0819d63447c2b", - "0x0000000000000000000000000000000000117ee5d863045ed0f1f8a3268a44cd", - "0x000000000000000000000000000000c42efe335044bad810e4db5ca3a9a90b33", - "0x00000000000000000000000000000000001eea6c61e4ba0267d212d7d6a01fde", - "0x000000000000000000000000000000278bf3b77e15b280c8d91851ef86e22130", - "0x000000000000000000000000000000000007d1cb6e175db110b93183dc69610a", - "0x000000000000000000000000000000d7d26293651d377457c5f70fc897df4d02", - "0x00000000000000000000000000000000000ee609268fa9ca425545724809dec0", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000059f7a0ea97f63ad48cd0ace39569e0e2cf", - "0x0000000000000000000000000000000000104032af6f298e3ac85696d4973026", - "0x000000000000000000000000000000a4c46e1adb8515fa5ddcd4296d689f8e51", - "0x0000000000000000000000000000000000172a0575991ea836ef0e3040f33e6e" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x0000000000000000000000000000004a89413217aa26a02d1673611c718e3f40", + "0x00000000000000000000000000000000002a74011d7b1576ee63e514f36d2ca7", + "0x000000000000000000000000000000fc6ccc829e509138e5ecaf67c0a21ae3ea", + "0x000000000000000000000000000000000025ff9c29534f6fc12896ca920730a7", + "0x0000000000000000000000000000002709461b8a6badd93121132b357506ad42", + "0x000000000000000000000000000000000018979b97518955d80ea51e8795dd65", + "0x0000000000000000000000000000002086ceef11774f164dc1826039e29a08b2", + "0x000000000000000000000000000000000002706e4d78635695a83b8ee7fe2852", + "0x000000000000000000000000000000f48fa484144b68aabb48f3c67447f619c4", + "0x00000000000000000000000000000000002c00e7b78d2dbb440843c2b8bb9d5c", + "0x000000000000000000000000000000de8ddbcaefce22d2dd0f1a9cf8505ad74c", + "0x00000000000000000000000000000000001d75f1ae876350f117464d47581ea3", + "0x0000000000000000000000000000004bbb761087bee09db612cd1683c9991da0", + "0x00000000000000000000000000000000000a1f0b2bc8f3940a7767ca70f869dc", + "0x000000000000000000000000000000e4d6e66fe44086d4e95043082d7660511d", + "0x00000000000000000000000000000000002857e0d300379ee0a5657b0628ac68", + "0x000000000000000000000000000000377899dd24559db542bb2da421c7aa5b2e", + "0x00000000000000000000000000000000000f954842d0809f870031c014244349", + "0x0000000000000000000000000000004500fe7e27caadb3185ec74d1d8c9c23c6", + "0x000000000000000000000000000000000011e0156211bae38b72e70774aad837", + "0x000000000000000000000000000000d64abf570d80329272f3ac73e763a56074", + "0x00000000000000000000000000000000002221eb3028e13e02824a2cdbebb343", + "0x000000000000000000000000000000e6ac6ff13cde0a60ccaefe09ee9f6e4951", + "0x000000000000000000000000000000000000042f684a98fd028e51ed457fb6d2", + "0x000000000000000000000000000000b1795305b34f2f47e00fefef8e3ff03117", + "0x0000000000000000000000000000000000219d203b492d7debf5d8e7df9d2059", + "0x000000000000000000000000000000bfa96395c8478bacb512c36590c5b7b901", + "0x00000000000000000000000000000000001088537efb9ccd4bbaf4c519fb15ef", + "0x000000000000000000000000000000a63a7e103f77ddd62d4a2aca5a18595bc2", + "0x00000000000000000000000000000000000ffe27c096d9d37613d28524ee24bb", + "0x0000000000000000000000000000008b2aa8f75dabd90ee7f9d45da83109530f", + "0x000000000000000000000000000000000029197cfde9aa521758643b088ca6d9", + "0x0000000000000000000000000000000c60bc3c5493f56066aeaf379eff701730", + "0x0000000000000000000000000000000000045592a6815997cad253c4d4360857", + "0x000000000000000000000000000000fe9bb200d66804b00fe6af2cbd06b90be1", + "0x00000000000000000000000000000000002dfca6770dcd191d2cdcd25959b927", + "0x000000000000000000000000000000d638a6a9b28e4cda3be3200ca416f090a6", + "0x00000000000000000000000000000000002912073cf985c4e403f2e81c78f0c4", + "0x00000000000000000000000000000017b813b81461e0af074adb3ee3a06a2dbd", + "0x0000000000000000000000000000000000193d82b9851cb7b79be69631dbed9d", + "0x000000000000000000000000000000585192fdba2a34dfe3cf05bc74f14aa04b", + "0x000000000000000000000000000000000019c364971252aebd3f848754f68cc0", + "0x000000000000000000000000000000d6c225cba31833473b544e439b76525948", + "0x0000000000000000000000000000000000172a802a4ccf4f87a056c01096e603", + "0x0000000000000000000000000000008a86fac91395708a05f2bf567c42624355", + "0x00000000000000000000000000000000001c5122e5aa5acc0563a65f2fadb548", + "0x000000000000000000000000000000c7ba316af264f3d0c9ffdfa37abe8449af", + "0x00000000000000000000000000000000001e4e1e04112cc99e43eaa819700377", + "0x000000000000000000000000000000171f9151f102c97ebaf8155f92f2818ad4", + "0x00000000000000000000000000000000002b9c517d5a5ca458d9a42ae50a21e3", + "0x000000000000000000000000000000a9ab641f6b11aa7b449f9d162ee4b41c4a", + "0x0000000000000000000000000000000000083f917d6f05453ad4449a07cb2db9", + "0x0000000000000000000000000000000fd8ba5a6cbe569669fa504b146a11e1c2", + "0x00000000000000000000000000000000002d96c1b0fb6b92bbdf9028c918ab12", + "0x00000000000000000000000000000001b66bc49279fdcee016dc50f445385e2b", + "0x00000000000000000000000000000000002b27073221dc103e65d22ef60f7565", + "0x000000000000000000000000000000d9f07543a10843697cb26aeb1e0fa41864", + "0x00000000000000000000000000000000001af76ea4d294fd82e82426b2247091", + "0x000000000000000000000000000000c95c82ccbed1535404379be4d37b661a7b", + "0x000000000000000000000000000000000004c2eb0e09fa417808cf776e09d9bd", + "0x000000000000000000000000000000f7ecd4caac36af30f57c88f8aa8758994f", + "0x000000000000000000000000000000000007a8712e54abef6a5800fb6c9f797d", + "0x00000000000000000000000000000032261b0e19195842c9e13efbf6677d3e7b", + "0x00000000000000000000000000000000001a77dd002f088f48be1c495240a4f4", + "0x0000000000000000000000000000007a9784569003accf3b18631652c41efd9c", + "0x00000000000000000000000000000000001a3bc8c8561c039ee8dd33dcf97bfb", + "0x0000000000000000000000000000008a638165173e41c0baef2a580cca67198a", + "0x00000000000000000000000000000000000ecceac0ea7acc23801d0b99315ed8", + "0x0000000000000000000000000000009c864dd9c99b9871c3cfb939d4197834ef", + "0x0000000000000000000000000000000000131aac5ec5b228a425c6a1d954f41a", + "0x00000000000000000000000000000011cae94a9b789855cde56a72734268be61", + "0x000000000000000000000000000000000015c8120597f6b5302046b58b445198", + "0x00000000000000000000000000000058f4333384b72ecdfc0a66a3b34a9870b9", + "0x000000000000000000000000000000000013db543b79ebed9f63c95904240a6e", + "0x000000000000000000000000000000c71b7fdef4cdc241adcddb23c473ad222c", + "0x00000000000000000000000000000000001823079555cf386247dbe609c2fd06", + "0x000000000000000000000000000000e46930d371eafddab0c6053b1ae159c463", + "0x00000000000000000000000000000000000c0bc40e324750ba1c752c09daed25", + "0x000000000000000000000000000000137e3a04a63f70a2f6971ca99b7844dc67", + "0x000000000000000000000000000000000014c957a738079d071b3d181b99c0e7", + "0x000000000000000000000000000000815544c36c3b22a89d3a78b3553bec6f68", + "0x000000000000000000000000000000000009c2204fe3bd67f8872d6e75792d19", + "0x000000000000000000000000000000d3e085f947f7511f7d7f87a504e99f5546", + "0x00000000000000000000000000000000001d1e1a783d6fde70d844bc2c83c3ae", + "0x000000000000000000000000000000109b3d637fe0d1d5013b3710fc1cddf89f", + "0x000000000000000000000000000000000006101682027f56bffe9486a672801a", + "0x000000000000000000000000000000797993b995dba1e0e98de672a76a776c3f", + "0x00000000000000000000000000000000002765c3ceee9f9d0f11bd159621fa1e", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003ac18237da8d96caddaa1c49a178b8b47d", + "0x0000000000000000000000000000000000174dfd5c124039dc6e2a38f0f99775", + "0x0000000000000000000000000000005790969811e28ed4e16d2729036649f344", + "0x00000000000000000000000000000000000f9c6e462a5b03759c42538b9b7c36" ] - hash = "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56" + hash = "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa" [[inputs.previous_rollups]] proof = [ @@ -1235,8 +1235,8 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] @@ -1298,10 +1298,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x095ff6c475ee1af84257c77b73b727e6ebf0cc7015e0318ea5ceb14044e637a8", - "0x28810b36811d26c3700f0c7867fc191986df3ef57ea3a195b396ae8e1516b1a7", - "0x0d0d075374c48ade348ced65280060db0bfe6c16752688a5d65a07afc55cf16c", - "0x0b29f6eee3031f85d7f5ce02982c80e8fc06b552319a441c5b0fc3521d9c801c" + "0x019c8b37514a1a54433fb4ee411ccaf6da8c99234b4e5d11cc5f6b95c3989bb5", + "0x026875d420939d38c5495ee684f0a31efd5cab908193ae929d1c426d68bb9409", + "0x1a8c7e8add3b6e5ee547b84164a1d59756426ff82c71128c0627a7c01c830220", + "0x081d1fadf8d9a49f296a172486009b0c5f64d52de31142cfc01bc2b08387210a" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1316,10 +1316,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7f9d34d" ] state = [ - "0x23a9bf42f5fb21102f92950e5a129127b977ad0e0d8cc6f021b0fc620b733c63", - "0x04c04f44462b3c2c334fe3f7466d2202283eb1f9c7e8b4ee679f2942ef98b57a", - "0x1a1e433d1ede575233704d82d0e09b65957a4d70d9e9184fa3aee3879ef746f1", - "0x06f9428dc4495436f76a28564601d6e45f10a9db4334941163eeea845fdab3a8" + "0x05153cbf60a272f44025c5df22636b8efe554dad1522a47a40dd5b3441326171", + "0x23fd331bfec83c48528be67bfbea84585a5f6d5b5528c5f030c222fc26331f3f", + "0x04c2cf5ad5cc66f41b327d1a4cd4bb4bc6006cc48ccda31a9bb943c40cfe4137", + "0x05df9fe44f2dd2bc21e2883077c78aed05e35c3b27b4acaf603aa29e7e17ea82" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false @@ -1327,131 +1327,131 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000008580b9a8c85e4a3c1e7b1089bd79f3bc28", - "0x000000000000000000000000000000000022dc01e3ed0e1b10bdcff9d093431a", - "0x00000000000000000000000000000054f9950035e8ffae852707e9d1a9032e59", - "0x0000000000000000000000000000000000276c56cb94e0545b3bfd85919a8ce8", - "0x0000000000000000000000000000009352ff9d82645804416a2b338260fa235d", - "0x000000000000000000000000000000000010a253776d2bdcb7129acfa2e91ac5", - "0x00000000000000000000000000000095babbbc4a6d5a9b68707c3a8e1e9508e2", - "0x000000000000000000000000000000000030157ca77e90f7ee9155c1009b06a1", - "0x000000000000000000000000000000068047e82e283284235befaa9cc7a1838d", - "0x00000000000000000000000000000000000bcd70cc5042e81e440b1ea5ef3c3f", - "0x0000000000000000000000000000007702a95c1bf5e2923ca69f26cc2d7efe0f", - "0x00000000000000000000000000000000000adeb0e8b1074c68de2b2172f21c5e", - "0x000000000000000000000000000000520354133ccbbccfc69be0c01b92abdf0f", - "0x00000000000000000000000000000000002dea248e3c2fe054c698a861bf4c27", - "0x000000000000000000000000000000f93b6112b7de5c27298a81c68d502b7beb", - "0x00000000000000000000000000000000002be3a33fc9502b0cc8b9427fcfe50f", - "0x000000000000000000000000000000168f01ff83f4a014a90db19e5d882a0a0a", - "0x000000000000000000000000000000000008876edc3cc7e3825dc194e21cb011", - "0x0000000000000000000000000000006d1df389f06e514e1829af3744dc64294a", - "0x000000000000000000000000000000000022e86ef68622bd107e5080cc062a4f", - "0x000000000000000000000000000000d137fc89e86049cb1b141b67b3361b6298", - "0x00000000000000000000000000000000001d7ad7d0634dc08d7d9816b5b6814c", - "0x000000000000000000000000000000defd2454e2c3a75ec8e0730bd3640b9408", - "0x00000000000000000000000000000000000b189f6ee9395b1ca5771c361501d7", - "0x00000000000000000000000000000001fccf755f5b30a7d544b2f78ce075cb5d", - "0x000000000000000000000000000000000026f5423942948047e155a519b195e8", - "0x000000000000000000000000000000a9efc76daffb8dfe2a39570b2d5d046767", - "0x000000000000000000000000000000000026e7dd89fe96952a4603c2b5555538", - "0x00000000000000000000000000000008262b430328dcaab242dd8acc504e8ac9", - "0x000000000000000000000000000000000015f3ab1410f0e5dd3e00f03b9f563b", - "0x0000000000000000000000000000008fca5ff8ed9a5d41fe9b451f02502dd1c9", - "0x0000000000000000000000000000000000266aa6e4947434ef18adeba3700713", - "0x000000000000000000000000000000d93cecd04341f5da304f3c92f0670afc43", - "0x000000000000000000000000000000000020165b3fd2bfb72a4de3dc68f66eed", - "0x000000000000000000000000000000094a6d376eb3cc1ba94b4da00dea583eac", - "0x00000000000000000000000000000000001caf7742d251b04f3517f0f1e5a625", - "0x0000000000000000000000000000003be5647cd472ad0b06a48f632997e3eea2", - "0x000000000000000000000000000000000015fb4d9ecb8125b3243cee37698c48", - "0x0000000000000000000000000000000854a3ab5bcbca1e86d4949b1b7c5f4b0e", - "0x000000000000000000000000000000000015450314fbf315448dc3379dc82214", - "0x0000000000000000000000000000009c2c55d2ea5bdf5fc5e28f1a78b1d29625", - "0x000000000000000000000000000000000020b36a8406ec64352600587cf04194", - "0x000000000000000000000000000000f14d08d9dab6a54412d741166146188ae6", - "0x00000000000000000000000000000000001b5a34ccd7eaf5cd09ab920011552f", - "0x00000000000000000000000000000074b7827a59faf701f7f41df26e5476c40c", - "0x00000000000000000000000000000000002decbab1c87b933da1625951860793", - "0x000000000000000000000000000000751aab48a0e01094128242ea0aaab63ff7", - "0x00000000000000000000000000000000001a2a334289adf8d23d4d52caf4cfe6", - "0x000000000000000000000000000000f6a41261290460b25e1e7d7bf69b564ae6", - "0x00000000000000000000000000000000000296925feaed4585bb03319f126d96", - "0x00000000000000000000000000000055b70d653ebd7df04f720951e76a27369b", - "0x000000000000000000000000000000000019744937a687edc9f46fb8323a46d9", - "0x00000000000000000000000000000047978fda5b64d8fc4571f09da3e8ccc7de", - "0x0000000000000000000000000000000000139de6a387109f47ecbacc74e03742", - "0x0000000000000000000000000000007f5afdfcb7bcd85aa293676e18e899a03e", - "0x000000000000000000000000000000000006a2971c1c947f4cadb07ebc9bc980", - "0x0000000000000000000000000000006cdb69a57b7f7a25b99e18fc0f83c1bc70", - "0x000000000000000000000000000000000028f2a76a01dc3cc927cdba29383e9b", - "0x0000000000000000000000000000001bbc4d6033de44907975ce473bc0f4f148", - "0x00000000000000000000000000000000002642f26fc1850c4b9b7fc4cd860ab9", - "0x000000000000000000000000000000ac996074e35eb268f6ebbe99e9c7d26c47", - "0x00000000000000000000000000000000002262620617978a01f75646f1909969", - "0x000000000000000000000000000000e63aa32bcc098428f407b5e07d9cb26118", - "0x000000000000000000000000000000000022b294b6a7dc4c17319f9a91a1b443", - "0x000000000000000000000000000000649d9ce9147431632893f55d3c6bbc158e", - "0x000000000000000000000000000000000020698c9b0787f14aa66a57bc232ec1", - "0x000000000000000000000000000000b4fde29f9bde909609d70bf9862dd65cf1", - "0x000000000000000000000000000000000005fcac9b75cac50d87ca827678c070", - "0x00000000000000000000000000000071e27b0a0dd0e2180985072f4a949f0c1d", - "0x000000000000000000000000000000000025d2d1388eddcf016213f1cadc763f", - "0x000000000000000000000000000000b216bad715cdfa7c382d30d7a368cc1346", - "0x0000000000000000000000000000000000302dbbf78b13a6d71d1978b5607145", - "0x00000000000000000000000000000002ebdec49969d2ff9220240bbcb8730617", - "0x000000000000000000000000000000000027f41cad8540e47008c1da90340ef6", - "0x000000000000000000000000000000e8259148321315cc34166a206fe910c6cb", - "0x000000000000000000000000000000000013444efc30c7688d961f36de252af6", - "0x0000000000000000000000000000005b7c7ad432291e9dff1dfad51159e50dbf", - "0x0000000000000000000000000000000000205ec973a0d1c898c1def7852353b3", - "0x0000000000000000000000000000007940a7e88fe5ce47af688975c92be1b62a", - "0x000000000000000000000000000000000015bdab44fe41eec6ee62ed58f55ff5", - "0x0000000000000000000000000000003693b90aedcd664eede665df6f376cf526", - "0x0000000000000000000000000000000000207c38fd6851d1568fe18a83585f31", - "0x000000000000000000000000000000f1a8a60975b9b092aab1421166be08c2f5", - "0x000000000000000000000000000000000015450d2e8ea17db209302582b886f1", - "0x000000000000000000000000000000526e857040a344bd434bfdbf94d3a49196", - "0x00000000000000000000000000000000000d0112b922a852c4754ab3929d6d02", - "0x000000000000000000000000000000d88041fa28c8118a58ceacbcc8780844b5", - "0x00000000000000000000000000000000002584170ebef150b71c5e6aa93e2fbb", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a2c4fbcbebac01e208127093cbf44780d4", - "0x00000000000000000000000000000000001ca34545a074b1cb689aa0b343402d", - "0x000000000000000000000000000000a58c28598055d8818a6dbadd0018904386", - "0x0000000000000000000000000000000000152154cbc213630f5c7ec1ee37751b" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000f944590031f1d3b251c3dc90ea2821c71d", + "0x00000000000000000000000000000000000d31fd1a4942efade625e012c77df1", + "0x0000000000000000000000000000001e9acd89b92c18e3d89b881b26312bb12b", + "0x000000000000000000000000000000000000736f00a23cbea07da614d8b767e4", + "0x00000000000000000000000000000012167fb1f0d3b9afea7d534404e3b36b53", + "0x0000000000000000000000000000000000021e6d056d0d40c720927abd39c872", + "0x0000000000000000000000000000004ea3f0c21ee1056b3e2ad9c082242e5a2e", + "0x00000000000000000000000000000000000c574204fd079871ae599e192d72c8", + "0x0000000000000000000000000000002654c5b2b175f95fdb2ab405dcc4220545", + "0x00000000000000000000000000000000001fd13a35df71290c2354c6c5f610de", + "0x000000000000000000000000000000d5e3b3464d67c82f035b33016912264b04", + "0x000000000000000000000000000000000009fcdab45c12d2f313f95b94a1dcb8", + "0x000000000000000000000000000000768c5a9d8ca0081f67ff3171a7ffe3ba49", + "0x00000000000000000000000000000000001cd676b8d32bb0bb898d83a9f49a2b", + "0x00000000000000000000000000000028650bc3473de217fbfec1e9fb10e4e999", + "0x0000000000000000000000000000000000260c000ea0ebc3db3ba672328007a5", + "0x000000000000000000000000000000f1948fbf68599bf0628f118156de61f57f", + "0x00000000000000000000000000000000000033e796d200425f6a499de18dbfeb", + "0x00000000000000000000000000000016a35cf8fc5f017037adf860723e6346e5", + "0x0000000000000000000000000000000000088cf6d72197800bb1300677f734a7", + "0x00000000000000000000000000000047169c153b6cc24bbac1e4126410779ccb", + "0x000000000000000000000000000000000022b70bfb92e8c7944ae65a49b7effa", + "0x000000000000000000000000000000425c661c37104ad33c2054f3cfde9954d0", + "0x000000000000000000000000000000000000c36b8ecc5963bef022dea4dfadcc", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", + "0x000000000000000000000000000000862e0c485b99696417d296ecc2b2bac316", + "0x00000000000000000000000000000000000ae46fcce211297d2d7fcab27fc041", + "0x000000000000000000000000000000551700c158e12cb40d8ea4ef2563b6fb43", + "0x00000000000000000000000000000000000b515d88939b250a4a4758e4e2ea53", + "0x000000000000000000000000000000f4bae0ad0baeb9d42c7fe2ae3d18c98fad", + "0x00000000000000000000000000000000002a20d66bd435a17fdf1eaf345d5933", + "0x000000000000000000000000000000ed8a8ba528c7088b1ae4730572e1ec32c8", + "0x000000000000000000000000000000000009506de430d6b9f9863e6f10cd35fb", + "0x000000000000000000000000000000682b627744ce0319f4d9191675057282fb", + "0x000000000000000000000000000000000017de059961f8c12752abd299396f86", + "0x000000000000000000000000000000b975958ec262178729e94350c0e7543fb0", + "0x0000000000000000000000000000000000220ce50e394560e53f025e094d17aa", + "0x0000000000000000000000000000001fca3a68a28d438e85e9dc955856752779", + "0x000000000000000000000000000000000028f8f3400bb3b9d19b02ec709e2ee4", + "0x0000000000000000000000000000004e35d073460b0634ebe216d49a3dca9b36", + "0x00000000000000000000000000000000000cb0f5827b08075c405353f10ba632", + "0x0000000000000000000000000000001ece860550ce14fae74eda0123ded56a74", + "0x00000000000000000000000000000000000a34b258bd3daaf8f9edd201c25ed3", + "0x0000000000000000000000000000008cb28ae85d58a75302229585a9ad114c2b", + "0x000000000000000000000000000000000014aac1da344ad32659c3036510fcc1", + "0x000000000000000000000000000000822b45036d5c2befa8a20df910513570c4", + "0x000000000000000000000000000000000011244b388e709fbcb7f54658cfac43", + "0x000000000000000000000000000000389de9951eb8fad7e25e4ad0a9229d2275", + "0x0000000000000000000000000000000000136e6eb0ee251f9b12336cb7bb46ee", + "0x00000000000000000000000000000088f21d9f6c7c54ce4e9a4c103a91b54a58", + "0x0000000000000000000000000000000000187f2beab9a05ca29d2137ee7cbc19", + "0x0000000000000000000000000000009c703a5eb43dcef0686e08fa57ef452f68", + "0x000000000000000000000000000000000012caebb183f1490d3e4f2a2c583ab6", + "0x0000000000000000000000000000009dab4a0aa8d4954a8e1761db3da148a746", + "0x0000000000000000000000000000000000230a08da3b62fd6479b4230760b686", + "0x00000000000000000000000000000081a00a1e38bbd5212603f18ef982a5189d", + "0x000000000000000000000000000000000021ae0f9df38f1e70fa3c26867f4ee8", + "0x0000000000000000000000000000001a722dbd34f841b4823cd055149fce642f", + "0x000000000000000000000000000000000002df2693a9b134670cfe72bf29b363", + "0x00000000000000000000000000000007c906c328630b844b0797e34cedccd1ec", + "0x00000000000000000000000000000000002ab2ae39dd9c0259f7dfb1dda47e81", + "0x000000000000000000000000000000ac6642a4923aa2df07a00a9d3e462b0ed1", + "0x000000000000000000000000000000000015afb7af6c0fc23a24457aa887df9c", + "0x0000000000000000000000000000004d916ec23ef29c0b6134f208e3535671d4", + "0x00000000000000000000000000000000000d37c6c25852903d79475133d414e8", + "0x00000000000000000000000000000029ad212431ba1972de7ee0ba9f12113be3", + "0x000000000000000000000000000000000005c2393db23155844d4f71bead84d0", + "0x000000000000000000000000000000c69074efa82a4910eaf8ab8689d7aafcad", + "0x000000000000000000000000000000000029f3d77437006a0eacf1a149c4b8a0", + "0x00000000000000000000000000000030926853da69d4016eca2f1f0df5e5316f", + "0x000000000000000000000000000000000014841d3291aecd45ea0e05657dbed2", + "0x00000000000000000000000000000052fdb060fe666a3f686088f1f6996a1cf9", + "0x00000000000000000000000000000000002be878eb09939603b391aa9ee0393a", + "0x000000000000000000000000000000d99de3b49476e64c0138037838cfc63803", + "0x0000000000000000000000000000000000260874b43f32c373783efe7ef200a2", + "0x0000000000000000000000000000004951edbb25e9c6b65d446e3418b2b3f16e", + "0x00000000000000000000000000000000002300fac13ab48d40a91114d1ff9627", + "0x00000000000000000000000000000090b8d216da73861ee276dddb17428d8c09", + "0x000000000000000000000000000000000028f906106984e5fa78812869cc1aee", + "0x000000000000000000000000000000ce2aff6eda49d5b8be6ee42104d2aa21e0", + "0x000000000000000000000000000000000002833f671993d2b772b5dec0e12056", + "0x0000000000000000000000000000008be4e7cfb1fdf317a33b7bc3530625e6b8", + "0x000000000000000000000000000000000023404bed8e224a350755410e5c96b2", + "0x000000000000000000000000000000cd9a812fad3fe3a89983e416b70529445b", + "0x00000000000000000000000000000000000b66296ff191a2cf6dbe6ca03dcd0c", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003e895e3756deb16393c59a6a9d3669ce0f", + "0x0000000000000000000000000000000000262d7f27b9058ca9bd2e0620f9a3d3", + "0x000000000000000000000000000000b98c4ce00d755cb57daf4bc1b860536fc3", + "0x0000000000000000000000000000000000017137ecc6753555f49859a34eeb62" ] - hash = "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6" + hash = "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml index 28d9ad79f9c8..e1c95dc4ee1c 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml @@ -484,7 +484,7 @@ proof = [ [inputs.previous_rollups.public_inputs] checkpoint_header_hashes = [ - "0x004d16fb29611dba53004101a433c88fddade0ec60446fddec1589851839a774", + "0x00ba58769fa3e9ec12fd9ab7b264fe69545833f8e7d80571d73ab23a5fc0d4a1", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -520,32 +520,32 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x00f30d99838de8d9e0b40bb5f19c53ebd2cea2e4e324a6b48a4db2655906ad63" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" + root = "0x1bd8fa52c473ccd76cdfd70179aff3b4c59093d598a639557ae1b8798c7c9c4e" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" [inputs.previous_rollups.public_inputs.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.new_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x000000000000000000000000000000000000000000000000003b2f97f0a76c80" + value = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -734,53 +734,53 @@ proof = [ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator] - blob_commitments_hash_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" - z_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" - gamma_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" + blob_commitments_hash_acc = "0x00d6847a188b930077a3101f4aa9101df879af2f4ba3d98192671bdff91d365a" + z_acc = "0x09fadf698f44ed60ef99f4cf1f02a5e4bae20ab2c777ef2f262312e4179af8b2" + gamma_acc = "0x152ea6722a0d24ee928218d153639be747e005105bbf45f366483a8f794fccf3" [inputs.previous_rollups.public_inputs.start_blob_accumulator.y_acc] limbs = [ - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x0000" + "0xf062c57de642dd9de6651787c3e335", + "0x7abcb3fd85a05e708716a7399c23b4", + "0x5ff7" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc] - is_infinity = true + is_infinity = false [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.x] limbs = [ - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x000000" + "0xeee029bf7b2bda4e9568e610dc676f", + "0x4a5f26a53b04bf523a03022d2ba283", + "0x916569ab4bdfdfdd5e50b597c6e454", + "0x019f18" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.y] limbs = [ - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x000000" + "0x238f6e09e67017cc5605af0151d6a2", + "0x568c3f78402057433fea52201c6c49", + "0x1608271b45acc1124b7031b1521278", + "0x03e3f3" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0x000000000000000000000000000000", - "0x000000000000000000000000000000", - "0x0000" + "0x7e03f0fd5d9259ec22f5a878b085a2", + "0x43f338bf8a80477fe9e51ec48ae296", + "0x624b" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00c6080f82da97cd32a6e6f96167937982d1b1d102f2670358d457217207a2a5" - z_acc = "0x1ff8cc937c58f2d72966f69b2e490b6dc7f6704680430ac91ea6c0e6207d4d96" - gamma_acc = "0x1684547681775fced98c96d09e82919f729d14549da6323b669a8512c9b3802e" + blob_commitments_hash_acc = "0x0033179ae5491de60cb7cb226671c0f9cea4921f3cacc19438be4d3faa3197c5" + z_acc = "0x293660ab12ef78b885259a67870ffda82b66285965582c47c2568e27fc16f0a4" + gamma_acc = "0x28353ccf291c3c96b0582bf7464325c8322a026d8cf818681b5adb4350148614" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0xd2054ab1639ea442bd23a5b1c57cf5", - "0x4b6135801975f6ab44b107b0a1e000", - "0x677b" + "0xb102ba7ec86991ae3ba7b2d12b0dc6", + "0xd76e5f1b5af021a20c74cbcd8aad8f", + "0x5d37" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -788,35 +788,35 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0xca945aeef9c954013ca54795553295", - "0x9c13e59f13d27ea1d0bbfde41965a9", - "0xf7f9f09f06a5e9f04fb45ab0edb363", - "0x18f7d5" + "0xc579f953d8a89a0c706ffb2abe948f", + "0xbaefc069fa51d7500378d3edc07995", + "0x0f70c87301439b44c18917db9913ab", + "0x087104" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xb04ef08577b05403570538b51898a0", - "0x2797dcc9fb92375446462d46b4ccbb", - "0x39156e19c6155c4ef0f97030dc5d90", - "0x0ad01d" + "0xd131744519d494f5e8f56689d4443c", + "0xbe7390d50563da363e58d775d860a7", + "0x17eff8005836b5a6ba962eedafff26", + "0x09fbda" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x6579a521845bb572269ce72673d0ad", + "0x8e766c234f30ecffc5afead1a0488c", + "0x308b" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.previous_rollups.vk_data] @@ -824,11 +824,11 @@ proof = [ sibling_path = [ "0x1edc2329182e13c58f5ced1e4ca120ba845e074e81d59ee64d0bbd583ecdd429", "0x1f502972a4bdd0353e082932afca85331d93e89c99ab3a78511939c18eb14641", - "0x1f0a3ab28f16510e4f9a5682a8b5f2826f55082cd639c6b76e6e970d8bb4224d", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x18e6586768e6bcc980c4756fb8e50dc355a096b22c3088284883e77065a2dfd0", + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] @@ -1437,7 +1437,7 @@ proof = [ [inputs.previous_rollups.public_inputs] checkpoint_header_hashes = [ - "0x00db58820ef17b4cb952c006ed78296097c3fcf7fd0fc3e3cec1f8260fc64045", + "0x008fb5a2af014eed924e6550a1a568a936137e0ae9596268bdd3a5e228642d41", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1473,32 +1473,32 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" + root = "0x1bd8fa52c473ccd76cdfd70179aff3b4c59093d598a639557ae1b8798c7c9c4e" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.new_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000d0f074eda98980" + value = "0x000000000000000000000000000000000000000000000000003b2f97f0a76c80" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1687,15 +1687,15 @@ proof = [ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator] - blob_commitments_hash_acc = "0x00c6080f82da97cd32a6e6f96167937982d1b1d102f2670358d457217207a2a5" - z_acc = "0x1ff8cc937c58f2d72966f69b2e490b6dc7f6704680430ac91ea6c0e6207d4d96" - gamma_acc = "0x1684547681775fced98c96d09e82919f729d14549da6323b669a8512c9b3802e" + blob_commitments_hash_acc = "0x0033179ae5491de60cb7cb226671c0f9cea4921f3cacc19438be4d3faa3197c5" + z_acc = "0x293660ab12ef78b885259a67870ffda82b66285965582c47c2568e27fc16f0a4" + gamma_acc = "0x28353ccf291c3c96b0582bf7464325c8322a026d8cf818681b5adb4350148614" [inputs.previous_rollups.public_inputs.start_blob_accumulator.y_acc] limbs = [ - "0xd2054ab1639ea442bd23a5b1c57cf5", - "0x4b6135801975f6ab44b107b0a1e000", - "0x677b" + "0xb102ba7ec86991ae3ba7b2d12b0dc6", + "0xd76e5f1b5af021a20c74cbcd8aad8f", + "0x5d37" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc] @@ -1703,37 +1703,37 @@ proof = [ [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.x] limbs = [ - "0xca945aeef9c954013ca54795553295", - "0x9c13e59f13d27ea1d0bbfde41965a9", - "0xf7f9f09f06a5e9f04fb45ab0edb363", - "0x18f7d5" + "0xc579f953d8a89a0c706ffb2abe948f", + "0xbaefc069fa51d7500378d3edc07995", + "0x0f70c87301439b44c18917db9913ab", + "0x087104" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.y] limbs = [ - "0xb04ef08577b05403570538b51898a0", - "0x2797dcc9fb92375446462d46b4ccbb", - "0x39156e19c6155c4ef0f97030dc5d90", - "0x0ad01d" + "0xd131744519d494f5e8f56689d4443c", + "0xbe7390d50563da363e58d775d860a7", + "0x17eff8005836b5a6ba962eedafff26", + "0x09fbda" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x6579a521845bb572269ce72673d0ad", + "0x8e766c234f30ecffc5afead1a0488c", + "0x308b" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00ff28bea8c07e7b060d248cb2071f813aa6e39e07e3a527c1739e6a7793c093" - z_acc = "0x11b2ee0dde26d315a246f5bdc01db8abe8200c6581201debd1cffc51ad26f95d" - gamma_acc = "0x152f389c138d41dde799d4f4fc748753332ddcd5bcd19fe35e4fbe60581534c2" + blob_commitments_hash_acc = "0x00996b577cb6f53aa9d5d22026fa7e7ed5a2a8976186df5414ed93231113a1b3" + z_acc = "0x04b51a58745a148f28f5c26a2d502c8001354179837d098e3af3955de34bf714" + gamma_acc = "0x1bfd4f0bfbabe502f62a2825f8fbc6b52df23371928e6422797997084279f299" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0x4183756e36181f92164c36776c2ba3", - "0xaff710205b13b83794ee63e35bb424", - "0x411e" + "0x0194e1d1e3be1d6f12d6eeb0e18311", + "0x447972f46deb3eff934723afb8d8de", + "0x2435" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -1741,35 +1741,35 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0x6e2f87b978f4bca529d7ad90a41cd8", - "0x734aa1582c8aee32f8334cfc594ab0", - "0x21aa57d7e1012415e25e37ee62bbcb", - "0x015e58" + "0x5e7c6caafcf94afa0766159ff528a4", + "0xecf78cbd1e0c5335e42da88a421390", + "0x39fa11170a3706ed93d37f65f0f7a4", + "0x169dc0" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xd8e530734ccb89f49a545e13ead68c", - "0x914523b3ef75387e032ac9fef36157", - "0x5342c94a6ba1df16b871173b323290", - "0x1604f8" + "0xb6ad8a240910f66dd9deea18fb02f5", + "0x7abb241ff936e62fe95dba9efaca7a", + "0x2a5bfb0a073fe526435c3e8bfedbae", + "0x125deb" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xc0250cc6b8725b2b00687dab94d327", - "0xd7f65a721538376d885811c9aafe6f", - "0x297f" + "0xc962ef153772fa92ab05d6d4de0b69", + "0xc842f223fc7445950dc69c40c23ee4", + "0x05a5" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.previous_rollups.vk_data] @@ -1777,11 +1777,11 @@ proof = [ sibling_path = [ "0x1edc2329182e13c58f5ced1e4ca120ba845e074e81d59ee64d0bbd583ecdd429", "0x1f502972a4bdd0353e082932afca85331d93e89c99ab3a78511939c18eb14641", - "0x1f0a3ab28f16510e4f9a5682a8b5f2826f55082cd639c6b76e6e970d8bb4224d", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x18e6586768e6bcc980c4756fb8e50dc355a096b22c3088284883e77065a2dfd0", + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml index d140961b168f..4082395687cc 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml @@ -483,70 +483,70 @@ proof = [ ] [inputs.previous_rollup.public_inputs] - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde108" - block_headers_hash = "0x04c025c44ceb642aa54659bf652c91b00ccb432f9837ec84c1c282e567c223fc" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2d77" + block_headers_hash = "0x09ae38c4bdd7cdbfee06b35cc61272ed229c502820948e040a4acf7081f149e0" in_hash = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x0000000000000000000000000000000000000000000000000022e452ad469ea0" - accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + accumulated_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" [inputs.previous_rollup.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000043" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" [inputs.previous_rollup.public_inputs.constants.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.previous_rollup.public_inputs.constants.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000003699e8ba0" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" [inputs.previous_rollup.public_inputs.previous_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" + root = "0x2d7278322ae3f2f02196f7b5eb323c037067b5a8bb27bb36e5936e01618b922e" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" [inputs.previous_rollup.public_inputs.new_archive] - root = "0x0f84849714aa969caef587fe17273c9fae12f846c68db0f1ab092faf93a29145" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000c" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [inputs.previous_rollup.public_inputs.start_state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001c00" [inputs.previous_rollup.public_inputs.start_state.partial.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" [inputs.previous_rollup.public_inputs.start_state.partial.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x0c877a1bf89b9eae6a04511e6f74bfaa71157ae9e20aa265ec7fb092914f6726" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [inputs.previous_rollup.public_inputs.start_state.partial.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x21c0735ecdd66391ddb7fff9448a7973f1b8b4399648b1a150afb92d3a0d0ff5" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.end_state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" [inputs.previous_rollup.public_inputs.end_state.partial.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [inputs.previous_rollup.public_inputs.end_state.partial.nullifier_tree] -root = "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" +root = "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.previous_rollup.public_inputs.end_state.partial.public_data_tree] -root = "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -567,33 +567,33 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollup.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000011" + num_absorbed_fields = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.previous_rollup.public_inputs.end_sponge_blob.sponge] cache = [ - "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b", - "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a", - "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1" + "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe", + "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0", + "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" ] state = [ - "0x0e1dd9cced5f0826c6e4058004b9cb3a696b39c148c0354124d03d9ed9b4ef46", - "0x0e88efccb1b5effd0110855538123edbbdb2e94b791607a00b954bece2a9bfc9", - "0x1957ffd20204e64443fb09410f7b76cfb098ff3becc10b9e08208fad4d4b03cb", - "0x0c822003a2f7fd4b344c8b039a0d20ff579eed35b7d7e49c8d2fbda1d2e1560c" + "0x294da480f532f9cf8882572adfb599fcea5cf5e13bd97e903a0edbc71bc098e1", + "0x04a930a66e3a346e476c659793e6fee319f3cd0b2657de9fe293ceeb8e105ff6", + "0x203d216c6dd630eba962b8072458bedf7d9a44841805fd481883662fe854327a", + "0x095b497103f425dbb2d5d2fc815c146b922f8b615a25957df526930cea50a313" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollup.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" sibling_path = [ "0x1276688c1c8f1024c963d35957328b73153c55580532254f0676c26e2ad55993", - "0x1025a6a71839d2ab10e9652312547fd6944d80234a52379f6a944c2500ebc294", + "0x086165748e62548024cf40b2812afa99e17d1b248dc89861b56485995305a5ca", "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", - "0x099ef6a9a40aaf85e056bda90684adf858addbb90af303d82f8157b86b705b92", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x24cead94db344ae1716301e94784822099e114c4deaddb78f16e8724ee376aaa", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollup.vk_data.vk] @@ -718,10 +718,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints] previous_archive_sibling_path = [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x1cfdc3f191fd4278971f73de8ee4302bd29051bb0c93c1ba7a8a7feaa4e59846", - "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x021ec3586514f8c888aa40f75e3da945b1504d409908f520f3e65c85b552495b", + "0x304d599cf4ed52817a3206c05651477614f9456baa967427479e1f1c475e1e2d", + "0x150ab49c0bdc816db61f65db0c30c6c26aaf7ad56f042affb9fe006aa795a971", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -757,145 +757,145 @@ new_out_hash_sibling_path = [ "0x00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c" ] blobs_fields = [ - "0x00000000009c707518000000010000000300000000000000000000000000000a", - "0x2ca391890a7afa0a4098cceb64d9aa356e84a1055e6e2b3df10e2a5033f0b691", - "0x0000000000000000000000000000000000000000000000000022e452ad469ea0", - "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef", - "0x2935995b8343928a25acdb09654bdc27aeef345ec185caa48fb0048bd475fbcb", - "0x0000000000000000000000000000000000000000000000000000000000001c20", - "0x0dc02e099550676b3dcfd522010d4db9d2c47a4556dfa28aa20a4a0eb35c54a4", - "0x0000000000000000000000000000000000000000000000000000000000000af0", - "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3", - "0x00000000000000000000000000000000000000000000021e00afaeb15ed67ca0", - "0x0000000000000000000000000000eb8dcdbf0000000069fde1080000000b0001", - "0x000000000000000002c0000000000d0000000003c0000000008b0000000a3979", - "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1", - "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f", - "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1", - "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b", - "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a", - "0x0000000000000000000000000000000000000000000000008c63744300000012", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000009c70751800000003000000010001000d00000000006c0000000083", + "0x0590b52cd0b0945171050227160d7339dec3eb41a5be14a84d97c17d2bc80ff1", + "0x00000000000000000000000000000000000000000000000002449f1e83b9af00", + "0x13876606079602e1a9f3118b3d14ccd36b2b01915abc971c97eaaf1ad6032a7f", + "0x273617117fe26c8b346c634f743b8d215d0d188fa290d3e3283106fb06d380f1", + "0x1bdad00a23307084c2c182515aeda85e0139ca1eb438836ae93c331dd90e6e7d", + "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969", + "0x00000000000000000000000000000000000000000000021e0219674fdaa32380", + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a8", + "0x09d3e27b2b71e2140366b7b610129b819b841efe0dc06bf715e3eb5b68f65571", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0ced49df8bad805ad50a3b054eb121748b0c4343ea4451686bfeba125dc7e294", + "0x252ec1d53f8683ece6631cefb05fb44afc9ed830f13e8f8e68f7c94210f02eb9", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", + "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", + "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", + "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", + "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", + "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2", + "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x20f5895a4e837356c2d551743df6bf642756dcd93cd31cbd37c556c90bf7f244", + "0x252ec1d53f8683ece6631cefb05fb44afc9ed830f13e8f8e68f7c94210f02eb9", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x2109f5b7c318644c97ea14f3207164f6704cdd3416bd91448360b63c45d7ec6c", + "0x01d0aee7b081283eb5d46eafb04dd16f380df7fba4803ac42ad7e92c61394ba5", + "0x0000000000000000000000000000000000000000000000000000000000000c3e", + "0x0027000204012800000104804a270000044a2500000041270203040127020404", + "0x00001f0a0003000400492d0849022500000064270202044a27020304003b0e00", + "0x000300022900004304ffffffff27004404032700450404270046040027004704", + "0x000127004804022629020003006efc2c540a2a02030427020501012402000400", + "0x00000084230000019d2d08010427020604040008010601270304040100220402", + "0x00061f3000440047000600220447062d0b060600220448072d0b07071c0a0709", + "0x00041c0a0908001c0a08070400220444082d0b08081e020004001e020004002d", + "0x0008010427020904020008010901270304040100220402092d0a090a2d0e080a", + "0x0027020a040b2d08000b2d0a060d2d0a070e2d0a040f0008000a002500000a61", + "0x002d0200002d0a0d082d0a0e090c2846080424020004000001352500000b7c00", + "0x00220944042d0b040427020704012702090403002a0709082d08010600080108", + "0x0001270306040100220602082d0e070800220802082d0e07082702080403002a", + "0x000608072d0a07082d0e040800220602072d0b07072702080403002a0608043b", + "0x000e00070004230000019d2902000400132874f50a2a02040624020006000001", + "0x00b823000003372d08010427020604040008010601270304040100220402061f", + "0x003000440047000600220447062d0b060600220448072d0b07071c0a0709041c", + "0x000a0908001c0a08070400220444082d0b08081e020004001e020004002d0801", + "0x000427020904020008010901270304040100220402092d0a090a2d0e080a2702", + "0x000a040b2d08000b2d0a060d2d0a070e2d0a040f0008000a002500000a612d02", + "0x0000002d0a0d082d0a0e090c2846080424020004000002692500000b7c002209", + "0x0044042d0b04042d08010827020904020008010901270308040100220802092d", + "0x000a090a2d0e040a27020a040b2d08000b2d0a060d2d0a070e2d0a080f000800", + "0x000a002500000a612d0200002d0a0d042d0a0e090c2846040624020006000002", + "0x00cf2500000b7c00220944042d0b040427020704012702090403002a0709082d", + "0x000801060008010801270306040100220602082d0e070800220802082d0e0708", + "0x002702080403002a0608072d0a07082d0e040800220602072d0b070727020804", + "0x0003002a0608043b0e0007000423000003372902000400bf0791460a2a020406", + "0x0024020006000003522300000445280200080406402d0801092802000a040641", + "0x000008010a012703090401002209020a1f3200080047000a27020a00002d0801", + "0x00062802000b0406410008010b012703060401002206020b2802000c04064000", + "0x002a0c0b0c2d0a0b0d23000003b82d0e0a0d00220d020d0c2a0d0c0e2402000e", + "0x00000003af2d0846042d08460723000003d20c2a04080a2402000a000009f223", + "0x00000003e41e020004001e0200040027020604002702080403002a0608072d08", + "0x0001040008010701270304040100220402072d0e060700220702072d0e060727", + "0x0002070403002a04070600220402072d0b07072702080403002a0408063b0e00", + "0x000700062300000445290200040025a995770a2a020406240200060000046023", + "0x000000062d2d08010427020604040008010601270304040100220402061f3000", + "0x00440047000600220447062d0b060600220448072d0b07071c0a0709041c0a09", + "0x00080000220444072d0b07071e020004001e020004002d080104270209040300", + "0x0008010901270304040100220402092d0a090a2d0e080a00220a020a2d0e070a", + "0x0000220402073a03200043004300060048000720020004210200062d08010827", + "0x0002070400002208020a2d0b0a0a27020b0403002a080b092232000600460009", + "0x002d0a060a2703080401002208020b2d0e0a0b00220b020b2d0e0a0b27020c04", + "0x0003002a0a0c0b0008010b0127020b04002d0a0a0c06220c020c0a2a070b0d2d", + "0x000a0c072402000d000005632d0a07072402000d0000057d0a2a070c0e240200", + "0x000e0000057d2500000b8e24020004000005b3230000058a2d0b080400220402", + "0x00042d0e040800220802062d0b06062702090403002a0809043c0e0604230000", + "0x0005b30c2846070424020004000005c52500000b7c00220844042d0b04042702", + "0x000704012702090403002a0709082d0801060008010801270306040100220602", + "0x00082d0e070800220802082d0e07082702080403002a0608072d0a07082d0e04", + "0x000800220602072d0b07072702080403002a0608043b0e00070004230000062d", + "0x00290200040035be18a00a2a020406240200060000064823000008272d080104", + "0x0027020604040008010601270304040100220402061f30004400470006002204", + "0x0047062d0b060600220448072d0b07071c0a0709041c0a09080000220444072d", + "0x000b07071e020004001e020004002d08010927020a04050008010a0127030904", + "0x0001002209020a2d0a0a0b2d0e030b00220b020b2d0e060b00220b020b2d0e08", + "0x000b00220b020b2d0e070b00220902033a032000430043000400450003200200", + "0x0003210200042d080107270206040000220702092d0b090927020a0403002a07", + "0x000a0822320004004600082d0a04092703070401002207020a2d0e090a00220a", + "0x00020a2d0e090a27020b0403002a090b0a0008010a0127020a04002d0a090b06", + "0x00220b020b0a2a060a0c2d0a0b062402000c0000075d2d0a06062402000c0000", + "0x0007770a2a060b0d2402000d000007772500000b8e24020003000007ad230000", + "0x0007842d0b070300220302032d0e030700220702042d0b04042702080403002a", + "0x000708033c0e040323000007ad0c2846060324020003000007bf2500000b7c00", + "0x00220744032d0b030327020604012702080403002a0608072d08010400080107", + "0x0001270304040100220402072d0e060700220702072d0e06072702070403002a", + "0x000407062d0a06072d0e030700220402062d0b06062702070403002a0407033b", + "0x000e0006000323000008272702030265270204026e2702060274270207027227", + "0x000208026f270209026c27020a025527020b026b27020c027727020d02202702", + "0x000e027327020f0263270210027b270211027d2d080112270213041c00080113", + "0x0001270312040100221202132d0a13142d0e0a1400221402142d0e0414002214", + "0x0002142d0e0b1400221402142d0e041400221402142d0e081400221402142d0e", + "0x000c1400221402142d0e041400221402142d0e0d1400221402142d0e0e140022", + "0x001402142d0e031400221402142d0e091400221402142d0e031400221402142d", + "0x000e0f1400221402142d0e061400221402142d0e081400221402142d0e071400", + "0x00221402142d0e0d1400221402142d0e101400221402142d0e0e140022140214", + "0x002d0e031400221402142d0e091400221402142d0e031400221402142d0e0f14", + "0x0000221402142d0e061400221402142d0e081400221402142d0e071400221402", + "0x00142d0e1114270203010027020400010a2a03050624020006000009f2270207", + "0x00041e2d080108270209041e00080109012d0a08092a030009059b5bbff74a5b", + "0x00ff190022090209002212020a27020b041b2d020a032d0209042d020b052500", + "0x00000ba027020a041b002a090a092d0e040900220902092d0e02090022090209", + "0x003c0e07080c2a07080a2402000a00000a042500000b7c002209020b002a0b07", + "0x000a2d0b0a0a002207470b0e2a070b0c2402000c00000a292500000bd22d0206", + "0x0003280000040406412500000be42d08050c00220c020d002a0d040e2d0e0a0e", + "0x00002204470a2d0a0a042d0a0c062d0a0b0723000003d21c0a03050000220447", + "0x00032d0b03032d08010427020604030008010601270304040100220402062d0a", + "0x0006072d0e050700220702072d0e030700220402033903200043004300020048", + "0x00000320020002210200032d080105270204040000220502072d0b0707270208", + "0x000403002a05080622320003004600062d0a0307270305040100220502082d0e", + "0x00070800220802082d0e07082702090403002a07090800080108012702080400", + "0x002d0a070906220902090a2a04080a2d0a09042402000a00000b232d0a040424", + "0x0002000a00000b3d0a2a04090b2402000b00000b3d2500000b8e240200020000", + "0x000b732300000b4a2d0b050200220202022d0e020500220502032d0b03032702", + "0x00060403002a0506023c0e03022300000b732d0a04022d0a0503262a01000105", + "0x00e408504502b58c1f3c040201262a0100010575fef108377c8a4f3c04020126", + "0x0000000305072d0003082d0004092300000bc42d0108062d0406090000080208", + "0x0000000902090c0008070a2400000a00000bb2262a01000105d007ebf4cbc667", + "0x00903c040201262d0103060a000602072400000700000c392d00010500000104", + "0x000100000304092d00030a2d00050b2300000c222d010a082d04080b00000a02", + "0x000a00000b020b0c000a090c2400000c00000c1027010504012300000c3d2d00", + "0x0003052600000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000eb8dcdbf000000006a0b2d77000000080001", + "0x000000000000000002000000000008000000000280000000008a00000008992c", + "0x2d7278322ae3f2f02196f7b5eb323c037067b5a8bb27bb36e5936e01618b922e", + "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b", + "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe", + "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0", + "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a", + "0x0000000000000000000000000000000000000000000000008c6374430000008b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -25334,64 +25334,64 @@ blobs_fields = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000" ] -blobs_hash = "0x0098dfcc50238facc959eceef09a4ed661501b8a94815f8d69ad5b265956d2f1" +blobs_hash = "0x00682a8ea5dd86c86fb5429635732ad886f0310197db03f05ba37d6cf07b72b3" [inputs.hints.previous_block_header] - sponge_blob_hash = "0x208b2bb1ace451b93e09ef0119c861c986fb26bb867456eb5c93661b83befc33" - total_fees = "0x00000000000000000000000000000000000000000000000000d0f074eda98980" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000001baea4" + sponge_blob_hash = "0x0be6bd8144feece3fe238707409045d13f60f729f75a291fc5a6e8a9d652fc2a" + total_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + total_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" [inputs.hints.previous_block_header.last_archive] - root = "0x25dd04dc7f0a4299651ea908c014de487c4be771db4d68b458d16aa041af02ba" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x22143a53487336dae7b1e2d79f04e2d69537775312e313a6bd2ba1631581b2c3" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" [inputs.hints.previous_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001c00" [inputs.hints.previous_block_header.state.partial.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" [inputs.hints.previous_block_header.state.partial.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x0c877a1bf89b9eae6a04511e6f74bfaa71157ae9e20aa265ec7fb092914f6726" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [inputs.hints.previous_block_header.state.partial.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x21c0735ecdd66391ddb7fff9448a7973f1b8b4399648b1a150afb92d3a0d0ff5" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.hints.previous_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000a" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000042" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde0c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000007" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000021" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2d2f" [inputs.hints.previous_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.hints.previous_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" [inputs.hints.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.hints.start_blob_accumulator] - blob_commitments_hash_acc = "0x00ff28bea8c07e7b060d248cb2071f813aa6e39e07e3a527c1739e6a7793c093" - z_acc = "0x11b2ee0dde26d315a246f5bdc01db8abe8200c6581201debd1cffc51ad26f95d" - gamma_acc = "0x152f389c138d41dde799d4f4fc748753332ddcd5bcd19fe35e4fbe60581534c2" + blob_commitments_hash_acc = "0x009da512df7feb01c37d5bcb7e907e17d51fd84ad4460d4c642413504a87bfdc" + z_acc = "0x1a9e1d4cc81124337b17a9c662071843771d6a41f3cf53ee36568c2349b3647b" + gamma_acc = "0x070699060ce578bd02837627c0a9fa9cfb31bdb9f2a27c0dcb057bcd76292927" [inputs.hints.start_blob_accumulator.y_acc] limbs = [ - "0x4183756e36181f92164c36776c2ba3", - "0xaff710205b13b83794ee63e35bb424", - "0x411e" + "0x677c77feb299419897580647b86f12", + "0x1d6d20f741d9fa453db4cbf0848ef2", + "0x45f2" ] [inputs.hints.start_blob_accumulator.c_acc] @@ -25399,35 +25399,35 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints.start_blob_accumulator.c_acc.x] limbs = [ - "0x6e2f87b978f4bca529d7ad90a41cd8", - "0x734aa1582c8aee32f8334cfc594ab0", - "0x21aa57d7e1012415e25e37ee62bbcb", - "0x015e58" + "0xee591e91d1df051f9b267a38554db6", + "0x6494af33697703d42086d0bac214b2", + "0x42bfd42f76abb7a4329c55bb6ccce5", + "0x10b49f" ] [inputs.hints.start_blob_accumulator.c_acc.y] limbs = [ - "0xd8e530734ccb89f49a545e13ead68c", - "0x914523b3ef75387e032ac9fef36157", - "0x5342c94a6ba1df16b871173b323290", - "0x1604f8" + "0x8dd9d1424edc6766a3ea218b160e52", + "0xe3ee3c4c4e4e143f4caa4d794524a9", + "0xe208c7435d9f16c77e2d4bfc5a9ae7", + "0x0619ab" ] [inputs.hints.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0xc0250cc6b8725b2b00687dab94d327", - "0xd7f65a721538376d885811c9aafe6f", - "0x297f" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.hints.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.hints.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [[inputs.hints.blob_commitments]] @@ -25435,18 +25435,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints.blob_commitments.x] limbs = [ - "0x1f41ee1ce165ab1325a3d58dcce4b0", - "0x8cc2d9c146e110aecfd6e1d0a88478", - "0x5f035ed6b113a1d400984d75519e9c", - "0x0c2ecb" + "0xf54d4bafcdeb415daf044bfbc4959a", + "0x4ba7a36a0219a6a364c57913dd510b", + "0xa755c27bc765ce4d23bcabe820b2db", + "0x053fbb" ] [inputs.hints.blob_commitments.y] limbs = [ - "0x6e4b336ccd13490195783945cd06c4", - "0x87ab466617f89f75e1b4e5cc2de3cf", - "0x5c00c3065f22ed5a6511f4ef9144d8", - "0x0290b1" + "0x2937637584e15ed0d59e47f0f3fe13", + "0xbda1b755e5a650bff2324b1f83e52b", + "0x107c15e866e8b12ba7cb457e23ea8c", + "0x0ecd31" ] [[inputs.hints.blob_commitments]] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml index 98a0feb10878..e2377934e954 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml @@ -484,7 +484,7 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x09f6fe2394de36a32f372c238a502348b0b79debb779fecfd9de7388dc2df8d3" + block_headers_hash = "0x092d9c9b723f4a91d24cb333dd118c5f17feddbcec1eb988d00b2dcca8a12aa4" in_hash = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" out_hash = "0x00bd3da907cbb210cd100bd369f8dd7eb04b938c69dce277dc1efea8403ed88e" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -493,8 +493,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -513,7 +513,7 @@ proof = [ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x0d5581ddb590b1f2e972ae3399ac1639129b04a4b4282a219285a5dba6553cdf" + root = "0x10abfc1e58ab5ed471d9c7fedcf2b291ad533ac85d136968ea047db10d73d599" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -576,10 +576,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" ] state = [ - "0x186114d0d063d6e6ddee6515e508484b364b20eeca9ca340f8566e398b71b198", - "0x114fbdb8bc7b843c83778ba1c8780534af4f59451f33adcb6a437c245d4bed64", - "0x2808ea7e05edca8293485bb1dfde34257ab644659366d516601dd5beba26639c", - "0x0ba75ded1f1125dbe2d4e7a5b18a7b2e2c238a70c72ed529163eb34be09a36d2" + "0x06b7a09d376432aa2b0a7411a06aaad2d07f77fe65a5401eea06ab9d30b77ceb", + "0x06b7ab96aca0b2e842d7692f25a662728d09309529ca41b0e61eb20e19a7f38a", + "0x0b211453e69b20a81d2247120eae55ca5f80139276d8d9a7bb790996624e335d", + "0x1af797fb95b1713b94475070546774ffc67e4d61c261abb49048a7834cc7e665" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -587,134 +587,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000f" sibling_path = [ - "0x15602bffd51fabacf870d678a216f360ee85085e4b283f99086a716d2be141c1", - "0x02e6f22eee7e3e5aa6291ccac5ee76b8a2f1e338a74bf57530740f36d19c9b2b", - "0x14c22836312c6ac50d8aae1289b45c06410355406e5af5ecf43bf59432dcdd17", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x0b292d3b888b2793be2b844d85cf1ee4c10e4646758de66819a7d9483c294c05", + "0x2a4b8973bfb7d252bd970f41d74702d12b8bc7f63b15188bc79d78bda4a9413d", + "0x07a849e820943807a1c5531526528e89be50a06725dee96179285d8108e565c9", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000015", "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x000000000000000000000000000000bc40d1d77d5f27602c7a5c9dcfdd10a577", - "0x0000000000000000000000000000000000290d95127ce2d246f860afc4417008", - "0x0000000000000000000000000000005cbd5faf5f59e15c010fc58d3fe9e540b1", - "0x00000000000000000000000000000000001c1664bcd931f8720205c14774d342", - "0x000000000000000000000000000000e387aea29d37cb480af72d484d55b6db6c", - "0x000000000000000000000000000000000009819e8a531a4e83e8b585a5144e20", - "0x000000000000000000000000000000a1608d0aac1cba0b1a9be724adb7bad88c", - "0x00000000000000000000000000000000001dd226cbaf4d26d6530c6515111999", - "0x0000000000000000000000000000009cd23598a766328147bb89f172954d7b29", - "0x00000000000000000000000000000000000d423e810f78ea0c2de42822af19e7", - "0x000000000000000000000000000000a55922fba9387fb37978bbd6af4459e04a", - "0x00000000000000000000000000000000000006ecc1eebeaa91b95f82ddf0e88f", - "0x00000000000000000000000000000043557bb0d6f710fca0eb9026bf8a98125a", - "0x000000000000000000000000000000000009ff26fbd0bad0ae72c988daff6c0c", - "0x00000000000000000000000000000006859f9f51510814ee09ad960084d53608", - "0x00000000000000000000000000000000001acfe8b3a2dd74d8013a77c604ada6", - "0x000000000000000000000000000000584d59b5e078a46e2662eba84435d2e4bd", - "0x000000000000000000000000000000000006482f6bf0fb0b343d0f97ef69c6b2", - "0x0000000000000000000000000000009d06b99a519e14ae6c8cea34c266f500c7", - "0x000000000000000000000000000000000025948c8dade30c58b5de9219f2ca95", - "0x00000000000000000000000000000093d02ec5125183c643276a59b448fed664", - "0x00000000000000000000000000000000000e27bbd8a3f92cf1dd4964e4973b73", - "0x0000000000000000000000000000005f8e948b5bb98b37d2cfa364c13bf016c1", - "0x0000000000000000000000000000000000111bc97b3a794e05e394f12e060ce6", - "0x000000000000000000000000000000de739fa0af1b1abc39f66b36bf6babfc93", - "0x00000000000000000000000000000000002ec2db775d5362c26b1211d0c67b33", - "0x00000000000000000000000000000092bff11ad703ff9e37f33e0254b1cae0b3", - "0x00000000000000000000000000000000001f2e9c9949c5722f9c0f27d4c01426", - "0x0000000000000000000000000000003627cef107994ae39ad4e69391443a0997", - "0x00000000000000000000000000000000001fb58a2ef67ec15c272e5d7d9fdd12", - "0x000000000000000000000000000000f49addd07ba78c471bfce78c0e211de5e0", - "0x00000000000000000000000000000000000f8a586c69ee00ea0e41154296c359", - "0x00000000000000000000000000000064ef2ac931af2758da6f7f50962ac3aee8", - "0x000000000000000000000000000000000025844bfa45c1614111a515cc924942", - "0x000000000000000000000000000000030d10358e7c9ac3f42b647f523d169a58", - "0x000000000000000000000000000000000018749a4984c4b5f9f4776ee6119102", - "0x00000000000000000000000000000034847db5296ad05fc68d47d76af31b3fbe", - "0x00000000000000000000000000000000000b15d1ae95f4b0db468e55ac0124d8", - "0x000000000000000000000000000000ed9af9fc0f97291c7f59f97bbe779da8be", - "0x0000000000000000000000000000000000188ff968dd82e23e5fdbbbd17a1d9f", - "0x0000000000000000000000000000009484b03063127bfe6d86b88c8ae47c01bb", - "0x0000000000000000000000000000000000108ae749d0d2eeb1996779852c330a", - "0x000000000000000000000000000000c6ebd746a8b5176e70a61f91162a6d4e2d", - "0x00000000000000000000000000000000000b89bcdd866b9cd89975b5ad0e6d89", - "0x0000000000000000000000000000003a110dd7b65b005ebf4c552b3c67ef1555", - "0x000000000000000000000000000000000029162ed048f542c4f7b03cb25b49e6", - "0x00000000000000000000000000000068316453bc8319f06cedcfd6c32608cd1f", - "0x00000000000000000000000000000000000e251b62bf239581fb597eed6740e0", - "0x00000000000000000000000000000025b00fdba3615375ed7d3976b356e495ab", - "0x000000000000000000000000000000000019f6c87da0b230ac04532351fe4b1d", - "0x0000000000000000000000000000001e23899052e207e75d15ce3d53d5e32847", - "0x0000000000000000000000000000000000019b9ff1c73b02d0f4517a97cee440", - "0x00000000000000000000000000000098bdab2108ae94ca4f485f5d02848d78d4", - "0x000000000000000000000000000000000004286964c20572873b6cf4da257471", - "0x0000000000000000000000000000000f611fb20ca3f9a6e05b17a755e0d55789", - "0x00000000000000000000000000000000000bd64babea596e197f373eb7aa8a43", - "0x0000000000000000000000000000008b37d49bd8ea21edbcaed541649fa8bdf5", - "0x0000000000000000000000000000000000267b1d48ccf67020ae08c7626a6c1c", - "0x000000000000000000000000000000cc687415f8c3305515f13d525e24085188", - "0x00000000000000000000000000000000002ca0b4b1f880019458bb2cd76f1f6e", - "0x00000000000000000000000000000030225fa6aa96e3972e46e3696527aae07d", - "0x00000000000000000000000000000000002b4de086c87a07bba4c423443feeab", - "0x0000000000000000000000000000000185f97c684593ba3560c433759c004853", - "0x000000000000000000000000000000000023cb3980074547c96e69cf1b54a618", - "0x0000000000000000000000000000009f864e1df408fd077100e0708be9692950", - "0x00000000000000000000000000000000002d465fd67c5262361e605c6e12915e", - "0x000000000000000000000000000000d4d9d690e0e19ef0a850cc44aeb72d291d", - "0x00000000000000000000000000000000001a1575ccf82dc1999e30c8bc1cd879", - "0x0000000000000000000000000000007b9c3ed13d551bfbc79f7216b917bdd693", - "0x00000000000000000000000000000000001c7905dbeeeafe6a96e0005768c3ad", - "0x000000000000000000000000000000abeca755a49df461a20ac6f0d8aa21bc90", - "0x00000000000000000000000000000000002ea0bedd06b133984bc27df51d6cb1", - "0x000000000000000000000000000000b07d6e88b09f97805879886a4f6f2d38ea", - "0x00000000000000000000000000000000001d0d1ffb001c9b3899d7be3d350184", - "0x00000000000000000000000000000007edda6116badb825639e5ac0bc35bcc72", - "0x000000000000000000000000000000000000c8ef5f1d8a85d3f564339779a623", - "0x000000000000000000000000000000e98b4e97afce7c1eda4af175ea75a95ff5", - "0x00000000000000000000000000000000001fc215448b3315991812153c3ff4c6", - "0x000000000000000000000000000000a05a9ffcb63515d19bd5c987c9d9c8e29f", - "0x00000000000000000000000000000000003018d45fe1f2d7b5ad3f1be15c2f2a", - "0x000000000000000000000000000000f7b12583d31b279777eff4b5cdcb77fdb8", - "0x00000000000000000000000000000000002d8ba043960803f8bdecd1765200ca", - "0x000000000000000000000000000000904912e20bb0691aaf85e36dce6b473d7f", - "0x00000000000000000000000000000000001c69cd654d955bce8b4edb9c7f1fe1", - "0x000000000000000000000000000000bf797dee8dfb0567fb3985708d7e353387", - "0x00000000000000000000000000000000002743e0b1f32f249b5ae16902fb391c", - "0x000000000000000000000000000000d82e431c626c79dbf17adb5fe768f904b2", - "0x00000000000000000000000000000000001bc72b2ac20d87b289025c21613b39", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000dc4a993f7acd99b494105345a2fdaa0a2", - "0x0000000000000000000000000000000000250b675604342cefa92c43e49384e4", - "0x000000000000000000000000000000b042a664238ae53b3e5a3c1c332c3c26d7", - "0x00000000000000000000000000000000000bb7745eec39ba256f4e95e5c1b96f" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x00000000000000000000000000000089079e540b719b4976bc29d819da265672", + "0x00000000000000000000000000000000000169511d89b1b0e96da32e525c72fc", + "0x000000000000000000000000000000e06e062182e6dfad1e73262298e47b4942", + "0x000000000000000000000000000000000022b5e38bf07cca64a821cb6a1c50be", + "0x000000000000000000000000000000844e6f07bcbb405a7eccb53cbe0dcdac25", + "0x000000000000000000000000000000000019ccf675743a22e6910df635b6c02d", + "0x000000000000000000000000000000b3f7c9c54170a598243436c12b5e714430", + "0x00000000000000000000000000000000002565cbc85f940dbde932bfc4eb2b46", + "0x000000000000000000000000000000df6dd669dda6e917c2ac2ef5dee2599599", + "0x00000000000000000000000000000000000871514dca64f33dcef23979db5be6", + "0x000000000000000000000000000000a6a76f61c436e1325c59d9ca45156088cf", + "0x0000000000000000000000000000000000253be2ad6c1112a4293bfd778dcac0", + "0x00000000000000000000000000000061b34f5bbdfec177f721dc5f52ce5dfce8", + "0x00000000000000000000000000000000000c45d1ecf903c7083b085bd11e7a18", + "0x00000000000000000000000000000092b8c18509dc81b2af5c0dd4eab9e950c6", + "0x00000000000000000000000000000000000285d5abda6e0c8cc477b2b6d5a7c8", + "0x000000000000000000000000000000c31ba9fc26a1b329bf3a87101fe6e021ee", + "0x00000000000000000000000000000000001906c827ab4161488be3c186420748", + "0x0000000000000000000000000000003705e273cf24eef2d204884b0490063d93", + "0x00000000000000000000000000000000002a897d4386a8d79d754334ed1f277e", + "0x000000000000000000000000000000ef186aa03a1ea746fdfff4df4032261232", + "0x0000000000000000000000000000000000039bf4b51ed17830647b92c603871a", + "0x000000000000000000000000000000bd63d8fb924d2dcb07408e87c266c7b98e", + "0x00000000000000000000000000000000000824ca926bc6de275907dba25bdd31", + "0x0000000000000000000000000000004724cde9ce06e5411caabd7dd4fe2dcf89", + "0x0000000000000000000000000000000000267e7e5f0e6e2991964e87475f961b", + "0x0000000000000000000000000000001f11b31d10d889999d1f1349f99703a55f", + "0x00000000000000000000000000000000001ca2da1bd75c23c6533fc450360e0a", + "0x00000000000000000000000000000027909050e7b7eb67e7c9a4d6345f0eb69e", + "0x000000000000000000000000000000000011db3d79dd9d93947d2b7dc1c10672", + "0x000000000000000000000000000000353c06fb739bccbdcc744f38fcd0508a03", + "0x0000000000000000000000000000000000182f67bb76281c69170de22262dc6a", + "0x000000000000000000000000000000aee4088b33f36d708509b67a51df161c1b", + "0x00000000000000000000000000000000001f0af39954e92ebe02d2d09a9c019a", + "0x000000000000000000000000000000bbabc0cbdb5576ed44ba86792c4f0f3778", + "0x000000000000000000000000000000000001f9dcf9530d2449c557570860964f", + "0x000000000000000000000000000000e712b7c295c2913bc21ecd1c4fd978aeae", + "0x000000000000000000000000000000000020e9f99d67ea5e7fc51a2e22bfee4a", + "0x000000000000000000000000000000cfeace77443d79774754135c7968bf9d09", + "0x0000000000000000000000000000000000200ef4e004b1a6adf1c77145207df9", + "0x00000000000000000000000000000041d5b70488ce0785e27d77408b6085664a", + "0x0000000000000000000000000000000000206ee6f2103341c45c9b7671f392dd", + "0x0000000000000000000000000000008835d9dc525cd7f5221558932b0c0b79dd", + "0x00000000000000000000000000000000000547db4cde23842669a45900d460fe", + "0x000000000000000000000000000000aa8e1629d9ad0470808401bde58b032ad1", + "0x0000000000000000000000000000000000268f1b5be84cb1098c37af45c316e0", + "0x00000000000000000000000000000093192140c3ddeecebf383c332418a14eeb", + "0x00000000000000000000000000000000000129bf9dd7ef08589bd72fb388080f", + "0x000000000000000000000000000000ba08e502a40fe2d53953e74922703c4dd1", + "0x00000000000000000000000000000000001832a1f9489f19b4cabaeefd71ee29", + "0x00000000000000000000000000000007c6d0327de911d59b21bdaa35b13c198c", + "0x000000000000000000000000000000000021711257b12d37f6cc6bf0563cb71b", + "0x00000000000000000000000000000078540776e3fd93faf9c54d5168a662f856", + "0x0000000000000000000000000000000000002d078a43ad1d6c7f5b3d402a6611", + "0x000000000000000000000000000000ae81eb3cc1ae191ee4aa4214664d38a1d6", + "0x000000000000000000000000000000000015bddad4ba217f293029f383450df8", + "0x0000000000000000000000000000008b6c95adb242724e37da69f7a7ea68a5bd", + "0x000000000000000000000000000000000003b5e4a74d1e95b020f39d30eeca27", + "0x0000000000000000000000000000003102092e740ebecabc67864cd9cb36bc7a", + "0x000000000000000000000000000000000025ecef72137002818caafefff75640", + "0x000000000000000000000000000000a1a6659848b5210b9dcb9cbb0ea37359af", + "0x00000000000000000000000000000000001fd1df39bd8e442aa9ed4ec9818bca", + "0x0000000000000000000000000000005bdf45263c9710d45361e5a2a3f368d632", + "0x00000000000000000000000000000000002f00901bb28669af54074c0319ea4c", + "0x00000000000000000000000000000052d2ac68ce89bbd7c109c1ee22951430dd", + "0x0000000000000000000000000000000000291b0c8ec2d5a8ffabec390a97a0af", + "0x0000000000000000000000000000007332fb2757456b72c08ba53f2a6cbfdb99", + "0x00000000000000000000000000000000001c0e1cecfbdc2bce36f4446718039d", + "0x000000000000000000000000000000df0a10f65a3b192b15683732a7af4d35fb", + "0x00000000000000000000000000000000002d21b2fdc09d5c66d9cd3cdf1155d2", + "0x000000000000000000000000000000a419c6200eeceddf7c2310c1d55843fe57", + "0x0000000000000000000000000000000000164d6ede4c1c9cfad8019f4fef5607", + "0x000000000000000000000000000000155a288f925fc795dd91d8ffb9607e7588", + "0x00000000000000000000000000000000001d1a7044ac92e07e3f7a4d1adb808c", + "0x0000000000000000000000000000005006485f5f919139ac4cf8f2b48806c330", + "0x00000000000000000000000000000000002f38995bad2db25ab25059fdf2b6f7", + "0x0000000000000000000000000000000fa857db14df227f02ccb383869d141032", + "0x0000000000000000000000000000000000035df66ed51a2c5ebe05f09679be0e", + "0x000000000000000000000000000000ccd13789864d814c1c8e1d1896cf6d0d77", + "0x0000000000000000000000000000000000138d6ef3e6963f4fe192b274487006", + "0x0000000000000000000000000000001ef73e731e5c4ce7164d5fdb07175ea87d", + "0x0000000000000000000000000000000000178a3808d159a83c5c9966694f8ab0", + "0x0000000000000000000000000000008bca1f7f73e29b028b131da2a003bcc042", + "0x0000000000000000000000000000000000252d50a4729066a33228a590d3eca1", + "0x000000000000000000000000000000b027810138d0953c2b6ea7e149e4565004", + "0x0000000000000000000000000000000000303c0f2b5d507eb93d0ac0ebd043c2", + "0x00000000000000000000000000000002743dd7f3f2b76f827352e8e6b866e3ef", + "0x00000000000000000000000000000000000876c0bf77208a49e0cdd002dc3d55", + "0x000000000000000000000000000000720c42b7569cc2f3149f891bea025eb3e1", + "0x00000000000000000000000000000000000a4a472694ec96876785ee52db9117", + "0x000000000000000000000000000000899f74d8c6cb5d6913934ce86bf7a8fd2f", + "0x00000000000000000000000000000000002351d8cf62e447a6ad623d1576c70e", + "0x000000000000000000000000000000eff011caee40885a1228037bacd671c917", + "0x000000000000000000000000000000000028a9e4afdebabed8c9db5043f651d9", + "0x000000000000000000000000000000df5feae8869502a1c8b84f2bfa88460397", + "0x00000000000000000000000000000000002a4aea8df3da995b6993d106db01d7", + "0x0000000000000000000000000000007865f93da8894da5579d078bc52c865a23", + "0x000000000000000000000000000000000008ff54796b152dd8613c8b78175f0f", + "0x000000000000000000000000000000a6451fa917a48400fa444deb67a7ae56c5", + "0x00000000000000000000000000000000000ae3e2509278517f5cde67366a90c5", + "0x0000000000000000000000000000005e1f735a0fcf0b9170f0fb96b149aa6bfa", + "0x0000000000000000000000000000000000121155b0e2aa30081d1cd787338972", + "0x000000000000000000000000000000507a37d65b4307ff81bc9bb1dda679defa", + "0x00000000000000000000000000000000000eb66dc9635ca0b929275cbaccb034", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x000000000000000000000000000000cec3be02d424d395a16063578c12504acb", + "0x00000000000000000000000000000000001a583a66b4ace72db0600f3285f6d4", + "0x000000000000000000000000000000ef5f8bd3e2da9628dfa8917ab2f40afb41", + "0x000000000000000000000000000000000025c530a8f279e6cc4fb10e10984f2a" ] - hash = "0x0d000c0ce80da2c814b0f1508b74728e2eb05f4fdfb0396e1e6939106be41f29" + hash = "0x2781192850bee4946aa72958703bc69fec3ab04ecffc00c34abcb81befd3c88f" [[inputs.previous_rollups]] proof = [ @@ -1202,7 +1202,7 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x26882f9b919de7921bc48927adca4121d39e03766a0f70e268c967ac959fdda1" + block_headers_hash = "0x1349b8af6fa1399d3367ec1646ea31a8eb527fa0a93f7df141a99b8087c242a5" in_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" out_hash = "0x009be21298b4428b38b9b314446eef3243121c400edd3780e34da475ea5f17c3" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1211,8 +1211,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -1227,11 +1227,11 @@ proof = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x0d5581ddb590b1f2e972ae3399ac1639129b04a4b4282a219285a5dba6553cdf" + root = "0x10abfc1e58ab5ed471d9c7fedcf2b291ad533ac85d136968ea047db10d73d599" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x215f1b994274f12963668b1b1e69654c637c40187eb26d2f7bdf49fa7d1960de" + root = "0x2f6a583f6610c5573c95d4b79eafb659b67b4428dbf13990edf928f599a03ef9" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -1276,10 +1276,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" ] state = [ - "0x186114d0d063d6e6ddee6515e508484b364b20eeca9ca340f8566e398b71b198", - "0x114fbdb8bc7b843c83778ba1c8780534af4f59451f33adcb6a437c245d4bed64", - "0x2808ea7e05edca8293485bb1dfde34257ab644659366d516601dd5beba26639c", - "0x0ba75ded1f1125dbe2d4e7a5b18a7b2e2c238a70c72ed529163eb34be09a36d2" + "0x06b7a09d376432aa2b0a7411a06aaad2d07f77fe65a5401eea06ab9d30b77ceb", + "0x06b7ab96aca0b2e842d7692f25a662728d09309529ca41b0e61eb20e19a7f38a", + "0x0b211453e69b20a81d2247120eae55ca5f80139276d8d9a7bb790996624e335d", + "0x1af797fb95b1713b94475070546774ffc67e4d61c261abb49048a7834cc7e665" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1294,10 +1294,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x06d941e09284387689272aef891ff6ec71993e808f3a832c4d1fd74955b1901e" ] state = [ - "0x17da65d95854743f81498e2d569a4d11fe47a652ce11c27768e392475e503771", - "0x0fdf668913527d70795bd6225710f94e802493ca2ded968c29e45816b9366662", - "0x0de554ab6116e8d6245bfb791eb15006e14be4f10497002ec9a426a760a73974", - "0x28dc4bfd4e171c7418cda7f902dfd3e22433e1341085ae4d528f8b7082131ae7" + "0x1525d886fd143dc1893161cc7bc9a7a29cebdd09a955543f883ea4d2823b10e0", + "0x19060008e02e5f734643d2a087bae8c913fb8e79e47b50c5718e729cdedacade", + "0x21ebef3c51c070c1f17b925d3d30851b9afaa56d85745d6b8c0ab8586a014c29", + "0x124caee5596391b2756e5c3339afc57827b191b7e89529ef096b427cd6c19f89" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false @@ -1305,134 +1305,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000e" sibling_path = [ - "0x0d000c0ce80da2c814b0f1508b74728e2eb05f4fdfb0396e1e6939106be41f29", - "0x02e6f22eee7e3e5aa6291ccac5ee76b8a2f1e338a74bf57530740f36d19c9b2b", - "0x14c22836312c6ac50d8aae1289b45c06410355406e5af5ecf43bf59432dcdd17", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x2781192850bee4946aa72958703bc69fec3ab04ecffc00c34abcb81befd3c88f", + "0x2a4b8973bfb7d252bd970f41d74702d12b8bc7f63b15188bc79d78bda4a9413d", + "0x07a849e820943807a1c5531526528e89be50a06725dee96179285d8108e565c9", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000002fb0b1381b4486fbd49fa9fdb4d74afed8", - "0x00000000000000000000000000000000001b03700ad9942abf5144e1bd7393d2", - "0x0000000000000000000000000000007f3e184921857992c24753b966424214c6", - "0x0000000000000000000000000000000000283119b961cda64e529c68e135fa17", - "0x000000000000000000000000000000c251b282c34c8a6d712e6c12903362497c", - "0x00000000000000000000000000000000002c89e5571ae0b09fa870346cbd5cee", - "0x0000000000000000000000000000008eb0fcf7af2d945fd3266cd7b0b449e8d3", - "0x000000000000000000000000000000000021d78ef089716338837787911d13b0", - "0x0000000000000000000000000000007f691d58aee9d65248c5eecbbaddc13a98", - "0x0000000000000000000000000000000000098627646fa61b9928d6dc11c96e13", - "0x0000000000000000000000000000002c58cf39b7f2b04d82c4338ef8958a7473", - "0x00000000000000000000000000000000001aef806cf0aba5af2f1f8978cd56d8", - "0x00000000000000000000000000000082bb268c0e10a8bf5c0ef242f9906e4892", - "0x00000000000000000000000000000000000c90d93936cc598061c4d29f0b25a4", - "0x0000000000000000000000000000004d114fbbc4055f5761b7f8840f0da32908", - "0x00000000000000000000000000000000002957bebd162ed2169df723dde18c97", - "0x000000000000000000000000000000e9eea3e81c31b1aa9400fa13197b7393fb", - "0x0000000000000000000000000000000000218c3140bfb6edddbcb2d4cbc126bb", - "0x000000000000000000000000000000c0ff9e22fab79999e9ed7d78e138d2987d", - "0x000000000000000000000000000000000028bcfd13128cabc46955265a1e05dd", - "0x00000000000000000000000000000023a74d6f1a3fabe39ff7f0f6150be9ec00", - "0x00000000000000000000000000000000002e2507d7bf2a01aec6fd026fa0a409", - "0x0000000000000000000000000000000a0acda35b6f3d1a438d5fcf5783a50797", - "0x000000000000000000000000000000000021e1c9a570c3d0417707daa478fa20", - "0x000000000000000000000000000000c10049e49d4cd16c33bbc1e8eb3238ea26", - "0x00000000000000000000000000000000002578443465dd684c74b9c635f2c33e", - "0x000000000000000000000000000000770092209b5122c863dacecd7406bb2d48", - "0x00000000000000000000000000000000000f3fee6266059403a65308d4c5d7eb", - "0x00000000000000000000000000000093ed6cb8d6a2d5363b2c995ec9f930a714", - "0x0000000000000000000000000000000000276fea1e0f63f52d1e7564b9a81494", - "0x0000000000000000000000000000000389f3a2b3a8f8cc2f5f5d1cd72a8d196d", - "0x000000000000000000000000000000000013bcbd1229609722bcecd1798d4a4b", - "0x000000000000000000000000000000fe9ce7b1fd6536624c2fa96787f74d7bb0", - "0x00000000000000000000000000000000000c3c6d07104e24ea5acc68c3423208", - "0x000000000000000000000000000000b8da6eb9140a2d5588a8710a2d6d6318a2", - "0x00000000000000000000000000000000001b1f1fa538a3b66f72c15c53cca715", - "0x0000000000000000000000000000004730a9529ef0eb509d55e1379829c016c4", - "0x00000000000000000000000000000000001ce37c2c228f312b7c1e64bcca1dfd", - "0x000000000000000000000000000000a378c68d165ba8929cf5e20f479ed90e1d", - "0x000000000000000000000000000000000023024fd5c636e9ead7d63e4eac96d9", - "0x00000000000000000000000000000082a25f4e5374c7548fa507be32b596f423", - "0x000000000000000000000000000000000018ca6faa15b5b52e1ae8b15cb8b83f", - "0x000000000000000000000000000000091c75d9a46e8a66235f387c882bb14df2", - "0x000000000000000000000000000000000018f3db0dcead736435b7467239e00b", - "0x000000000000000000000000000000b87fb21960e7763dfd42205c459fdc41fa", - "0x00000000000000000000000000000000000267a4a344f85d00b6b0040d1c2150", - "0x0000000000000000000000000000000bd1017af78a6260c7d0f6eccb3a8d3890", - "0x000000000000000000000000000000000002641016e4e2bf5752b1e9472dde95", - "0x0000000000000000000000000000004697a8a794f990510a018a5b2c50f35b76", - "0x00000000000000000000000000000000000de0ab75e8b485639fe023a368024c", - "0x000000000000000000000000000000be33c35449966234d9bdf48ba396a57c4f", - "0x00000000000000000000000000000000000df556c20deb7a8ab0ee850f970c51", - "0x0000000000000000000000000000007e5366f459b2b033ca3664ff8f4a641d18", - "0x0000000000000000000000000000000000192f68a938c5a9ea9a5cc9f2181675", - "0x0000000000000000000000000000003a6f876985d4d54592c5b5c16ab8b16750", - "0x00000000000000000000000000000000002da0d2ee45300969c52f5ae43c7402", - "0x000000000000000000000000000000c0f7aa427b2ea5fe4f0e45dcb2eec42f83", - "0x000000000000000000000000000000000009739dbd1003e81acae3f329654c42", - "0x0000000000000000000000000000009191ff080e493eb7d3eb33ec9823178f09", - "0x00000000000000000000000000000000002c951c03d7dadfa04fdc92a298ea8f", - "0x000000000000000000000000000000245cbb1c8e9f243b94d55edca314c340d7", - "0x00000000000000000000000000000000000de0f174fce3433422830fdb869c6e", - "0x0000000000000000000000000000005348fbfc2bff27c23db0f849baac752835", - "0x00000000000000000000000000000000000fa0fe8cbbf06318ad99adc23d2e0c", - "0x000000000000000000000000000000b37df3b0cfe3793620f5315db38c0dcd29", - "0x0000000000000000000000000000000000011ef80549887e786cea0d08c13608", - "0x000000000000000000000000000000e085aac6fe78f6a3574c61f888eb0ace80", - "0x000000000000000000000000000000000015ea74a6e14e77ffea0611ecc18015", - "0x000000000000000000000000000000635cc32ee452dd83211c337fd3423850ff", - "0x000000000000000000000000000000000030399e012ea636c746005ba35a4536", - "0x000000000000000000000000000000c6c09fdb5d8cbc0266b956e5539ad94b8f", - "0x00000000000000000000000000000000000728658d282bb922ecff1634645aff", - "0x0000000000000000000000000000008fc753267c4b4393209eabc80d1c4fcac8", - "0x00000000000000000000000000000000001add24bab07f36d9d6e11beabf5bb8", - "0x0000000000000000000000000000001a38a11d04a6dc1d788b1cc4da1d171341", - "0x000000000000000000000000000000000004eadc7d1bcf2320272a6d96972ae7", - "0x0000000000000000000000000000004749834da45ee7f8ffc427cf41f3b715e3", - "0x000000000000000000000000000000000005e4285178878dbecdfd0c6eba227a", - "0x000000000000000000000000000000182e1a0661bfd39a43bcbbb18e3691b327", - "0x0000000000000000000000000000000000262b3f8b46fac1d385cc0f3bc24ee0", - "0x000000000000000000000000000000434d5dbebbf6fbc03531f25d963f155b9a", - "0x0000000000000000000000000000000000082a0f4d55eb1206313a4955f41f03", - "0x000000000000000000000000000000034001bbce1dcce343e80ff7a821fc3444", - "0x000000000000000000000000000000000013176cdf2f7fb58e75a4954f0bfd28", - "0x000000000000000000000000000000acb6987d4aafb95942bc208f40df86f426", - "0x00000000000000000000000000000000000e52fac6880e3f51e7641ab893e82a", - "0x0000000000000000000000000000002377224018803fe8e8922c797432d2d985", - "0x00000000000000000000000000000000000b3d671707c2cdc4842e4e8ffefc09", - "0x00000000000000000000000000000095b5d8b7b4a63b05df652b0d10ef146d26", - "0x0000000000000000000000000000000000099e3bd5a0a00ab7fe18040105b9b3", - "0x0000000000000000000000000000002129af3a637f5a622a32440f860d1e2a7f", - "0x00000000000000000000000000000000000015b8d2515d76e2ccec99dcd19459", - "0x000000000000000000000000000000222b888108dc25d1aa450e0b4bc212c37e", - "0x00000000000000000000000000000000001b917517920bad3d8bc01c9595092a", - "0x000000000000000000000000000000482141c7ebe42000a1d58ccb74381f6d19", - "0x0000000000000000000000000000000000305e8992b148eedb22e6e992077a84", - "0x0000000000000000000000000000007c86847618681dc29d8a9363ab7c40e1c3", - "0x000000000000000000000000000000000016465a5ccbb550cd2c63bd58116fe4", - "0x000000000000000000000000000000439973ac12d7ca796d6fe98ca40e6ca6b7", - "0x00000000000000000000000000000000002e24d420fbf9508ed31de692db477b", - "0x00000000000000000000000000000028edd1a7e46c840d9c943fdf45521c64ce", - "0x0000000000000000000000000000000000043d063b130adfb37342af45d0155a", - "0x0000000000000000000000000000009330952ae74c573d1686d9cb4a00733854", - "0x0000000000000000000000000000000000261522c4089330646aff9673619494", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000005d656b6df65180c7833e41dc3231ba543d", - "0x000000000000000000000000000000000011345e9011207695e22c16713acdb8", - "0x0000000000000000000000000000007d63cb71b503d4b9abe5d31e76ac70ff93", - "0x000000000000000000000000000000000026b61287fe7afce1e989dc0d30a961" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000161e5bb10fa2b7c7380009239b649b4734", + "0x00000000000000000000000000000000000badbf533a087faffe865010dc5b37", + "0x000000000000000000000000000000381bfa95df551e67c494b29f07bfc5149c", + "0x00000000000000000000000000000000001bf4738c48442b6d952222d821547f", + "0x000000000000000000000000000000cdf67a2562ab96b4917ea73217efafd3b3", + "0x00000000000000000000000000000000001b0666d4bc44552a2ffc0223345a23", + "0x00000000000000000000000000000052e280645ffe873ef1e2cce244d3b23265", + "0x000000000000000000000000000000000029365e95dc11f595f23b37d9c475db", + "0x000000000000000000000000000000e0546cf49094bcd8d9e4a0e2f0b0d21d73", + "0x00000000000000000000000000000000001dd314bca6a6ded1a4a64266a516ce", + "0x000000000000000000000000000000c529043942840056e63f2fcffad4221afd", + "0x000000000000000000000000000000000011c2731f6fe0cb9f3c7d88d710950d", + "0x0000000000000000000000000000000dccca0374b5478a2414205ee24ca83668", + "0x000000000000000000000000000000000007e95f7cd90c21519b280c7c007fcc", + "0x00000000000000000000000000000004de3a9f180f0a4f01dab186eba8530269", + "0x00000000000000000000000000000000001372faf74b763ba502d7cc0845a54c", + "0x0000000000000000000000000000008aa4681b00633c2a5a63702641a6d36041", + "0x00000000000000000000000000000000002dc7f4ccd6922fc4b6654e175f2a80", + "0x000000000000000000000000000000d0d4f6ecbd8ee863fa3160211931061e33", + "0x0000000000000000000000000000000000263cb61cd13a131bdb313fa1159c3c", + "0x000000000000000000000000000000739ca3af1ec76a87a037f25bca5447ee69", + "0x0000000000000000000000000000000000065132cc73a764a9958eaf16937aac", + "0x0000000000000000000000000000004f397550e79074d0c4d3108fe675be5a4e", + "0x000000000000000000000000000000000012a58f58ab7bd421ca8f0fdf7990ed", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000dbe8bffec86d9a9c4e194450aafe44569a", + "0x00000000000000000000000000000000001ad711549791cb4bfb26753da71976", + "0x000000000000000000000000000000eef413cdd499365c5aff81234c29a8e9c8", + "0x00000000000000000000000000000000001c1a2f7052492deb0bf3831f1d659f", + "0x000000000000000000000000000000a430987c325c792662db95707eeb73bcda", + "0x00000000000000000000000000000000001fc6620d5b4b91a2bb7e967e4ca0a0", + "0x000000000000000000000000000000d3010833f9a0a6df8b842d2e94c7443271", + "0x00000000000000000000000000000000002b34c8b03764d6438d76005e33f136", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000090eb905a6ce8fdcfb3ad69b20f37b471a0", + "0x000000000000000000000000000000000015411f1068f3c41c0f03f763abc15a", + "0x000000000000000000000000000000afca164bedcee548eecb0590ec5abf1127", + "0x0000000000000000000000000000000000145ea9d00e643079977aa78cd2c109", + "0x000000000000000000000000000000854f1c53b1fafeaae64bc08161c77048b7", + "0x00000000000000000000000000000000001e235518c5c034960eec5fc45a716e", + "0x00000000000000000000000000000035145365e610d44ef42fa8ea613a9df4aa", + "0x00000000000000000000000000000000000f949d81fe0404cba9da3dbe012bd7", + "0x000000000000000000000000000000c5f55c78208dcda151683ee8cf95e8bc47", + "0x000000000000000000000000000000000012b17b8f64a8606a7817da004b71c1", + "0x0000000000000000000000000000007359e5ac4a48e1c4cf0e5665c6c059d99b", + "0x00000000000000000000000000000000001d7a0474a2bb254bf932f10146b961", + "0x00000000000000000000000000000024e0b7c596516bb0b5a2e8d6cb248b56a2", + "0x000000000000000000000000000000000012e9c9b3e8143abd574124134a05c8", + "0x000000000000000000000000000000dbc92535cff5ca03ba09ca111642d39fda", + "0x00000000000000000000000000000000002043571f43cad61de3a5e4328a4aee", + "0x00000000000000000000000000000079d599186f46e769fcc207b0cd6cbdc01e", + "0x00000000000000000000000000000000000c5c2f9466df09ea80f0ec14870034", + "0x0000000000000000000000000000005f94f587b12643ff51063a28353833f770", + "0x00000000000000000000000000000000000cf56aa28ed4b4beb7ff157d7da3ef", + "0x000000000000000000000000000000de4b43f87ff9317c8e9d9c4588fc2eef2d", + "0x000000000000000000000000000000000012d0aa842859d2ee838f5510f9bc22", + "0x0000000000000000000000000000006f2fdb4213da0129f8365bc86a01f6164d", + "0x00000000000000000000000000000000000bdc73bc5280a4afc7e65947531e51", + "0x000000000000000000000000000000f14874ba0df22c460d8352ca030bd9a861", + "0x00000000000000000000000000000000000885382903e5ffbd837b5e0e4bbf06", + "0x00000000000000000000000000000066e80b7e34ebe3899a4d07dea4f62cc7df", + "0x000000000000000000000000000000000013f829d0878ad53de418679f370067", + "0x0000000000000000000000000000002980ae9f85fad098e5a76ca9e6bdac5779", + "0x00000000000000000000000000000000001a774ae589e96cfbefb418dddcdaa2", + "0x000000000000000000000000000000327c44b0ed90d01976c32c94f04ef2cea8", + "0x0000000000000000000000000000000000225d757cb4f2bfbf6d13b8114d7b16", + "0x000000000000000000000000000000bdc629840f4a9d071f9fb1384008254135", + "0x000000000000000000000000000000000004e75cee70f3e11a2402faef92a73b", + "0x000000000000000000000000000000f40c508a906897027558980610fc4df4f2", + "0x00000000000000000000000000000000001f959d41e40d111d021ab23b4ef843", + "0x000000000000000000000000000000587fcafd86184e71ec3d650b3ba85f03fa", + "0x00000000000000000000000000000000000610c97af06081281e7404f44aee4b", + "0x0000000000000000000000000000007b029cc296434696323f9c37b5e4c9cf55", + "0x00000000000000000000000000000000000614733fbf8d375012614cce5e4aa0", + "0x000000000000000000000000000000bc102f5fba012ade36bbf671474a9afae2", + "0x00000000000000000000000000000000000d2b78d31298fc946624e482d61850", + "0x000000000000000000000000000000c1c26c3fbdd4fb7de13c6af78b90063442", + "0x00000000000000000000000000000000002da9dd34c453f3d5a99691ba052769", + "0x000000000000000000000000000000a788520d601038b7bcb1ef241547ddc5e1", + "0x00000000000000000000000000000000002a280445997573df993f3eaa9cc9bd", + "0x000000000000000000000000000000ec4d9274437dc457e7da9ee9f5d57b0825", + "0x000000000000000000000000000000000029454eff7f180c04c3dccd1d762531", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000007cf4b5713ad71efb2e02fe45bb7fc9507f", + "0x000000000000000000000000000000000026cf1fe248bb52d3e86b9f64b3c2d3", + "0x0000000000000000000000000000000e590349a07b67f041c3c615e4f436aeab", + "0x000000000000000000000000000000000015a097ca4d6bfa82e4dd755b3ebb59" ] - hash = "0x15602bffd51fabacf870d678a216f360ee85085e4b283f99086a716d2be141c1" + hash = "0x0b292d3b888b2793be2b844d85cf1ee4c10e4646758de66819a7d9483c294c05" [inputs.hints] previous_archive_sibling_path = [ @@ -1476,7 +1476,7 @@ new_out_hash_sibling_path = [ ] blobs_fields = [ "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x149ec99267de2c967f076659b1ce7c2ef1e39b2de7a3c8fca6144e419a0274c0", + "0x1fa8c9e190ef51acc5e052f31c13e3b45f6a971ff92a5b3a128ab4debc2980a4", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7d1b000", "0x00000000000000000000000000000000000000000000000000000000b7d1b001", @@ -2838,7 +2838,7 @@ blobs_fields = [ "0x1fe2338f2916a0bd017ff73606723336792d97d6c91a387862c4d5ab893a6f29", "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922", "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x12ca038fdc7a689a9ef836b5edc09fc0ebba53d29405ede497d098f12b33c642", + "0x10b5b722c0807e2bbfb09230febb255d9c0fff9c50469e2389e88d9ee38a3189", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7e5c000", "0x00000000000000000000000000000000000000000000000000000000b7e5c001", @@ -4194,12 +4194,12 @@ blobs_fields = [ "0x00000000000000000000000000000000000000000000000000000000b7e5c34e", "0x0000000000000000000000000000eb8dcdbf0000000000000186000000020001", "0x00000000000000000040000000000200000000010000000000fe000000000000", - "0x0edef98680cbea2855c4f0f152a0ecd69358e68b10da7b7e301f35ce709c13fa", + "0x27b365d73aa1b8ac1eb39c75262e2b87a238d041cc98fcb795f4c597c620ce64", "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449", "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8", "0x0bb359d329306f1fc12b8b3a551903d4732e3e8814b2de27816ea59c24f1a2f8", "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x26fd006fd312bdf184fc64451856f788e40cf4aeb9d9a50da4c4be19d40adb31", + "0x1be1bf28dec1713b8bf50f30d29338963f2661a98cc83b0d7edf2010ac8b6e26", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7f9d000", "0x00000000000000000000000000000000000000000000000000000000b7f9d001", @@ -5555,7 +5555,7 @@ blobs_fields = [ "0x00000000000000000000000000000000000000000000000000000000b7f9d34e", "0x0000000000000000000000000000eb8dcdbf0000000000000186000000030001", "0x000000000000000000400000000003000000000140000000013d000000000000", - "0x0d5581ddb590b1f2e972ae3399ac1639129b04a4b4282a219285a5dba6553cdf", + "0x10abfc1e58ab5ed471d9c7fedcf2b291ad533ac85d136968ea047db10d73d599", "0x0058e56291a20ba5208dec6c4e6f93513a7e475709e9292d09b7ca1c7147703e", "0x06d941e09284387689272aef891ff6ec71993e808f3a832c4d1fd74955b1901e", "0x0ed4dc2f0161f133a04ebd27d3f9b7ab3d7046c1443c15bc9530cb3f5d9e9e08", @@ -26052,7 +26052,7 @@ blobs_fields = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000" ] -blobs_hash = "0x004081e2169fa22b2772ab0bde677d1c43254458e4af0c5884cf49ba3f4b72ea" +blobs_hash = "0x00031d7de335de20811f08b722d4fba78989fa94027ff1a8eec54aaea67fe5b0" [inputs.hints.previous_block_header] sponge_blob_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -26139,13 +26139,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [inputs.hints.final_blob_challenges] - z = "0x0d9e4f48a791aec62f6b7d1fc9035386da8a75d4a5eb234257b0e38a4cc7b9ae" + z = "0x0b4ef7a0f91b1c53bd4db4aec602254a28846ae5a42f2d8980d1912799c4b733" [inputs.hints.final_blob_challenges.gamma] limbs = [ - "0x810f80bc31d4ee4b1bc2e3cb4c28f5", - "0xcbb430183357d87fc1f80f3d1d31da", - "0x0b30" + "0x3fdb267131d938840645510fbcb081", + "0x65bb921ac3dc8dd116a3f59bb3183b", + "0x121b" ] [[inputs.hints.blob_commitments]] @@ -26153,18 +26153,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints.blob_commitments.x] limbs = [ - "0xcce5778469f0cecc548341f35f9ebb", - "0x8280546f7e9cb753aedf0a06fa034c", - "0xaf119193234c6f715aac4220979f16", - "0x130f08" + "0x665c40a423c8604a17e3da76ccc812", + "0xfe81e0faede6060a8108ca85ba9088", + "0x82c2811283002382832fef00453c0b", + "0x12b897" ] [inputs.hints.blob_commitments.y] limbs = [ - "0x5d218e9fd26f0a1c61e85eefe76e5b", - "0x571b53682bb7dd0ffcc88ba0f592a8", - "0x3058c697809e40f6e414aecb1c9a0a", - "0x078a44" + "0xcf949ef8ac7b342c359434c38b287d", + "0x129b3a7a403691b2c1b2b8ec052995", + "0xf4dbd895942ad8f1d6ab389ccfa412", + "0x070c7b" ] [[inputs.hints.blob_commitments]] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml index 64ff802314a0..5e87e095cfff 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml @@ -484,10 +484,10 @@ proof = [ [inputs.previous_rollups.public_inputs] checkpoint_header_hashes = [ - "0x004d16fb29611dba53004101a433c88fddade0ec60446fddec1589851839a774", - "0x00db58820ef17b4cb952c006ed78296097c3fcf7fd0fc3e3cec1f8260fc64045", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00a8a666b95bb2db4e3f95e5bcb8f5f962fa6ff42a2539a3c486aa868d15446a", + "0x0003467aeaebe55a1faed0cde7a7ebecc0b4168ff83de06f64342187de9b266e", + "0x00ba58769fa3e9ec12fd9ab7b264fe69545833f8e7d80571d73ab23a5fc0d4a1", + "0x008fb5a2af014eed924e6550a1a568a936137e0ae9596268bdd3a5e228642d41", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -520,17 +520,17 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x00f30d99838de8d9e0b40bb5f19c53ebd2cea2e4e324a6b48a4db2655906ad63" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + root = "0x22143a53487336dae7b1e2d79f04e2d69537775312e313a6bd2ba1631581b2c3" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.previous_out_hash] @@ -539,31 +539,31 @@ proof = [ [inputs.previous_rollups.public_inputs.new_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x000000000000000000000000000000000000000000000000003b2f97f0a76c80" + value = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000d0f074eda98980" + value = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x000000000000000000000000000000000000000000000000003b2f97f0a76c80" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -772,15 +772,15 @@ proof = [ ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00ff28bea8c07e7b060d248cb2071f813aa6e39e07e3a527c1739e6a7793c093" - z_acc = "0x11b2ee0dde26d315a246f5bdc01db8abe8200c6581201debd1cffc51ad26f95d" - gamma_acc = "0x152f389c138d41dde799d4f4fc748753332ddcd5bcd19fe35e4fbe60581534c2" + blob_commitments_hash_acc = "0x00996b577cb6f53aa9d5d22026fa7e7ed5a2a8976186df5414ed93231113a1b3" + z_acc = "0x04b51a58745a148f28f5c26a2d502c8001354179837d098e3af3955de34bf714" + gamma_acc = "0x1bfd4f0bfbabe502f62a2825f8fbc6b52df23371928e6422797997084279f299" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0x4183756e36181f92164c36776c2ba3", - "0xaff710205b13b83794ee63e35bb424", - "0x411e" + "0x0194e1d1e3be1d6f12d6eeb0e18311", + "0x447972f46deb3eff934723afb8d8de", + "0x2435" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -788,35 +788,35 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0x6e2f87b978f4bca529d7ad90a41cd8", - "0x734aa1582c8aee32f8334cfc594ab0", - "0x21aa57d7e1012415e25e37ee62bbcb", - "0x015e58" + "0x5e7c6caafcf94afa0766159ff528a4", + "0xecf78cbd1e0c5335e42da88a421390", + "0x39fa11170a3706ed93d37f65f0f7a4", + "0x169dc0" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xd8e530734ccb89f49a545e13ead68c", - "0x914523b3ef75387e032ac9fef36157", - "0x5342c94a6ba1df16b871173b323290", - "0x1604f8" + "0xb6ad8a240910f66dd9deea18fb02f5", + "0x7abb241ff936e62fe95dba9efaca7a", + "0x2a5bfb0a073fe526435c3e8bfedbae", + "0x125deb" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xc0250cc6b8725b2b00687dab94d327", - "0xd7f65a721538376d885811c9aafe6f", - "0x297f" + "0xc962ef153772fa92ab05d6d4de0b69", + "0xc842f223fc7445950dc69c40c23ee4", + "0x05a5" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.previous_rollups.vk_data] @@ -824,11 +824,11 @@ proof = [ sibling_path = [ "0x1be72f1f471a29db247f7c4f19c03e11631575edec0695c29deba92770cce437", "0x0c0e71d61b37e5093a79987574f6a04cf58c7a6b47f650ec04b30cb9c9b3ccec", - "0x1f0a3ab28f16510e4f9a5682a8b5f2826f55082cd639c6b76e6e970d8bb4224d", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x18e6586768e6bcc980c4756fb8e50dc355a096b22c3088284883e77065a2dfd0", + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] @@ -1437,8 +1437,8 @@ proof = [ [inputs.previous_rollups.public_inputs] checkpoint_header_hashes = [ - "0x009751d5fc5ec4f92e16f7b70c3b084aced0c7e9416fae20ebc6fcbca6b9501c", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x004638ad10c7cbda76930cc7f1472de2ccc8920da89114128202779de93410ff", + "0x00afd2bd40cee0982472b0b99c78d510bd9001cbb785bdc1a1b68db9a0a3175a", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1473,38 +1473,38 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" + root = "0x164e208dc9944fbd2d066b942b2d8d46c2c8818ca65c808dcdaa555f43f1de9a" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x0f84849714aa969caef587fe17273c9fae12f846c68db0f1ab092faf93a29145" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000c" + root = "0x06da63b13a4fad622178ece351f2198feaf74e70c18ba14fe5fa6e4834c0ff51" + next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000d" [inputs.previous_rollups.public_inputs.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [inputs.previous_rollups.public_inputs.new_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000022e452ad469ea0" + value = "0x00000000000000000000000000000000000000000000000000d0f074eda98980" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000000000000000000" + value = "0x000000000000000000000000000000000000000000000000004d2c208a4b8060" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1687,15 +1687,15 @@ proof = [ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator] - blob_commitments_hash_acc = "0x00ff28bea8c07e7b060d248cb2071f813aa6e39e07e3a527c1739e6a7793c093" - z_acc = "0x11b2ee0dde26d315a246f5bdc01db8abe8200c6581201debd1cffc51ad26f95d" - gamma_acc = "0x152f389c138d41dde799d4f4fc748753332ddcd5bcd19fe35e4fbe60581534c2" + blob_commitments_hash_acc = "0x00996b577cb6f53aa9d5d22026fa7e7ed5a2a8976186df5414ed93231113a1b3" + z_acc = "0x04b51a58745a148f28f5c26a2d502c8001354179837d098e3af3955de34bf714" + gamma_acc = "0x1bfd4f0bfbabe502f62a2825f8fbc6b52df23371928e6422797997084279f299" [inputs.previous_rollups.public_inputs.start_blob_accumulator.y_acc] limbs = [ - "0x4183756e36181f92164c36776c2ba3", - "0xaff710205b13b83794ee63e35bb424", - "0x411e" + "0x0194e1d1e3be1d6f12d6eeb0e18311", + "0x447972f46deb3eff934723afb8d8de", + "0x2435" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc] @@ -1703,37 +1703,37 @@ proof = [ [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.x] limbs = [ - "0x6e2f87b978f4bca529d7ad90a41cd8", - "0x734aa1582c8aee32f8334cfc594ab0", - "0x21aa57d7e1012415e25e37ee62bbcb", - "0x015e58" + "0x5e7c6caafcf94afa0766159ff528a4", + "0xecf78cbd1e0c5335e42da88a421390", + "0x39fa11170a3706ed93d37f65f0f7a4", + "0x169dc0" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.y] limbs = [ - "0xd8e530734ccb89f49a545e13ead68c", - "0x914523b3ef75387e032ac9fef36157", - "0x5342c94a6ba1df16b871173b323290", - "0x1604f8" + "0xb6ad8a240910f66dd9deea18fb02f5", + "0x7abb241ff936e62fe95dba9efaca7a", + "0x2a5bfb0a073fe526435c3e8bfedbae", + "0x125deb" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0xc0250cc6b8725b2b00687dab94d327", - "0xd7f65a721538376d885811c9aafe6f", - "0x297f" + "0xc962ef153772fa92ab05d6d4de0b69", + "0xc842f223fc7445950dc69c40c23ee4", + "0x05a5" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00e314212187820bcccc75acc041531f0e6f2139db72f9962951480b5eb309b4" - z_acc = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" - gamma_acc = "0x28a8c47b24266cbe95e6e5df4d8f583081a6e7d873a03dfabcf3fad3204acc2f" + blob_commitments_hash_acc = "0x00dafdb7b3b799bb084d877da599210547153bfa1d95e15454e5ef8828ee2a97" + z_acc = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" + gamma_acc = "0x0249abb0caa46e44620756bbe031549d27fd3993d9dff07bcf79463630d05de0" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0xca8704c4fce27431f9bc6cf6bc5ee8", - "0x2e59181e0640e995e15724147eea98", - "0x5a08" + "0xca5f370e7aab4dad06c01870c19fbc", + "0xd1fb9335d20269ffbc84bda2f21514", + "0x566e" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -1741,165 +1741,165 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0x1fc2db53f95236761d435a3d7a82eb", - "0x4f0266217c841c706ff759bcd9619a", - "0x6b2dfe9b2403f250a44b3a4a85c7a7", - "0x09f649" + "0x6d0f563da7ead85edb604d6454b7b5", + "0xeb7000efa3ffe5e92db92568794b8a", + "0x1189810c2c041ab7e783b85fbb3468", + "0x0afd1e" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xdf0f6a879571ea5e99241f6a774cc6", - "0x962be4a71909fb2b0c13c6d8aa4780", - "0xd7e987a1f4d2937f67abc39e2ce5d4", - "0x042b58" + "0xa6ae6e509b73011d557a87995f4632", + "0xfee59d3ca5668d346a68e82ace828f", + "0x5699038166c3c7de96889ef819f997", + "0x168603" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xed650727d9732d1fc427beb2dcf581", - "0xdcd9e8dc02a33765f813f467a095de", - "0x0e9c" + "0xeb5d3ce954df93f05b2310b2c784f9", + "0xbe6bc80053e1871b4cb41540dc987f", + "0x3255" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x0f20024c268f33a3baa0f8f38bddd3d70a7fe791632d4914d95c44e2099fa150" + z = "0x0a1d5f2cad6d077246e31822fa3d9bf34b71108150947dc49662788446571e05" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x551bcc798b08297e8823944cd61ccd", - "0xa11af380fa73225d8ac70a4862f1cc", - "0x24db" + "0x5eb6986fde6ed42731f6e9df63ce57", + "0xca3d4bbbb8720e742eb38a1fc0d350", + "0x1f5e" ] [inputs.previous_rollups.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000011" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000013" sibling_path = [ - "0x1edc2329182e13c58f5ced1e4ca120ba845e074e81d59ee64d0bbd583ecdd429", - "0x1f502972a4bdd0353e082932afca85331d93e89c99ab3a78511939c18eb14641", - "0x1f0a3ab28f16510e4f9a5682a8b5f2826f55082cd639c6b76e6e970d8bb4224d", - "0x268f759e38c9ff705a78c055b44e19f7d2b0227f3c4f2e31d6874550d498abec", - "0x09f661abe743a7c8125aa0498ca1d01914fdac9cadadb415e0d1a05934997b99", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x1be72f1f471a29db247f7c4f19c03e11631575edec0695c29deba92770cce437", + "0x0c0e71d61b37e5093a79987574f6a04cf58c7a6b47f650ec04b30cb9c9b3ccec", + "0x18e6586768e6bcc980c4756fb8e50dc355a096b22c3088284883e77065a2dfd0", + "0x250cea05d65b650bc11faa500fa1f37a16296eb5b39b3e19b292aa79cee316b4", + "0x21b9424e712ab7b467087e9f1c9ace17a7caa46d2e96b95fa0e136a68618d37e", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.previous_rollups.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x0000000000000000000000000000000000000000000000000000000000000015", "0x00000000000000000000000000000000000000000000000000000000000000a3", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000302787373675614b5065e413ff7cb47635", - "0x000000000000000000000000000000000030223bf53e330987976984cbc8b777", - "0x0000000000000000000000000000005d7e3c622753bc9765188b58278de58e2b", - "0x0000000000000000000000000000000000155d33c8914989120390dd1f1b565a", - "0x000000000000000000000000000000ee6a96b509792fe4cb08ba5b690a829260", - "0x00000000000000000000000000000000002334a82c7c45a013fd6565043b3e34", - "0x000000000000000000000000000000b64df10cafd4414f4ca1cfcc9df1104b83", - "0x0000000000000000000000000000000000146a7f5eacb3170bc6517966b91c32", - "0x0000000000000000000000000000009d478f8685010a03b0c7e082a0bc36f004", - "0x000000000000000000000000000000000000ba76040d675cb33d320e90572c0b", - "0x0000000000000000000000000000003be6828a9dfcbeaf8f85587eb0e140f22c", - "0x00000000000000000000000000000000002be8cad756fc14e20e65bcdac55d84", - "0x00000000000000000000000000000060d5a42641ead1f373092743119aa3af8c", - "0x0000000000000000000000000000000000164fde87f47eecf92ee4516ec82322", - "0x000000000000000000000000000000a8a3b797a6fe3470f8e4f7869dd43c2bc7", - "0x000000000000000000000000000000000017ec5446085f31ee161d9b3aeb1dc4", - "0x00000000000000000000000000000058cb2aac262dfffdaf058bcc776cd9a491", - "0x00000000000000000000000000000000000c3392013d42001efe4b51a9f9839d", - "0x000000000000000000000000000000eccc64c49eb40425e8fe5224ccdc43c1e4", - "0x00000000000000000000000000000000001f6506bedb6d949f1f86098e65a72d", - "0x0000000000000000000000000000002dd78f1fd00370a8383fbc3ba9753685ec", - "0x00000000000000000000000000000000002162b403b60b934527df3cdf67eaeb", - "0x000000000000000000000000000000d68ea8aebfb824365dabd01f6423c18a43", - "0x00000000000000000000000000000000000e1416c2f366756eb6713a61c29e0e", - "0x000000000000000000000000000000577c33d5c10b485d8c213d16ac4664dd62", - "0x00000000000000000000000000000000001dbb32af825db919015b2f62ac527a", - "0x0000000000000000000000000000004089798ec9503f6d851e3f36c8134fffca", - "0x0000000000000000000000000000000000258c2a8625473699411a82c908b205", - "0x000000000000000000000000000000900e70ab0eb295b2339744f30290816695", - "0x00000000000000000000000000000000002b8710de153dbcb980c871c8641455", - "0x00000000000000000000000000000064c8a69e30c314b2c9f307b9859388b725", - "0x00000000000000000000000000000000000274811b6c58c4854427d143980169", - "0x000000000000000000000000000000bd95ab45995e60444bcbcf2f650df95bfb", - "0x00000000000000000000000000000000001f24b2f347e01bcdbd025ac0559c85", - "0x000000000000000000000000000000ee494e93426c721d97ae5aa62c90310e73", - "0x000000000000000000000000000000000015237248ed9e657735f540e8c7756d", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000013c3bccc5388da92f5d871dfc5798c6f7d", - "0x00000000000000000000000000000000001ed1d4ff8584dd1dd72fa169b590d1", - "0x0000000000000000000000000000003de967fe48c15d8973f84a210a95dd64de", - "0x0000000000000000000000000000000000127264f024fdb1905c1b9311a69989", - "0x00000000000000000000000000000067ab29550dc70b79125476307dde9d4eb1", - "0x00000000000000000000000000000000002dc480e42e6eea643f7ceb8de96baf", - "0x000000000000000000000000000000b78c2d92f2d7d849bac283fd66764341fb", - "0x0000000000000000000000000000000000230044dfbb796950437c31b1813440", - "0x0000000000000000000000000000002864afee535c3f2025e8d4270039646e66", - "0x00000000000000000000000000000000000dc28f5cecb40979171218dd29e4fe", - "0x0000000000000000000000000000009a0ffd05fb01bef000cc4c463054f3c151", - "0x000000000000000000000000000000000021d43883eb57a05047400f4a96ef19", - "0x000000000000000000000000000000acf8cee1de7f48c4f06266c8cfbad2151e", - "0x000000000000000000000000000000000006cd8fd38f0b7cd6f9151b5ac5337e", - "0x0000000000000000000000000000005654df5102eb796e74c9de073e107a39ac", - "0x0000000000000000000000000000000000028174128b65de0f5263c0e175b23b", - "0x0000000000000000000000000000008ca702a32d860f9280e625c387f3521f13", - "0x000000000000000000000000000000000019d792292ea80445492b5514e0dddc", - "0x00000000000000000000000000000050bbf69e0ae3345cd601a80f62379ab9b2", - "0x000000000000000000000000000000000023cc9e9fb3e9cb8b7c8e06200a279b", - "0x000000000000000000000000000000c3b8f00f6e9bd29ac661c44ce1a18528a2", - "0x000000000000000000000000000000000014a93c6f48de42b23c9ac1f7dbe811", - "0x000000000000000000000000000000f5328aed500abdc6320165cddcaca4fffa", - "0x0000000000000000000000000000000000232b23c95bd3a3df804c4a93de6472", - "0x0000000000000000000000000000006676bec8a1892b306e941dcc5d4011100c", - "0x00000000000000000000000000000000001df5186ae0a33ea8836ed671a892b4", - "0x0000000000000000000000000000004bad445ac665f80bc6acf512e07e85bc38", - "0x00000000000000000000000000000000001d2cdff266585d4078e18118fa9092", - "0x0000000000000000000000000000002c610edad308e27919b035922986bc8bff", - "0x0000000000000000000000000000000000088752e898b6a27f557963cf76e0c0", - "0x0000000000000000000000000000004f28478251fd7e453b7baa9f3020a953c6", - "0x0000000000000000000000000000000000169c31849094fa7939daae18f3c5bb", - "0x0000000000000000000000000000005dc0a499195b7457c28e8736067f4aded8", - "0x000000000000000000000000000000000025d7847b139148f3fc3f063fb052f1", - "0x000000000000000000000000000000789ab89aaf1ab942d695d28b895ed5b26a", - "0x000000000000000000000000000000000001b405d8ca6f44a8937d1becbe4681", - "0x0000000000000000000000000000005d3e2c6adda13104da28bd3d0d40726903", - "0x000000000000000000000000000000000006657556bced744fca4baebc7a7a08", - "0x0000000000000000000000000000001f1e42fe306d2ed7e063bc7dcaae2d30b3", - "0x000000000000000000000000000000000029f36b235f098995d51d6825cea708", - "0x00000000000000000000000000000011de9fe4ab7736b1c511efcb2eef509918", - "0x00000000000000000000000000000000002b60e192da925f3d135e6641d4ea6e", - "0x000000000000000000000000000000f088858045a80449ef186d814d04b39f9d", - "0x0000000000000000000000000000000000153d832bdd7a9f6463622c3507f239", - "0x000000000000000000000000000000d8a9eebdce988c3fd2f0999930a15138b2", - "0x0000000000000000000000000000000000075f1ac6bf2a6b487ae46aa505d3fa", - "0x00000000000000000000000000000087ee2dbbf2a048bad137c4db1b8ebff300", - "0x000000000000000000000000000000000011cbf2a4f1f11c63d8eb9513ee53e5", - "0x000000000000000000000000000000f5e4c418c7383a63f7237510cbcbb73c14", - "0x000000000000000000000000000000000028199b65e442cc03e751b5deb448e4", - "0x000000000000000000000000000000a702cc20da20448c18d688e550e57c745c", - "0x00000000000000000000000000000000001f309a205e7f82854e940ece89372c", - "0x0000000000000000000000000000007aac52d4113e4e71f28eb47905e925a389", - "0x000000000000000000000000000000000020e9e49e102536e6956c9bae558653", - "0x00000000000000000000000000000001ba2d9676f12016903f2696eba0098b47", - "0x00000000000000000000000000000000002f61c08a9c545fd795f8433ca00c12", - "0x0000000000000000000000000000001edfe50b3721a067770f9499a6083d4c77", - "0x0000000000000000000000000000000000248065a6e53c3f8b8d3db47272f7b0", - "0x000000000000000000000000000000ae34cb14f3eb595d76a2dd9402b1b23d64", - "0x000000000000000000000000000000000017ec2c75eec02d3be50d530b2b11fa", - "0x000000000000000000000000000000b0c14b05eabc7a7ad842ef1166b9fbdd8b", - "0x00000000000000000000000000000000002e2832206b3d1167b6287b5eb53374", - "0x0000000000000000000000000000002bf99439219158d7f65fa75dea73dc9a15", - "0x00000000000000000000000000000000002149e5cd921f23b5d7de4650b9daa0", + "0x0000000000000000000000000000009a433e100615459dfb183f916b2062d61d", + "0x00000000000000000000000000000000002442616e2b0dbfa98b7ecbf193290e", + "0x000000000000000000000000000000c01f6dba139585c4cad33c1af1fc441f89", + "0x0000000000000000000000000000000000171aa053d4084079a830588b22ba81", + "0x0000000000000000000000000000003f6b7aea43a81106f616f3e575cee60863", + "0x000000000000000000000000000000000023f454864d42eb2c5024c72da2c08c", + "0x00000000000000000000000000000005987b401231fb970567be0badf86d7514", + "0x00000000000000000000000000000000002fdd84af6261fa6ee0f99f6bc1c881", + "0x0000000000000000000000000000001a6fbc62493ef0dc2c39bd5488af0fda32", + "0x000000000000000000000000000000000019f368e2c0dd3ae06755c7d83e1381", + "0x0000000000000000000000000000003800b8f4c83ccda2d5cff8bc18913d60e5", + "0x000000000000000000000000000000000014f1a75a1c0ce95480335398dbf82e", + "0x000000000000000000000000000000061722135564a0c33a56affa3ee1eb0c3c", + "0x000000000000000000000000000000000028fc5b4ae27c4be3b68af426e5cc25", + "0x000000000000000000000000000000094a72c62cd7f643f998a774a3c1692a9c", + "0x000000000000000000000000000000000002e23f17ec6396bd3bf8497546c82b", + "0x000000000000000000000000000000d7775db81e7c0c37e6940e97c3026fc49b", + "0x00000000000000000000000000000000001a76225c5d8d4a24eac9b6060483a5", + "0x000000000000000000000000000000d1322466b768603245adbfbe707afc9aee", + "0x00000000000000000000000000000000000c423cffb03800ad0f6f0b5bcb0a1e", + "0x0000000000000000000000000000001ade4e785ba270672b708c1cb93ca2fdd5", + "0x00000000000000000000000000000000000b468b6e311689fa6ec4503d2d1b5d", + "0x0000000000000000000000000000003a8473fa13716d7c47fb0a41d10f538fa6", + "0x000000000000000000000000000000000013151dfa49a54d259a8c4fec4736bc", + "0x000000000000000000000000000000f09823147b5a2f1315af76f84626faacc5", + "0x00000000000000000000000000000000002cfa957d32526624e97ec08d0763b4", + "0x00000000000000000000000000000095f75874399828c93364b7d272bdd91ad8", + "0x0000000000000000000000000000000000169d8b404b534c0a246767dc1b6cc2", + "0x000000000000000000000000000000579241f2e3236abb3e318f1a4266ba0431", + "0x000000000000000000000000000000000015c834520f6ae2df99028826545250", + "0x000000000000000000000000000000f31db19daed1017929ae88f4f3f8521a77", + "0x00000000000000000000000000000000002e3e6fa8fc5c271d95c32504342c96", + "0x000000000000000000000000000000156ccc48324606bba2a81e44d3033965f3", + "0x00000000000000000000000000000000001bbd1a661b55e4cf8c0bde338d994b", + "0x0000000000000000000000000000002e67e823cf8228948ae5c34f71a8347851", + "0x000000000000000000000000000000000006afe3e3e1b881c6df566f4532e8f0", + "0x000000000000000000000000000000b2f235dc16b84add85650d924582ec7dce", + "0x000000000000000000000000000000000013ec9ae6dbfc2a7310ee57e4cf96fb", + "0x00000000000000000000000000000043c924cd03d3652d1c7a1fa38eee85b013", + "0x00000000000000000000000000000000000b9e9493e39b71b0126548ef5f3890", + "0x000000000000000000000000000000fb37e6795aba9baa1a7c554c6614ab1276", + "0x00000000000000000000000000000000002bfa7eb130ab19d31141f4bd1a790d", + "0x000000000000000000000000000000aa4fa8ab5e1111f572bc0be8c5648dda2a", + "0x00000000000000000000000000000000000d1a47317b27c288eadb2a2fcec2e9", + "0x000000000000000000000000000000148d3def2091cffc18e7a99af26b32c426", + "0x00000000000000000000000000000000002978869bbda368adea3c9c670bfebe", + "0x000000000000000000000000000000f29b693ede78010c05b1ea2f98e6287d5c", + "0x0000000000000000000000000000000000285f6de42d2f63b6e09f638916be31", + "0x000000000000000000000000000000c529156a781367b9b39ccdb6f714cac912", + "0x000000000000000000000000000000000012afdcb744cd9b85dcf16b7e4794fa", + "0x0000000000000000000000000000003f0ee19f812e23c3e0c17d24cecf19ea9c", + "0x00000000000000000000000000000000002f68f3fb589c01cd8aa6215c944590", + "0x000000000000000000000000000000035e524c6948e5b34c206582bf43bf55ed", + "0x000000000000000000000000000000000024755c3619d8c89bb48b9d266ac87c", + "0x0000000000000000000000000000009a82ca92daff9b5992759a94953b8f8628", + "0x00000000000000000000000000000000003038a4b10faec561f34c2ea32bc713", + "0x000000000000000000000000000000633018b6c00a2169cef96b4073117721c0", + "0x00000000000000000000000000000000002f17430771a2fc7344dd1c104fd00b", + "0x00000000000000000000000000000069085f0ce834cf4d649d802da99138a95b", + "0x000000000000000000000000000000000006947eb82654ee05b374bb416cf04b", + "0x000000000000000000000000000000bbe898ab38ac7a24524eef7b79d2639f76", + "0x000000000000000000000000000000000002c40b232a07d9d11f3dac35b85dd3", + "0x000000000000000000000000000000047258f098b82fad4617620d0189f879e0", + "0x000000000000000000000000000000000026c6c071c1d3ad9e14eb001be27125", + "0x0000000000000000000000000000000c49a35af28b7e551244d77b56d59b5512", + "0x0000000000000000000000000000000000189085667c613410461cbd17b30c56", + "0x000000000000000000000000000000ca38ed6144991e99907f522e28860f0de8", + "0x000000000000000000000000000000000007c40e2ecae3ebea24bd3ec55ac484", + "0x000000000000000000000000000000bfffcabb70a790bc545c4ee3bfce18a260", + "0x000000000000000000000000000000000010e55bdeb1092f2a6444bc396cb56f", + "0x0000000000000000000000000000009c4e20b003ed4f70b4a62cfc57204f24c6", + "0x00000000000000000000000000000000001e00b7ff0421bfe32f28205fd0df4e", + "0x000000000000000000000000000000cf5869f07bfb05fa6a7b3482f3331f9d8e", + "0x000000000000000000000000000000000022c6e62a5e3445a01fbe8fb277eae1", + "0x000000000000000000000000000000b5dced535f594636ae43aa82db9c0a562a", + "0x000000000000000000000000000000000015b098ffbfd590c9db9622f8456377", + "0x00000000000000000000000000000069eea6cb45c453c7458f7a14981f8a4639", + "0x00000000000000000000000000000000001e577951336e913442cfa05d0e9a0d", + "0x0000000000000000000000000000009ef7b985877ffb4041cea6f6912eb32a8c", + "0x000000000000000000000000000000000020521a7cfd616db7e549b3c64d777e", + "0x000000000000000000000000000000e9f0722fce51e4bf5e31b757228e9ccbf1", + "0x00000000000000000000000000000000000fa84f6bb49d001a7506c96419e7ce", + "0x000000000000000000000000000000a761f66f198a2c14c07c32f6604cf578d2", + "0x000000000000000000000000000000000019635c073e9a560147b7295882e765", + "0x00000000000000000000000000000033deb909e8f26ca9aa0417a0172f02690f", + "0x00000000000000000000000000000000000880fc020fc451935fb66e22daa7c1", + "0x0000000000000000000000000000006367288f16161fa5df3f49cedd8a8e34b2", + "0x0000000000000000000000000000000000304e31fe6eba575d1b3f3ebef0066e", + "0x000000000000000000000000000000c5cafa7e75b7c69af15b1a1e1bc905d603", + "0x00000000000000000000000000000000000056634d879eaebb861aab7f6f754f", + "0x00000000000000000000000000000075b6c4cb8ee2d596e52fe1b3d9405cb208", + "0x00000000000000000000000000000000002bf855c3a58ee0e60041a921be728b", + "0x000000000000000000000000000000a4e608225e21e96a15388fd855afcb8bd9", + "0x000000000000000000000000000000000001eb45674390c99d0df7b66959f3a6", + "0x000000000000000000000000000000da7a7c3519858b8c78980a95a3c0ace91c", + "0x000000000000000000000000000000000004b30cecdd534cbfb3c9ffdf2ef2c3", + "0x0000000000000000000000000000003a35ed1dc0d1ff7aae4209529a34930921", + "0x0000000000000000000000000000000000210c99ed727129a1d40e9f9a7adcaf", + "0x000000000000000000000000000000fd35d6cbde8ca6b8e64652a47a495d4eac", + "0x000000000000000000000000000000000019c18ce002d04e602c1607ffe9a256", + "0x000000000000000000000000000000a3a317653f93cb7e27ab835d087169be62", + "0x00000000000000000000000000000000002f16044c7d21455e2e0af21446869d", + "0x00000000000000000000000000000052868428cacab9195b92aaa5470ecc2279", + "0x0000000000000000000000000000000000008866d791a72df4357df8031c5f7b", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000f6e131d6ce506eb0d3892b0c27cfe0f4a8", - "0x00000000000000000000000000000000001668301c6c961e364526eb8abf9792", - "0x0000000000000000000000000000001ace35f485f93f441c7e0a6df02303688a", - "0x000000000000000000000000000000000010adb5f7e278a58893faf2b4b3ed80" + "0x000000000000000000000000000000009fc2164d514381cbd046643639eb0897", + "0x00000000000000000000000000000000002f78c031ec3c08a5ab5a89a1d10683", + "0x0000000000000000000000000000007152fc85b72cc8621b05374d34058fd1dc", + "0x0000000000000000000000000000000000045f49a06cc7dca8937f78ab17e851" ] - hash = "0x16e2d4dba2d1561651bffffca7396ffbb146c6eea7b127f67a4b056c70bc7da3" + hash = "0x1dfa2952af644c59aa9d8ddec361d72059e139e64ce4790c4d3599963ba40244" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-private/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-private/Prover.toml index 0daea78c3d23..7494b3844f3f 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-private/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-private/Prover.toml @@ -3,7 +3,7 @@ anchor_block_archive_sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x08ead7d93a6e0ab74b47c029605a16640557a4c3e830a2f6294aea4559e5325d", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -3061,1017 +3061,1017 @@ contract_class_log_fields = [ [inputs.hiding_kernel_proof_data] proof = [ - "0x00ffd75efda6e34b65121fde81a69ba5f2a45acc69b143f1e333d23658e80f55", - "0x0094776a12fb89f4b79a211bfa3a123207f9ad5633b79be105497666fb335bf5", - "0x00d17297ba98cbb8657cb604ec67599c7a85328c46b50b54b0cbc52943fd2264", - "0x009dff5d1b2b67b894899ebcc54bca90dd7480e42a685a692c75d0f8055bec2c", - "0x00c0d25d3d357e684dbb3e1b28e7aabf97967a5ff28a67c38886575be5b6babd", - "0x0022cb2794ffb670f60a8dff4602cf5e93ca43bf651c52fc0919a8fb973374e9", - "0x00adf3b1bad196cacf4bbced5c5901d3efebf39d6b89e517f94d45ccfb1efbd3", - "0x0028c69ebe9961c53434f6c4d4f3e9921ff5b652674b535f132a1fc7c8228de3", - "0x00fe3ad1f7d405ad161fe64ba928307a2fbdb9ac1157dbe82e2d6d72f5044edf", - "0x002dc6b27c1b5fbabceb49c8ed5d3c2dec4fb00afe60324b03cca49974726d60", - "0x000f1525f80fe686760ef1f3b292c309ab7452b0c3678b4c0654b5ae25a3f32d", - "0x00dbcbc18aef1cd4c03e4335ecd088883fd93e6a2ba98c10d2ac34cda77dfc48", - "0x00f4e56686b75cd63c78b800bc9a5fe549ca6bcd9d6eca61c1fa5a104fce5546", - "0x0054e54c83d00911ef88f8f1ed287779c630a34045420201d0669f14c1b4de66", - "0x0018c65a26ab7e3b8ebac5221afa73da55ae5c36c08d9a0018da7d5d17e29872", - "0x00711647e952591a6ca41f5620fa9a03bb75790f8f81db6dfa82c31548480456", - "0x0013925676e49ac65094b4d49d52e1a170e5039602fcf864b0ac6f7e9da2e562", - "0x00d91b375ddef300c30fbb8aeab90cf398034b025f3a80928e5648caa4305977", - "0x005482eb58c00660408674a52b2dbcf144f6cd81e8eae46f8472f23e676656a2", - "0x00eaca2a637d4108f9d875a6894f7b6d422c7866620003ae177a6e3d0f8144f4", - "0x00e94a79f13f9ac53694a4f4a7937305f9ee22511b40f32cdc5295f811329b1d", - "0x0092a64411b0146c87875de91204ed5887e86adc0e1420b95095a40c3bebe4e4", - "0x000b8ee89f7b2e5b15306b27947219fa81b6ed217c7e2f062405610b17a3eac3", - "0x00cb681d138ffcd55f855e933bb676a70e00ee0cfe6b052c3ad9bd98b0f2830a", - "0x004ad7e724966e80273dd1cbc4438c33753f51003cfa7a9539e655b5500b916e", - "0x00da0e801b70978301c27e0932a556f858dae29306da56a5e9fc4d12ae81d4bc", - "0x003c88b248de4edcb308ffabca61a81d0badf09ab8c0db324115cac211a33315", - "0x00fa54e31397b715b3b4f78d101a92f46182627272e4bcaa9661c18423b7aad2", - "0x004bf3e6103dbc0f11e88e4a96ae979650b453fb23293d6042f422ecee105c8e", - "0x00aa32266a8e4a7794d11c5cdc0b3a94828fdec171940886f71c481595573c45", - "0x004d234cff37718289fedc718cbc31527aedea95dc6dbfda696e03b7eabf9023", - "0x0072505be5605360c6974f2456aa1ef0a20a9d080af340cf4ca3a9a605398257", - "0x0027fb05374784e684c91cc9d14237550a7c4f394cd83dc375629c0992093892", - "0x005a78001cf50b1003c738fb1d5bafa348bd87a995a627ea058d269df6467538", - "0x00f5a712d8697c55a2d079a425ea01b2d5f1835a6024452a4dee96d8d84ce12e", - "0x0049b1ac87b46fb780996fea081b31f7fc3a48e93b44c74b961086fac1dec208", - "0x00fad978518359b69586fd3898da97a077f2c7cef71f5092a187a0c514c3af05", - "0x00c59283427a17f123d663975bd19939ee89775b8e7c94fcd9bd5b3241ccaab4", - "0x00923ee87ab5358cec0dbd2a80b8692b4bf7f4dad1f8d844f4a7f9ab4d8bac8c", - "0x006b4cfa0700b36c4eba18ff146692a3280bbfd3ca77afff2ed4f28b77279806", - "0x00b3df44b2ede48afd7f8623cc1effc2ba735a26f84c7bab2fbefcec7811f5e8", - "0x001c2661dc49f216ea9d0a8aa92b42bd3b47d33fd14489514cb7f8bc27904e48", - "0x002dd11f2ea077b2dae65a51527862c022df36c0307acd228dcfeaaad24c348f", - "0x00cce3192f03077621ac9dfa9d3c74578df9fc4cd92279c5424a5005bd96d494", - "0x0019b5385a04d7a04bc5e959cf3c7ab40161643e708d0e7fb4ed3e041ea05b27", - "0x00c69e7eee0f2d74ab6f09f20334f09d71c70aa1debc9ea6982a4466a1b0d940", - "0x000470dac797cee8c98eff759b080f250f4741af184c23ce815aea4cfc4e8c48", - "0x0077db2fa409a80393e0e0a2c11e9d70c2e5a8638c1c9437699dec6294712973", - "0x00dbe9cc8ea14f3af035459adf3a81e8907f6825ecff3d23339995592e3ef0ab", - "0x0005cd8fa6df56ff6bea8aca5174379bc05b1be3005208151bc6ff12127acfed", - "0x00fe3a1af45ef5e3ad0e4600434f0d35e2f2497d0f2b8af16731563ca0e61964", - "0x009e0611af494263d72231e5bd024838ee9d685df45054adc5605287dd911383", - "0x00cb244e2dc1b125f1b63565440a6b12d7fadd2f224dd9398eef59dec2c519f2", - "0x00ab953633f658117abda1c94812bf746724499504dab6d9f73ca4b1e5b479ad", - "0x00a5e839bb44dff0b346d4785e34274d2efbfc96466adbb951531aa23745fdec", - "0x004081ac19c5d624029d58663f1a2d81fb43559ee9f4a0ada6939ee3cbcb59d0", - "0x00fc77c7714e75ddd629369407eacc37d4f06ebb6408e1a674c2e6f7458486d4", - "0x00200f4567c708d8bf6305e1596756bf740c1565b6685bed4acbec81c21e334d", - "0x005190221e0ed1fadb52805279274d6070b4e66e8f99d6d677c5ac7698c5585d", - "0x00c060759e742ac60dee8624e7bef11d95c25a75752ba54a9756cd8a3ad29b49", - "0x0088bfdbc2d149a96860d92213b3efffe302b8047b685f2f070f92ffd11f126b", - "0x00a9709e3d7c990f3e9df6aa1158b267befce727676a06470440a3d439493fa5", - "0x00481b00e3ea9fed099f355ff7d93f845461ff60187d1a93048e185fb3fa17b0", - "0x00b0ad26295afe5052a8a146fcdd7256616c8502f52c581d39939284c10b88e7", - "0x00f37729095752021c4c756ec5f82a1665dccac4838106225af649aba0719466", - "0x00896364974c0f4ab9ddf0ff8efc0ea0291196a724c38c9f0bfaa824669e735d", - "0x00ca06d90a05cfa04f1f12c01b554b77ed4a1803ef900d1739e5b7e0fcc4298f", - "0x005cf219fa11cdaaeecc9111a3c6d5d9f6b6ac48d73cf2ca8459f0001a7252aa", - "0x00a0dcacf4d8909895fa74ac2fb19dac071f3eebaa87a9b288569545d3d4a459", - "0x00560885c50c9b3330f2883185fb9fb889d8274b7aad7c09287602cb34b57736", - "0x0014091ac9016c73f76c16da9ee2d7c0fcb1923dff44069f3e0c48516a489dff", - "0x0011f6cc01f0c634990c827ed8ce622106bca44d800dfceab72eaca7b97aaf26", - "0x00062a8bdd4c181da3c0d8db39fd5e3fb4a2c73502e74d1582545241cee24f6d", - "0x0002dcdf3ef72c76dc4f2db72b71f0c38092e7336e4819ab3071674f1e213948", - "0x00d300b5e4bc03e1786182b5e2acb06b9bcecf220dcfedf8282cb66daa14b336", - "0x0098bd593aba34edd8c5ab0196ef9decf21b554fdefd3d65e20e0bd10615f893", - "0x00bdae3b00f52e096681762b639eadc26f8d5ae0152e435103664816630998ab", - "0x000d4377eb4b67c45637153ce4e9d91ed9cfb974ecc78b839f6accdacb71dd92", - "0x0074b62778d941a2539ff5f3c5612df968c04a5edc39722fa9c58fc6d79531b9", - "0x00d4ebaa8947bf046bf3d9c56661d4974fcd2c59db6b00534c338a65567759eb", - "0x00a53e0d5d5a57bc2b20f0a6212d3dee63816e0ac3adbfd7c3c688a6477d306f", - "0x003dd28b3becf359f1038832484168f47ccfb88daf62379251f125c14c75000d", - "0x00049973f1c05f070fe62138443073bbe3f28dbe2e0389ba7350220dbf127c8e", - "0x00450aa2c34fbfcbfa2ff9c037426f06c3fb1686ee6f4f12f5b4f5afc073272c", - "0x004f8dc9c25c46adf54e838982fcc9ab2396a13a8810d4cf32cde4168ca64f56", - "0x006e8e03f85bc18191b58538adccb21ad65246f59e591f97f48733f7d6bea23b", - "0x006cd3fb83405999e677cf5d7487887acc7b1cc496aa44e297166bc89ce65024", - "0x00960212536689cdbba2bb302a06be296fafa80c8188d0f63e081c7c8024e9c5", - "0x00544a83d08c93b1389d7725528861b5026c2c3e85cbd85ecb68f3082908a73e", - "0x000e7a9088d83afd167463f0837390214f4000db121bae34a90bca1f159b7e8a", - "0x00f98fc88ea73c8f6942d155ef39829684cb33dc0a9b408309fc4c1bfe22b894", - "0x008e676979c9c2c35c2e53e771cd34706c337f220952e07aec75be0d51145027", - "0x00f3f80db41e4d5b34a48bcfbcc7f82f3b878d81da4ee41d739eca84037b9e2f", - "0x0054af458a4daff7aaa295af26733ea8d49749b759bccef54de69638fc93799a", - "0x009d699fadc87947ea6d2c12445c1a5265ff01ad0c91582fa4bfac62d95cd3ad", - "0x00a2a16b2d92288b9f954d012ae4db21e50d538a94c38558cba0899d7e73e2ad", - "0x0067b4a5355b3b0087041a43f2ab03ee7745df904fef5ea244d039c903ceb091", - "0x00d7a48abc04a190ba3912271166e8dc93fc86be702a6411d7d66d6ecb9b293e", - "0x00d38a3a570b4d0e3bd2a304c34898351936db4e8e9278f331247f77c736b210", - "0x00872ddb3e904029c680fb188e5475e855fece2fedd07f2a4ae1bad46ede51d3", - "0x009075efaeaa2b761ac8520a05f8d633d5018f63fd4b27bb140fda33483b33a2", - "0x0074283d7872f1ea5f1b97b8f9921faea86c1cdbd66164eb39dffc6bede8558d", - "0x00c56fc456899d3e6ce3f1affbb9b7b070b7606a4378c1878555c38dda18ccd8", - "0x0077628608d0615b89905aecfc878a2e56ece2359ef12a196f200d094862a2b9", - "0x0028bf28f847b0f28ea3bcf441390d6688d6f388d6c14d056bf810c0a2e36012", - "0x0094b752463346e22191e752f55e58adca12af840b7491b8630e12e5bd53d87d", - "0x001f60ab6e2bfdac64e66e9d67553501cf841d8ae37fe2aa8f469ee7680760c7", - "0x00dfb73cb441dab864f6ca5fdbf5cc6278ba1905b663970340175eeefcbf90bb", - "0x005c57d2a80127b9902f9799f172fe384852ba94a84e8454b823bea37b6c6bc6", - "0x008350a4f1a5bbca102bafd6aa0fdb0d547cefef0f251f0fac0bfdbf45f6f535", - "0x007e1655610eca51be0a6518710cd90ff44cdd78a60ad37bca7a6a99e784c81b", - "0x00c896fd7f29c3be28f83c987ed24a96883034b4e2c86afca477b70ce3bb48a5", - "0x00ac938106af7be51e768d9f6c0b31b2e8a5aae4f948fcb965e8b512b1b115c1", - "0x00821ca77be45ecab881a47a312782959c9910da5c92ec3b465363bb9318eaea", - "0x000379a5292696b0c00395f7a88f399d57d1e82553fbf2b00edbbdfc4b1cd670", - "0x006a4a43463fb2797c2a64e82f5ba9cd0aada8500947b370a2b6c1509eeb96ef", - "0x002320aebd6d209852a8b20bc96027da97ffe47230146f331c3b2fe3ef5fd166", - "0x00084900fa32b26e930cf45f312d3c951b715d8c0d92b6d7b15ddc6cd2dda6f6", - "0x00094fe8e88d007793fbbd41812b45ef1bb92bce16f1759c030f0f30e5a78b35", - "0x001c4ae4a057fce62c55a015018840fbce0155f39dcd90f1c85bf0d3cd478320", - "0x000df43e5f53ebcf4dd664c94eb5cd93afb3abe811d9dc9da7b1679ece9bcbbe", - "0x00c373b8a8e96f6c15f165aa1f44677c65ffb3cf2586d235017d2ec7202a83af", - "0x005ac0d0316e9e5b58c9cda198618bf934350ca446e1d89b9678d8febfa7097f", - "0x00db546a5ffc90afe616014af94fba468e0bf9294a9fdc9cc018fce0bd187f79", - "0x006f0f795c70daa026780016ab81ae08f980dcbb16f5b66a48bdc8c1d8ed78ac", - "0x0053112e3ef6b8bff7d3c974890bd8f21f73fcd29104743047857d1b28cd5272", - "0x0012dfe8535397ca222b82fd8d1f81049b6b329fc8e8c04b9df4b6b7a31d8d5a", - "0x004c579a0cabef2ba7b850c224d97eafe93ed023c801ce34d404542dc699ef11", - "0x006438d149b3d5c954b5c2c6bd432ba51f72db66407335f43b20487cbcc1526f", - "0x00e710daf787f00e5b597f9bdc0d9a4386ef718fd709986b1a8d0b28a5eb81b4", - "0x00729aa5d89c00f22753a7b1e4a2cd1266de1d310b8f7d3bad6082bd857b7bd5", - "0x00403c0b7e953a13c5256b9462c07ea69472714235189cd7734e0d538b8db887", - "0x00fd4ef4be186ba095017acc419a1a8d7ebcc5d3973c4cc77cc164beaba73754", - "0x0099e12b2609e52f328f354774bd596258bdb35f33480df2474ea08696b87f50", - "0x00b82de1aa129698cca68f2628bab1079b35b17e437002ca53ed3255e1d9da34", - "0x0065c3db031004b4a6e4990921825f56f6f422d1286d4979c7f9d26c6358e712", - "0x00b9d89ee4ec898236d76f64d2dfc13960d34c857f9f14d1bcde5a6b3e34b7b3", - "0x00e6fb2d7923e923471898b2a6abd8e68b1e633fb5d8f2a97fe606e6da15543d", - "0x006bbfa2f0f0daef13ab7e09bb0ef99b279a6b7ebbbc12ba5a9f47b9106de112", - "0x006595e5c105f34c8c4c4d4e67d31ea16155682a65c1ba7f79cf27212b8d361c", - "0x00d1a2660dde4ab6a0ad877f0df31e2ff0cd0dc5323c01821f599d642b951be0", - "0x0081d8bcbe038387d02c809fadc3bce26132a1ad7a47e330ffe839ea1c89b3e5", - "0x00576b8bd38a2dcb3ec1b8ad9e096c202ee4fb55aebffc89a03d2d47f26add5e", - "0x001cba28aaf197f41e1dc41a81d0c88fee35fffb6d042d4487154caa422a6d8c", - "0x006b81e2330ab8f4d1ce4db000b983bfce4791b7abf2efe5595b55360dca7969", - "0x00b4401865c0c3946f1d81289ab27a6033fcbe235401c37f22bd02c7c2e24428", - "0x0006127b874f1cecb3957e777b4ca2fe721a97d2fdad5a2af4f68413ba979959", - "0x00bb7c0a9934bd781f9f1c681acc25f427f07bd2e78aad85a501d3b606984495", - "0x005d76103ead6a757f8fabb9c72020d6bb90ec103d3e6ea2f8692046cdcbb45d", - "0x0019709bd085b1f93613b32fdca2c6dedd0730a646912fc2f49339ad308144f0", - "0x006eeca96beb05e0f9f698616df386f9712d15f0cf1c1c5cfd6afc5225c66948", - "0x001eb5e07beca7bd38bf6c4b02e7997ecd13980eaadaa86d6ef58c2d3918c62d", - "0x00fe00922708a2aad3a04daa28a593b6bf6acdcd823d4625a931c0a6485a5aec", - "0x009f237894bb526fce60e5c637901a1d3e08d385a075700e6b022717c8f447a7", - "0x001cc87573a2403b57c33c7183741d6d36c15842cdda37d23778d145d14da4de", - "0x00a9adcd8429ef9b8f3d3ae132171c592dc0802fad274195e50ddb73824694c6", - "0x0047dc2ffb61192b0c493947c88b1ad1ad7dc0ffdc3e0c04cbafaf769c536220", - "0x00c059a88961db19f636a82854f64d1ded34fecd9c585ebf9d4aca2394379e28", - "0x009351d93deb3b3ee7a35aa01333ea9ca7d61c992964c07401b25647bb37ea37", - "0x00db6b15ffa6ec93d39147b7a9af6aa98bcadc690909f308f2503a780811cf9a", - "0x00fd6c330d8dfd651c813ca035f477797596fb899bb11a768f1b1a52ea85755d", - "0x00c7774db0f4e18244137cb81719fc2eab000d9d153103ed8dd8f32c4edf1c13", - "0x00afc4f9d1ff14d489dd68521e0ded5455d70830991dd6e2708a58356ca12e7d", - "0x00929192a946977e99104ee11d804b4a08e3d3da6485657ca0627e4997379710", - "0x006f0745aadf72ab233cfecfd29b3597360c903c1e84df03e0520ceee23b4a57", - "0x0046f5e6db10eb3714b755db5c5e7c2b3ac2668774fdc08c735441279ad42d3f", - "0x00ebd085fbfc64309b050d27d23aa593384f8675192df988f0622d2326d4b5fa", - "0x0051d30985d7420fef891dcf954577f43f72442dd14958007069161715fb81b4", - "0x00412c89c8f0decc36298b1fc5ba23469ac29cbc49c69daaead41bd19dc09582", - "0x00f8fce0cbef040beb905b34ae2c996a0ef885682bbca113f8285d2db57577b8", - "0x006c0ceaba27ceda641a17b1427740c990e1e437c77d5e23266872cf00a36c2e", - "0x00893b6de2c88c4a7683f0ff07674b3df94027059859af2e7dc961c5dc5ef422", - "0x0035e01687f7b8d267ddbd5d06d920c1dd38bd2df81ea60b19c5462473a330ce", - "0x00859df0bc08c635e533612e5076771e2828591753e04d3334e3e0d05433f144", - "0x00cd9272cff295baaf871105b6ec5122314d3ac7c2ee1b2f9d0e7879318634a6", - "0x002c87cda016444dbc917e11d0d8335f61ede22f4fe50626bb5f6ef828730dac", - "0x008224e5fe0d50a304acd9ee9c68e192b08f6467a546e34706768c971ad66147", - "0x003f1a06b9f95b85a086f203180d62e04cf14a37d78619467625a2d1f1633f78", - "0x005cc6b58453d764cd710d8ab736495432f18e38d08c003727dd87bae7b42c93", - "0x004454633281b2a338fa9c95968a5b275f6e1e5aafad780934864602f1cd2087", - "0x00e5c8023938a790e06abc1b8106aa928f46c2250bbbd4775d1a54cce7baaacd", - "0x001f916f9091b389c433ffdc4213efaa669981e189ebb69d3c284978e61bc15b", - "0x00e98e83d99d75d0fea9fefc315b8948d0f9a7acf672da99de21c3404da94718", - "0x00feceb7c5e1072097e2a845688360588446cbe818d5839cef07ad1e2993bae6", - "0x0005cb012c5aad05df939c952d4aeccf8fe41c374f89cceeec9f052b9e4d36ae", - "0x00c5120938da314252f6bcecd19c59c6dba4ec7b5c8e520d843d4a2de4f1b600", - "0x008a994849701000b98dd8fcf80ce7b201a879c16669149dff6402bc40e5a7c0", - "0x00c97d832d3751bc73fc6fede1bd7cfa98dd2c4bbb68a6c8383839300e682450", - "0x00b28f05bbfec9df9bab03e383b61e03be7eab8296ea15b4dc9ae7018b05f410", - "0x0045d0948a36255ead2a4e3f67a7998d1f43ee582cf8e2fe33956ecfbd94a3f3", - "0x00803739861d21c9fed48738f35ef388d3f824a867c3adcc13867a00f7aaa841", - "0x00cbf27734572c73b5a951d1d670c4424d6a334eb0df45d45eb6e4e32bbcc1bb", - "0x006626f2d2e74ed28ce5e8e928a6cad27acc9af56f54bcc011c5e82c797f635b", - "0x00ed10c007e316321f34cfb631ff8260203cae956ae96e5af80c6422a3898917", - "0x0063d2fdb6e2c228381da5d260f4b417408d813df544d3a6e8bb00801d051bc8", - "0x00fa593e59765b7a27b7c31f5328abbc901fcd4984bb548637760c7d9626a442", - "0x00b97fa0058eeb124eef202db8a976dfb69ed659cacb39f23bf56f948fd7c796", - "0x00f94c2010645d948185e5c3a2ac60462840e4a871a92af1f64df8886a580286", - "0x00cac18445eceba6c8725cd0de1263d5c4173e5d0cf7aab73d738b6a31a45a85", - "0x000a2113239fe3d27b3120542813e1bebd70cdfcfaa953296fa32af0d0737178", - "0x009f960132dc779a78675640b618f3752d1790204bfaf8159cff245718f7241a", - "0x00e67a98c71548b543e46295c54f2231970d238c26b24b9daed786aba53a2545", - "0x00fb5df950e6965168f0a8f3f66864b1b620d6a96fbae80716c76f59c3a281df", - "0x00ed3914ebc916dcf26e790381aed9a941d5c69b262037cd75736e96362e2094", - "0x0087f910e892ab621049823d5631488bb2258fa10af61e8ca5b7dee6ff5422dd", - "0x0039d386b2a5d26debe8f0fd33593877c4d511c07f036693aa8a7bffd79479bb", - "0x00bf53f9ef776b2dad1e14cf570da2b3c6ec5188abab81f5b629d7a6331c43b1", - "0x007ec3f9527a354470924841e137b1df52cf2eba5ccf5b9f5d9b886749bff249", - "0x0053071b4a36a52a417530d34c3591139d44ce602dd2c8eaf988a95746395db3", - "0x000587592f2468934db51946107a54558d95367c0576c1ce536744fba4492d71", - "0x0065af317f0fd32d37e628f8e18c9174fbb669203ff313a65166b7431668cb6c", - "0x0044e779e4e05417f85967929a69a34f86ec199d2ce31c4848271b9daedce37d", - "0x009d0d7d8695c61575a96975e8ad5bd95322eddfde0a6af9e1a7df016fc070cf", - "0x00c187c9f42d0b9e52ec528b8010a89dad2195422406a6e3985fe3d93fc67b23", - "0x003435fdf41c90a3026d126b5c7d27a4613961d4e9140781c2d9da7cb93c5177", - "0x00a4d559a67cfafa5586f4dd41a127feb8922538dc5fa6f674df6d63b2c51ecc", - "0x00a9226ab679d1fa7fddad4a15866812cb88b3a4c4b36c2026390fea5b69b389", - "0x006c9b8b90fa6126ec0aace713ba6b250b0667032cfddfca72b473d92a5007cd", - "0x00a0af11b05e1aa5560947d6c7addf8ca31018d34f2dc6d32b3d0ab074e63738", - "0x00db831fc2d3815776aaba48befcd028892967d4699164bd5074f8d157853d53", - "0x00cdbbff416de0f6e41582566437308ba8c076848019d74ad8b49627c51a4f73", - "0x008179ea3b56e7a97e80c54948dca87bfc121970837357339727f1620c444fee", - "0x00569197e1d57f2e55dc558445e60eb39874afa6398f62d7e5b13c7122f0920e", - "0x0033b1475d787c2328f268fa21ae15aa7f23c91f1807c4252b4af906b0a5017d", - "0x00ba222d8faab6bab3fe7924f542c42703a4532ec2b12db64941d6da94042baf", - "0x00440007981d35f9807cec4ab3c1fccb1a7663b4b519319a8ff702168148cedd", - "0x004b6a9db0814e8745b843820b311ef303424f7d59b36e8196b431eb4ad1b5e2", - "0x009974c2cf09239241ef41cc58a9876f8e139cb9901a4fd601661e61738effe7", - "0x00497d94e7ee3502f82e0372b6dcb2c7d6a6baae2806e8f33e1102b8b09b9a42", - "0x00caf15f143864b6d30bc45cf25e31b4e44d059e9ee5d3b680a0cefd653efe0d", - "0x00434f6eb2de9d610084a97a35db3c96eb243fd1c32f05c2838366978de98723", - "0x00c295e4bbdc97aa43b76749cc47e59454add92f808ffb8da24578bcfe3172d6", - "0x006f9d8f49484fbfce068b40e5a8a861c2f337bda1d4a9f2798b7b6930df2812", - "0x005bd671744dfe868cd0d6cb537aa55aa06384c9c6a996cb4c9ed464c7dd57e3", - "0x001c3d99745d675ba6ecd235d74dbfd695e266a4d81305f4b5657ad324874b27", - "0x00a2f2e6e5c4841bc4b10bdca84461f16fc075f1571b5755f05630cc92fa14e2", - "0x006b1592c2792f603b60674378f9497d74c510028b91e488de73febe4861ab07", - "0x00bd696fd25342d9857e95ed3ec8f9e98d115f47e6bb66036785e8883939987d", - "0x0015c4a748cadd901e0c9b8349b807c87b6831e006005fc9b413c8c9bd698fee", - "0x00e107f7e3ff4ecbc45df43d5d1cec06baa93f01d4b4615a9453414084f403a9", - "0x00efb6503304bcb43f887f3f0486c57dc0ff4e4e669e32687e889f3e5d46b9af", - "0x007a9dbf1a582cf78d81a3a40e932e2bc00ea172b755d780920034f5ea6e1b60", - "0x00e7eecf2c063dde782cd63eda3ba4b42f9827e68711d317e414949fe9cb0710", - "0x0008935dcb8e91efc2b9831d4bac1dc4e56b98a8159a40cd232c178d5fc5cfde", - "0x00cf1838d052786e8dfef6a7883190317f4a73357652d5d665202cca1429deb2", - "0x0010c3ddf277ebd93bb2d5fee0bc7d0edb843359e64c5dfe82c3b0d48efa873a", - "0x00c824a9533b66ab045697eedd253fa18cb1e95d850249d3f09c2a938dcae0d4", - "0x007156d6b02b018cba8760a0af3756a3b94144076ce812e11ea9b00d050c0efa", - "0x00b4d9bf8ede6d11f69b972edbf54e36e94707f49fdbb17300caff5b7a1d070a", - "0x00013d8a25340fedd8e15e8d25ccb630aedb822013524edb278818c9cfcaa81b", - "0x00394cd7963cd247252695b972c18ce9682a027a22a351d06181645c929e82d6", - "0x00de672f48d3d8eb72d64a03e3672b70f9239c913e3fe02eb0c35f722406e1ac", - "0x004508757a2c12e60f996b6848ca330fb8cf405e12865aab691bf974752ff42f", - "0x006d7f4d16aa07e6c931e737cc01a9415c9b02373acfca42f3dae9526f71fae2", - "0x004e7f67cc8442552e1c0e09d9f758a3e5a869e284fd3f8bbaec144c7e9a3bac", - "0x00afb991b35b029c85b0ce6acf7ea08c11e33a5e7fb6d92fcba5217e5ffd1a62", - "0x003f485ce8bf7b480c4c4734ead950995025911a1d48fbcbee5095fbccaecc0e", - "0x000d579c7b1e0ec1f4730f510b9c72f956117d17c8a3e6e5446feaf5b9d4a50f", - "0x004c890392d4210e246aa06c0053b88d0bd1a53f5e4f64bd3bab3f5d9ae99c82", - "0x00625cf279886246d867cd940c2b3bcc756668c95c8ed06025055e7d38c675a6", - "0x00b1d6b739b9d1b27a244adf9bb95e7de44f940729d73bc50928bbf4e7a075ad", - "0x0056dbd27a9debfc94f76a80513b02c16280ff7015f6231530bd24d860650416", - "0x00d25dac66eaa0d1bec2a3e5a4a477a4d5478d15c628f0c1ddbcbc1631bcc567", - "0x0063e82a55d1561156305314214f1ad41985feb85435f9a31dfdc7503446a8d8", - "0x005e83f1c176cc85d3196e495e6d2418374c83b2e945e632ac5ebcb51e5ba22b", - "0x00b82bd386fdeed319d28d5c0c7b979759b86cd6112475169a5dbd8c447743ae", - "0x0043f95a57b0747d61d6528638f74c23a9292bf01c68fa7c9a2ed646300605fd", - "0x00b6a28c85cfceaa33b6ff1e7b633844f464ea90fe4803ab8d6c70cf789ddd27", - "0x0061eba3447dccb6af71f4d2ee1a0a2b1c536e4e9719b034783e668ee4d22c93", - "0x00da3da7305e90e2470ad554f72c3fa39f0ab2ff4a027da47d6fa339eb54d458", - "0x009aa07e92693637da6b27b1a59b7269ddc3f6fde9c2f7f0b0757709ad5f10d9", - "0x0095e4e9ebc98e0fd1a463945051c4fad05fe8e7a40de7ba0955481c23246e5f", - "0x00786591f30ea8cca4d2e6cf5e8e167280fc88b492ba3d66a4e820c4b58ddf31", - "0x00d293eced477f1b512b571a896748fa28fd7b959de24a27d18931cdec7f95ca", - "0x00488fb8bebf5aa9a9bb8fb15d198700f164dc312c78b13d7a549bd7302093d7", - "0x00ece734a1714105e1efca2a23fa52b530221dfbc77068d6102ff528a2a5bcc0", - "0x0004dfd8541ee0983ee999f8fb3319729345ae2b3874e3dba25d9e1cb2a86136", - "0x0045f7705a9d879316b815a2168c2aa064bac071079da801743be070c219399d", - "0x00080b5740d36fe624daa440e93a2726b3c06d73f7fff4ee665a2fa7348b43d5", - "0x00d7ca72828209ef2e035b944b77626bf623f4d5a47efac129ddd51080dbfc3e", - "0x00a8532039dd04a051582395ccce3f4b0ca8aa0bd97a14ad5a596795bc55bab7", - "0x00d3b7dc8a994af1eb3b4cf640a038752d50e6b13ce2ab32ae9fa3c4094bda53", - "0x006cc4a20d6fec9047e3216c530863d6937f07a772545c8a5b0a6d7c440b1ea8", - "0x001ce20b88ba8332c8dd90f2b68f22cc0485ec1dedea804e2cacbc8678ad069c", - "0x0026104e7b5f85abd4de1a71197f15ad38742bd9e760914368c4b18670379c36", - "0x00b01e7c7738117af7cebe580cce6d7a7e612f682d56ec276cb1996eb8900d37", - "0x00f4485c9ef6dda339253649b1f9d67e09508c3bf3da93953a5fca7e6e3978bc", - "0x00793bcbe79176a6c421979524aa30b789772322ba10fae14225b629fe602a56", - "0x00ff6805402adc003952288a2353935c668264ab168c10ab655a1d77ce168d1d", - "0x0068cec87c83f4ba2cbbb2ec4dc16984e6d86261e02900d88e17f89b8a8eed7e", - "0x001d932cb122169859d58ec76cea9a7e93322ae34e59fdf0d69fe03731a23b1b", - "0x00c31104b882eabdb66a593989ba644f242cf5bd93bc558be98baf02f595946d", - "0x0073547358ef777cb56870a820a78f20697c40498b51d11e0dc34d6711f4e24e", - "0x000851cac7427e53b2f70000c0a2c7c96d31f80566f35986a22730f35a9fcf91", - "0x0035d7defd9d73f7a6bd058f93938e352e372f580d7098058b2d8751043f9b16", - "0x006a5adf37eeb382765b95f83ae4e95c9df07d89fb47481b299664aa254babc6", - "0x003980f4a613aa9dde7568b58f4a86c9c832cecf63d2800e6ce4466fa47a95c9", - "0x0010b01decd2829c49145c579cc8e6b8b1066ab168df17c7f2ae4b218c396225", - "0x007cf6b636072af9ac70356d3d42b567e39d1c0c725c1dea9a8dd2000185a4da", - "0x004dd769682eb9d81c506a8305de20847da1a6b6f1b0b62c9003ad4cafaa6a9e", - "0x007194cfe26ae27ce1aef7afe598369b3d08cddda1175f059174c81f391a9885", - "0x00322d54b321e759ff7d83d1e28aadb279abe9d4d1baeaa8de5ccdf42c2e0d16", - "0x00f3f115f2b7025c38ea32578820435340af0036dc7360d1a3cfa69979090872", - "0x001f7bee2bf91a6d0ea6a10496489f6aca2a383905803c545c7ff40f0f711142", - "0x0011a91dba977a45fbdaf8adfff1eb57b66b8f87e7db1de8b8d4c4eb9ccebe8f", - "0x001e57696e18d9a688cf0002eccdc684c15cad451e679215e8a65f862e3320e1", - "0x006421b1cb7bd2b13311a859c59da97fbc3d5d5bc25aefd900ad4e16b8b3b0cf", - "0x0026b17fc8bc48c88e047c8b528edb21835a18af2e0d874d381303aa904eff0f", - "0x00c1961652e30e94d73fda8d799e423d8bc764f6d97dd8ede1a19c6c5dc70464", - "0x004a6e001397659e7a0bb279be9b7903f532e7b44590f00b6848754bae009d42", - "0x008a9dc9489f4523e93daa72821dd65ffaaec5717b18598c93ec6ac079be3069", - "0x00da341e23397c124f0d53ac401cbcdac3c44747c1bac1096c6d98c0da183d5d", - "0x006c58a3f37c5df707e8d94c2972beb52f15e47355539b9addc0174d6c6be209", - "0x00cb187f0e15164cefa73998eb47927a9916aa3260c64b60a3d2d6f652904e21", - "0x00ba08f432383d58568473298f2de33e1f8ff2166a2c0ec30fa2f77c55d4a045", - "0x003462a547dae02a2afc2acabbc6bdd6d564c04cd3adc5ecfcee0851646d7e60", - "0x0004498ebc76965512143e2f787b1616d4f25a3dc0faff3e8683c587ee70d949", - "0x0021f3ce4afb60658b25454056f963f050534837c6ba9e4a7644623ca7f54783", - "0x006d6e9c5e2ea31cafffb24c503396b596cee93175fafdc93727e4e3e6c700f1", - "0x00ef307836469011447a855cb184a328141b2263b4cdc9b1e7414f7c419b801b", - "0x00390b4f404ecfff6e61d5ea37e9d75f30d3dfc700b2555495d1f31ac8341c8e", - "0x00b887045c4b1a3daaa05c483381500a4d462982b2ea46b255886f513fa8ccd1", - "0x005d616f0e3db7ee09628b2b5f553b7af1ed979b2c627b15feb2e2a3655c390d", - "0x008cb16a58c81f3ac9242693bea36dab1c50b074ef01ac832250d6a4302071a3", - "0x00e12fa70a8ecafaef84b55ba80724b6cacea2737fbe24cf88abddbb787ac08c", - "0x0009afb6dfdb9ffd01daafafb6286cfe2bac31f92985a50964163072902afef1", - "0x00a8bd1773264a1d771aaa2af0b6acd9123bae285aa5514f984b16723d012868", - "0x001416245c921a142996e804c835df3f152603640503b91e1695efbdaba4dc2b", - "0x00c918d3e883e038e1622256e0b92f6e2b483dc6d18c306efad62b49e82ae128", - "0x00f3b35c543b95d32e7bba0a9d40d8f2707e7761e25122b1641b028920750774", - "0x00b76f6e2559d53433fd0f7a199bf872490e516ee6cad92a6b5ba4cd3ae186c1", - "0x0089ba99c77ef9780b4d155011a2f4be68102064f5de3c9b7e2e301e40526dc0", - "0x00be2d0597949f9d9c9504d62cf42800915108f7874bdb80227ba6eac6ef21f9", - "0x004a2801a7cde7cc3f2832a3679272e0a3e5d8392b8e2ee39ea2af9e44c329ce", - "0x003a6669029fb7fdb889d5f2a61bed8afde5b92658cfb1b9790740b7709dc500", - "0x00744d53993651b565cf3ac0be186f072b57d58e01790106af3ea9adae1dd9fb", - "0x0072c624b81dd98e2341f99652ced6e5534b0a3f0c0ae34eb18f1eaedc384a5e", - "0x00a9ade86c9d45af0b9d462a5b73cc0fcf8d23948da0d8a879e5d319e0c466f5", - "0x0080b54ef2ded4dedbfd66ef0ba785c940d875fcfc8046d6376bf027f65b696b", - "0x00ce8285bff4f9bd5f1fd8871ee0cb94afa7495c6d23111b7269db4028a6c80c", - "0x004033d9de20b0a2adbf35cfc89a91148b1a3c0cfc810ae87e978f7ab158bdfa", - "0x00fb37db0763807dc792922432f401e2aa6f0b43b3b0d99f0fc505c41deacb9c", - "0x009042c835698764223756a75e4e754d7872882ec1b6487892dd40fe7e947581", - "0x0019469e129651a23956b741323800a8003ad1f154c82057536f1479fcbc8eb9", - "0x0085a7dd1da394824ebcd8c349512ab79109e2d69e120aca982a54e6253efad6", - "0x001654187a7ddf702ed68ff0314da3400e77c69f205d62f8d4c4829f9c0e4f7d", - "0x00b032c8a30c02ecfaff36a090c65c5ed0204d83a2508ec5b930ebf9ec3c2a94", - "0x002537946c16ad9446d343d31d6b3a6da11b522106b62da38fae227827ca4c61", - "0x00ee302398f310892e0dfd2c30dfe79895528ec3cbf6dc19b898c2970729ffff", - "0x00acc97dd23e719129e5990eedaf3d1e21da53ebbdc0385f7632ee42c28e8ed0", - "0x00266d99956b450493165e43a9bac9c75e2fecdfe698cde7198f9825a0307abb", - "0x00c0891aeb4aca038b55ead25ed2b2a6fd08d2e03617c0ba507869b5ffab3ec9", - "0x00661e6ba65aa316a460e18997db703d4f419e24fccb80e45c8ec5778d1068a8", - "0x00a9c9a8c5cf6fb7ad0407acbce39711c602305c9acd0ab571a4ae022aa1fbdc", - "0x006ca97c7f6f9b6e5e6ca99572bdb5ef6ea1ef1674ed72b0b65e860db70534c9", - "0x00f646a9d6393cb8a6d739fee207bdcee1e4ef5885e293e91f8837f2f9dfbce6", - "0x00409f54eaa65d9fde410ed788caf4328dc8c11c7da7fea0bc65e02543e32d09", - "0x0007f5c48dcd6dd9badabd9be9b0ae377d1235818ca2e7dd23869a4bc1d05a8d", - "0x0047e7238f9a0789b896bd145b1cd27d89615ff4e02f24b69c4df920970fdeb7", - "0x00b1870d17a845e1d321dbf9df2782a031ba2c1694ac17048ea39e3a279b32e4", - "0x0097ed075b27eda5a524bb0c33d1c16000aa42c945ace6a6b3f6cba29bd55486", - "0x0047e4a3c59ef42a2439c4054e2092f634d1e4be71edda6016a9e36c66b75818", - "0x00b6cba9846a1c443e1384be55cb8289a37de3e01ef6ea93338e615213ae71a5", - "0x0055c2809553071e3328238505be68c0f6b92943120e337930599823f072cbbf", - "0x00ea39ea4611fe1dfc8233d0c9c849ab55488df89dff6de6dfca46888ca192b8", - "0x00f0bdc36eb0e9dad5ff34bcc9f0b41bc48d07509698463a874bef497c861016", - "0x00217d4617657a01b0e5718bef2c24a9046f291f5472b19b43ee97852898e8d6", - "0x0032dac077fc4d8b956ce1317d9469ed367482415297e1e90b685b1fc43ff436", - "0x00b8711e7a071cb7b56a056ab9fd6177c38e671449c65cc4e6a9a8c3f23d038b", - "0x00561fff112ca35dc86d3324a8c34e951a9ed2d9805100c8c87d35241702681f", - "0x001672d552d381810c18254aa00e15ff776c5624bab1856437824b1c022392ce", - "0x00f60c036bd0d0f20d2c717cd667cd36f290048676938ca2eee79fa9acc28119", - "0x0080ed0fb199b0258cdfe5ce1bba69aeef285f775b497a30134f26bf3b218911", - "0x00484720db954a7287a71b3aafb3c309a20175e377529c70f8fe949492339e05", - "0x0028cf2c06b89102b18a48d58cf628e98487ebc4325fbeb78d9c0b39f7eb6236", - "0x00db83e1058527ef71062910be25fbe1244a6761d60cc2710ebfebb2531658c9", - "0x00cd66e2b6d3cc96966047f2a6d210628de71d4579116df407aa8713c5816f58", - "0x007210d79dd986fc766d83f84b26d47889394345fa0bdba93f4b1fc927924375", - "0x0078fbe505229973b34f50bc7d800eb5e54f38584ebf346075b4b91c6575eec3", - "0x00cfa6bda52b6b9b5260308cc6ef7673e7a816deb11240175bb24f3f44121255", - "0x0077d6ee969ace06ff026c4232e04b9a7d91ff661b4aa595984f78fc2fc647be", - "0x005c9a73b0dc3b552016b09f935c13851dcf923b38b0f9b565185e1322ee1049", - "0x007005acd61cc31a25bcb1c86f7fd494c96b2c6edb1bcff9c963e91c4f937c9a", - "0x0093f62703055f2acfb1ce64b01d997072503f2b6739225cf46f1b0b2fff76fc", - "0x004f95a24b9ec9b5debdeda93b837ec389825cc41b2b0d4ad99cbb9b34e1399a", - "0x008bbc99bb2931303f81974758301d3667bca9c61b7cff15b4e98d6c51a2d40b", - "0x0012d93de24b10defac6d8ab6cc14cf17099a58d55c74519efcd6db0cda04c2d", - "0x0012d2045aa8610ead37eb583bd8883b55ec25e97e07de162caa530676b24c4d", - "0x008948c810a65d05b43102985960cbabc1351bcafc9c57b005300e197e4b89ec", - "0x0065751b37243be79651133c8a9dafc3a434999bb33f82c743ca826ad40b7e24", - "0x006de73468028ec48414e25e31bb6154c4c9d71d7c40396b9a9dcceee76907e0", - "0x00d5fa9707a1c546be3dd8ed53c83c701e5ac9f5ae5efac8e6bbd98fb0d336eb", - "0x00a8edcda29f05d7fe0e83ec541e7d5e0650162decb4cb19623ff358f5be62f7", - "0x00a3d83bb966e0f8a72a78d4758432c19c77054980a8fc622cc826c885a5c219", - "0x00c5c2500b03d552f2ec0cf6b96247c38d3f96042376752832d93b895e3656d4", - "0x008a2d8206f35775723a2b8b7c0d7c6d5ddf0562d9e360db11857dc9e92b9fd8", - "0x008c3a1409f27172db6c7fc7adc05a6a3b693de2824648b36533e03543ab8181", - "0x009eaeafcea45fe3ea3919d8ae2f55e057779d4ca17f65b9e86b0e8e337a4b38", - "0x00a03033165e54784b15dc62c28eaaa7f1f4e2ff511e1729717e3045cbe83013", - "0x00998960de16b36ef856cb58a5076f93fc6778993b83220acf056c9d55f9a6b7", - "0x00a496017feb079dec75831874e7f10b7cde8df653af66c19984f534383943bb", - "0x00d2ddc484cd66a011147f0b759478413ffaeb2803d5ad9e3615d5d635fe7144", - "0x00dcf5b0287874dd87c97dceda2702f398087a25e3f5f0a5e0b9ed68e8d464bf", - "0x00f210ce35ab7693a0437187f16a7928dec107197d9430942875250080cee682", - "0x0005db2d6c79fd4fbd599a298b2c936ac244d283cf3814ff42d61a77da755364", - "0x00480de62399d8f975b616c06de7e5f89334051b1e35d91d5bdebccc2e2859fc", - "0x00afc8d62a7d2b953635e396ed755c2c8a9130827f6bc416a9676b2fb452d72e", - "0x000e595ce3aeea011114b7f0458bcf35dd112f5f84b65ac8b6d87e14a126da08", - "0x000fb0493b58d3a8541b39685a930a569118a285877a389664a54800dd8d0999", - "0x0048762dd339e3d7c2b2ffa7659ff832408439df6d6a12a7d74e805a64e9e437", - "0x00d596b111641be8ce5560ccb7909fa2d1396fcc014d0a1b85a7428ff86978a1", - "0x00f12241e3d6682392e65c7277353b477bf2a1db9cfa2be44065f63822dfc4e0", - "0x00aa8231b45f9c7e2fd0210affac698932fa89f78dda34a21c7690f119d0f4b5", - "0x00dfe4f32cd8929f7edfb45424ea5123054ff8b3cf3c0e1fb40a7bb7775b3d21", - "0x0059fb6fdd15b4c49a247816956ab5ccca31a7533bf6e4962f0b32ffb48be944", - "0x0038bf7726e4aabd1a6ee826ee8249a35bc792b134e848ac350efb9ec1d14c2f", - "0x0096ea99f28904f5059cd6ff82e80a9e99923053abb9148f04aca00ceb486aa8", - "0x006556e173193ae07fb43041162ef5e009e33433ae6bd7df4b20c9d7b372e71d", - "0x0095df3415298995a4087cd4f1582205efd7754f6ef946a1b73b7ac949eeb1ed", - "0x00b7eda6d48e90c26712b625efcbf9727e5aed6d36200d9e1a5833321ce3b5f6", - "0x0033c17c709b639e33b568dd4f60c7d2c71af4d28ff90570e6e193d26b5bdfba", - "0x0060153aeed79ca04c20b4070468dbc26faf5891a5df6c915843030620b5b614", - "0x0029c3bfc42b9cfc82e2bf4d52cb47670af49bf1028cad6e6894767813b2be1a", - "0x0014b72401d4bf7b31114d0c3c26b136937b13cd5843a394dad41fa778566d0a", - "0x00b7755c9458c686061f150fd48d240c9069794ec778db6cfedf61f1519643fa", - "0x005097979a6d857e9a1581f1ba3aa21acef7a3c765d47a37b6ddcb988fb52aaf", - "0x008498158549c70232c861894475c612daa5d64db078546396c50a166954d320", - "0x00102bf3372e5c28041ec1505e0a9678596fab9967ada6156b7546bf4066285a", - "0x00daaee3ad08ecf5b38e69a70d305b7bc96efc1cb4d99289f72d738b9e23eace", - "0x0090fab262a6059137abca96794e43feddd453f2ead489117ff739957eb6bba3", - "0x006049d41185c94b4ab6e0354a86719201c1aee19546cdf8493bd1e81c004fc5", - "0x00e7dbe10471ec8ad58060f4ef0eb17b25b002aa979ac08d6d03b0c417e60f77", - "0x0021b8d731ca7a24bd1c6e58d2291450fbb6a950bca4cbd8bbb4e63cec3c8ab1", - "0x00d9c607c5882fb21b92f570dfbf4c7b9525d3da2f5124acfeda662a54d2f464", - "0x002be5b4db952607075ba6ed781d38168fc27b412bb67fd9cbc19ff5066514f0", - "0x00a05524194f092d4412455321f096267654e21df7566c782c3d712f8bcfe1ca", - "0x006f4f7d2d3de4189b3fa02cf7f0cef266620c72611de4dca2dc8e18e2d763ef", - "0x0041022c77a6aa6c2d445ec2262e26745d58a409c0046bfea0a0525b0f748895", - "0x0092199f6538b4c0195ef48dba387c35351e88a1a3c030b888e21f4cb8323f05", - "0x00293645a899f76bc8a1fbd2c1c7efe5b4a9d507918502000992efbb51011f60", - "0x0074da5b7e2829d67bc4c79cf9b1e78f00f6ddcdc858051dd7ee4cc1f925ec18", - "0x007c9f970668b6578c805799b524a36e4f9d0bd59074163982b5fe4c733217cd", - "0x004162ce1a5b24b66a7de04543a98e40cd7642f6ac7017f4e189f6be8662ecdb", - "0x00b3d99610106ec1f812fe0f5231ba4cab4d1754f217071f3ff5f7b433969e48", - "0x009d7dc08d508ec044cf2586b0a5f215684e0407db7390e28af84955a3165e18", - "0x002a54af38f59bb7ad99cccf08157311064cd26cbc31d7a6f8a2050430cf12df", - "0x00634dfc782ce17d0c583528c670886ce70a555d3be42a0bf377db313de3410b", - "0x00f4fbd9fa0608dce992ef251b3d68ed912eeebd6a6756ca654d1e3bc6a3f39a", - "0x0055796fa0685090728af59d441704f74bd85f75e507bdc000e298b2fb342933", - "0x00ddcf0b29027616546167319dbb263747f91298f743bf7280fb1ce4c6cc5747", - "0x0097e9eb907fa16d3dfb810ced857ae805b6f36bf6e24a260aad068881440ee8", - "0x002b873d99eb62fca06c2e72bd872848c45f1d8f38bd05fa7fe396bb938a2e39", - "0x007505014763582dc3009f488b11f0f5a1f1e80ce370d6c279c818dbae21372b", - "0x004c0bc970105312e78d80cb1fb4ea0dedb06430058d6917efb0c16240fbbe92", - "0x0054792388230a394b7133c8dcb644ce477dec4975dd1f6a4e247eff6c32588e", - "0x00e1a0e351c1fdc95b88e2d3edc3cd88d15d714380099bb1dfa12067a04f5602", - "0x00cc933a196908e0f083e130c07528b094037b92c74bb0fc4fd6546192740edc", - "0x00eeb5cfba3f5d63989adc24f1dcf875a6af907a541f6809e62ce1a4dbbb1a11", - "0x0008a19c7933639087771172e8638a3675e33c6630b7fd901e115f5ab2251e42", - "0x00d4bf83c694e7ca5a63fc8bf89bb261d70c19cf495cfc33114f2396650ffe17", - "0x00a6ab05639fa4a4b634ba063da57fc9a6baef246d03673e7f3cf0d9fb16de1e", - "0x00699e3781d1a49af75590e48f3d4e6a7d81ecb5a78eb9bcd1fa80d25b5dc41d", - "0x003ef6de9b5c589d7a3b4f30aea1ea08a97fb6a6404bf37ec5504c5752b0f6a4", - "0x00f3ae3a93fbe0ebdebeefd121abbc0ce765950d40261063ba6117c1110d498f", - "0x0083d2cd99fcc40a4c7a2a742691bad197d4ad53e44920038b39c3e4924005d6", - "0x00fdd09bec815874e3a26848a3cc0b29225ff87419385b8f94f0d3a44fa0e089", - "0x00f923677e08cb610950bf7cc4d27df21c7d1fa14b969cd7392924a696b75a25", - "0x00ac51d27b8a8f459fca2eaa01ae85c814af4e0e548daaf3d5fe3f4a7a2020a0", - "0x0094701cd0b4ae19ab085afb2316d8f559eb8a8d81e9d342552ada721abe2799", - "0x0066365258465f584cec3e37ab0ebf3f9216d835f26123237013d19650a7ac36", - "0x00402032be6d26ea8fa1fdfe41f5205a71dc126cbd169d7ed5ecd0b01f2bd172", - "0x0077e181ba4e01ca49c8f08b6b63bd1c49a24818dd47315253ff67a7ff5c6fe0", - "0x00592a19fc5e00c50ec5c619279614d87928a6dcfa86a304eddc736fa12b25a9", - "0x00b72403bc8ddcf7095150079be551db86914a3b982a5e67709bebe3df291a6d", - "0x0027a666071c954b6ecbb1663a9683bbac38b0f10546c52dfa69997095a9c0d6", - "0x00390d4e8e1b28e498c8e4c160ac7d21e081e8375b301543320cfe51197cc406", - "0x005b2e7bfd08886719b2e673d65936d68655a034c9c4834282873474769fc854", - "0x0032420c144255fb4edb3e0d22fd59b35340d0a7a74039e281031d3b452d9800", - "0x001d050a728c649e7aec361f259e5e5757e0eef826182722ced6c5e122442ef4", - "0x0069a2279f8cc23cf9446b70d8ec025243f4278f7c6ea20402a6f6d27fc3ab5d", - "0x00c0b611a2224fc66b9890a4307bbd5a134d0a15a0c3fba75389e1b96577cf04", - "0x0032b94f760391c50624b626ccb74c2d72ff41ef56a45417388ff9daa3bbd547", - "0x00ef16974c80019ae0b0b631433f7ee5594b7e4e65eda02b01278f63b271eae7", - "0x00cc06ffa62b8cb12e1c9f0a79eb16eada591d8b8fa70f3396f90dda8bb4f2b6", - "0x0074c8c2c1d84c1d6202d2e20a05b62de79155dacb0fab4646e83daa84fd4c69", - "0x0038157f808bf17ee0a5bc8a8acda426b38fd5ca0ab80951782932c5d0c9c7e2", - "0x009059d0280983f24981e1a95de80c3664492b455c038c9be00f50749d632f11", - "0x0096559ba577aff2696028690877693dc52f07ca721a7d7553aacafd17393ef1", - "0x00bd7c6272b42ac7205dea4d5dd2d5874eb97e15d596f08866cebc5cec7f24c6", - "0x0041b812202d55296df7d47f1520934cbe378d60f9c0bbefca21bad1fb0335f2", - "0x0046cd913acc3cd16414ee1eae07777a489b4bf15a2820fd3097baa3de5da280", - "0x00f9c2ae9f3fff3d3bfe0761a682fd51eec42c9c1c33092f43621eacc6a68400", - "0x00a5e59d03936b14146cf70552ddd33290b2a892ade5cb2fe74389eee36c303d", - "0x0047be7b5eea3b502b91236ddfc93df72a8aeed993412a761b78b99e4648fc1d", - "0x0089eed3e596fe002301915e7251ac3907a14179a2e22e5555719d2c78af3af7", - "0x00f18ad1dbcffec3ba086e8dfb19c3f054f34dd5c62665497d3222fcac9c338f", - "0x00626b0d015e7cdd4d13a97d498059a4f341cd9169e8561f02a3746c15485f81", - "0x00e87174b78e5070f64b18deef4b4bed1507dfbc95ed53370fce13c6c42f25eb", - "0x00d6b0bc1959ce15124135490d2930047268a82e34cfc2910494c9171dabe191", - "0x004e5b3147d777a3bbf235d8fbcfffda62be7d41370c3e81c2dab75496721659", - "0x0089a4050e736bfc6ee6ae6dfd2ca19af625fb68e4686823ca901a556cc74b12", - "0x00b51c9b9ae4caf000ac8510c45be95fb3a985dfeca04f66babc054f12a8be6b", - "0x00c2418704a6d6d599b4167643be571e460c33b88aa7bda5526f810dc1062062", - "0x004212f364f8d0557b912336f78742d8220e85c4e82fe9e029da475161799b20", - "0x00e414e06f2aea7ac7f9447371477182e38cac663ee3d74ef8bd726766c1cde4", - "0x002b831cd0102a507a3a79e1a522d4a8f0ba947ecdc7b31e38c09783222bd099", - "0x002de598eb5b42a4e7a10d377638b6ded34d130cd59902fb490ed3bbfdf5402b", - "0x0072b51174bb9c421229e955394dd594f7c44600d701e80f47b20b473462b7a3", - "0x00dacd8c36027d4a1f712ed0500e5a93c46cb0326bca1486293bd235d63daa90", - "0x00e66a6d98dc335ee91f44fe54292bcc22baf95aaad1547200a88f9ba0932798", - "0x00f0b092c92f1848396e4f8b6fcb5a7650006bcd250fb61599e996c364ed6c28", - "0x00db5869cc1e5e3b594dd4e4250c4dd446d31c6344dfeafa1ff339827a2ac2e9", - "0x0082e0bbfb54d9326adfcf2040f650438e506498dc6b32f3b90584ef09305347", - "0x0058216aa87aa505adec13a4e9b4be40ca1452c4584ebe9f84fb1d2ce148b135", - "0x00192435918b999e569997f880b1c9eb9db98a8c580c99b0173d9b7e5bf84303", - "0x008dad1bb65f21c3ea82e6fe2623c550b4a3cfe8c6dfb79ef97b77efbd88c0f6", - "0x00f8a14e988d5e0a4285842523ff64f7cbdc8dde817b72a4072abff07d8539c4", - "0x007171252adf76eb3897a57e0f565dce28ebfbc3aad498031fafd58f5bb6a72e", - "0x00d3e1e3b900fad00c2c1be9fe63b39cb8958468f71c1523a5c7023079fda99a", - "0x0078442f2ce373a49f88417d921908ad1ab0863b9499aecd6a0edc6f6505a9d2", - "0x00e15eb6d09bb440400fe301159866d6add5f56c906a24916d90f860e05551e6", - "0x00c327250870ef6734c1dfe580302360cd235f5a0605aca9a1197e263e87c178", - "0x002b4d422f6844280324000bf44339c9b0a48598bd81f649a548205920c2adf6", - "0x00faab41f2cf26027730ac78dc444bdd6338de6ae5341b4406b3ba6d80cc2971", - "0x00dcba5deab25edb0ca6f5add9e9f4d36b88a4adaade4262a1d07f154ffb4bff", - "0x0020772efa3b24c42bc01ea949485bebfc6bf03c9be80d573cde650f9f359575", - "0x00eb785eef4ca0f66109f7913518c0cbed0e6e3585dbbb47dadf756fe79dddc2", - "0x0037fb1934311f1bd0268d61ecc312c5a54d2906bad5a8fe5e05802ddbb9b98a", - "0x002cc2a2fc86bc4299dc446eef84639c93dec0f438f33219a3b5af8912c61084", - "0x00b4091748714489ecb634c47cef630e1cbea1669f94fde6674fb9e19288ca0d", - "0x00968b1772eb98e304993437b5eb6654a5899671091cf6b8cac002b2150001a2", - "0x005e7dbdf94a95140f98db3128d42543526f0f6efc83b3ca22fe538c433bc5b1", - "0x002b6e6edb84dae70a5c0cccc64c3c8e1abc132ab9edd158ca5cf92ae59add34", - "0x0023b2e04f4af1ce58208cf9718bbb45cfae1950ee31aafac39ae6357feac75f", - "0x009973e488bedfad6ab93c33a975af8ac588f1e81df42d36dbcb593c679d89f1", - "0x000751599bd51fdd4b4a747d02f2eaf671d5c322193bcefd43f30a07d5432eb0", - "0x00eaf0b87a45431fb41aee5cacf4f7d266dc9a51bee21580e711941664a1b2d3", - "0x0035e4608811d77ad97fb20c283715bc8ac76196898cafcfb570ab294b7d2858", - "0x0055d5cf2a94d3cd98920f232d8fb3fa22c46437369c201b6de71032bb3ee3cc", - "0x0082f04ebd3baa6b6f9d0cc6fb0c92ea8f15cf5fc27ec9718f21a14f8eb09b63", - "0x00ae37fbe3459adce07b45fc35476e2b9c41d586acf0cd2a18cf509f3b3c08e6", - "0x00164540b3ae1688f379dd4f1873eec2b7ab6700230bd34962adbd7f4aa9ea8c", - "0x0027fddd235266b54c4f348ed59e70e6c1cffc14e743517a7eb07fd15b0431a2", - "0x00555c532a06d63e531df3de39b26a20c5f7ed54cc32b66ce5c6b673ac681f74", - "0x005d92bf45d9bfc85a1a8e7281631b8a4206464858d144392c157d3c5e0b5f01", - "0x009bc493067afe64a880b6da5fb5f1c3bb4d232ecceced74ddc15f069e441205", - "0x000b50dd3b1f0680f1b2d43c81a0a66f521ace5c6685fd9c13dee816e43f8e85", - "0x0007b54a7d55a84824b3c652d5cfbc1f252d337d9e27b681f2425859d0fcc90e", - "0x0029311bd6809b80124de04db0836b010207abb5a1c0c2e5639e29388c52eccb", - "0x00c42c757145ce367dcbd0e8bf1d7de81d873488096ea6ccd88b3953403d7eef", - "0x002d0b31be6716a7f533336800c1f7e6506a644696880a54f3da44f837c4b5ab", - "0x00ed205d788b03195a32416c9c93883d59644680cb88975032f8321e0b94fcc4", - "0x0017619cbcfa828629587488069dbc7ff205c84890823fa0c336fa52ecca3e5e", - "0x009ab0bfe81f5af6d1daeea6ced79e00574632607edb16f48aa84c5e96050b56", - "0x002981c4f4d4b85f6e2d65e01160555058b056bdd17e24b3934ffdd37a38af64", - "0x005f66ab0c33bacd650bc2c3f37457fb3aa8008bbd96105d6ac5fbc1b0ebafb4", - "0x00f623f102c60deba54e75e23f2193567bea7e0b8b572fb2196f3591bb5e89f1", - "0x006b88ea09650ae8e34b3e3e94dac4bde8595d1119105c461054d1f105b9aad4", - "0x00ea7d52ef74a94ec89b11bdbbd43f3616ccb5a5195f24fabd46579ab21ca6e9", - "0x009c0c2abba646d55471850556b0f45ee59d4c6f17fdb58440e654fa2f29659d", - "0x00ac034710d0eaacf1ce171ea0bf8e93342f3cf452bc0ba08d745673c314b917", - "0x000b5d43a8b74d3066fdb89793a12b4a205da8c7dd6f27a67bd5c7dc76c9f76f", - "0x0073b9aa68afe300d5739b6926719db7e3cb040a93621060a5ba76f74c7e9b6d", - "0x00a06235c58c0000064c210f15bf8ee1ae4384e1bad464258ae743e432d96ffe", - "0x000e3313fb5bb0775ef510c6c2b2a7562bcb91e5d3153d4121c3b2818504b9f1", - "0x00a5363dbcba0410a9256a96cebae752620b7483d3cb19365f7870155d0e95d5", - "0x006b6bb243779ea267ecdbe821a7e639fe925b5118fe74c9f58f86e3e7083c7e", - "0x0070b0028d3407b02eeaa816a6fd7ce6f89e515dd84101b33606b88d03a85c80", - "0x00a2f438bd7997a72155438a46e92aec6df5db9f8962cfc17dcf289b9b68d520", - "0x0040239249061450a0d8c77d7a604f8d633ee7bbac2a087b6884f1bc123558b6", - "0x003e36a893a8b911f2a18f7139f1cf22b01e3fe7ea2e38b67c1a43b55b8336ea", - "0x00978143ae5b309aebc7c97714878fdb5c4c7a6f859c6bfefbec2ea92598d0a0", - "0x00ec5f0f47a37c4b6935e7bae756405a449a4abf2902c48dd435eb2ece0c1d15", - "0x00cadbcb3c86719ca1427234c2f931f315e624c8f8756f691e546c501591916e", - "0x00fc72b00ccb764d6420a14bf31b0080e9e1cc38d02c3b3734f813ba179e63da", - "0x008e3c075b3b9116c6e21489b750a0aff10b0db87188aeffaca35d3f782357a3", - "0x008e466b9eb264e84d6ed99aff0206942e6b7283a5a88a7201bb5a89baac6b99", - "0x0043046a364960d0fa1a1cf43ecbc07f224767bdab8a8b323e540f302c4b8443", - "0x00a014111dfbca436cc249678fcf79ba14162fa9d28e42ac563c05046c782a69", - "0x0081c0be4228e6f18973ff864cd41bdd772a847b57cd106644ee70099cc7b596", - "0x009277b21e2b06988b271d0cb0af9624d994cb894e0444155b664f05b31feeb4", - "0x0029e268031faffe37dc6296b2b77f81508ce511d75a499d54da0d96369e0d3e", - "0x004103229ecda07f2fc9ef7e0ebe1b2c2fd99b4b875f9856dd5c5e35e72c93e3", - "0x00616312396b89125cbabc09e74d545f397789240c536ba4f39b226f0b467dd1", - "0x00679486beabf52631223dc04ed39d7b3ff26e9f56609b587d8bcb74bc0e13b7", - "0x00d93fc63692714cfb113e50c2bf10f0963344c2c9982686edbadc286ab137d1", - "0x00a4c8d59622580491ea4b07e1777c0a5b9c3c7d35cb5eef20c196df60e3687d", - "0x002dd063325975883a311bee3760f5814886fe2142b88f91a94869e82fb4cf9a", - "0x00b59bb79b5bfdb1b51e723e5e6dfe345e50d4e61102f770a356f371cca1cafd", - "0x0018a22cab9c4eca43f9a364ff22842e637fa0981c67755df11a134f278de900", - "0x0044cca4c37bc93c12fcad395862f29f9cd39cf050c7b8eff8be743369ae509a", - "0x00de40aff78eaa74e9f7ed6f1b7c7a06fa9df3938515631b5c30f978d2198300", - "0x00fb0298ac2468436c7cec5b0e9c25233dbc06c94134eda688c9a967fdcbc130", - "0x0087ca5125de8ce4b5ef973b1e0494adc5d41b703067ca4b1f6ba3228dd4ea88", - "0x0027ddde931a385c4c7f7b992125d3c0a209e71a36644970170db7b673b69aa5", - "0x0039f76dad1a2b49cc65cda1c97f996a21447b2320ac46e3cf8f7da852cc9026", - "0x002de34b3d6bc958035b2b57cd80ae5ffeb17534337d80c005728714de53de8e", - "0x00c4dfe4f22b613d29b5b0e28ebbcd016e84a43168da46b0521822bf2a257d14", - "0x0041e799d0c373d2b1ef6921be31d6f0827387e9e19220825e873da4dd9fbab8", - "0x0021a99eba035761bc4dd19fd87b8d5079c289497c942c9023d25973510b3742", - "0x00b0d37a0eb3735e6a55afc8c7e57f5e160dc30bd6468019788da2d27b96759b", - "0x00bf30f8b3563533737e4be28ec349e45e67fcd81318d4f8e53aafd2f2ad597c", - "0x0077d4990830670e3863d31db4f3ce62954ab950f6bc6737e2ed1aa66d85e300", - "0x00d997fa3f42f65892596ed49c1a7a5b77db1e816d61114a6f6e605e06a42ea7", - "0x00ed7af15e6c065e851baabc83b524ecfb032e77fb9ae63a005a2eb81fd33c99", - "0x00eb0a10582156270dfec4232dca2c28a683e3b3b5c3eb4ff1b005efc1d10f19", - "0x00d5fd441995b347391ebad406bc480a5b819c73af1989830f64e7d3397718f3", - "0x0068418a26b36dba791dc8c574f3f113552f692f501c5f195d2aa054e0a2a892", - "0x007518cf85e75ed95334fa55ee5ebf341ba4467692098f21465b39597d2cd35f", - "0x0033a2c8aa616b948579d426ee403f858f7cf4f893ff0f4dc10a39042ed34a2a", - "0x003fcf16ee44efe5bfbd419d4b0c437df93d209d29eb5f2784468dba39d52286", - "0x00cf14b3d06768a4f8e3d8c4a750a72b64a15b40361532a1d110b7539f84e135", - "0x00cd6e6d1df77609fd7fc8cb3192b94290725a064de6e8f3ddf67e1ac0edbaee", - "0x00e9b542e054c8ee647531621bca9c3cb1fd7229b7e78215206f556f45555a2f", - "0x009428a2e69910f4614badd58afc732edb8c1c828e33c9b928d19802b4827906", - "0x00802442282af8dcd3f2f4e307f78b6db0b1cdea4180b54875c7615f39025e80", - "0x00eac9f396cde654588fa3ddcd1c02fb67471d46fa6cf75a66d458c188614c8b", - "0x0043db2c78b98dc917c82f403acb6c7637d77f9b78ef35191ab65f5504896fe1", - "0x00f0932e30acc8d8554b496c09ad84dff13002b8cdae2fbb5307c8a6872e666c", - "0x00b5ac28c7aedca0a7f015d9a0fb4e33db30f278266fe07462470e6e873fddda", - "0x0078626f66518fd5b756a0bd154cf58a9a43b1b91da0bbf99bb0cea380b6c6ee", - "0x005cfe096407fd6a81066f14a495f77bfc7cab57eafd38f60717ea84b053ddac", - "0x0090f9bdd92b3c2ffa75a3ef70c163e2666b2012051fd303c976ac6fdadfa765", - "0x001ed3187603927a0d54e3b5f11cf1747025a64fd74f638835c2abc7636936c3", - "0x004f6b0e48d2e599114f46a4a7ca06bfc2b6d1a138abde15d5c0356648e0b620", - "0x000204006daa305aeffdd9c662614eb56236f772f55f84d54ac4b1fce77bca3e", - "0x00c947625d2e5a47d9ddc83caa8d08e7c15389122a9518d681fb77008007fd93", - "0x0057e0795f0fd63508b002328596534a0afe56df1c75d7907eb9a97cc9ffcf92", - "0x00e4dd42e02e368b789ed2e013b29f655acc73cdcd2152deb0a348f13bc52283", - "0x0042c1f3b8625af56499fa22f1cc9aa50857b665af9d59ade878b4ef5f4e30f9", - "0x00891c2dd8c837960a07146a93de27562eb06cc9ccf287f02377c62320274c36", - "0x00c1a1cc9361c0392c79007acef33fef59381622ceda07e715071bc260724b71", - "0x00974121c30b2f2b3f9572ea8fc358cde0a5bae6e8acba3e616262140e09c1f1", - "0x0060860f6a0562f7f15c2a3a31a2ca4e8438ee07eef3ebdda28074b76ddd7d2b", - "0x002683851b781cbb5505cb4dc28b03779303f214a0921ca431c018c1924d0e32", - "0x00c7930a4d3f0156cd33f7933fe069012a5018f4d7ae791bf78d73f2dd6d7530", - "0x00029c262085df0f677aa233a4cf69ebef7a75235f89dd0c1a3c950c9d2385ec", - "0x001db2937fd86c799fdc72eca9147e3550d1065585885f187ffdbb4eb33f2494", - "0x00f549a1d51c88bb1346ffcbbfe842f222a22a8dfa589038c72074a90eb64088", - "0x0078667e3d201a88c4e03e3983130b51474d42a58886478db9d621910067adc9", - "0x003423abca055983bb638b1d4c8266d4cdedab104161a807043ff8e6c0f3913d", - "0x0081ca1bc8681dc8401c096a8e00cc001a5d78ff4487bbe8cc123a4fb5905742", - "0x0051121b11a844b5b30d3ce7791f0d33c4e149f7e78a78d0e6cee8d80fb23dae", - "0x000660f87a3cdb53cad607700257662dc4ce7befb1e819f10daf04b8c28332ba", - "0x007c26bf786d1a9e283f6b93b4e656d234b9ed80c67f972fbea92145618e125b", - "0x003a1a96fcb937a7f3ffe3d11605cc8464fcad93990db68057c0988857874fa2", - "0x004968f1d37d38feb58a89ba3820e50a5a68df03efbdb182fe0c9ac4c85c2c53", - "0x00e3143eeb5e59b0cc30660c828ae84b9e5507cd92a53aff80ed2dee70a55042", - "0x005b7a1986caf5a8174886d8e487f9107a46ca078c5f348714428b124036e4f4", - "0x00562682977e9f57930b7b2f3130520332e76e890aa4a9e0128e9c6613b662a7", - "0x00b083cb8e8f1d64be69876b979cea8c154b9f667074f678b3d1a4a6eb31a214", - "0x002769239657f87ad773404a9f2549211c25412271dfb57b76059e5f8200f0c3", - "0x00aaba85ea5f87e0f47c13aa3cab5b8f7ee889a92059670b9f69379b41be65d0", - "0x00b36708702fdef91ac6454d6f09e232e2dfdb3ccc1c53f595ae7bb1ca378f8a", - "0x00fbb5b2164f6350f811a8510ceec2ffd3fdddbe426c1ef7b4324790c88dc3b5", - "0x0002e1d6c3ec5a8e9d5e1314812f914befabc338ae15bbf90ed669fdf570d117", - "0x00a1913ad8b715ced73cec8a960bc7ad127648632c6d64dc9a0e8b5cac5153bc", - "0x000be0b83f17294115c1a087ed035eb4a5bf18881296436cf4bf3b9f51a00104", - "0x00b773300ca26de7d001de1d3535787309b4139fb7442102ff07e3e0342dde67", - "0x00050fcf0c0876a27de926585694e0048ef14c6b8f4d1ee757c7aeaafeaf1e05", - "0x005d558bfc6603800e93d2524d1c4f1d22f3760e782514e9dcb81bef54792c90", - "0x004b64fa5da331fbb080f87e8bea5854e890bf6931d147a0d9d5a04c18bbdf95", - "0x008c1a857cc026c0ca5f2f3422d544d265f1be098c41d17acef13ac303ac6d2f", - "0x00bf9224ff41d297be8ed84bfc8b232f6ecbb48b2544cd7a644dd47200907625", - "0x00da65ff8f8f9d9bb5918a334f043b5e4f3b6eebc57bb6e544836afed2f013e9", - "0x009bff7b93d682e90dbfb1d74196ea0af7e157c2d22c16d2dde0fa3d3df45159", - "0x009ecf2ed51fd2f8ac15c9903a8efa25ad306311d0e92ec7b4d8fccd0254932d", - "0x0045d5b5b79528ab4518ea5f149a9d7a1a3ccb2d1db616925636d6feaef307cb", - "0x0045ed6221fec61f74467815059e3885331daca8c2931e661b86bb4a99e35067", - "0x0022a7bdeb9f9d56724caf6383a20ddc5d5d632f29e6ba24053850ec39bf6f15", - "0x008a2fb155f227684b21ac494a2c02836706a16b9ece517e39f1bea82d3a02a4", - "0x0000ba19fe5cf8dcc74671dd43bd2edbc15d0609914c2aa4afafabd345c5891e", - "0x007df6a50e24de48a49923d4d2c905cc616332722fcb663c61ff3712cbab9899", - "0x00c3f4f1206823e140b891f2a8747a33954a466cb7dd885c38ed6714cffe9fea", - "0x0004def546f9b959d77844d258b5ca5544f07474302da68795409f0928232b4d", - "0x00fde46a16c4242cfa6be47b87166a5b0023f785b41735234a83eb74fcd4621f", - "0x0051dbc245a2077947ba455ba1c3602160e3c59698fadeb0828e2ea3808d8fb1", - "0x00187c83f0a5cf18ca3970aae39323a750265faeee0c59d5715df646332cf8a4", - "0x00ea1d548c59f6981a65f1db95b508e5ceb3dfc9035adb5d0db3d04e0d8474e0", - "0x00844a72ab5ba8b394dbb5ce94837f6ecc7bb909b7ccde6233ad18fd121c605a", - "0x00769c67624ce4e153f531ea4293090a1f94f66671e99f99976eaf357f2c43d0", - "0x00841acd621b9dfb17422420b0fcd7f7a31313e837942d29488011d15f575b68", - "0x00bb4d793ab42a89af0496ce239f2c1c22de534ec7770195e3d5a28d700115e8", - "0x00bda74583737476b1bea6c1f92fdddb7d8e25877f6187be6b674ca09a9322b7", - "0x008d57020f8fdfe37aa0a9e525f1e1cba129333cc57ee42f4f5772928d2e9cf1", - "0x003e3d05c52d155c7c796da073ad7b7c82695b25c5c1fb9093e6ee5af9859f7d", - "0x00ca8cce459b3dd8a7df9eca756c1fa8a65bf100c16409cfe18df4e562b7b568", - "0x001d89155ca7d77451651fc23eef91ed7d266934195d637e868b9ffc5b77deef", - "0x00565cbf92785c3c08c4e88cab5913d1bd88dfcf6a06a521f80eff885485e47d", - "0x006a4130ae567e8eb72b9e21d3bb9637380e91f88010e3551fdec59e2785e165", - "0x00b70458a7572e33479b35bc8ccadd038b9d79f82a1f27c55e2c5f9bc12cb3fb", - "0x008df6c4b1b88f68bb018ddc8307eaeeb54e495c1f10a2921666feba14902a00", - "0x0009b11df1d5424ca4edd8eb435ec78d350830a11a0f247fe0082b404250e84a", - "0x00c4a45408ecd9f5ac8f5bfd10a1345add1ea5d394d7c5c9ea6460dfdce8600a", - "0x00267d2e825e33c5f1882ee182b4f3df95ad09e633c4d0e2b49f3b6d70d9fa8d", - "0x0037d310928e052b9fbe2066e0a06aca882578f14d8c82b3c56c51b706d616fc", - "0x00eb89ae35fadaa7d4d1d080abcd3b8c4b023b35cbf11deca059a7fe7b58c44a", - "0x006aa1d93af7df5d69c1e50c5beb369ecb695331493182314c55fb761e3aa6e4", - "0x000fce57d97ece79f17915bc01302d696f958df690d2b757c702dfa51b4839b8", - "0x002511a48492e8ad15d1c666020d80ec8640c09f4fea99e88ffdaf969e628053", - "0x007413ae919641dae994be0b87e33e130baecf81e5023cafd825ba96dcc9edb6", - "0x00660f3526dce6106c945c6638a87aa361e8c2d0ccd5c35697179140ceec93a7", - "0x00a1cdf1a125a41be0fbd0ca445f0c3a2daac605b8a4991df18c088b98500beb", - "0x00fcb4d25a3cf57254e1db5c78d62fa255f3fd0844bebc59bda17046233c8629", - "0x00e1854a7b4f2967d3e508c93b92479bd0517eb59165c815fb0121aae9012df3", - "0x00b4405618b66c8a5758fa196cd50337642b2308276f5a29530411aafabe2cdf", - "0x00821d31ff4bcc14d1329f88a0f733bc406c4b1ccf79709253e343dde797b720", - "0x00eb04e18aa1d62d0e51292102628f8ecf9bafe112e0f9ee5ecd3a68d738d2b8", - "0x009fb4e1d8665aa33dbd4f64bfef86da2cd0056a5cd3be3b7b111b74c0e8e8a8", - "0x00881163850e2be179bc8b6d4c62f69e6d09189c6c197b3231bd7ca80dfd7071", - "0x0050ef48a6150a6af7e5e78678037d02c535a60e5294ece5b79970f73e65ace7", - "0x001bc3798d16af8352692601754c1a13233084a384c296cc564e9523315e6af5", - "0x0093ca9274b2744c9e382d3d56ef14a0c94e43b0f14492de3296e576c085b92c", - "0x008110f3e7d41e155cb6a09320132afee984a532ae627acd686462cfa1e165ec", - "0x002d385599e108c576bfd30603ea300dbf355c692a5b720e8335b94e517c25cf", - "0x00fbbf5ccd869b16fa371ed0d1c694840d6c6ac178e76501b90429e9d3cf820f", - "0x004f080c1ae5ada8b995a8b2207f03af97479ee57a5ce4d564d24d12481bf9fc", - "0x007253bfcd5eda0c0e93a19084b2c650831f3ee8c179a3d86eb6a3b2953b5e7c", - "0x00079e83add6efb2cc092a9f5e874bcb7b04504cae964ce9be1831d3f2bb0e93", - "0x0051e8988555abbc8256410da0d3fbab806f5f4db6e705d88e8d4c3e5aaba1be", - "0x00ef49fedfb5f1f118006f0bf777a9b7d62a6756e4902fea42e031e01178a7fc", - "0x00d6d8ccded4358d89426596b475de2ccef482b48d3e5200643d86d7e14b09c9", - "0x005694b86e45c15ec9ad63f0c30dfdc23f2df4d81bc8170681180eee28e38b66", - "0x006bd217ca307b9cba3457a47e2eb7e8bab39d84adc8410668450905aa7b4d41", - "0x000f4ac8e7e588f614af6cbefffbfc7caeb6be747cbde622276167d80386b61a", - "0x00cab2bcf27dd054222508846bf4b1b0384dff0ce58ee0336e4ee13adc4d54bc", - "0x0077a6d2afe3f9ca9a885a479042a419dc6b8592ee6f4a289547c682b991680e", - "0x006505d1d65ea5f8fcfb80ff011a7cb2462e451af2fab2419c23c518b471026c", - "0x004d8139f1860984f71985a15e6f4ef1d970b0b4cf86779b5efc9aba46de1d28", - "0x00b18e088f7872e9814bd07f96bef095606f77e3624df06402e1e192fb5b9013", - "0x007a0e9b4f733e2526dcfb60e64abdae60400aca33301286898715544a11c52b", - "0x005d1f38940350ebaacb628c58d12b5a9dac466106f4438cb9fda29013c857d4", - "0x00f528e83f574274764dfec83d966e53b4b32711c2d01a381665fd28fac38c94", - "0x0020134f308f6940d72205c32f3c9e39cdb2a5da5ff596ea30b536b0eb0d1b86", - "0x00698d613ede794dc44ea9d6cb1950ce1da6bc32239a1405d83e3133ff8f65ec", - "0x0011569f18e732261cf03a4bce81ccc41a23907b783f42250dc87014666ce539", - "0x0002eda4482e8d6aefd45d9cf8ffd48fa0fdadf65b5f9f289222d887614e2f24", - "0x0043babadc76fdf6d848d6ae291530bddd3b856f3ba433feaaf23aa4808f7be2", - "0x0040ca1e1a2e1e35e31a87be6c3b132c2f523f15705d0b51afa5d83e1615f53a", - "0x00c2581b99c40b18026fe2c1aa73151b27e3e5bb6a7eee2d4ebdd46fb93b4903", - "0x00ae0ff13151f1596a0e1513b53ae1a162adaec65b06f3afe3f2559ef623b81f", - "0x005af7fcf3923934689b4ed32c9ff5678fefeae5a00f6710074af1bc11094375", - "0x0097629be6e0d24c2fbdafb63f9fdfa61a55ba222a47ddff5fb8f84fe390ec1d", - "0x001d526cf1844b746e2efe0ad40c6d4942989368184318654cac4323f1de9e9e", - "0x004ea1163d5815a29a0376d95dd7967c2a93dcf3abacea1b1ae40a6aff754c86", - "0x00fce018722147568a48ca40a7387ef5b9d0833d39ea4499d2543d1dd949504f", - "0x000e9e509471d4f4264d1baf7bf5f726ff6f3afbc556564b43ce625307f54f15", - "0x00b616cea2c205b5c3e3dc46dc365c7081d77081305333b0847628cae6456f28", - "0x00ed9f0c6759624dba966298eca85ec8d50d7e7f358ed1fea537e1a2813f7b24", - "0x00d7837b54b387f3f8b1c8ffb27f5085f2aadce030505e251bf2722f2ed26629", - "0x00a46811b7d25c81c7a1a150b3142fc694a9b6c8074e7fb7bb91b74a9b0aba41", - "0x009a38db52b18e04ac4a74217a7c4c9b5d0d8abe908b6add6f04368a55eef5f6", - "0x00f24efa8d47d8378bcfd3f920d9282a46bc6c98243dd3b0987bdaa40302d101", - "0x00c2a61cae149e3904cce8c64992f85aeb22262de76d599aa6356ac5e78075fc", - "0x0091a78300ed0bb40283ac5b92d3979bc396457f4578256271b45bb27e1bbbcf", - "0x0024cb7533fcbcd1244fb9b3c7215188b3775cf0e407d0ead993cc7853c59ca6", - "0x00eb84b959b39f4e0248f9e4074794358ad2af2ecf610bf1a600d3030207e151", - "0x0011c7774a5558df6cf5af4528a9510bcfabad823f0f0fc25a52b406d46e87db", - "0x001108e419d0c2f783a04b1b810f53f1a847b985216b05d2c211a16a2bd06f4b", - "0x00e7682a67068e1c0b703286090647e5e93977c1d3352f11959d1dff3747dc2d", - "0x009508f3904681212761b1eca71ce1758a6aed0f0a05733cb8267b82c125fec5", - "0x000444ff11be6f5178c7175ec10e22ae4f8005fe6896aca25fd122d91980c4fc", - "0x006f7e76aee4d71aafb29bb42fcb81412cf125b2f330bc939397255a7fd55090", - "0x00108f389ade9406ad815b88b15472278a0ba0409f6ffba2db1edaacba7f658a", - "0x002507e80c190ca339f34b25f7fc14c7c9ff623a6cd63c12e02a8af5abba5026", - "0x00ef327d6bea8fe33b13369691352277d384e9326847fc5287330a9f2165b219", - "0x00d84f41ac36fc58f0ba8f031c6da338658e7badb2924b8628ef4510d0591235", - "0x00cf1ebc675da03ca64b3d930e2bf62b92bc0eff12dab2f9478f17067cf2bb21", - "0x00145942979d2b8e05ec3745aa5306706a006cc7ae95f691231d0a362cbb6a68", - "0x0022db9841a92cf92677ac7bd26a9b8ed82d54b0190d99fa0cde0d810a25a8c1", - "0x006874c045f8330ea928f51b4ca6a069369a71ffd17ffd1d9679524077a1b35a", - "0x0068480397f24b760c9c98080a9ba8a8cbd25b0634ac117c323593745705d9be", - "0x00c92ae3ad1810ef0122cc330dea145a56bb0011136461da7cda1fc3b44a457c", - "0x0014596cc5a6baf93bdecf95fa3580752cf2ee4ea980fd32b49784f59800b5df", - "0x005c8ca8973c24d90e87692fe89f55497a4a37e356537a3ff01f12bdb90aa092", - "0x00dc188ed323c43894b1c81f2fd5a9c71602e67dba3356800ab4ac1e2c1d5918", - "0x0066518050366859b45629f72ba26016a9ea62535f02fa82b523651df0b5d753", - "0x007442188c7b459ae9027d62e0408111c70180cb38696e9bb469661fad8ab200", - "0x00aeda161fb36670d595671d2759cad450e43e994a571509b7307da2aa723f06", - "0x00a6f430f17193d4c08b9e2e89035ac4d8bfab8ab646bc7da15b1e57704bc5dd", - "0x004ca5ae172216d54669382ce121f3a275d3e5fc044ff1e82402e2a7840ae117", - "0x0000b160d73368b23cc6954b3ab36d6e3f5bc8b200c8b2ca3167c0f63921b6f3", - "0x00a2a638f8dc3c94034a02e4c4c26f252ab536e3e1899f853527a0c5f596d11b", - "0x0053ee06a92c6a39f18a30195bb14dee57199a888513afb5ed96c293930fea69", - "0x008913ee1dc9d441d193909fd3f142cb3d9118a7ce0c29fb4780c6fc2005c683", - "0x001d5c6ac837b53f43847b0bfda41a7fd10ec9ca240b4a14314b16d5c6db729b", - "0x00236ac2c2651d2152a66fecc752a16761f8d2cb03ff26e5c7d40c6ba8cd2cba", - "0x008c397f7b243fb6c624af787f85e023fa5f91e1d6fc5a4e611d64bbb7742d70", - "0x008e86d281851b5d65ef3a4d1e0adfe21b2350e8ed182f827f4eb96a29aaaed3", - "0x0024c02be87b6af706aab85764988814006115cf32368cc999e161486a7365c4", - "0x0050da706549c8e7d7261a34204ee3ac75bd5fd13467bc76cfe1de3a4874ac73", - "0x0097b3ffaa681883d2aa3e43ab6808d44f29efcf58b5c72051c308e0b6f6bce3", - "0x00f77183d76edd10d28dd53e043ff91864cc55e219a91b8e444d1fa9b5ec9b8b", - "0x008bda8621ccb9e6d7ad9d7452e7a15ed36fed3349fa68616c27b061430742a0", - "0x00494e0aa240d8a8cc98a44ec7fdcc692bebcd9c8c5553c3e9ebfffffed9bb62", - "0x00582a238d24f79658f70373187bfa961a0c97cb79413bb25772781ebede8c65", - "0x004e3b24dff1e3bd91cd6a680a369826443c2600580ad22896b326692704acdf", - "0x00d99f54580ab536eb9c83b6dc46b3aa59f841e7209ae6596cc439101bd2b876", - "0x009a18ab053ee8b9705411619a2819881964e3869d7395f69a167c6ad005f03b", - "0x00eabbc443eab6b5681b34624aecff8486f9f46f2ca3d2bd290d80476542f376", - "0x003735f74c28745ac427e6a4b0b7777db70f193741c4fb3a3ed8432ee4e03452", - "0x00dbacf84091bc52f3c07adb8bfffe12aaf8abc03f13a2d7408d0cf6d0b3fbd2", - "0x0055f1971b168819a50aee02f4b5b444cae85266d11d30f58cb78a1996c44d6c", - "0x00041c059acd7c464cda3bcc426fa783b01e48e43bd6805dd610243ef8596c14", - "0x00c7c64b53c75ae5820dcdd3f31a7f03067e387b1e0ee47467addbe8f95a6f94", - "0x0081d7d1b01a25933dd08901144e4d5e155945d65e9f3e9d25d5fa336ea52068", - "0x00cbcb6203fd77f6dff2004d30917ab260c2d5de1e60b523200950a027fa2d1d", - "0x00fd9a38b9cef8161f8248e0bfa1bba169d2f8f6e08bbd12f721cd3bd1383d4f", - "0x005256e541218a56543d1a428f35f80b4e223349782050868671676f0172f094", - "0x00834a7a5ca767845ed4779e6b84bb76744370221339959060cd3b002b79b9cc", - "0x00fc510acc2b43f9999f70f33c28f9328da1a32ad9f76ba78221673229f1186c", - "0x0070eead671aa7a870a66a5ebeda458d897988f9c2ca504ecee4b0a1211c7654", - "0x00102c397adc498b428ddde3bb934383425e0510d7caf05e748af3ec0828c822", - "0x00d7e2bb5fbab534626dcd8dc17c0534c60cdc84479b6ad6a567bd0d42c5ab01", - "0x007f966013ce0d62cfd26987a00ec5c6340223cde34421f2ceaadcb2e0c5f96b", - "0x00b46b50616ea709b7b9cedc3d9350bfccfd8389d7db3d0c61feb4704b018586", - "0x008e01bb301e44ea4b792a73add7c93fc75e2791b6e8b538323b2be76698775d", - "0x005088cad74a7ea673e509bd39785182f7dbde615702b9bf0c6b6d1caaaccb05", - "0x00119b894fc7cc06e38efdbef991d31506d9472f0255938e2de37058fb374ad4", - "0x00dd55d25ade2c9ecbe29a1b60cad71ab2238319991389cfaa686ce92df47e5e", - "0x00a2f2a419de3953a02c2acadab62a8c75ffc5c5ba591c1d86c90babf1069830", - "0x0075e268e9d735e820c988689b5c9365e5f8f4a9a13103a1ea6b0d74cbc6644d", - "0x004534f640677f1a003a02154d9c676b6f02d67e633d37176e9396072d2eeffe", - "0x002e0ad5a2d50f07c485fa43078f0bbc6199e19bf181b4433c6f3eb9f34b390f", - "0x0028f84491466af62395ac7f0eb47ad27aa55c7bfde503692f626906d91da08d", - "0x00e9538d2f6375dabe77cdd730f4577c30070f6d84405c4b11764025e5b63355", - "0x003a359adf80cdc0e8169aa6e5854191c4df8c40d21a937d8a3f8d47bffa4be8", - "0x0049fba612072f6a39ad502ab6adc2c4917464030c26c07187b94615b1f515b1", - "0x00ca07c016fdf1492d559c4355168c7a1094c30ea725f43d546a970ef28d160e", - "0x009190671b2c5b1a64db617bc69220c610d0bf5cea5d113440b9fc0722fcc333", - "0x0027e1becace65ef820a7b969198142cde22c8e8f9b49a9db6959192f26f3587", - "0x00ac7b19c39414a8e0ff70d9499c3a60edea3e81db33837e1084a75899dbb30b", - "0x00feca08240358a3d9cad5081facb5373d7b5a187e90519aa4dc368dc458a994", - "0x00664d0a856917e53f3ae86cff7a2f507494bd9eab92fb6ddf930332e43c345d", - "0x007628a341a1d9170a3d0603bb7df61f5d8c0f75c825a3072dc08cf1890bbbd6", - "0x002055907bceab4216899125f71b8f8e7ff6e11d3906a45c18ad2f8d337905ef", - "0x0057963ffd640cfedfbb1c461d4a56615454d52a0d4062f2f8dcf8301ba1adc0", - "0x000a2234f6fc2f28499f1473b00facd1c5eeee9fd8821ee5dbacb79d5e6e4ff1", - "0x0019da34095714ed53ad090eda2bc9cdf0833ecc9569fcec272eafc3ac2a1f33", - "0x0096295d0c45ede71b5504d02035c0bc05cd2c4f5b1eb909c96d0c8d2bf4142e", - "0x00e0f8cec46c24e6e925edea4b94d38f2d9c7f9233b9f76296b7a59c520514c1", - "0x00b60827f815e65224c33175ef0e6cc78d1d4b39f98b7a94e45f96c4db469fe4", - "0x0000217e3247f7164f41d694ddfabdb3cefb6d248d1cc583f5d3223b75284c02", - "0x00775107d20ae35064648a3727e8e2b9c18dd4fec982b45bc7de5b73923f731e", - "0x00e015078cd0975060d0742080729ef60e01d13359fa7fd17e4bf4ab9c5c8e56", - "0x004e928545a69e9fcdd60306aab358803cb84ab248aee8da7009254dde182a79", - "0x006486ef2803a83cc18ede6f2bc98213fcaa62046be3b08918c09b4cc12fe770", - "0x00b8303d1c8966136bf0219706678ae22cc84d6c42c8d6a3191308f79d34e65d", - "0x00c1799307023adb77d8dea967595753ad9090d0c512568f58bb87d48793aa43", - "0x0066652609deac8c8c4d580eb9d4d3d98d375e85038cff0c9892a8a5119c0cd8", - "0x008af6666f071d471afd3394939e5771d14b1daa2d98c896ccc7438c51f44d01", - "0x00c0b836e693463f32b049e5d31fc966cde21c13a05428d277b057383e10fd76", - "0x0000f4d52679f0cc5a1e7af23b753adc14dba05db147298736b4f3aab62cb7fd", - "0x003936b4500362d18767b18d0824d669c709e05bd78050119a9a5fa3ab3c84c0", - "0x006c7b28aab8de729dbc03189a411309454f66bf7142458077156027c08b850c", - "0x00c6a89a60751800c298a6bc18b2faed7b2df137e7a6793edd31e2e6ff985a74", - "0x00c803cdf490b23bd5b0ea67330c028b6fbe3ac35f8a9a318cd69aaa47cdc52a", - "0x003a5666dac52fc68269b27b44c8690eaa995c42f1d694702db632086d6af501", - "0x00849d0e9b252b8522322b034b27c2bb68e4528bfe0f75ba17709901f688b42a", - "0x00add646a69972cdd16b2290ec6fa12afc9c96bc7d99be37212d12f6cdb4a438", - "0x00381c5fb7a77e6388eb5f92909c7469af764f27d9ab901cbef45f6e843e6dd0", - "0x005a7139d01c8baa5528c7fc59157cb2c49c628baab9c3ef6422f1140b6ac1e2", - "0x00804ee8b0a27172613b0be8785881a068b92cce35accfabfad88210523f564e", - "0x00f252d1c48e479853877b30d8c06dc9a59e2aac0be9e245fce4e8542416b0a2", - "0x00674074e43964a3afe009a4e4de3fbbe767d27cb1727a8a5d330be16084e495", - "0x009409405870d94dde70e188869e989cf6212c62495a47f644763c7434fd8a58", - "0x00b7ca67d0b62ee847e8e545405ce1fcdec1883353ea54f0befe21e432fa5eb4", - "0x006f52663aec0e95fac70376485a933d51329f27de604f6db108161932a1ae58", - "0x001d8975e6875c47df6308000f9379d2afa5a1ccc5da3756cf8bb4c32d945c27", - "0x00d18d674a9b02b9cc50cac7793a5948966fa3e5b40be5ae6774dd810623e7ec", - "0x000f709230189dc3165cb5979210daad95a5b9fbb8539c9d8d71c46530d72a63", - "0x0093b773e6a5ca2219a6b3fed02e00e2184e70ba055bad491604c6d969c22f6c", - "0x001a323dd93e9fabcb8a0df96c457a57e8e2145d57780375aaf889c9d8a89dff", - "0x007459faddc443ea711f62209f6c45dca37ed52375d246e693aa1d08d6b30bcb", - "0x00210b104e1f8e0c99d61206a7ae4bd716bbf774b7eb27359407d32f92e83dfc", - "0x004b61b9dc37dc4f246aa2e0bda7f2646b39b83fa27e45442eba67ddc79ca3c2", - "0x0050db8fa088727c0ea1b8a24ef8f4020deadde169591739130f3ffe463a0033", - "0x001f8b0175d5b04905fe081a65231318395a5b52258d07fb0189beb369a502fd", - "0x0064ca66978c44296ac027233efe944902510a0362efd66c2ce7ee6a8be43c19", - "0x007dcaf373a162095c24ce0ad090fbc5b86e055c34b70fc6c65f3e2f60bb1bf8", - "0x00982c9b171906abd046984344676983226a3cf418838018ceedf1ffe3de9864", - "0x0077d8a006572b8813fab61ce6154f3d12f2ec61e6662888f2f5279fc602534c", - "0x004dfb4cdd14662226e67ac4f981e8a446cda79d82d65b3e7eeb47d787c054ac", - "0x008f41f49b193f56cfb4d5140aa35fe2d6c41797ce03b706fca0710c75790c09", - "0x00893edd2adc5c38a4544e952655f79c9b9b4f4ae56ac7df4363043d0a35a089", - "0x00ea0247b48d845e42fb81c474343e7be2a99e02e379c3da17e497d750326484", - "0x00f4f4df1e0ef9faf02c848d7cfcabc2226f8421d8f745fdda324685478afd4a", - "0x008c4de699acb61c402968419dac950645b1d5f0a8e576fbb372a4b4df6da80f", - "0x00461af7766e32fcfe292337fe236db3e3ed8d8ef6f2f258efeef8fdcf487d16", - "0x002ee8187d14337e5b45bda6314ac6438bd26709297ae68fbe333882be8a3b20", - "0x00ef68d89466cd293a450d344dbd754daec056a4c0fc8265cf1ed54d3a8bceaf", - "0x00c39d0d028504a7033d80ee254fa52de159692489833146bc2d6c99b7fbd11c", - "0x00cb540c434a2e196542c84ed38ae8196e379295e4016ad272549ae906b82723", - "0x009a6745fb1235e1c746dc401f041cb5bd2f059234d2d9fb8601e9ab589f4fff", - "0x00e523a13fe340ca2afbb8618e003557cc7e127d7cafe295571ec651600461d4", - "0x0008492b6e31978961f59d1d47a02ab4243d1bea425134b8e164abf9cb0efdd4", - "0x0064b2981bac1dfa5483b0cf4796c8d6ca125efad2f090024398ec847e69650c", - "0x0082fba81399d98989749ed130c02cad4a243cd54ff71eb23eadb7a6d31b25dc", - "0x0009ff9f87c691dccaedec33f12a25cd393d6f5005ad9d4a0a0e164f614848bb", - "0x0029badbce2d2faafd63c5aa9fe443748f0ed1894d8713c96fb2308f098c0b1b", - "0x00e39c969bf2e0dafb59c513f0ca05b5d9c68725c98467440dfcd936d60bb296", - "0x0064ca8a53c1dc473adcc757870589eb1becacb245ec8e062aee3c01fa0fdd38", - "0x00a8c990d0597ceaf0d5e73008aee34edafc7c2f99b552933e94ecf46059eea0", - "0x00023bbbdca7321968bd665fff8fe0f1580ae4da60a2e359b4289bd435fc37a5", - "0x00dec6d3ee43d8b8e48844ceab1d937c62d0da17badbb5d1ad0d024dc7c88409", - "0x00ef74463a8f764ae4cfc85d9d2da5ad0cfb83617dfb98dbaee4f60c1c37d331", - "0x00bd51917e184e968908cd28f93fcbde494be761658e468e12aa189a2d8001b6", - "0x007c0d8448a9a2a8768eb6bca937d785d80828f4c56990b36ac3ba8369e733f1", - "0x00b60e28ed5596f80d555e06a5255fb766ffad1944852c6b6cfad33f3acd091f", - "0x001ec7fc56d14cd79e184c42333217d20e3148b127690520e269b8287f4f413e", - "0x007c826b1188b3163f13e38235a298e26d549132560e7d5b9bb5c4cea154265f", - "0x0076763fe90ac659473c3fa10d658e1f6c3bd5963e7d3cc27f8776ded50b79d5", - "0x00afb7be07cc43887af184d9b2c1f98df9451bf2a8b6fa960dd207f71a32aeed", - "0x003822c11cc46d4165924199f0010fb461c6383c905a38212837e2c0a9dd3e00", - "0x00cf521401042b4d40348d1ff1f04c0e1204a75c0fd525ad783c3cc211031022", - "0x00cc79e40a73868006375cc886ed89f2d26178a2ce40ff252fd7b516e0fd5c3d", - "0x00cced604baa3e5786db1dae0a3aadb881ee69e16e74908dc1293a28c80f40c0", - "0x00c424e2f2b60c910d1ab552995745e328898a6bf89287412ab9665460e0ccb2", - "0x000c6ce6660302f9952613646d9b8fd127c7eacc536c4876c95023ef8e199caf", - "0x00f5ebf18400e5a138d6410064d533796a887211a38f2b32802380380ac0fd7e", - "0x00c0f9ad51f1fce3d154d38ebc56304f79175b69f6cf912bdac2eea1d5a2b7c2", - "0x00325f617a66b3f16b4268b3f4095a91566d2f1626c284837f5fe4056d893883", - "0x000427a812fde4eb87de7e80787802d793dbe7d761e62aa3e6d0443ec795cd6f", - "0x00bb01ac2279f454ded47b4f886f24c8bf6a3b4c5d4bd91a9ddd494a1c63d4b5", - "0x006f81d775a51df76a45ee6e4dc946b8887244305eeeec6aad84c718a03f273d", - "0x0042abe0d13bf2896c9f19b62fcde90703ad9e18be7faf72e0507bc5ab787340", - "0x002d7a27fb528704810b11ab4bb3cd6d33debb8ab1e94cf6ddf7f5446ccbec02", - "0x00dd93ab4627aa895d4ef096b7685ed741a2b901f6a138ee4b3cecd704eb0f48", - "0x007ea2dd17102df4a4610295ccf474ab601dee62c5bf3a4362fbb51d8d0dcb24", - "0x0067dda7130b167c0e8db85b71f9d4f884d9d769d1d80ebf010d180d79a5b55f", - "0x001d9c1a1acbb3e9acaff6421ad9880f7c85eeb052bcc1e91692fd8fe7a3dd68", - "0x00dbc455870a1849973dc66bff013e147e2d774c7b707cc64c2ef084b82c851b", - "0x0047b5fe61cd7b6b4f51e6c2bd8cd4bfebaa7155afb368aef0471a4184fa0bf1", - "0x0079bd71992f76162423cab5d7b02258c0c5a1477f832a41c08cfb6b9fa9233e", - "0x004a8bd86f3e6e31e6ffd125dad1b9ffa27d5dfd14f85ce9ca1d926693cdab6c", - "0x00055c188c89250af43ded608cbb34f4b5b8de45993fdd8be5c5f92c45935f4e", - "0x00f201664a8e76bff376b62a6d46ee4e1451fd32c2288f6dcbc216829297f1b9", - "0x009035391ae3c7c35f8639f35a9135c50bd13a5ab2b15eb81e7472d718c85ac1", - "0x00cdebf25966caebeebeab624d4ba3d7b3d68e6806ec9f515c7066f52b49a82a", - "0x00240965252fce3f76048fc610c0e5d79242deaedc1e9e30d783480ba51d3c50", - "0x00edf5cb5bfe7161d54b8167e590177353d923d4c20ff3671ddc41d2014457f2", - "0x00674cae373b064d834f36edfb05f12c74d9f7a25814fe91ece47169e75d9a39", - "0x0071ad9ffe21b9ca1343629a502fdb90b3ed53ae6cb2fe5a81e5516bcf1306ab", - "0x00917e5999953767a18e196a80fae79ae4fef3bb9fce342de81945f898a04749", - "0x006f27b1281cf6e6b0e5ec12a6339f7c1b3acb039d38a5bc4c9cae67d691bf89", - "0x00a18ff97605ea633c60a4fa6763efe411737606ea3f7a8d9e01445e087f0b24", - "0x00a5185c2e0e3339eba8ff51e09b675c1ab7c5ace7a98e33e5ffce2605d24aeb", - "0x00cea2b81b4df3390d78771a9de9426b2cbac5f33bd3f983ecdd08680be8cf4f", - "0x00a3f28fc651ad7614a36d5b08b9a6e8d8229f2f337905ff13e9ac235f4709ff", - "0x00fefc822d08c83273c6582432c171dcf5265a22496097e66b33ee68779ab400", - "0x0024c393fc7a3f523b33a34411909ce7929e0333f8b807adf471a70a0bfb50a2", - "0x0085d2445ebfdff44d4c2cd8e07f55d0ec993d34c3efb25aeb704c73f01c09f6", - "0x004d683331014d99ac2725a9d993d0b4059ea223b7e31d74af3813bffcbb3130", - "0x00f41b4cf36d3208e99621ce733d354a006a7ae7ecb4c0968d073dbadbb6fe7d", - "0x00478a2f7b7cb66040b958d016432afb638f3d8fcd32f9d408c88e8c2d7df648", - "0x00ce7d3ba45022039c48fae4afd18cdb36e299c45cafa764328c38d3e0a0ef9c", - "0x003a12fab23caada924fd3d6c019ef1259c9cc304ab02dcb3dd072ed3a1662d5", - "0x006a80fbc35c26bbf6ed6df2f810f9bd44b4ee0b8076f48b4ea5d2eeae00f3ba", - "0x001b0d41f959428f337aa0b50c4e24e534e52a83a4b096092eca5873d70bc6d2", - "0x00f497ec2e2258557795bcff5c2df277e6251ec4905f0017e2b41642c1d2addc", - "0x0071cd93c85ab2dfab79298ed35454be48e9a3a345ba5e24954744b7a87b1a92", - "0x0072512b56f373b8ccb05d86998997bbd47c14c8c2377bdd67c44133123c6883", - "0x0094794ca3a4246c0e6047135b7e41438ed077f16fef9b7b96518ba834d37950", - "0x00a95f9e79854c280aea8e9f9417e2943ec2762a646dfed73c72bcafef5194a1", - "0x0029dccbf8157a663c2c4e736ec8b7f524fb2158e620e6a34a52496f37585e84", - "0x0063b903262eebbecc0df8747c6bf3ca4ba8641116868a6d2afaa987eb2ec965", - "0x009e0bdfe6e49dfc32f9c9c7e7993cd3fb8f6be6190a38fad20e64db2997cd4b", - "0x00460e501c7564af3e1717d76200a7d98fe2b347778f0d4e479878d893ea3b82", - "0x00a5d52737d0f50e88e25681ed0bb6f3e703c1537856ae7ecc18fa16fa84adb5", - "0x005225656c6cd4a61aa51d2d72cc2de7e92778db0457bc11fd16823d05d1adf4", - "0x0000d571ef44c866096d9706a5c4c2082a156c5aded42980f3ab3faf9573118c", - "0x00cd9acb959fa7c5eba13e45ad849e473894d1b810976ce65bccc7bdf7618694", - "0x009583c849a267b0661f3043abf775c315b5feac5975fc33381cbde33cac496d", - "0x0085d6ccc2f950949e87b4b3a76f5546742380347422be1b78e0844db3792fd1", - "0x0033944e00247a5a2712226c5067fb43f396f96218fcfa79553a1fd16106601b", - "0x00d433dc8fbc3fdf0d98b9bbd39ff30cf78eba28b2671bba8feac5f0725cc1a0", - "0x00521b4bb5c5d5675ffccf4d134c4d2c61b34bb48f50e7d9ed0248fffb5d250a", - "0x00de20e5083c57afdad62274b8a61f653d17203ca3b3978796bb8a5fc419fc39", - "0x008c02e3549140ed04aa5a80c47bf257f8b120c6e11f3e207d5a0462d6b8d136", - "0x004a5efa0b570bc3101d3f395ea473c58f1337c9f965efee56f01ee366ebb4d9", - "0x0017a8e4340c45fc07313f8b1d879618cf3c6929e076e72ddca28ff30728c527", - "0x00076e324f29cd5f138e9dd030e07cda9096e17208a3fd24f56fcd36376de916", - "0x00d067615a678881766faf0cf0f1061e6e0950638d7e83f61cb749f997925f1f", - "0x009f5a78e33e4d2b1ae65e8efd8dde16b9c57cb9b757a76597c8418fbb755952", - "0x001255b42490b7576e5c4e7d45742e557e8e0632b126439096819bceb83a6f67", - "0x00ce056f6c2ce1aa2846099beef049d0fe7194857a77dc6c53b15e3874b6b0ea", - "0x00328789d08f890c6ddb568b460a23372dda56fb30c4397622123c902f3b0deb", - "0x009f18f74cfb3987b2e49f1b685bf90fb0268a4c91c01ffbd9ef1935ebbc6ea6", - "0x00b440dc28c5f36ec86f47a99d2c62cfe59d80efca93f0ffc14e27df8d22902b", - "0x000c6a77b74bddd3ee6d8a4da66dbafd46671de68c48e372a1ab579f15be9ae7", - "0x0086a67d462288424cfbd79ca8b4478a74ab1c9b213388c3abf16dd732b25e01", - "0x0059293d1940c9b34b751a16746984ff27f12c853af142b997a973dbd0c37a96", - "0x00df07f6dff6d0b9ba69e2c38c7aa0cc48ba7761965d5b53e5cb0085bbb62ec5", - "0x009203893b6c573ce30925349a6e4ae86eaa576854391ee123c798a8f6fc0c9d", - "0x00b82067799880e173140291dfd8462b375381c698da9958d6c8cbdc0f14f6bb", - "0x00a80239dbcb4f5697149d83172c3abf04849a76637c1ebb2f0473228c6fd440", - "0x00ff27a0cbd5aa22bafdb4fc8937ff815a34b401708fa6ab21af96802dec7652", - "0x0035ac2ccbc1bc48a606f69a7b04e86e5575cc857b876df5b715c0b6936da828", - "0x00f4d3a2bb1ba0eb8bfacb451b4aa395dc91407a413430e168a30bcb417a46d9", - "0x00987a8d90f196ba2d3703f736c063fd2dd7afe3aeafe6077cf7e7d9768c14cc", - "0x00c761384c384407bb9cc03ee4730883b7a90652cbe148d568d3bbf46c06e59e", - "0x00390eb58be8348057c816fd69146603f4446d38119059c4f3be314decef985b", - "0x0032c102042079cb329e90a71abf160a2936716e129a4252ab2c9dfeaea86d35", - "0x005bccf7ac0055e048ba2554840c6fa949e9fde33fb429e45e50ebffa12640e2", - "0x00eeb1af7d16dd99b1de776ad3aba50827429382485766fa0f7901d472115d6e", - "0x00e94d64d74e248a84eb00621ee86e21af7a2e961e09460c0dbb8681e4f92c2b", - "0x00ec7c5dcd849b1c90081a0801570080a301c88089f10e083779fbb14a8996b9", - "0x004bba0512c20c49a6710d76868780612ffbee35374d8001d79425e7cc5ed0b4", - "0x008f33fa89948e107eaa55adb6de704198b6f981534be89baee435f196565057", - "0x00e6ab12712bae9e6dc657971003f8523df152e6c3e904d08f4e549df89e8631", - "0x0075f3a4c15b6b6a31ceb5a7af49f1ada67f2ea5665ced8e2ad65162d004caa9", + "0x00578d43f041e50b25334c3bb2b1d7b037430032dffdb0fdf0fac685436f9131", + "0x008c1ddb3fe16a677a7013dc46451258f676264a0e9ff88a7d2b4df400f3776f", + "0x009ecd55adce8af8a89840cf73e198ef33f6b6e3505196063428c1c3b3631847", + "0x0026dd699592efdf150163f27db25c766977d00f06483f41138bb33dc2038d6f", + "0x00bafc972a62bbb45b73d76b66dd3b0c9471478f0cb5882a1975940276d787ae", + "0x0078bc41f263e836de0668b2b8d36e6c933eb9552c5a91164260c3839f3715f6", + "0x0087a7e5c6def6f873838aac982367276385373b80bfcf84755db81ee8033d25", + "0x005b5b1e9a41823fd1dab140f135f6cf17aef196b629a654a1154f2f5f174678", + "0x00480478161ab98b58e8a10dbba738b41d6ab93759e93fc1d66c19d59227d5df", + "0x0074efdd3045e59cff41159d75ae01f472625953d58cd7349583155c367ee553", + "0x00a444b6344509fb27312f345f83c2113c41cbff4d8ea6337363c943e42c41d8", + "0x00a11e06a0c67b9a60aeb60b3127420d3fa2080b4f6dae4f5d0e992e8428a509", + "0x00c40b7dbbb27f50dc25c79721da892e4e97115b68e3313e9d53c946dbecd64f", + "0x00b88d7c03820a7c7d25c35cc79a618c2c46463e396fbaab854e010cf956fd3e", + "0x008e7a7acfb5b140e47f9d2e4fa661d2bd6a976b171a943be292f003fe6754da", + "0x009ac295beb428f23996ca47fd6477f5df08309301dc680ebc2763d5d690931d", + "0x006a9fcc1c94584274d54739b3f86da5b5a159f09b004a92e7c622a7a6dc8f69", + "0x00e10b93bd8d140e2edeeb714a8a1e3831e86835109861ed2cace5ac1cec5692", + "0x009055848acdc86da7e93faf0fef2c68183b876c58a2af4db73aa68f175dff15", + "0x006a6ce5c5e0cbfc14a0e9ab5198ceabf64bfa571792d990a1f39d303e859c30", + "0x000c65051e15d2d824cf89c82c935d78a1f68940ab182d297c2fe41961f8f7ba", + "0x001041d3b483d9c259411882871ccfedbb0b44cb063967267cc51880482d7338", + "0x0049d3d9689473dd75622f306e492fde2cd3956f0571726c50da5ee1c8d6d9d5", + "0x00cf26a939f1f2372455f9242368b7085fa1c1bbf9ca7abdbc1935dc5880c3ba", + "0x00cf9513e7cc82f2b961f888dbcc75916ae36ba95a5357d61079d9094ee16e79", + "0x00e124fed9a3c4b8508622e895f7b96410150378b26a98146a1a27f499e7978c", + "0x00bb9cd4b8255064004ab3a0c10ca6b677afc0f8488f236fe3db502b23607efb", + "0x000cc97ccc64d92fed5303a0d3d28e0564cb60e5990cd5ad0fc1d91c9b1e7a4d", + "0x00e872351d120287255393bafe2248c5bda50cecb368e48d6292f80f3331eb81", + "0x00137e9b02b323fbec450b31abe05cbd9084f571ceaf21b64b650468477724fc", + "0x002860ebb51dea6093ea3920ed948125222e592c9d9325f2315ce6675c1452a8", + "0x0064b99f602c801de1fc2436133847dbf39b436d278e45c1341a95d8ed174925", + "0x007fe8be09677b3127313b8ae72f94868141d2dec2678b16a91abff9c91b3ba4", + "0x0095d750e0f35d352bf7b8453cd8b08242582bcd4dfa298af3968e2b077b1ece", + "0x00c19aa73dc22d2cf409ea6ed8cfe4a0dd7aa8e3da04376059c1865102084444", + "0x000d15b904fed4af21b85e26e75f0f53cd6194a90dae40415631c058a3336867", + "0x007a4f3dd15f759cae1361898cc23172f281dc30c9d0fdab0c867c18eafa8e32", + "0x005187a3cec0faeba5539b5085f66f6804d0c5411be3979f4155b382edd4f8e5", + "0x004d657c502ffb0898c3e471a0c487bc50ba95262d4db7d5c1ad9d744451e03b", + "0x009a66b12e9053c55130d2ea7361fba5a7ca107828ae792aaf285526094303be", + "0x00bb5b7ca244195b72c6743b0c9fef4baeac9b862b15876adbbbd3f6963883b5", + "0x00aba2f973ffe6cbd6f3718ac9e63b27d15b38b73a302f6146998ad49542872d", + "0x00927c341096acdf5025b44818ada28c6093c6cf4c6f9450e801da847544c02f", + "0x0011100a4fada612280656cba9fcc31ea469ca673b7c1f3d50aaea8b681fd3e3", + "0x00d254c051e8e66e7994d314c6228b01567c32a0c06cbef9104161dc8a3cf3d6", + "0x00b515ce8da456c6a0c813e02bb1fdc5892c75298655174250d1be9019439497", + "0x001fddc6b9b45aa1febda3184067148961d3d6eff93922491f7beb6356352251", + "0x00fc0c4a7b3f379bf63fbca7632fc26416e741a20af72e67d29f4ebd8312db08", + "0x00b10dbc00d7b1ba96e1b2a6a0d11db50f1a632523194b1a5b82de76783197a0", + "0x003d340f701346533304dae289b8e36438a4d78d46f749dbcf4b081461721b33", + "0x0073d0c55961ebe517b4ed9f2ae2f987211d8c9637f359ae59e5c1b62026de9a", + "0x00b30793ed232625c9e6280816f879145ec6c984bbe0657f303a667cd6cbaf5d", + "0x007644d231b7d9ac5aa8b564c2f5953ce36b8d7f773ac46e1d3068aa8dde8974", + "0x00a050d09cbe1087db7421a4371e2044bbf4fe4ac10ce32b81b2286a91fa9941", + "0x0092ac35beb87f0ea1293b9274d3489d2911b7f4f899b87329bf6001e858bf91", + "0x00556462f5a7c7be56040794e0f42c816152150737061e6396a72b58ba3c6f15", + "0x009a31b0970c1d6c93524c4d0e3ac785c30e704fcf24386b3b551a477b41dfc5", + "0x00b79c801f9d3100593edcef89a249e82587f4eed8fed762e96dd45c9e4b9e7c", + "0x00c80efcb95afc30dc43f3369c2027e8c69da1a08ffddba606636e8d7403bdf3", + "0x00d9743040563b1b896fa73faa0cb209321f9d70bb17bb22c867d6f15e570fe5", + "0x003d855eeffedc36df919f2552df2f7f28e322e324fdb430f24d650a4ba55636", + "0x00bb331c61a4dd1d18b7944cf0316eac99569c6613480387e0a4f61ab3b27619", + "0x005d0cc62c90c99b04dec483e1c413f55692ecb8b688f7cd50608779ea9942d3", + "0x00462a9733f8c1f11ca2b46bce3fe6721263f89e2e4c622f425ac26789930bdb", + "0x00490fe12feebd382069f77dfd21aef3c5dcbdbcab180a92c6911d0684c975eb", + "0x002201f07d5f407b3d5a2661d8bfdc0db9b22eccc99afd25848165ca4161ac16", + "0x00294b1bf8998d1124ae9c80e5649a95fc68d3dab2b25d5e1c06fa60ac7d18f6", + "0x007bf04a8e5ae9d366546a47fb66745d74d516d8a98db096b3a831cf42a5f6e1", + "0x00868b68b7aa5217a45faa2e267b252cdfbba1ddf72d538e118f3ca6379d2292", + "0x001bd48c1ffe76f29d48f903232781af49d1b1d9f68497e2fa9c6d382703c063", + "0x002eb02f04f12562dab473033871c077adc62e3a32949e32a94ce30d780d56df", + "0x00e2fdc57b6ee5d4d13d5259a1af1fdb3a2d193d1375978aa286be3fcdeb0fa2", + "0x00346b88f8cc57edae7ddd57c9bc726d4b57ab11d0759c7ab313f9fe973c2631", + "0x00558719d97d204cd5e0406a9eeda04b4d60899cf40bba85217c62e5679460e6", + "0x007ff92e9072f8ea906361dac50b3f1e0b1087fc20773aae56566bdd90e61360", + "0x00dc78fa48451ac5578bcbce68c276d8e89bcda64e291db1b14ddfa9abf27ddf", + "0x007b78b6959d28a9f76cca2dc7c364fa81f9f5c894a6af655890fdf172e059af", + "0x00c8aa31a21e9680c72c2a94b1f5ce7033a385295f90013facc764cc295794b1", + "0x0030b6b59280e3d06e539afffb37f498a199a4a9c1c6696c27fe21ec56dfd8e4", + "0x0004a3d927cda7f76b04028598ddc19183758f2ff6ad191d22f2e8a1554b804d", + "0x00b3b47d0c763a0113e4c346003b52a8be90f3eabad0cb167a97454e8402563b", + "0x00713cfd9e596c4e7e601f608fb37c946925485583f62c8455017b0b8c091cd2", + "0x00cc1511a3a3b29217def16011e7cb0803c48ac48fc453df77319226f1ea228a", + "0x00999bf591a8ae14542b098f4e4f31f8b734f01f75e4d9dbcb4013ed1c58dfbd", + "0x00d99567037d6a0e166d198fa50bfb2458a47407ed32f5f42b22575e1a93590d", + "0x0099cf79f66dcfecc205d6137cd4b1a20d5e25b664a994692003680fdae83447", + "0x0027ec3971321572f8dbd83056f7c29d3403b6036bf343ddb227dc325ec71170", + "0x007bdaf6b369ba9987ce11eb7192f99fcde995c0e9533479c9d612aac44d562e", + "0x00b5c4b5d2118afee96cf2b3ba01b5c842f02d60eb58d8e0ef613c64406de186", + "0x0032586531babd7d5cba0e9756a468987095ada2eb6e774d256fc2779bb2fd5c", + "0x00c032942a14748c943797972137d2a3159e7936690789aef301a570298f2323", + "0x00bb18d9096c13b375b7a51120a67c9158cbfa8c7bc2ac620ebde1c5a53ac8b6", + "0x0057be8436404bff13eaf719d3e947b020f073ca2a20fd38a328c245d7937576", + "0x000c86ed6a4699b49f29897ebbb4540a088d3d8363ba2a821fc8760d5528f5d0", + "0x00258f54aa27dba5cfa5f20efec02d95da16c928b37116ce5a8d95ca164f5d93", + "0x00fab329be1b06f1d4b8c9026953f6b23d57f426f0b9683a98573def4cafe90b", + "0x0077fe89cace67a357ddea71bc59a97331d2ee782ebb469fada14933ce4458d3", + "0x00bbab31a886f73cece4cee6865ab89e8473bd363358ba3691870365b6c2ceb9", + "0x004553a6e85145ff8c1179b055353fc81811b015190def011e86c842ce176b4a", + "0x00d18ecdb99ca70caa1d68436a839ce876a2e69f3fdd25eb381b2dc9fedfeb4c", + "0x00d7716cf8aae7b791b8aebd7ac745216462e06b392c46a106d44f977d195864", + "0x00488c3ab96e133b4f28713ae2c5d3dec9685477502add7ce166a3a6bf0a9cdc", + "0x00d862f57a4c3a4da8a9c2dea5a532dbc87ef26275e4bcb29635f2475d45b659", + "0x00f49a576d8b6429babb9ea90659d9395dc29a0f757a8e50e03c8c1f41d8b8e0", + "0x00b1d64f39e73bc1b4315a083b05cdf9183021cbdd71a8b03965321a376ba4b2", + "0x00ade6fc194e89206722ad93e5176b4247d4e42be1113a21ef03b7a50cefcc0b", + "0x0015c9e49ae21c5c8c860c44df9920cc3bc8468e11e38797b2e6b2d0e07a75a2", + "0x001f0ab3f199ebeb003ee98401aa5fb063b31a6c8fc60cdec2a6c5b5175cd7da", + "0x00fb066c26cdc21941ce7673d8300f2b35fe16610a8013056c84c1d1eb14a132", + "0x0095714a3857b3dbe91f049d2f4274860c26773e57743fa3540e767c8a011d64", + "0x005e346a82003f4a43bf5ec4bdb24b9835f998563b537f8f1ad075185c39d835", + "0x002daf22be437e7e0fb23822f908c88a8d5f92ed3199ea1bbe60e621b511a9ad", + "0x0064685f603d4184a0b911a7ee30588ce73ab085d64ed5b2560b42de3b437203", + "0x005738f8981276962f2eb7528909f434eb80390781748ffbf50654066750535e", + "0x00105a81244452c5258ce039d5770c34429f04094cd6dae35e92b07ae10293ae", + "0x00c3ab90ae46e13d5483e7f12ed243a04381e43651f330d523e7c807aa6beb1a", + "0x004e5e1366a19115d3eba08f05819a6190e2b0af9c02f17690b28dd0bf3fda2c", + "0x00266082a1079976f35538167d03b046f643f77f7451a4ad5ebb18e31900d0b5", + "0x00e30de9dff80573b9274cd424ee1448f9c5b0b71fdbb85288a18ff45f5f0c4c", + "0x0095a0d9ff9097255e3023a8d7bdb7f4f7a2632c0014386bcd55d863e1fe204e", + "0x008ed7ffae78f20f2dc86b69f229bd3ff03486b23ff7bb53a3a8404f8f955022", + "0x00cf79dcbee8d086ba0ccfe19500899e2b9fe03a803e5b8671869626e4537dd8", + "0x00643aa28829de548e0c3e3f7fa3ab8d521a913e18848ced0bc9b488548f3ce0", + "0x008f23a3be4eb55e06502c5027f6a212410e45350b6ff1287aa30a7b24aaa773", + "0x006f0f294ce4a3e98d439723fb7d2f411063eacad23be3aa4d166dbfe6a7a5ba", + "0x00b73b03632bece76fe3103dafb8f809326a851969227a4dc537cc3fe8cf7122", + "0x009f6bcb01b119e3fcb82c89d934e63be7bfe9fe10b857cfa02ffe30bfcfc76f", + "0x00f6505d2d063d228de2d4d4d6abe43fbda85436a6cd9f7f7ddcb872dce6c589", + "0x0057723f4290727ebc9b7263043f7135d61e91ac96d75b84453f94eb8b5db5e9", + "0x00d8f0ffee2bb5d20a4da326b91ac4a8668c44dd21dee89bae111466915848f8", + "0x00467362fa742a03a8fd6ac63b4db9ca85fd908ff454429cc2a70b15372c22bd", + "0x00f57d11128b45d015f845f0339f897b9de7d46deda79bda2d6018f3ad17a48b", + "0x00d5ce7ce79ec12a4a1d25f5236bd8c42bb806551e1bbfa175ffc40754d86199", + "0x00c34cfa7170d4e2a29514d8957df8b80e635d7fc8063591e3149beabd4b94a1", + "0x001dd35eb986d3b186bcedb428f737309be36242c54753a682ecf1ae056eeaba", + "0x00dabfdf7f06242646760fc1ecc84c1512072f0dace0160001b8bd955aa8b003", + "0x0080ab93782b07b9f6a0588db61bb7d0ebed1648bd61165341b9945d90f426c7", + "0x0059dd91bc34ddee4732e10dfef2e2c5581f572fffb95c7f965f7e9c40a1701d", + "0x00443b84e97f199f0f05600c5e17eebc46c69c80867056372061f401aac9ea95", + "0x00e5720aa7a191766987f1733755d830805a7f90f554949c06291fc9b80f0dd4", + "0x00b968e4ab4ad8348d80e3e5364350c556c4a10fed5c30ba6d43c21867171060", + "0x00e2381180a151482e5fd1b189650a058dd132177065784b6d583bc486331668", + "0x00ef283c6ba2f03c894c48696e32dab434cb3b8565331dbab56f0371fa14f476", + "0x008d20b241951d0174f94cc741c0ba97ac495c255ea9e9417009bfa8fa3cbb79", + "0x00a1172bb798e95caf9f4d097f15a310c4ca770fad655a492aee05aaed6d8303", + "0x00742390f7115fb6ae3375f2139f92a73baf82d176201dfc4f30e1016d8741a8", + "0x003b23308efaa2caf7e0109b45a2b971b9c30aa205eb2b852ee1b2113c09150c", + "0x00937907d1ecc8d65a82b435df3fa73a0883e0b525a95759c75c24e27719c3ab", + "0x00df41f709bfc7383d2c1c27dfeabde2cbfd856c7280f0740d37d5ab3d1b5e0b", + "0x000d00995a6884dc6a170393de7f39ec1764e8f52a1c0f514d46e0372a5097fc", + "0x00a517d633ca5726ed5c54a5de033173b84c31b2f338a0c0474d78fcdbc3a613", + "0x001fbcd26e22abec08dcb65357b1fd10c6622aa23c19c76bda6886585820efd5", + "0x00794915682a26a9d94fe849b3bf279a502e9588b2cc364af7b221c3268b379b", + "0x0060631112819b2a3f7d5054d3c10a522910305fa31936f110a60024292d2729", + "0x0001e44cd0ce0bbc9aa13ea68dd3c35686e947280fff550d8ddefc0bf57d0591", + "0x007b188e0ff582b0e87b39a7bfbe32d04821b07810d2151f626de7cefb8b512e", + "0x00142308cbe17c13fb38affffe05212244b1ee7aac8d71fd3b3f556b4dbd3c85", + "0x007df65f49081160299ebf007f4744a687c78339eb37b7bbe424d8639c920def", + "0x00a71f2705a8f1cc2546f9ddbe9e0cb035af979a1ea1ba84d1830460b021e206", + "0x00562e33649c802b03d55fec9e59a129a4a5ee8283f3cd953553b22a8c7d527d", + "0x00300052ec57fc469959f56e4fdc4dc6be108774f6c863951d3bad218205a226", + "0x0007ed69838a4f2320ce49b8dc705ce5e2893bb1be3d616aa1e2f6c233e11d6e", + "0x00d038a12a2eed1a0ded1491071197f91e79de98fd858209c44a1dc2a4b6cdc4", + "0x00193b086099d6881b4ac3731bf8dccc6c6f625ba4aa22f3634001539f644dbb", + "0x00f6b9f5af808f4b905b9a3500d97baa2787231e953cc53cb47a762ec63b71f0", + "0x00866e5e01e37e6c09ad54ecbaa5d467c6ce7ea5cc6adf4e4cc382d7c253ec6a", + "0x00f680c6bf22ea98c26649a86f8a9c6c5b1449c2ef71a2be6f5121f4ede9b9c1", + "0x00c6c3ba338e314ce2a76725ac11ff670603441d540007b8f9e9a5f641438bc2", + "0x00ca429444fc5ec1859eb70e85a614f7c2d0b0bbe25dd775e90236455875e871", + "0x00d94c71ecd5b35af0ed68f6c1b5f02e14c73b36ebb14f691342db8958577994", + "0x0031284d881c8739d0bba660826494493d411eaa7af6252fa0bf2e03e913a3f1", + "0x00f983077fb8e8e20b4271e0cd2e15a6dd0104d1b4f178108acc8886ff52fa21", + "0x003d30f6d0954285df1f7990b62d85596845d3391aa754e91944ab5490bd43f2", + "0x001db9cb5dd2e2043bfe4deb31595b13373a3fa69afb263f2e29965cea8f2731", + "0x00b06838986312e765ee8acf910c4dd340d63d524eeefd500ae75a4282359d3f", + "0x004bfedc70ac9eb7e7b67cf688aa74256e9ecd31d67dbc4e458f5cd851b7dc5d", + "0x00a750e4437f9d327f820bf1e43e35d8bf667699de65c0635f7dc19c556e564f", + "0x003f3d0069b4dc5f67fd1d679d4fc270122f8ead1de0e543a55de03bdf8f831e", + "0x00fd8db1caa043ca23ea412b34798322574a8407f8f63eaf0f9c399b4168cd4c", + "0x00b0239bd6e95a7a7cd87c83d2401184ab6feef674baa03416d8b0a66862738e", + "0x0074cd405ac7b0683d142a2bc7b6c55d2220247c0e86f670a58db9c29a1b4923", + "0x00e5ff2852d6d4f13ae00d01171c793d21bd5d2cbace1fcc055ce01558001a95", + "0x002e75838f758b096f292a210f8716ecdc03f69c59a9284529e0550f96744395", + "0x0009546b4a9b2a3e62ef89cd5523c5490c8ef6332cce071e34175a0411289b94", + "0x008330447aaa237b11837364269b459804292b3afb6b180be9b01adfe1d880dc", + "0x008554d853c5fe4399883ea56900202d1d4fd3c34156fbb8db992f59712d53a0", + "0x007fcd50e985c70d9dffb4d6aa8f2b586277bc3a882bee8809711aeac7a44361", + "0x00c2bd819f6ebc8d4a41b75f526c444ba19c860f112aed13978a930279a02383", + "0x006a74066d06b9e5124b439684ca38be64aad45ddf43f98b27f58c56a09861f0", + "0x00f83c3832c1366e40cc18c3504ff64d99ca00fd099e56d404d9d1046dc9bdae", + "0x006a2365f9bb663988b22343da9199ab431f4e83ad926eb49a6370b547a4da33", + "0x008a258e0791cc29b28bd35165768f3fdcb465fbd68f69efa3b56a8d9beeddc9", + "0x007060fbef8522e02d7f4ac61cd4885ab1411b6d2645c4bcacb461fb4b7faae6", + "0x008fefb297ef57edfc3e078f3af1ed41c68ba13474e7e9762d271a139f0a371f", + "0x00c31d0fedb29319a96e84eabdbe7b5e412ffbd1b77cbef251e44361a8422246", + "0x0037305452089dfc1d0f2aa61ce0b33b8be693804dc63b38415ea3e8018b8320", + "0x00f8c7d1b46d07529959b63c87e7aaca51713e7bc8d52c237c0f2a36a9ac2a43", + "0x00d3aacb19abea338275cf20070122aa61a99634376cc190d1fda23f09572c7b", + "0x0053b44fe190c102f9b41dabc2f6409ebc092b2ae14ee6a2c6ce22fc3103eb8d", + "0x00f4ec27aa05a96a81a6b1ba90f334386b179fbe5925310b4b594b7eb714e872", + "0x00eb1b465091f6b8cb0870753e54e736dd64ff3095862b45a9153519549272cf", + "0x00b818af9f935456f806e494fd0cdce08e95adcbc5039830e291948b46a98aa2", + "0x00c7469130ad3a807dbec268b2ed545144c7a085ca4af3b94388872647adfd10", + "0x005a901b2a819d41a13197b83135f8e4b71ee85139b72e73e60d6861703eb6fb", + "0x0015247f138311e69ec61a773947757ba25ea8dc2966a96334fa6314e9d8b56c", + "0x00d7925c5e2c2751ee57dd094b573316dbe145dfc260ca47e2f15478cf0a92b8", + "0x0002e4bf0435704a0a09dce89caca05684237d72a1d92f44a0e635f0d1edf579", + "0x005e9f967369eac066da3c70d6625698a554fcef2bdbc3889a9c53b2f990fef4", + "0x00c557b55796669e2925cf25c3d55a2735f24c5a0ce25abc68c7279f4e491686", + "0x008615968c010a0b8076110269d207ec7656645c78826f6c0db0476c377fbfc5", + "0x007383cc59dee2a4e3f0b07407d5dceb2418e518fb32f032ab80a426d9237637", + "0x00042c65b1e8dd40a1d6d00b3cbccf3e3938019c3e8e8c242d876bab76362ae4", + "0x003e69f9a233da7a9ced17b6543d09272a0a9c743506e96dcc98856a28aa9de6", + "0x008dd71adfe6382c4697bd1c48d3789a3025579a8a2367f73926079992a8e791", + "0x00a52c7c2e9283d980fb37e90985475df7296f3e69240c180bb38e52e4939b76", + "0x00167b8a9de2d7c07f4fc21fb0cfa1f967b9f056e63b40e0dd2605cfcde421d8", + "0x00443f74e5e6fcd1b10760bb3a5a577102cbfe33a40dbedb863640567904fb74", + "0x005ad3630ee5f9d41b29efc0848824291bbff2bdfad895cdcb7b12d3a78e4667", + "0x00cf333800097c8ec23ab0c69f915bf4bfb9488e503b9a288033f6a48e5c62a4", + "0x000ed51f87c9a56af472ceee7f295c78acba29b046aaefe1ef024654f06513e2", + "0x00ac4f6db9980e2ca5a6bb0096b017405a5ad01ff51a65f750e57888f6a40ad0", + "0x003025e494c1d3efae152e11fce47e929c6b8583c6d35bd6f860afaa46437f73", + "0x004427eae7b7ad50fd81555c98f30a9f8927f396f40853e0bf3e95ebc5a8db83", + "0x001e631e60b75f5fd624333ca0806da3d6d45ab093b1b8253b117f260ecc2d5f", + "0x000da2b3a0b6444644a433f7b6c3665ce901e842e899da009aad29553f1bfc12", + "0x00b1397e2203247ec0aa1b9f43b73f43e8f49ce8e354af54ff5dde3df5e51e6f", + "0x005d3a15c4c758101ee4d68c77ba0af001c0372fae2affd7d2c2f5cffb510f11", + "0x00ceedf9aac775a6e84d731333b8f5a3cbc58700c6c2543789183931a64be27b", + "0x00994fa90e9e18643ca25f31e310521362e6226e6325cc6151341a41ab150708", + "0x00a96946881fe9a5784474f88dff8603b6a2ed33956773863c6dbc1cfd6a5aa1", + "0x007523c2ef7f6c8735bb729bfb90291d3ad923c41d9c340d75d8f08e6c33f500", + "0x00087655ea93a5126109ab7fb557ca21214e5cee7633b3229202dab608d76436", + "0x0096d1224fbaf6d461feb12dce458cffc05bda5dfb68a6498d67c9a0972053ff", + "0x004d2d2ec10ac14268affeb121083afcbf103eaed7b30bf9f3a9d49c5b36350b", + "0x0054e29c96179a295ac8905af4591f4d5f21ec687aaec76d4dd117b0cc53c318", + "0x00cfe3622487c45d5d47aa724dca7fea5f0ef8b00879d4eaf9d5c8f1f7157c58", + "0x00b8e59c57c763b3b9716eb87bdc2d08f059b0841b5c1c59dff4e31fa6fc75b3", + "0x003b603e449fecfca351b40abf48be5526824f81fcacdea677139d058601e8a1", + "0x0029012c7a4d828d86075f5fb6549dcba2d9e4de4677e89278878c39b4bf92b0", + "0x0006161fb07523e3234c2f60ea402e8f3287bc4fc6740f4b0656222a56c5d5cb", + "0x001427ed7800ccfaae3cecc09708ef7947f35d9eecde32b364975eca8c088012", + "0x003cd8a2693a8431a041a59c7de8cc4bb688855b684896981d41c5d921dd364a", + "0x009021eb3f7a66000246ece170c75273d9ab905e026cf02024dddad4cc61f54a", + "0x00a77401e16b28e687818fda6c991cf9d1fb3f090433975ccf08e76812771720", + "0x008c1c25b01df0dd9740eea32f55e92f26154cb17070cae87a4b1ea760e11e6d", + "0x003a82f7ae6b8cc9990bb5efcd7037eb81227f55bd2b2ab9da3c322dd67d7cb0", + "0x00b11705ac6bee66a2545db80ed7f7057b5937335a29ffc547741d5fd412b326", + "0x003d9ce928033ba7d226d2b628f25719ba542013acd53814887b490f4a180cba", + "0x0024c99f45a6d14404a59048fccdabde6e3ab565450eb9899cf9e5f1c8cd849f", + "0x004c827e1232bac81b840913aa79905474448c8295fab9c4805871a8db731d1f", + "0x009f3bc3b5cc1dd63773e2ad1800152783a2602933caa679119760e3c1ae9118", + "0x00e51600c92a4eb77385b25100fbf2730490900bf5c73a25e6ef778c132ecc1d", + "0x0041c57e0bfa00ce329b2418d167c8d858d74611996c3e2bdb49d041e039065f", + "0x00cf16dbba23ca07157819273519263321cdfb48e2310c29658b115bb0cf1c03", + "0x0097ebcd1af54d99b4524fa288162a966410f500a85387ecdefd4033b556773b", + "0x00d5d547d8389741aa534bde2737b1d51879dd0a1bfc53b064068b99a8989585", + "0x00c8f7239e34ce9ca82087ddd79d6252a7a19f4ac074abd2cea5e431ff823085", + "0x00d3ed29e8e8c6db192c72a649bb65d6253faaa69969a6ec79b95b8a7b221896", + "0x00c35f1308a3c3e9536300c83b884d2f8216ef58b8b21b8b04b701b6c0cd4447", + "0x00bc830cd79ab04d7d50615e8eda3d563486c96ca9f4707940d07dd140a408d6", + "0x00c53281fed38fdc84c5d842e92c0f3a4fe6e05771cc117177607d7bffb8fd98", + "0x00c8a2b339fdb7a1b08d322d5e4a1d1ad8fd7acc39ad5b9df402474d9680dc97", + "0x003ce1688dbdacb2f93a0e9c7e812315ad99b4c53980d57353d418806f4cf14e", + "0x003435dd91d11c9c042ce9e8dd41a7a441fa6552a347c292c9a100eb7ed83985", + "0x00faf43ac8a31358d5f648aef904445d2c6267560923b0de6b9f49481b494d11", + "0x005b06f14f6bc33b9513510e4560519b3b54c6f3b8bd9cbd72b95a651bddfac7", + "0x00dd6769011d6513b502a02cc67fc9758d784547ff25c5859c152f3595cb189a", + "0x0019a533814eff8f0d9f42b44be70dbc6b0966bcd514da615ecffad6b83223c2", + "0x001440f624766efafcfcec13105ba32ef96e2eb3bbfa343ce7bcef8a73475049", + "0x006d3271557c4684430032623bf72a57ba663d83e3462d489aa8f56aee05c5c2", + "0x004cec823af0f42a25b26ef9adf22714c83849cb38ff75e5e1b7dcef2b4d9d44", + "0x00372c6ed4248a06db9d58046b72b07a8279170c5231d17a18ee75c503552111", + "0x00f45456461cee1e37855147ae30823388b7723b147528614510e4d9cc58d5da", + "0x00c8c0a707a74b396d4df253f4838386990636026356a99413c0260df7db8052", + "0x00f20ebc42325a78e74719bc0051f7fd9c4af34eddaf02672756726f42d6272a", + "0x0029fcfb9bfd11993863f67b37d5fff9d265195eb1060d9901a50983584fdd89", + "0x00ce46650067c026e42aba4d37045c2d978e85c9241be68ab1491d4c6724964a", + "0x00304d516caaf5e57ee7333bb733a972dbcb9beeaec156ea7e4db160e54f5bf1", + "0x0089ffaf051212c856505e0bc081e9377ae84d74150dea6681535ed9a8121250", + "0x0060e3ebfbf24189f319f856c9cc3585810cc9f0b84faf843c555d1671949d26", + "0x00e58b5e812cc112e05773106d1f1ed3203e6fb84472aed4de38367266450c08", + "0x00f430901b5e3ed316800405a04b937452230b95f5ed9e7920b12cb714995b8d", + "0x00640030d112a9733fe6b1152ab08533254d581d76267bcd26fcc6a1fc045f94", + "0x00372e9d04e1698868aa8bd3c167f5436a6367ab79feec140a56cd4b1ba62ea6", + "0x00d5e370b8c6730c454e68722cb9a37be1056fd359668d118f372f5ee4ac6829", + "0x00b52762e5346f9dea64392b833ad2967489f8390f3c19c2f290133c1cb19f49", + "0x00067102b9895dcdc07fe1f7fa49d8ee9e60d99eec7c799eb43ee217820786f6", + "0x00fa7596f56da982fc484656b1c13a1722464c736cf8ad0ea613d10910fd70a2", + "0x001f42e65fa2d985d678a4a5ea1f6cf4aeca8da9f9e7e1193c0ef7d768aa106c", + "0x001559ffd60971f0517773119be557414ba35fc4600bb4e04870ba6c09e0ba30", + "0x001ed53666e366ca3326058e57411c2c2f66446279e2038fd5860a41fa06c8d5", + "0x00e61211ca273ecdde70bf2d46a530cb3d5ef3a2b6d137d0565b552149a8c053", + "0x00a80cb61439612d3a50a64811a4f42a8af99d8fb26461680c2d06729ee1cf76", + "0x00fbf64622c55642e875e9ea3108fb198cc24832bf03b01a802bf1dcc2aa12d7", + "0x00eb7db4ce4ae3958e3d03dfe4a99d11cbf2c6d224b30ec876d87a5d2b10f11a", + "0x00cdce3fe1e8018f2a7cbc481b84e28c2f4c022799fe54aae56fc05720fbbe85", + "0x00655cd4c2e7e3561dd5fd670314c879cd61d1114425b61e310c8e337b18ce3e", + "0x002b57050aaeb58d5f539ea1739b71c191bca2df6642cdfee9888057fb4969a9", + "0x00b7fb604e759a9b6aad1210019573e8dc1fe913ccf46cdcf15e404ae273954f", + "0x00d239cc56362b69f935eeb4dd5b9aef11579303e05b7f8572a9606ccf7ab0e2", + "0x00834bd8c4a9909fc5b5dae5b81c2d900eacb4bd74a3fb5ef80969ad03f47bf4", + "0x00d0abb3ff815e8be8394744fd580a5e794bf50fbb59973b5bf5667d05081aa4", + "0x00fbb6ad9031289ae63e790a332325372a84fdd95757cadb25584427ff965f23", + "0x001c95b6c4a6fe9c71cc76bc4fc1b03346f80afd7e9038c7919b920c89561092", + "0x00a110c81f156060c7c83f97b82cfb1d0f1e24831669b8f14727164fe224ecd4", + "0x008eb2cec91735a8c912e3f62e907c5785c3048b7f7f24e3d650c726e1258611", + "0x00b8e228e8608e97de9cf062cc26f8d7fae29cb5b2e580d38024f3d78334801f", + "0x002f7b59fb5c3fc560418997c96d64775cf6f12084106ee45828045148221cb9", + "0x000d7fe04cf2b7463b1491350d666f265fc3a3991dccb98db17ef0069f1ddfc2", + "0x00e9cc7662f54126b2738caf510701c6162d67b3ecac048d95e7238adf2858ca", + "0x000f6ba65b9405223b328a41c3e3cc312bacb9d7f65233d8cc6b29003e9ab57a", + "0x00bc868ca5047fd8c463387c9dbea24a56c16e535b8c961dbd325d1308d45173", + "0x008b6f9640a6a6436a67fee6e9106206d9546a512acd031155805576667ed093", + "0x00ac26747a9ec2629facfc760f06c04d62739aedae228d96a9d471781c412e91", + "0x0091525bc02f5f98e068c4fc556727982907c15316d807d5d06aa7951eb6f8f5", + "0x0065b47f6893c1173c767ae7f9fdb6b115d696d67f458db203faf796c68432e2", + "0x00cb2b3983ce23f70c915249729edc6b77ac36d929987afe33339fb08a621dad", + "0x002347bd513f7fe2a279baa0d6a1165192c05434ebfe58be91168cb968f6f02b", + "0x00c20bb7dffaf03931c818bca0a1d752c3cecfb281f85cb4f902bb1708ff6e17", + "0x00e9204943f3c0c404301f55fcf39af7b4786ea03472919d1f87df39544db3fb", + "0x0000b6d1c634b4583696167dbd75d3beadd072cf1fb655d403cfd10c1253baa7", + "0x009c1207cf649c0e907625ed0a07ff783f61c9b9b40c8976983104f4dd690c71", + "0x00291334f05c7055a92eaf148b78b8772dcb4dbd0202cedcabbd486654e5cd79", + "0x0056cbf2e343645c3485dbbf894c991a5a09030eaa4c898dd3e8224794835834", + "0x00463507f3581316b7813fe773e68042738e1caf498019e827d64ac500d1960f", + "0x0091975e35ecb4efc52d1149b07e8b3fc4c34e5eb7ef18d75f50110d561dcf29", + "0x00ebc497743a04302732aae5b9681d3195fb9a83a212311ad0c2217cd389806a", + "0x00efe1e5ffd5df0c8023f1b14dec8ada8af0a4f83aab10946b924708f0aced9e", + "0x008864664262164e1cc333a9df453e951e0c8b643dd5ee3cc14884da43371927", + "0x002141c99dd0c6b07cda2c063720df7ebff1e4feace6395cdfba7364bc07ab91", + "0x00cadd328e4ff6939ddf37b02189d7965dc5ba2379adf5351b070dd5735e51a8", + "0x009fe5191f3c190600145f796aaff4b57f305b4e803cb4f226a46431e90a16d6", + "0x002a1bfc2240dd886145d93943acdd06e7caa65faca316f67df36be141140e7f", + "0x0000a8c3c90dd5a723b1e8004b90ec4c03189679b7fd24e7da1ec436744d95bc", + "0x0044393919fc7e624e0dec063c9ae43a1a3e1162ec475aa4811707c16d4bc259", + "0x00f54d2a61609cad53fedfcd927bcb73e77e280bdc7907d8923c9018a31de6b1", + "0x00a757ebbb46b4bb969e920a8f316720e513f4edaf807dd069a82ccb45160871", + "0x0016e952c8d5f4b81e4a6fb14258607cdc8b89ecbbb347f364b1354d1aca4875", + "0x00c8917a4360f1f36806c46f1c255ce97b5c8248e158a6f8ca4f20d471ed649c", + "0x004c29fdf5dc82205c4e8bef9ca931aaefd2f37c85168fe033074428439070b4", + "0x0005ef155ceba75da577031161523ea99eb9459439f189b79ce542631ef18b18", + "0x0024d86302086673a8d6fe242b4f75d751f2de04beb90cf9416e19918b59f434", + "0x00357a655d969fc33f263b97157ecae96828e35b67f9acf5cc070e982408bb43", + "0x00fc0e422fa16588652c71251b0ea3db809e07b73d2ba2703d2fd9d8661e193b", + "0x002d15ebba724a79bdd2f06f0c44c8565e83d1ebb54c2b1a1591296444fc631a", + "0x00b85541fbf7a120a0c1e0e22b78dda9855c5f94b1824121fc932a489339473f", + "0x00bc2324bcbbee379602e502fd7d45d8e053c37e2a2425773309107c334da5af", + "0x008b9eef0fd97b8ce20f2677301756a5eeca5980ad5920f6bda6df2815cf577d", + "0x00201f7f67886fc2fec37e2e5a67c1136da65d35dce8e47391819df6cdf01fbd", + "0x001d6d5734fc3709a3b9927fa28110b7f59eb179a1a05ec09ed9f48b1c7b6d75", + "0x00d44d330382f744012a369e549db008a841809e376e083618c9633115ff2632", + "0x0058e4ec139219fe7520aa5eaf72aa29624ec76bbdd2f07b536056e8e477ff83", + "0x00d77ca010b80d372c0d5a3abb476c3e8971ed50a4f62ee869c280a28ae9c238", + "0x00e0a03ab52e37a55adfd9f217bb43a6888e1fff5d2c6b516286193bbe56a9b0", + "0x009daa109d1ce7fbb24ee83e024a0b7c2f86a877354383379dfb93405cf24b8c", + "0x00fd473c8e0e8385f1fc93084c1fd725ee63ee2d435445f4c13a2eb7ece497e9", + "0x00dc24ae34f92848d2835a9bb1fac178bd37979c725ea31f5ed57a5b46f96a3c", + "0x0018e614f06801337df497b91f20643b6c7097c7aa2a7ce2226fadf07079757a", + "0x0012af94d997e09956bf8c8ee8ca5bff6139593c3c9c966c0ac214bede9fb144", + "0x00094def406335f4022a92be68ee03ffc750bdb7d9429a55f70c686ff031e053", + "0x00e5000c6b083b8bac149bb0990c4daf08b5a935a40c8484010b94a097fd2488", + "0x00840b821e2d52f41da3299977c7c9d1e85b933baa63b3f7a33d59fd7ec8c581", + "0x006ddf1dd8bc93c78ef442414dd57219a30494de77e7681cdfbddf0451046a1c", + "0x0069792786cb01d3383143141248829d33a8c176395702f96a4845f0f27fc540", + "0x00aa15eaa42396f412951628a429cfb7918a587c234993a8c04760a1b2b23b5e", + "0x006d566de4c8bb17b806d37954ac39104b2c6114c0a70e2bd2b661c6ac6a7367", + "0x0007a4901396283e452d558181ce56def64d1d2b030ef8dd3cc093c747bc2c4a", + "0x00cd5b89fb72dc870ee9f27f63b37ac46f9a151f991ee6a6e1d7a0b57aa2eda9", + "0x0010950bd0da8cee3957ccc4d7d275301d1a294e1deae74ef419e2810b161f70", + "0x005b0a39268256c7a9f5845216aeef688fe2479fc78d166956cad1c31b82172d", + "0x0036d45e03a8cfc6b0ce8bad5f8ff778fb8f836dc6d741a6f50ed571894dee13", + "0x0037603a0cef977a3e47ef3cf7d767fd1d4b31889d5cf706292792aa1a52dbd2", + "0x00b8ad0dbc3da24f6a10f60bc01e58520df0e0ef3eff15d12f03e597734a40a0", + "0x007f51cb29f97b179ba6c796fadfc9f76a34f8b1a3a76de8130645b2152daa78", + "0x003e1b4eb051aef2ce33dd1d0acdefd99fbd2b41ede83c86f93373bd6ef2fcfb", + "0x00e5c3c291c700d0e50e9679381e0c4cf98d4dbdb9683d20947509281d212efa", + "0x00db1c308d2e8060a17e86ddd772906b6f87f59a0adedda10055c83e6b899ed0", + "0x00baea224519324c9184da59e361c08f7918e41c275e6af0a3ea932b7c1cbe99", + "0x00d76fea2d91c69555e3b5617df53a73903251618d40ace31528c92a61cb1255", + "0x004aa0c8816ad1830f42db907b850af3ba94bf706c8955935001c17d4ff3388d", + "0x00d960e5f98c85028e6c2fb85bdd426624b3d28c3735af2754f5d5a52cd5f8c3", + "0x002062a3e5d61950c65eb07624c5b87093c78ba23faed1fcc3eaeb528f243884", + "0x003ff0251d2640df9bdf18c9a8d73e12626cf6904b3953326bfb38c812694347", + "0x004305bdb2a898347b4cf415a35b5c7d1cee7958c8b5cc701adf521bf215e9ba", + "0x00b1c68a5d373c6f04de840483ef22f9d5abfbce7076f4744aafaaf0169cac58", + "0x008c79503cba956bcf3f05ad268bcddba0bd9e998b272242a744a6b8dbe6c664", + "0x006ee06b8df1961c69f022faf53457d47758e02a8850aedad03a9ae0a0b3e6f9", + "0x00c2140567ec52ac2b9041f3b61582f512972b8c376b0fa518efc69102a4a736", + "0x00c27707238bdb9f95e5293fa24d1e5ca4d7f8883b98480a05ef2014a0d31647", + "0x0010b77fc147f7ee574fac6c01ac02fbe076b5dc4ecac99cc4fd3568525ccb52", + "0x00c1eb2c62f1d1e17d0c1113c5fcf7ce332ab0f4257c670a38622a83632ad1d5", + "0x008c98648d5b1592772c9b03f4c30bfed4d276dd6909846b011860a4d7c12452", + "0x006f8ec64e35d5448bccfb03743f16c71df5353b3c91f5606daf145683d4f7f3", + "0x00421ca2ece2675ddf65f147bf3bf7844e35b4cae5ceaf9b9c4c0195502331e0", + "0x00fb191b3ce04810375b5a13d2b9135b65219a13e2be2874fa20d227d8306f6b", + "0x00ab29802898923f97fbfa37f0c41bb51d6059260b0311e647f99f87c323fc92", + "0x00e185b9193bbaa1e00cb8c14c6d2826b17e9a7cd1924fd437040aa294b0f246", + "0x005c6b09cb0ed9abb04a2b69dfacc55c6dcb70ddf2b0225319eedb97b7e85264", + "0x00188205e7c995255f73c535a2d4714b8930192eecce368fbdca2b6cfacbc670", + "0x00ede90e48f63597548988336b9fe8ed97d27590ddb846db07cced7a3764dfa7", + "0x00f51629505fd22e65ad9faec4778e09e25151e8e1bc7c05ca94dc3ae59db028", + "0x005addac251fdc37015fdd966a08eb2342594ba14959caad4b6b2d281b26f259", + "0x008d802f0f8be223b6727f904d8e3bb15112415152638f4c19e4a58ec780a67d", + "0x00ff0f07a72ca4452ade82c61b549936c7114b24874d3ddfe1660156e8db066d", + "0x0056374752298fb868de7eef0ec8b25c503e3e808bfd821aa1b56c1129b36b2d", + "0x00bdf3f73be40591d4fa190c43da7d0153d7e4ad396c03eb92c667196fbb5bfe", + "0x00e9195fd22d207c051a2a0aba2cf98409d73c7d10dc4057f2987f0614a195fe", + "0x009fe81382b481c52d68bb49530ab1dced37d644fb0bb9f349d5f14188686b60", + "0x00a8df96937da63283f9410d79bbbbdaecd8a92f8fd5bdd2694f1c0b1b6262b2", + "0x00af75314f0606ec85d0ae9a4dd7a5e6dd69dd62c4a86098efab6b719b5e6e73", + "0x0021fd05edbafa17e14b42e613d38ce8f901a3d20db14dc7751a6b6ffd569e12", + "0x00fb5fea52783286bbf41c5242b8f914bcf6a5441c962e6222a417851379de11", + "0x002ab134b0b97a2a28dd8e83f28405ae16f20d5dd09d094dfb08ea0767a336b7", + "0x00f750004c68c478e70d62efd058eba44cfa14683bb4cef594dd4e955c2a31d1", + "0x00bb96cf7ed3a1aef2ac7a0d521c129b3c56f65d08bdc59fe8a6e4db0ed814db", + "0x00ac3878cbb5760a6e633125ee30d1e4024eb1d33d138c641fbc64149bd15594", + "0x00f66e6e272a0273ea92e31908d9666f73f298954839a5616c0c20af39941dc8", + "0x00184ed96f271a4b75c811f87f56fc31d99353e26266092a52aad77db23dfdfd", + "0x0055a5729097536c57674df10f6ce6f9e351e63db2d9ac58b8b29d819bfb66e8", + "0x008cbdbe895a31d12948402d67005f9026160dd42b034206028798eb070b3c9f", + "0x006746cde2fa6f8143b716a0c95bb446646f1cda9f1e32680fb77c6a34f6a638", + "0x008734667959f352187a39ff6beccb3cebb5e913e91da935003792a205ef23dc", + "0x00c0ed6c8fec9547aeb80f63d2c294bfcf3c336c837d926d0dc0462924ca4674", + "0x00b53b7a6542729a2d5effc5b3c9df77d3a31741ebd1e70d1f19d5f9f6590be8", + "0x005c0e80875f68cdeeaa1dbee7822b3273dd08c797849b8a7446363363c992d1", + "0x006a70b49f9a8d1b1ed94fb422649de7379ba94a275c68df95b8dc4304704246", + "0x0089e039c63f38f1dabeefbd0ed86ed5b2c17322cddf16716b1c1ea1e4ef5c52", + "0x0040adc7cf5495d2d6edb5a422ab920a83c64e0374eba4ec64d9f77364a98c33", + "0x008ff2dee36c108d7b6c9feb6214c6bb4fb34f62f16ac7a86b99f569d64d40a8", + "0x00ce054f696f09f517bd828aeb81e87eb916e0a0cb539518806c91f69545d0c6", + "0x00a20a4c4bdb3d0080f18a90c6dfa5ef7c152c34af92d6c4d92d754e45fb5c96", + "0x000d07dd5eb4f7c4f809888b722161f30708afbcd52530bdc77ecb7baa75a8b4", + "0x0077fa6061cd79fd8634c1a2e7d698c404ea9253fd4ee28ba766c2118b275f6c", + "0x00b9b1f9595e62977ebed7dafc3b388fecc19c02d89c6425543df201dea54521", + "0x00649abe31e6f3aaf1706eae59310d9ad97677b0b8bdfe39eefbef0fd2f88ff9", + "0x00fec07d236b5ed92d62711b024040312ec1985504583e3ac3fff68d98a37852", + "0x0089437ca12227b83148ca33ba8ec1a379f4ff3e6a3719187cc665d25da365ba", + "0x006466e9ec432867ffdc3320d25f224b7b72ca1d703acea10f581e68843383fc", + "0x00d8500f4d749fc62edccbe7e65317a0325a0664d5eced6893922312ceb29236", + "0x005440b286cd762d3deeb0ca5f027658a99ad93dc1f3f20dc68df2cf6e9b5faa", + "0x007f30632d4d626d70b60574d96949ead72063998c005c4beb759d8145970ef9", + "0x00909a3fc510db029cda97511602c513ad86aba5a59621c7749d163bfa003fdc", + "0x008cd24f0a7cf4e423a524d18a143870f49c668bc913e5d053e092a892585152", + "0x00c4e3a7028e9877934d333d4f8ef6f8ed49fb619292f6d545eb1d3be6321cd3", + "0x00455bea0a889df93d834833c3f34f4586a95ac432248aca0aa9dca5885b69c5", + "0x008dd6c93d8edb2e2a205b15d4aa39dc02d7924df8e6d1e6aa164326ad932207", + "0x00a991623c3bc3863995687399bf95f0087841ff99abdcab713b7fbacecb4a2c", + "0x00d545c7703da835ce26b13dd30b9dc56a474cd77f5c1404287c904c1f658465", + "0x0072d4507c69fad98f167d6673b5a6948a4a3515f9d6f1a6fba29a5a95f1d136", + "0x00f0afada1a46bb9da240c7c898b95b6bbab9fcd959f9b7ee890dd6c4f4deb4a", + "0x00f2f0f614c5998260208cab1f86827b89ab955e864b89d1a9d97ce6b233383e", + "0x003a1150fb617f1736826722946d54fe2cd9f10d0674b8b4890ba94fdf6f1e23", + "0x003a59bf266aaf3c610e861e1dcbd471c30936210e4270af5838134daa3f03d7", + "0x002e88ad76cb03602c0a25a815afa27fb6f582396732b3b8c60f6f8e8c4b4ff5", + "0x00536b1c62274e9af2ca05b753cccd14489ecf7226a745e5e3e9f34e3e370fe3", + "0x001996a8889507901c8018086d987ea8b67002e2fa2fa92ed9a628532372d42b", + "0x009dc53cf645c360cda1dad98345f830f144159640d871014c1b1cb9f0adb9c2", + "0x00f0ca99abdc0e783e8604b8100ac2d8118bb56c9be1b9f07ab26dc5c91d280e", + "0x002a2c369810928b5af07ea0827c90a96a55d717a40fd8119f00db6b1e78e729", + "0x00ad6864a363d0f6e5ae3887e45dcd9316f19e083580f5e13e9d8ce81119f4e2", + "0x0021b6fd88fe82e81db8b703e1a81ca3bde2509faf7d0ba635d2146f18cec297", + "0x00422421b6b5cdfcb93fddabba13fa19491029683c39b41f30eeb5a78a64c4e5", + "0x00a2b7678a71ac153d81d944f2bf5a2e9e84cc0c83a14b843f149bd72e7986de", + "0x0038ee8c7a7dc63c3346e09e1518df4771c900c9820a4b746782b3c863d597b0", + "0x008ca1a3c2f4f4e736f1ed4d87e4f567a9c802a5424caccb83a134fedefe82ed", + "0x00dfdfc05481a892fa9717697035e7c36aa73ca7e0b16d610dab603cba7afe6d", + "0x0059a7b2902345b4c0b8cef85697cf0fbacef99fba1912b6b011b78b27ec9a7c", + "0x008559773f573d2dae717b344a61603eeee5587254979658f319fa6227c229a1", + "0x008e155eac4dfff3102f2deb1345e6dbefb3fb211972fcbed534deb111163339", + "0x0024a9535fbf4ba57dfa098e93ff9838da0ca1ec428bf40b61a77eaa80a9af5b", + "0x003f20a0e912ee9dbde0e97b426dd0e03fda38546df9f7fc002b203ff5b655bb", + "0x00c528a84eb0f3281c89edbcc8919c6ff4ada91514c454a3211e32504761ce9f", + "0x00cc11de3b8e5a288b7e4272a897d35e6d36c391d9a88aeca824e5a044df92d9", + "0x007605b8dc3b8ba7d4d04c8b65140f48e0cc9327def9b098086f892d0734815f", + "0x00a74fb96c02cfe23fce0b4b98ebc4b9e31d0aaa169cf3d29c93602007d2ee9d", + "0x0035546e0e09775bee66d8f19a420fa9ec581caa68ad277f444579ff848b4a04", + "0x00f904ef3967aec255f2562e94d1cbfdb4eb5b2625034ca4e94d2df811e7d338", + "0x000e7dda9ec3b8380028ebe014d0b99d5528240d722c036330830b9c15c71535", + "0x00a71934896ff3bbe9a6fa7024c0038d22b4c4599aba99cacf52246c77bde0cd", + "0x00661fcf3c597c0738dcba554640b550b0d32a0909a2ad8135f45cd017625cec", + "0x0083993aaf8951a77de115d5b7d3edf4abdffca39df4515530384a7c7461d141", + "0x00f07f0c72d6abfa7283aaa8ddbed50b25c771d279a6d93cfab0c5d24b13629a", + "0x001afa0563145f6849031e3f590c628aad1bd0ff9a81598fa7fdf6a5d49eb390", + "0x0007009227beb93641af18cd6bd14b1d1aae11d135d2b7920334e9afaa2965d0", + "0x00db2833bafd7265d994c2c770ca096c76ed8aa135d4b098c0fbefa40dcb66df", + "0x0082f7c776a02fb25d6886d50a22bfdaee36c52dab674b5c2911863557d97f27", + "0x00a3d666beca8180be5dc774bdca7ac8f286935719d83ee68e786ffa17785d4f", + "0x0003e99913e5e8a85c0b8232873ec5b877db25dd8fc5f59c04de435a193ff7d1", + "0x006c9babe4e252bd3d9d092f878bf5e43802d8c22f256a3e8f0e50c7b78f1b2b", + "0x0043906d8dbb1dd6b73ea755924360be8595bd99ac80522330f9be8f6a131f02", + "0x000c952ee4f8db29140021a75549944b6c9bd7d30f4c9c8061ca6d61a3b93ca7", + "0x00f2d39d2906a24b8ebc6cf65844968c3b8bca61bf36b9a0654b1eb466e098cd", + "0x0007cd435d87b57ba3a2885d5ea176388e3b41e874af685784a8e67bd71db795", + "0x004826a3f354770fd5761e7e22d9213d4c30f3bcadd3c5e665020a31bb572faf", + "0x0028de709b0940bd0619a343b312d6ae5900ca8a1b643073743be90451c8f93b", + "0x003d8f439c4596b0086e6ce7a077b1ab20d38754b880f7c14a9893405f96aaa9", + "0x003e53a2b6caa41d04640d55ad3b5009262d2c1f60c1bb4e5e7161224db2c84e", + "0x00aee0f180fa9c8396377d25fbe4a6564019c90c29fe62a8f92928f421c6320d", + "0x00744c92cfaca9de76b1db96ddf9fe10483ad7c941d709fc0e072388e6e092c4", + "0x00cbe9a1b8be150069bb6347ae7dc5b92d6a63d8b2e71e48e6ea84c8315aa3e3", + "0x00a5afb92b839238c63bb3111699702b4dc6f297e608e4c0b0f3837e76c97042", + "0x002464f205628a84ae10847d85485709f2cb641c74ee1fd60c9798f403084a61", + "0x00615c2a9dac4dff6d4629012900d7845a5fb0b20d84e43d1e43af8a2fd5bb4c", + "0x00460252300b17e1dc383ebe450007f925adf23d743392e57dbcc066abfa71fb", + "0x00bbd0d7ce4c1c2622e4b88e05d5f44ab2871e0830e4d200c6547bda96edba66", + "0x00e597612e77e1b03511d4b8942c0298a7c04563bc0152db7354ebd136e2b3ee", + "0x0016557c201242a9f3641390bd6c5ac879b75c21c85f9421bd288f1ec74c0b1f", + "0x00dee67ea58cdbe97d5f0a6098b65afb8b1a77f5fc0a33cb4cdc83b8c5e5a869", + "0x002f7dbca6717d449613cefe5ff4336cecff670f8f9a1840bfa8cec974b518b7", + "0x006bfc50f94b4740ccea0b1374d994b9a1da59b3ff567c0c1b4f284bda4303fb", + "0x00631eb45a1d0260ffeca492931a3fac60a61548e866b7766a199b35bdf69eaa", + "0x00635fadeafa0d3109a35ecfd5ffa64ff17dffcafc66d44ac1793a4f2fb1f09f", + "0x0081a875451ce57e8ec40740b24194020e4565887a00b3e63c499ec8df41e33d", + "0x005892d5a29a186f6806bdd7d19dd561bde46ea3426cdfe623eded04bbe47c06", + "0x001bc11540e8236eba12a9bcbe42bb866cdea59917fc70f4d26334cb17d48ad6", + "0x00ae508c4cdba09a33dcc076f5c41a9fbcf14aac947c284676128cc98c36663c", + "0x000ef01284c788f303e77b6dfba3277646ef024c695b769871ec3fb1f7e80aa8", + "0x00aa15a85964b2761f76c628c94a85a4132d0de2f56e4228af249a59d79802f5", + "0x0034dec5604e45c017032af945a141dde919a629d88253559d8743c0df3b47e4", + "0x00e2bf24139d7752ae3eddcfdd5d3966c3f123355ce3c718d329c5cd09c46e74", + "0x002ca482fc0dd55d3e15d7eee019a7ac63afef0681a3d77bfc5f91a2a9efc9ad", + "0x00d1050c18b0bb9e62ea01b3848eda382aa3a9ae0c728139669a5b6ed281fc45", + "0x00a7def6012800e7337f32a2288db7954541ae5b39308d138aec3f98e950dbf5", + "0x007d85517ed1b314242237dfd94c445e9c9184e005f8eaf2c9b50fddb18f4916", + "0x0054c896747451e3e737c736c11913356f8220d68bfb418d9ff09f3e9e45c889", + "0x0016c0b72585664f1b4ebc5da937df987ead7f2505e502c547d2fbb1d5c00a7a", + "0x00c6713eda85b2457f2506d223085186d8ba7578869235332d1473f4069e4322", + "0x00141acc879ed5fbcb594ce1d2915aeab077b14aacac69b3f7e0cb51c4886532", + "0x00607210591876f70cca333dde488f01144bdf791f6e916304cd1d5af82a99ef", + "0x00f1b6183fe628a6693f38d878f7c9714c92578602d644039d60748271bce30d", + "0x001e0df4443607e7019764598749ba87f2ba5399bb707b3a72c624af44e39260", + "0x00cc7e0670ed61ef504c3b012d36364df70fcae96b80505e313e4371035eb412", + "0x00d7776caf2c112bcea4dad0e2f086fe9b367318af20552ad89f1629d493d786", + "0x008c45e467c46492e30d6a530909c6aba230410fb1e10eb9004bae44fea78fc3", + "0x00b28303342ee9f3094a81d530d935db1283a751d9b5840a8f706ef400322508", + "0x00b103049290bd9b03cf9cf93b39323537029065700c496444b29dfd934feb00", + "0x00bf855f5cd30eaede975db777ef130e0f1d7776a61215c6d4dac3369fd27d9c", + "0x00acbb365576f11edac23edef27ed9cea3a7182e1a41804e498612da2875d339", + "0x00f8e7abedfb7f75b64ba4a5dc82acb01f275077b1e1e292cf0893de63fcb018", + "0x00f55a0c03c22f55d775241b7f9bf56ab2de8175dbf08cd6afb9a2402438cc63", + "0x00c1af397db0bb155ec19d19d24c1e519ab2d7e8f4204393f1839493da58a87d", + "0x009536fe888673415fab5a0ccd587aef5d9656018ab01c5cf6b99e750ad3eeda", + "0x00fe47f6efa1a4c52490e78f3846eabc6001d94392f070584e97f67fc30649fc", + "0x00a6928cf41afcd03c5db75b178b40591af2aa718d2a5a18f6f18f0b43d4bed5", + "0x0057d7e94547d3ef55a0bb621b6f6005d7172daaa693d9d055b910d92245259a", + "0x0088d5d1477ccc696104c8817c42eb3ac5c21baf9987b3b5cdf3d10321099e29", + "0x00137356dd2c2c7fafad21f38dbed01e30a01740e9d67b980b819c4c7cdcf405", + "0x008e9896d16c5b0f36dafe3bafcf8b1eef3c23337eac3b01622ff75b6ad6d27f", + "0x00ca1ca0817b531ec96e952f33f95c7355717f9e12aefa7d77556707553af4a6", + "0x000423edc5b2cda58cfbe301df1ed585b0ea93dd86ea2ddd55271fd45c6e2caf", + "0x00a1614dee2cb5f74a4d7de7699483ce984999e429b5fb812c6d244d1351dc93", + "0x005025aba41f51ca85339563747bf2ba81d6a1d8a4c183b22c9714d58fede22b", + "0x00e3a3c48e3f5d84052f433e938452ac07998511ec244971990f74c985f11902", + "0x002e04effe571f39d3b1149c44c380a45ef9f1f8b033a3d3737f24f507531eb8", + "0x00f7ffcf80d2195f025d23e9b76de3c7b1b0f2fa4748f5da71f11f22fae8d1dc", + "0x00493222e73304f1f43f6bed16057c3ab2aea20bc43c1b8ce663a11cb033c0af", + "0x00d7f1856086fc73efafafc47dd945a74c9043b79a0f23c3a0abcd8ad4222b92", + "0x00e4d0d528a91dd9a13e144ddc401d9abea4a1b9a9d126af0945a5994b9eef73", + "0x00e5ce130ce2a7057893bed312f854d5a1c3d78a4c0e0df3c78bad8985261611", + "0x00d1ecbb2f325e7989b53f1b45a28885c59158ba5e0fb8c7f6aa9a9f19f2e038", + "0x001ad47f590e8d8fc32aa5dabce0c104b677e1f6d3c4c42fa8b60d2b6d06b2ab", + "0x00b0053c38e2a19040dcadf23fbeee9c2f525d0e19a6712947432718c5acdcf9", + "0x008b77831fd02616523ab7d566fab79741e2f507618d99ea07320a238c6c6c80", + "0x0067d40f755ee4c63cdd9fce7fbadae3c1c5e65cd3cd8081e904d43ca89d8056", + "0x00e2bfaaddbc7cc917ea1479e724697b486c133b87fe6cfcad7784780f98e1c9", + "0x00564407b037013a205b05c9359243897592440305a0a20190e70d8349249917", + "0x00c139d64ce95ac253055a44c1b70056f8153265f59dae6d41b76178bd4eec5b", + "0x006edd15ff128e1775f15c9fb0c704235d611f3aaba14d1aa619f0a05a922f6e", + "0x008e5ac9b34a4a92394d19533938b92a21efacc7355fc9a75739b8cbce1b5298", + "0x00c83ff1b0f60694b190b99007d58573f876706116da2f581a5b5aaa8861866f", + "0x00e41323e5d71373e079bce185816b995dcadbb6bff1e1b2069465bd25f2fbaa", + "0x006af0f5565c96a494deea44b33e890737449409954b797e80e74a6ec6e43663", + "0x005cc71691a7d44ca214766c073aff6aa26de7d6598b18619e82643af12c7cba", + "0x009ae3c3aed9e63aea307b6b7aac913d6717e461d15741fcedeee116279d724d", + "0x00fe1e6ec5a8264b017ed2820afdb888fa8e7403a0bfbebe6f68360a3e3bfb2b", + "0x0070da2f8c6dbb137e625a3c449012941f9d16062d765d73659bc9f322ad8f6e", + "0x00a2ce406f6a4bbe60bd53831e758971aa5aa19d65a7ee92aeb52a2c4923f633", + "0x0049c6e8613c1befecd4c8585ed360f2e566b395f7df07f4a9aa002935ee2671", + "0x0036cf1ad0eaf94febe13b674d2f6a3b830d709d9f05edbfc7462ff4d83f12e2", + "0x00ff1fc2b862a75f823dd4fba92b14b9783f4309043e1aa241ed5ca692773b71", + "0x001fa1c540ec26e6a3dc37b74b28e5d8ab7eebe2969eac94c5d0a350e844fe4a", + "0x008c01720f3634b731387c18ea8576defc45f4e8a4f939a9414a97c783508c1d", + "0x00564257dbb48f271f6cb7f484f4234f5ad8dc397b769b8bd1f17c58305f0536", + "0x00379fb37ef3e206d8b6b028aa06a98404cbc16383724ebf3f72096e5fd12600", + "0x005a177d52a9b785bd822ed7b0fb22bf9f36b3a92b53d7bf082ae54a83dcfb7c", + "0x000f9c7b02c3b42d5820e5298030304496bc4cf24767b43ff8ca3fbe97bcb8b4", + "0x00510c5ad81c4344ea4230e9f87c3ac5fab6fc182212d028f8a8a0d521a41afd", + "0x0016cc6fa35686c054d80c0e63b3a6fce915ca5e7ea09ea8e69478b8c36fb731", + "0x0082ce97486c8c3292541069b6343e3cd3abc762313cf4ddb3dff3ad5b65de7f", + "0x00aeee1f8e089a98a370755fece332a68adfa1dbe3a02953d770abbbe4aeb983", + "0x005524661fa1ff7ec198e4c08ff6582096716265de4a8cda965d88e98e3b44d3", + "0x00f5eebfd1805f2785546498dc2cf8eedba90564f6da43630c222bd9a8f6816e", + "0x00ac20ed809bd1d79b0743d482c1bd0e6a8bd6d256271a9e9eab3889dec9fc0c", + "0x007dda517b8b56a65e1146cda92594b458a98acd435c9badb48ca4ff3edd8ea7", + "0x002e910b6ac608f55cf0ee37f5247ef7b040ce6a7de71990a8bff26dcb54025e", + "0x007de36c75a5c9ad3159e006cbb7d4c8eef697b80fe30649be3e0960f2381b9e", + "0x004bcece90ef3bfc65fa6c4c91458f2c205f4994044beefabb12a655442d33b1", + "0x00ffda3dbebabb56f4d62b54038e90bc371f48b372a3f7b775903cb790582f95", + "0x00f11065a07a0c28c83237a2045eafa9960226a27c3e945e59a6e3b4f15b16eb", + "0x0046fb4cba845316fdd94592a3a5de90500f79f24f0394f1ad0c4062dd0a6f78", + "0x00cd5674917561029c53fcdc239e4af2f606ad5663698a52db7fa611a3c91c15", + "0x00369fffe79c35644be45b98360b9d54b1e9d31b83a8c523605be6dfc94fd857", + "0x001e95a3450f40152adcc535851a3e6c0fb3df1a3e59583bea7661d84ab3666c", + "0x0026eb28842dfbc1cc996cf3ef83da7ffd8030f11714458232955dc9fe95a8a3", + "0x00d17ac17d942136b4ce271c05933274c42091bcc54ccb12372ef8c0388cf730", + "0x00318749db4de3108d34ca9cf3b21e222cd91a0a9c645fb883eedf8c5205733d", + "0x00315985f352543b45f3fbe7ad94bb4ea24a0473c8f124ddca69e02817f2c12e", + "0x003b5aa530ac24999ca687c7344bb5b90148d0d87c960a4f1b0fb068c45b1d35", + "0x00b9886d0c006ee2736a6a6687de43ec563528134953c9cd39d1dbed199e0c2f", + "0x001d6535187369a6a661e0925e88dc023296fc333aa1a358864bee551eb2bd20", + "0x009899d4b91646ad02cfe0226165a82b6f789bc07558301f7c7a9ee90ec91d10", + "0x00c4c737d5ae82188bf1583bdde5768c1413b682a4a23a5501638cc6dc1ae166", + "0x002398bcd0fa3671190a74240c1891aa6d85abb3b45b7331f6f8c685a917e827", + "0x002d9e5432ec1756b279ce5fdf96eb71d63ca1546cfff7867059e287bc3f0c5e", + "0x00421b3787295eb5fc21207c03af136652676462c9cf8ad4ba5a10586e769ba0", + "0x00350b52802bbfaca002d0e268acef9920c86a4ab21dcd7d6a34a11581c13de7", + "0x008eeb3e6e8e03955fdf2f7e398b340e4e67e768dcfc120fb677f26bc6a45384", + "0x002923b8ea3cfc0c1b9127d0e44d68a19664607e48465d96e69b53662239d087", + "0x00bbe343caab431effafa5b4e8741823808effabda6e2047ddfbf685c1a97186", + "0x001c6a9dd94993da74826229c51ee636df37dbb7390d673c4eef34c7e0d5525b", + "0x0065b2f768d7cfbecb907cc1d98936107fc09982045b991cf16b85ae631778fb", + "0x00a4096fb94055bbf51d21dc5f4b44810b11f358d9d3c6014d821ab6d8e2520b", + "0x00af0b8ff1d6034f2234eae5191d3f57da3abc1519cf571028f9d3dc4d830a3a", + "0x00f6005bd94e3cf79266f4f90b082b7d93c07492b0ba20164f6e48b5215fde02", + "0x0046e3cac093bb3977326ba19ccd1a1f7e770cc8b08dbd38d3dd2144327b1620", + "0x00af0f32a85afdf5206e896943347bc7214da505a36965c4d5be0fb843f24614", + "0x00033abb82b7274dd0ec956df5f33e944db39727481182338f27c8db5f173f53", + "0x002235077c0d53ea3c30bc68dbb161c6e5a472bdcd1c016434fadc9c1ff74a98", + "0x006e2181920546770c6f4efef7d6b3b547096e43dc6fb7e5105f43a7a484da68", + "0x0062607dcf405e3cc5d4b4909ed1f71b4b95e3399289ef233c1381de56b6c904", + "0x0068a498f85336d3e1242e5125c56bc348599139c72a0724cc49a0bf802b321e", + "0x001c7c8d345c4160f9659c1311a82e618f6ddc7a26862580ee7cdd5006c24892", + "0x00a3587c53163dff704789146c796027770ab738c60d275e6f044629cab52ba8", + "0x00da3365ad6f9a2975202353997021f60e71bd37e5b8e9d1988796b8f5357e43", + "0x0029a520be0f4044542b4a906de0af4ec65e232b02f4a17077f1738827c39425", + "0x00410cab2daf88854c72b56f5198ca47750662de198b43654744d70b1a576339", + "0x00c699d2deb82985f62f9def0acd27e44ff848ae1ff7c0ec9c9613b38fd54d1d", + "0x000909f60d1d4f89a2fa9307ba788ac1acd1d7dd0d78f899c9c57a1f468a3357", + "0x00f2687370eed8794b2ecce425d88e33f8242d05dbe571ba34903a14d95e891b", + "0x00198d47e1b4e419601ac167d324ef4554089e6d501b010b84bf264a0e20d79f", + "0x000378b5dcfef287f274aba0d42f4b83c9050efe46209c4924613e5fd3154443", + "0x008727698a90815c2f7cf89b3237df105c591c41d7e201743882e53dd726a021", + "0x004b2c536852b39af3b37f38d86b4cf5344857b405480a2937a302bb42ca8bfe", + "0x006761ebf156b136664f5f92778d9d16d12d6e1f3fd227b2e688e218fb0e9a2e", + "0x00f15fba34a67de48bfea135e8314825094ae6433b8784d644bb65523f8867f8", + "0x006df54cfd22c6994da5a651dfb11b8f7bce4422672d2645120ebf3bdb5f9045", + "0x00b3811b364d4520a134d54673a9c97e04952920d1c360a209c96c2a79eaea4f", + "0x0055206a9ea94de30a58f121c2245ed80c2ad62a6017c926decf285fe110208b", + "0x00da7b679e79e39e158ed71a9b7424ad08b4bba7c2919886f232672158e07233", + "0x0087b0ee4d0458ba866031a5c9a2bbbedf10c2494a5d8665a1bd04e619dd2632", + "0x00700aa238f47feda0cce0c37d43ea675ea7fba392fe58739b4ca00c88b7e60c", + "0x009f945062a9717cb7a330074bd6cdcaa1d7f17b6141794b97b4e6a804ba896f", + "0x00e298bb7cb442dc3aabdec9be6399e9ccb3ef47708c21f6ca1cf7bc3226f89e", + "0x005ef053018084ad3dba81ac3b54839bb1da568824cbfa0a97fdac6620e5408c", + "0x00b08a4c1676b9a5a2e08d912865fb02713ee0ba1c5a84290021ae5cb67ee348", + "0x0049b88b3e5f14917e2750a7176ebc1c0eae9152d23f8d30ac10ccbebf8f1a96", + "0x0022d5ca38dc6d91383d2d3d17239c5867527147ea9bd98d4b501ca56b626839", + "0x00c8edb14209666368adf17b456de719ca620e984ae2d8f2b14e21acfa598ca8", + "0x000bbdadcb7e7b6dd200c4ba8ca6fe14f6c6db720836b9f739ca9b5a8731ab26", + "0x00bceace5630e59c29f7c90c2227067d5a79f16770d98d5832642e17331380e2", + "0x00c17640e8140bacb22bfa851d1d35097f0013b144032342e5dce5186a2c975a", + "0x00627352f3209286700bb745d522fbf8df1b5d1dcc074778039947c1eef5a5c7", + "0x004ae7450d8a695cb21ec142394da3f0f500b07dee7b63bc88f89034a9d9a7be", + "0x00fb4570bb0d3c99302f91009a82a76bfad0ac39ef1c3f77a2a7bb49f60f8e1f", + "0x0016f7772793651ee4692254bcb589a4fe18dc8ff1c32c1a4e23c8888754590e", + "0x008c693a06ca63b8b03e23a190645c6710a894f7e1519ebb9bda88a578eaccae", + "0x00e5fe3b8dc1ed1bf3d1b98ac8f1a54d407c352b0d4867d2411f297f864cebb5", + "0x0018219ea955f9c2b9ffc5a228f43b76d583dd6865de9ff57fe5f6f18e90fa65", + "0x00da8bdd7895e44791d1436d806247d0c7e233e4a3c0d81e4cdfc7d9d7b2d9bf", + "0x002ab236b7b972200d03df41a686da769200f17707fb1fdc46ba036f235fb961", + "0x007a6a56e7d2e50df18ff008694204e1e497877a5b4e8b76c162e7aa6c22e973", + "0x00b184a6426e90274514014c073b9c7712d401bb03f9fb0a125aa867c1f3d3bc", + "0x00c62a088ece9694a537568fe3117652effa695ecdcf0123757a6118c7169add", + "0x001191a12e8fce172f2736c3d60d8a6c28626f09e0593d07b26f16081b32c8ff", + "0x0035a547a9bcddaab6f0dbe5d5f2190b05e3ec4b2094fffab1d5da8e453e62e1", + "0x00ec83c47e1dafb5c8c158ff65d77be051d762cb89c3f6e30fde1427e6f6d46e", + "0x009fa8ff679a2a0a4fcb5b22cc18914176b54dc3c7e666534b4eb10607444cf9", + "0x007c52f5c9a3747936c504b29c1f48dc3ef7eff53af015c47862b589b76ba5f2", + "0x007bad765ebb25e8f5d4e5f37023136681e105bebe287246ca80535dc2126934", + "0x0009c9126d49dd05ac4b972ca4eb38bf561a57f904bf3e1a01621de4ee3cceef", + "0x0027376a5f7c8ae393c37ea9f7ce2d5cf02691e38ab4001dfe4c69b1620b60e8", + "0x00627f421267013f2cf8a6c2b0fea08e60ef42e27b2a1cf4ef9ca851050b07a0", + "0x001cdbd40d871785a241f2059f7226ab7f52adb24de078a72b287f760538e279", + "0x00794e04b2fefbf60cde6bd40706bc4e7bae4c4dd3ec5c9e86f60bf85c8b11e1", + "0x00a0f8bd90448159219570ffe3800c759bf3b95913453e352d1108693ff49af3", + "0x00acdc46d8b6f9714425a08160f18245409830b49f6891a11412ee7f5ab2a49b", + "0x005e9039506c8b15e1200e3a957b0fa78581e412548f12bad62e6db79e1e747d", + "0x00561ec4b59e3fb603d2368905f6990e4063d58fcf32eb6e63f0282fa0974322", + "0x00e57984a179a986ed64a592aa1ea6ab6ae2933176425e1d228f2812ae0d889e", + "0x003500f3d7122b41fe27078513cba1f2ea8a51a5cf5813613b2cff82771ad389", + "0x002c8e78ca4b682ff89e22029f431651e8e15c7d0d0fdd83d44555d0fb0dd25c", + "0x008783e02b3dd9bf4fe65f89f03b58c5a6b3d822cf1655cc241234e9563520dd", + "0x002ca2bb5a795666ba51bb9cb01b2b3ec7a3c7974a5dacef56e993e79f8b1376", + "0x00a38fc87dac35c6dfcada684d2b47f0af175140af9bc906834a622ebcc21f9a", + "0x0066d4b869505855761fd5ec89c9e3a668daaf7eedd4c0f27b6f41bfd156e2bf", + "0x001f3b05d8d1384e0c6dfe592e1675a5579fdb388e319fc2cf53e4b8d3ff000b", + "0x00b371becc28d8c66be7a9d5e053061b709d6a402d41a964c3cac85277477d6f", + "0x001b8a19bf68201d749e94373ab899837eb803de0fc23a539a7d52f909a6c22e", + "0x000bbb66b4247a108e66a4b58d53930b7c77985043c9d81edc85a43d67ffc93f", + "0x00137c6f9b1bfe88fdd7fbf7e00fe16a0d86594f6ab138f5b856b92b9fb57059", + "0x001b97efc361fd8b90f573d5f9fb831cf7792efb59d067938a870773ff002431", + "0x00dc67fa7038294c732ba51ab0ac21506163f3df15075b844e1249a88727e1e7", + "0x00b00ffe5b062ccb77baf0e6b372772e28898a4f9b4ac289d24f4cd38b7e1d1a", + "0x00375c14972f58e3da2249d168bc1fed0ef17644545800ac376da98b6d4c1d2c", + "0x006d6867c499b60773827ce09a5d34d75260c0aaa6356e74cd8614b535c159de", + "0x008775c4ec0a0c51900f2f9483db4cc019dc83b46af48ecdfc8958a6f0b77891", + "0x001ddc732b1cacc736678399eb62723715a3616bb916cf9065caf4fa36034459", + "0x0077f8217269c35dce737eb0b64733c83891dc8484ffb560592bded450eaa7ae", + "0x006ee828f26826b1193678e4b029edf47122399ba13d41b48626242f3f46f727", + "0x006c10c18af4d6e0c2620d30a152b4cbcd1bf1c45f78e620ee0d50af02b24fab", + "0x007f86395552dd090a4daafd4e23804a59a1a030a657b309c2c1f8e838f922d7", + "0x002b008332921c404a616dbb2db663f598be93d4ca857ba3429f7b82a3def34e", + "0x00f489dcb10ba2699a731032160987f9071c1cbe4090e289cddeb51cf2e7f547", + "0x00ba2a046b900cb8354e4dc07c8410c165343e12a4c51bdaf9d0802ac61b0edd", + "0x00396cd3c94c193aed303d1f7a89455ea6a58af473bfdd1f367b9315e6ab2e93", + "0x00a69c15043ba8fd582d1e6950dd24f08ce651eabaa2ca9870abee0576e0d095", + "0x00469a2a6492dec2bff0acc3169da4d244856435c44545f175761985b22614b1", + "0x00ccc7b964c286c5d94a6c4482ce37c2a4a13adf2a8012bac1f6bb305de582c2", + "0x00e0f2f06b219cd3e1db685bdd1229c422570c5cc7bff38114bf5cfe20d9d167", + "0x009f728750639c4f96d5b80f5d2d4524f67ce3f7eff3a9fbd1fe0eba762031f4", + "0x00fe54a5c08c8421cefb33eae5660fa547d4eb9451da923a78f7e5260dac2442", + "0x005ede7dce6b73dfb9bf0b56fe954e171047bd3013c73a50a8fce792cd03dd70", + "0x008ca7663a803b374ad621292ed8a882b99dfa008624356887b118e7409a0bc2", + "0x00eb270c23ad0661d6ff80c5c9d2f16a010fef59a55d5d7409061d2ed2588172", + "0x00602b240652d573ebc080802af8ee36fd57ad2134a6899ed8d1f14d72832071", + "0x00542f16afa1c5f48f80fb2b9613b81d3367ea927581f6e76d1ac7487e665532", + "0x00a9e676b4079a55d38465e38e9f571e765870cd56afd430b449f6ec466d1e53", + "0x0087771d0d2c3213131105e236f4bd977b5caf2f6d8f2a29fa76012cfef2dff8", + "0x0080be21e26da89cd04b89d62fa0377056d5291709f3e48317f43b5da776080a", + "0x000ae081debebcb9b984e7a4bf3ed2df8594e08ccc60cb557a83c4f66010d1d1", + "0x00190c767653e21da5d3c5475312ca1353659f79d7305269c6cb8b657af0fa1f", + "0x001e020a8c15d97e86ae90fd125e595e9a420c49ab020ea98b404c565002908a", + "0x00a1703412b010db0e01cef183ebddc9a398e76f6f0a77301201e79d07001972", + "0x00bc338aee6b23df256bbc354f943435e7588e63c92ba2fcb6f15c9a0036a028", + "0x0040d51bf7980b36b796aa20ed639a6592c97671a0ea4266d484c4a763bd2c8b", + "0x00601dab93b22e03c90b84813419f93b3784b1e9971959aece586896e29817ae", + "0x0037644acd46c1eec8ba09390bb02c839d972c29dd3a2dafcd07cef3f6399c01", + "0x004195f89c9ec29dd2d944fd1a8967a2d5508d7c834742eb08fc051a90b29f16", + "0x00961785f8a7bb2890fa8cfbe0993ee3271500dc6fe9ddacb859b8594a614e79", + "0x00265abf1173c9df95081f9a7c5f3686ca71c11c82515cdf97368f86e4cb2fd8", + "0x00114f29cde13ad52ad1db5ef3da6ef1c8c60d9f270115e7d3e7f2d6cdc0d9be", + "0x00d7b6f71bd4cb2f65ec7781743f042563637d4b3dda268c9c1e59500fcd4a06", + "0x009e9822765f21f911cd63e731ea0c11b0fef736181d2268aef34fb55baafb59", + "0x004a42d830dea62d7116fa0657cdad9e79ac7eb307c099263289464c463287be", + "0x005b75874a0fde8e1c8ab5343bbbd9aedc80b5b215c0576c929d157619217b68", + "0x00a7b362ececab2d2c8c13ae6d129448bae0667aca2fa1296b8ccff05fd312ef", + "0x003f37a490aa4f43103af3e3073d7826af6236e6d6bfed5465f24491da1c1e6c", + "0x00a90a141e6d06e4e29e79efeacec91edfae7612581d2418f33fb725fa7400e1", + "0x00a8915028e26310943c311734a19ec2dd7d84ef6e98c7d05ee46bb54a7590c7", + "0x00fb76add26d7c5582e1682aeeaffec7956f7df0a7d18c4b0ac8b61d297651c5", + "0x006c66c4d8143ac281edef1f1a594128ab388c7b7fdb85c353999d0fd2b9691f", + "0x009fa9ddf89dfa37ac79c5a18dbd8573c9a0e27c5517f60e82f0e05c8892c712", + "0x007ffe8d5bcadc45dae7c30a97a64b4ad5f1ee3743a9a6229a29bca313ec7d8e", + "0x0009c3fc85f8fec72e33b82b5daaafa5dcf31ad7e1afe37bad9e679f4610a27e", + "0x00d5d9ae6f08db53f4399aa5fc7dec997e48f66b5e2ce1ab0ec61c0750127b6f", + "0x005c77ea569fdf4c5d020b8875299a71cd98631f24977db2f67d179a4412535a", + "0x00174e8a6d94e8aee09c5e0ae9d2d5533ff365ff2fedccb5e02b82e208b8d49b", + "0x0000c9cad232e6395616f02a132c6625e6a3403500f2399a4bf4953140ebdc95", + "0x0090881285e2caf2b7da98985e5bbabc33e0113cb613bac64c64679f6b3f989f", + "0x00dfc2f8d3e135b8a2b0006801f33a90c5a7a0df0484bb3947256d9e8c100abc", + "0x0003847ddc6ed5730319591e735581da65e5967810514351df9e3417466fd75d", + "0x00a310e501668c264d6365be857abe7b7e66892724f2d4339cc29fe6bfd73b94", + "0x0034212e00a5fa1112158519473df23875fd5cc969a85fc90ddc51d5eefd61c9", + "0x00680f5b49de8277f4155b7cf07ce9abaa1fdfa3bc26694805c679687c0b8ccc", + "0x00cf9a9e212b2d7a572e13456410374d8a6a2ab9f0f24544e9c38e926772c31a", + "0x00f323ec242436f7d8d44020cfd0e635b0f150becfdead01eec6b433c5d11daa", + "0x0018c5e0afce29966a2d929ec82f62b9123cc1115f7a76ac7f95a9d7ba69ae85", + "0x008e7567b24b43a5692336bdb34a808575c18a272e73c71b4949dff4cbb1ea18", + "0x00865118e58dbd42fb4fd4dd96fa0b4fdaa057b5e66c3602205aa3a9b8d12ea2", + "0x0018a10da461c08dc97aa2a9e6a60e65e5edfac04551dd3338f91f0981bbecc2", + "0x00e5d899d5b7e55960904e6091e2d1382d507ae7a9018cdac090c9b71d8f8a12", + "0x00a35468f8d216ac07ba8b38ea5c93d6a6f52f071c5fca296d5d036cd60c46d1", + "0x00eef3139238f601cd2d2173f5e441af295ec6cd0c0efea17b2e3a83135471f6", + "0x002769405cefd3db62ee6fc9f65807254af58eead753ce39c6c64a3afaf58333", + "0x00e89ce79fc77e8e2362b659491063ba0ea946189cb39b4df1c422ca334e3022", + "0x005e9dbaf57c48cbcaa54c193bd9121df987f0c1a0e6073ca2690142b9f22f09", + "0x00088468267eaa52dbd642d0520deb794bcf4d20517d94c6ecd2e0b28afeb894", + "0x003927bb8eb9bcd25e758ee2cc5a3e89c23fa4b4f824dfc316b5130e1354679a", + "0x00a661e8dacf1ca804efec24a59bc6d75ab44d7f8ef5b31c0be2f1518b2b6ff3", + "0x008125cec080f4130f2ce97a1237dcf1e154fa4832b3f19f6a37b241bfd9d2a4", + "0x0091b492f6dfa733701ba602a98349e55a8b819f87cd6c50ad2f03ae9288aa9c", + "0x00a91141476a76b3411c6996635eacaae56b11dd286d8a8eae672dc2220fbb14", + "0x001b23aed13af21e14d9cf0f5500dbd43b103a637ccbe9e52738cba7b9c70d83", + "0x00fd743113921c6846db1602c95497bf800f4f4cb030ac985763448c460f757e", + "0x0036d2bc4ea27e1d3e5f082cf9da3e98413da55d48bb561f6ae1d96d1600efc9", + "0x00734c01eebdfe281bfc4aa19ed6a48c20a21026f288cbb3be828307167f02dc", + "0x003a57d43ebc83bc118419a301482bd3de97f9bf1b9e7e98725f9e453cd0daae", + "0x003f669de44965410615d4b4a54fa55c924a49685d51ac6ac985d8679b5fb6f4", + "0x002f5fc1061af5d9e4c9259ecaa1dab8ae1dd8e9a60fe4aacf43a22c22714ba1", + "0x002923b9a381b1f51bab4c47e46c88f50ea9b9d857532219c29e4087a1b626f6", + "0x00726ac5c7108337908fd5552c4cba9cc509bd051ec7110186a98b433392f810", + "0x00b68fa15281e7e2c4cf4f77ab0962c51b9ae1843a3bbe105b5c850fb1f0a5de", + "0x00de2a7670253122d05fbeb5e9173f102fea26551e996ee42e3b6856c4e053fe", + "0x00270266c79aaa2d65c8b61a99b48bc32b3341240aa9cde060df922d4215a576", + "0x0058ae10a11bebe52a9ef7c1ce16d063662f8af9dcdd3bfabe3ed564b0be9d14", + "0x00f9159208c8804381ee45529cf830f624f2e4d4c3d01b17b84e4792abe6d0cc", + "0x0000c37840eb4b2ef06a5cd1532614c90a1fc5fda3b3cf9c2609ebece740c7e2", + "0x005267050d2a8312e139b855d6a36393fe3ee52d72498b9562d0669944a1da01", + "0x0095f0efc09b1bb49e91a63e421abc32994863db5666668e39472917c1ef09b6", + "0x001f4d8bfd0cdab2e32d206ac4e98538f5597d23946e8c83c6e496eeb65fc72a", + "0x00fe4ad3ef5a71412d9fba4460eb093d6ec740d38360fc89c17bc7362379f3d4", + "0x00a29bbcf4dbacc031b71ac62ea577634d148eac466f274238b19517a72ecce0", + "0x001385c2bf0d089092e66a5b4468a056de112c88f618ee5443aeb9035b35fa4c", + "0x00abc884167b4974f9988517e674c165a8b24279d2848ffcc12e53f40cdb77eb", + "0x00e077cfa06b593ff001b8bd409438dd31c1283ad8feee022d0d0d54cd562531", + "0x00aecfaed78bb0e27b0b9b5ce9960eee09334d556a34baf7433036190f969b5c", + "0x0052aa6fef5c8da7bd4693a3f494a6dfb3267b708379948efed69e696deddcfa", + "0x006b33874720a9bc9c5b2cfee84c5791d7f883259ec898e72f57ac968f60eb28", + "0x009f09445c70ec4a7f55e0116d6dc33dd93df7a0c6860721b1660a86fcd523a9", + "0x00d174b6420d81bb5a5308eb6aade26923d22dd8d60dd79475b164551c7643de", + "0x0028ec3d1e5ec22fa284d45def8c0d97e7f2f1a1e8057afe7a745e6c7898e355", + "0x0088b74fae1d2485b2393fafa3e2f887a6e916b1ee8fe7a6eead1e9dc74bc673", + "0x0054716297cf24223a89d573a5efcac22b7cdcf8d57ceea84624d2f2771d4b44", + "0x0021352e6d4fe252e8fbf30d723bfb69d3e627f820a21dd6adbb2b83db0b1a89", + "0x00a71c887cd749e80e8e356e40c9b8a5e81d480169e3665e97847a910f000af3", + "0x00ff544bdf4ad0d5fde152142e83aabe239afbe915c26bd71cd7856d9fb606ec", + "0x00605bdd46721f704a6704c62c066e75160bf24f709c0eb5402b4a066e2b3f57", + "0x004c54120a67ef67642c68bba2538e8e5ee395622da93fcd30f5f9a8226c1f5e", + "0x000e61ff22c05bc4d312fa1ffaad9e603de0aa468cae727e0b774c65e4f6c4ad", + "0x009692405e7cc5cc0ed49cf951da4ccd6e3bf78808cb82c7d5bf698f6c901393", + "0x00d25990aa96912e00b17698244476009b6b3091d0a5965dd94a232a5b9af35f", + "0x003bae82d33ed4f77b72ac6d0cc13863cb37222ab9057b5e3320f0a3b2feb60a", + "0x00e379743537cda2d25048b928cfd8913019f20c66f1f7f4337fd9643c91fb00", + "0x0008ff39c95c444dcd451d7c7612a634b93b91063c35e7919a379baaa13591be", + "0x00a509042dee9a82aa55c81f3c40f61f635779928e9ffcfeabd7e2f01996fae9", + "0x00179af0c679a37d7713b8c60e58dc18ac03455f309014e61ea489b51818dddd", + "0x00122924375fd015628b8aec8a3b8123b2c7fa2ecbb9762b0d0322a93e90537c", + "0x001dde22879df890ae4440ed8070b25b4b322ef31a8bb9bd62f946cdfd6fb4b3", + "0x002cd7dbc0aa86897b4be42152a447e99894a51cc904687026815cba7447e7e0", + "0x00d99af4220caa6da793cb4c6c63c58c46dd6a89ffc0981554916666675b8cbb", + "0x00743faccbb1e17982c21e1f00d0e2fcc37f3f75e6dc38a7f2180c093fe3d7d4", + "0x001bac07b686f1de2fc50a3d7d4718e69d522e956364212b150e1e9a06d306f0", + "0x009eb333e68d3426a500fd65caa900bcb724db2130b8c2a4c5fca194191d5e63", + "0x0083050446655c703b91592d65c0984de7deafbd5d53cfe5e762dfc871e2761f", + "0x00123192a4f7502afb1dd12b9631330b2901e2fde01c048718590ff5188ac502", + "0x00399a9e2dc4c0eec24c3f0c0499cb841bb5d3350cd7532596727d8d8b182d27", + "0x007bd7eb4828660b20343e2fecfb4a32847763f45ebbee46a5a9835761a59e88", + "0x003089c5f5425eb54fd2ec28b4d4327f61823a8f2452d9bc021d2f5eb6692016", + "0x008f37b3a53fc4174b4ef0daac0b7a5b0d14fa6997b71436101eb1c9b7bb471e", + "0x001df66c2e7fec0d700bf0ff1fe79f8b97ae6382f74f6f2dbb8719df23018a95", + "0x0092acb80f4ea0d1d9ce07db293af5abb7f2de24c6f4e8a8f5a0ed29891a4988", + "0x000927a1ce3cb35de266f5eeabf50e0bdd27377012b3b56880a089463efa2e5a", + "0x003aab75cb8f4b21c51587fb500e0eaff573c8b42788b29c2276ba2869c7d8bb", + "0x00da850235fdcfaa5d1db2ce751c1870df8ebb5e132cb664007c8b5ebb70a545", + "0x00b9865a688d49a15835afe14d3966aed49f5f0bb840509fdf002fee6bbb6b71", + "0x00df1a98df2df91be201f342c6fc1f6968fa95a70b6b080f9073c5b53d722aaf", + "0x00ea3ebed52d6ed37b068b4584cb152a06a357c6ad99fd04fb6961050172436a", + "0x00b7d0f7aa7bf49eba73e6bfa21e4b1a09dfc3c374ba5559cd49ca29d7021815", + "0x00833edff95ae7031e687f0cc921e64c09ec5fe2567dc42f88f136440788287e", + "0x00845933da913784231f9ce2003d6a68205cf7aed4f00659aadfa345678172ec", + "0x00372731bdff60c01cec3a99c1fc4e4b47de861e08aeed8983480a9de634a5e4", + "0x00bb008c81c1a566572b42ee774c2dc581863b05831bf5e645ec96962501dbd8", + "0x005b491ac79d1355832c45dadc1ca1a944975bacc28b04d00ab57332e68bfe2e", + "0x00a90b236cb48a54ac70cda38f1776fcd7398c477ad3f0cc7fa3d13129ffd5d1", + "0x00167353fc67ba25994d3001473ad7bb4cb4025c79b41913fc0830124601bf30", + "0x00119295154ac30594aadb834b9483ef3af1d3253bb604b6e79a40556bb6f4f0", + "0x00a8898b63b2ab4e22690adc2d523fdef4c8782edb64e075cf05dcdc1b090edc", + "0x00773f28e3879ed3fba1a86ba292448da856eb1a4fb7b038b59a1cdcd51db285", + "0x004294fe9fdd3d0417fe044ddfd360d09833e04cd398dba2fa018f0ecc827fab", + "0x0009f745c4f310e5f6fe9ab6c2b4bc35535cb32ce511c1a72c6bb2cb3d25337b", + "0x00befa487c7a3696a75c4cf36fb1ddf12a1cf03481e7137fab7b28ac55ee1226", + "0x003b2c1fa0a7ef76c2ddd4fa4a79256f69b026bf5db43df841d88614a40cd2c5", + "0x002f4b3c98fddbc449b91cca5675ed8626bafe401519cfe0627da29c82e1376c", + "0x00002159a42ed7b57c4d73da2bd9f420728f8d4eff09b0c2c5e677c33cb2dcef", + "0x00fe4d3f501fefd10ff2657911c7aeca0916f326ff2ba6ae0daa8799c7e98ceb", + "0x008f9da976e8796ad360d9ad2a87cb9567e726c53c118cabaf2790b5c7d098b8", + "0x008751f1135bdea8679f6a49c95381a7ddbe561e5e85c369523dc8e0146ac0d3", + "0x00bbc1a064b5a40349b6824f5692db02c758edee30bb316871d2a5f7967d604a", + "0x004870a015969d28bc2be27b4be442f00bc7eed2b63c9c76143e378b1357a817", + "0x00ebd004e7de1003e6f4beeabaa7f1ca6a3047228d1dbb2790f0764a5c261d35", + "0x00caf36fa36117449fc6b3ff1180c1ef1e6f75cadf5e4044209b0f5c8b607666", + "0x00d3d849e4d7283dded573a18324a66152bcac48f787f9a2d98326c0e105180d", + "0x0009e97d94bdf44683ae6e226c969014445d8f1d80293275e7c65a184f120a12", + "0x00b23c05001402a74284f35cf11790d34660b17d97d5022dc15204a98f0c6554", + "0x003c793fcb3c42d90448a6090738979930d04ceccc82a7aa6c7888372bb6afe5", + "0x00d2d35338ef4ad56627aad5a26843f221e76c930d57ece1a480c94c62c34b30", + "0x0081a87cd1cf66101ae48e39e7a9b447a582e1fe8496b972825b5f824ef5ca3b", + "0x00de5ed613f4c8541993074f95e26e9d9f8a3e3e72d1330c7b4af33ed3485df0", + "0x001fc252845c9cbb3675b8606f1e2b87c4de2639817b55610304ad8c1ad5ccea", + "0x00e0e47b0dddf0f4f19ed5673c3ba1efa383b178f9e63c4e675975ff073bb2b7", + "0x000184dcae551a4f427a0aaf38cdcffd58e1c9b2662f2be8b8b481dbf24a0ee4", + "0x008d54764bd32f85daef0af7b9133c23d7903ef18de33a0d4ff2bb304c69c781", + "0x00e5b9d11718112a1b5335cd29d4de904cbc9669ea81e4007dd97c6ebb645bb3", + "0x00a9161993c43c4d9f87ccaaa72063ec0299994db79302290246e6eec2b5e661", + "0x004b0c40182d466dca8eac07afd94760136abb11cd30d99a9a4b8edcaf74eac4", + "0x001313c4c4801fe3e110280828c3738c0d175b45286d6c1128f795ed245d5693", + "0x0073169a5fc6886992e12a4fa02a78d2e933a9df27881460c2ba4da00c5f5807", + "0x0044cd10759a6ba08f2f5f28573282ea605d2167f52f5d355e8af7756c49140b", + "0x00739fbb3d467ebe3c2f9856f2f0101c76df08859ed8400a4b307a05b4ed9dfc", + "0x00c9d11e0b280ec0ae375052bd26b062eab5b08640ba682d59209b1d7c26f568", + "0x00ffb2a1895f14e065a10fbe44e354fdc65dbb28ce6571ec1627d5eaeef85a12", + "0x002e4b96d57045441972c974706dd6c72660fe7450e82366a51f2577ecf50d59", + "0x00679748188b2cd57d71e356502ae4599ce693360ab0a4fd88d58bcc8b420fe6", + "0x001f8a45821e7d7978e96627faaa44dd1231c163368d4cb2a1d32821ff63729c", + "0x00f0501c92e6f3df5ca617b6f185134c69c310943452200c5fb5fc87df686557", + "0x00da964fd5fce9c631453c572cac86621ebcb9a7726f6eb6f59638901c507df7", + "0x00fce799379d1b1e4dd8a0d8d75b11b710f4e5ffd605fbd5e31c8caa303dfa32", + "0x00cc83df8b0a72aef0da0da7e346f27fa137a34cd7fa50bc3b95993e60f6fc76", + "0x009d093ef2e4de01477049f7d6e52597e2bf5019944b09d4f60c642e3b729fe4", + "0x004c78379ecdee7845eee4a318086a56dae0757749bd007bb86e83e4c581028b", + "0x00567d50f78a3cb1c67847e813ff8ccce9f227226d4cadece824f5876e49d6bf", + "0x0014f098190bb8bd9254291a12cddb970c590a2c15b696c367a4d6c0682cf92a", + "0x0057143d105f0f81de410a6d2ba0194f5ae77c2f39e5cdf155e807497d15d50f", + "0x00f9c6f6e3425e311031461c01e9baf02970213b89c51e2559ff35e2556c71f1", + "0x00fea2c52aa6e2384f7e0be11e09de011a43322e0df7c149cd91cc21449c42ce", + "0x0034675ef6709df12f812b230d910e683fabe35394ca79e16e7c5ce35e6f49d9", + "0x000a8db43236793fa847a181c7cc3826b6d74baa3c6f8da8d66fc2e6a42e4720", + "0x000692bc457e1f3483d88a63695285216ffc3047130c64bda589db6e3df59c6c", + "0x006077bee60f1b2f7ac4b5e65250b32d311e2671955378a86e80cb2a0c4b824a", + "0x009aef501fe0e7f3ae4cbc6709e2b7f3ccfe8796e3282657a3ecaf7a1f31587d", + "0x00d356c23fdf0feedbcf1603322bb5eccb3eb6a7e0c60f7081911dcdcf97e88d", + "0x00cf0d997c4c681b6b2505b28a0b088cc8da1ae86a9f75d1b8ad0a90e5bd9885", + "0x0092f95171bdc8f3a1d704ad330ad822f68576de9b9305ebc7bf35e9a6317cdb", + "0x0038e5b6bbb4ed2527db139a1fafca1e9315661178288580ac7deb1bd8d1e26e", + "0x0067d2f1570a04214472f892b736d8aea37cbe95e349a0d695cd358fa9f5b249", + "0x00472d78a0e58e90a60bf1e6c673702bdd5fa79c7e90630dc707175ec1a02d45", + "0x0071b1bb00287492e8653601a09cfe7203e3e73455243574096f43a98fa8256f", + "0x002863d63b3929ad84e0d0efc8c3df63f8ffa747cc3cedb19175b3e54b20c646", + "0x00a6fef2e3823b8bdb77a6588110a9cd36a7678e37c1a38656c69c6366650777", + "0x00b269d64cfff1a256cb0296eb7c4856c2e90c9d05d1cd110a20165a62dada09", + "0x00f5881da3d667fd0d054105e82d824ea07fc54aa17ff93074c9ff32069451b8", + "0x00db725d03edfd9f31eb8912076abaebeb30ad7127afd868383a40694ed006e3", + "0x004fa386aeb561a392b84fa60ad613ccb84669461bf2b855b7eea7cbad24e057", + "0x0032a5d5c55cee5eb1c50b45d8e671ab35fefb5d9fd94eca33eaa1a7a85ef2b9", + "0x00d3e31bb1405028d7b615d6593e51141598d45af8cba8371000e1b1a09246b1", + "0x00529423074d74612871dd6644eb5fe1dafc427f8bcb1fac7d43f53dc41c6ee3", + "0x00e0c965c0bb8c807a4898901fb30f9bced900e8b16599dcae9074b5dc36a33a", + "0x00edbce0b9ca8c0c8293db8f6f54084987dccfe668115838c05cc867ef044822", + "0x00e8d97347ca53bcde2d01638ce662753dfc3c0c265656d7c37a3c841ba3afd1", + "0x001ac3b9f9aae2d672ed1ff9ba7c283a1ca274d043135650ae0dbc594fbb0ce5", + "0x0058a0ea7c2b3c748072d70c255717034ffe9129cf9cd7c21e4837b47943add4", + "0x00a5fbc0f3807868c89d8f6143ca78aa415302b0b4b392798e7a9341a849377f", + "0x0043f4f91970c2721fe282c2205421536b43aa7ef4cd6fb4c6b527c324643bee", + "0x00a632e7af7251287cdb39e9f49bc44a132f9bfc8f18bf277fc7119bb3d7c210", + "0x001bfe4274ae40da83116e93299149303f6b9ecdd08b98c7510c4912b2639fd4", + "0x004be0ade3771c19ceb861e913ee8b625ca65a030d835f989b3587129fbe49c5", + "0x0056e39bffb5ba939f3d5080683108668cb18f14d95220aed641fcb623f494eb", + "0x00a3eb2a02e417e56d17229383b3c276fe484c229876157ab831fa539d1e29e2", + "0x001c666b4abb783808901ad67c53f9fc5e06a104c134d741d323f14659b02ce3", + "0x00dc9dcff33d403bd77b6f754fd485cf320377dd2ba9e4da0537a68a006d3d00", + "0x00daef04d2de2f2574942a135fb4b1e7524416997f8597e72aaa2ca6ab841a06", + "0x00dd281f15e896e7ce40fcaf9fb8402867ae33f9a992c76e78fcde216092acb4", + "0x006a56e8669cb555268672ded50212ed042bbcaca87209e5dbf30750249129dc", + "0x00b516a84fc8962c0f8369a943253abdfa8f609067f09989967659f8618d0470", + "0x009f202c09bbdaea9db09f49b5e550210ec3b2c4c530e4e86555faec28a442ba", + "0x005d786cc722eb262fddef23c362d96b8a2b3cf659f0fc39f721bf5184170b5e", + "0x002450bfc0e1df9e3f64094be072aa20e769e9f9ce164c2fd8cc303fac8d1f9b", + "0x00db58c3fe0e631c948bd2e5b1fe9134bcdffab8f2ccdc7c066dc78c2abf4bff", + "0x00c037b8d2642ff4eab9b8f1024bf8590635e901f04721cdbbf84667b41f4417", + "0x00dbbdd4a2ed8607327b0bd2755423b1df309e1dd4c8c650fd8f4be3e63b4521", + "0x00931e59d5c328411400af2fa634897bd19c5d7c6ab2cb31503032d0aab2d9d6", + "0x00684078aa752b5ee624fd0b0ca99002bd99571db012eb971398801a1cab9ef5", + "0x00e9910e6c54e8d2f517a6c763bf9b6ee6dba6e8eeecd889752973c3a6b21255", + "0x008df7df42630253f423bc75bf74908fcf32d5613890578c333aba7a45dcd5ca", + "0x009521c259ce8cada2ee081eb502a09c361d9750803792c5c5a9368c814fcc4b", + "0x00b19016fad1a6820aa1b283f74d325f004ef75aacc8ed5b070e801d9ce9b94a", + "0x0009c0f49ed7afb01a510699afa5e4d259139f5822211d5cd83ea5b8d63a12f9", + "0x006c70a70ef906a624bccdd19b28712f9df3be92543d71627dad2e0687efcef6", + "0x00b5312512a7df3fd71c972c4455172320772e4d42a149dd9bef0bc4919c48be", + "0x00e5b2e8617cb3601e8000461f71f01cf797cf732302d0859118c868fbee063e", + "0x0015315714bde8eb1e9e9993a260603a7fdf53d2c4d8deb2964e8a9efe0be6fc", + "0x00cfcb27f28265842a8a09c85758653e8e0d8425f08c47ca84f385400e2fe623", + "0x00ec5f3ff75a42ec99823569f2c3ab7e4bc2dcff824c9cc3eb26ce7ff430449c", + "0x004211f68dc1437664b53729185451169d507d3113118386a9a31970c617ce5d", + "0x003a626153e3014be32609d9df4bf9793647898abc7f9c9617a12b38f68d5681", + "0x0039e65d3cc5d7ccb80f16a160c3c64c92642f2ca47f1d2088c57a9b18e1dbb2", + "0x0082be09431245184e59019901caf8116c981f8fccacc4a44e32f8bfce775d8c", + "0x005c0a9d17df9a96cabafba9ea94bf891b4940a88ebba483bc611cedb3d7c764", + "0x009be41a54367b0e250a4809e2312d1729d67707b5635a5c2697451de52eb83a", + "0x0039319e8bb94c83b9e28d70f9824e27e7e51546d0110e99d3ec3a1de3736eb2", + "0x00538dc21bf9835a47a8f02159fb75ce547af28aac2668db6edbdff9ba4edfdb", + "0x00f91c3b76ce1277bdf344a5b3aacb13e4d64c1a96a8bb6a4be9d18ee700f251", + "0x000baff02bda85c7bf3650f776c760cc4214aeb9e8e8192ff176ae80babc403c", + "0x00196dad97f4bc1f93fcfcff4f754b4c7397049c78fb4a2f407d1503f76abe0e", + "0x002e6f6526fa14540471e57c578510cb628990bba62ef3193f5757e048c933b0", + "0x00697f19eda8b8fe006296c530fc7e35c1df8efe1623ef5a6b049d47c817a523", + "0x00e9cdea2a2e692c6bb7a1e497282495c3d132db44aca5841a99bec09679ef90", + "0x007aebb60041f6ae5d5a01447fb4703c4e866610c37beb8dab75b858e5f88c5e", + "0x0061075df819feeb3c606bd610774fac37db66262ae12eb1fb13459584b70d66", + "0x00d42cab0afc61aaa5f72f99215a6acb518b087215acc228ddb42147a7b7e7c0", + "0x00864c9090d607dd0de6db93e0165a4f83091458e25c9956d5d143f766fe693a", + "0x009d852a9139688ea87e49935a607e7d76948b294d5e63d09f27da2b7f0fee42", + "0x00accb8d13aa6d81885ac785499483923b1e1359a909b89f19ce489cd01b58e8", + "0x00e2a767e1bb7ab59c7b8ee3ddeeed90f7f75bb2e8dc16af79aff476677fbf82", + "0x00684bae9ed5f1763fa0c985d884fc88a8cbe5bd3072b54cffa843c80be4aff3", + "0x00f06d5d5de585203a7d9e2ad6f4317cd0db5637bb72a7606cb91f730efa6be3", + "0x006a02bdb8c551fa65e84714fe65769b76843cad2836b23a08a6b136050be456", + "0x0021f99757db2adf7c3c6d4a3a8d26355eeaa485f30bd8ff395a62c5896af1dc", + "0x004ff31f843561e5a9ebe5ef0f8f6cb1d85b24025b84b25aaebf39ea8761d700", + "0x007aa202b18a873c6fc866a5d1de1d36a9f3fe1155b4203da8cedc981184d343", + "0x006136ad055218ac36659f843b539961e02a668a27c5465e39afcb38fc697336", + "0x007967fd79eb3c580ed5220622e5526d77d764b119bd333603f11763c3efb07b", + "0x00bbc3c7cd5781921224c9c58558cb8cf447b6a450f07299d6d6c61a8eda074b", + "0x00e963afe31b4206435fd393f60bee69846def054be386020b3323c56646a1e5", + "0x00cfd2383f1d277b786ac9a49281e88386ea8429fff5a7b77cae6f707da2dcf3", + "0x000c9bc1eca10119523302a8595ab28d909974b296e742e4e47453de73aa34fc", + "0x00f3d98ab68b177df2e7822b012e56a47f94cce0978516d8b8ceda353b38a7ee", + "0x00bda596281daca5fffe62257c07885425cd0ab868b50c9ecca4dd0c9ca6cc00", + "0x007e79dbdf2a73c764af2ca536c09074f743889c12fbd68e6fe131aa4f92c418", + "0x008e5e18c2d6ce5550882a8ce8289d2f180ed8520d59987913b5a48c8ac24b87", + "0x00e9d1175351a02c0992fe80a23780c22390669cb00dd2bd4429cc086a060819", + "0x0019501180f48011b2953c9c632e727d1a5bd5a6e9eafc3ad6d272056d4ac780", + "0x000a55288c11408a3b36adf1946bc04a83a492a7b2c2a73d453b4fe83673b20f", + "0x00bf9310111257d619b3cdd6369344f43c179082d54c1ca9c379bb053bff9422", + "0x00c11be50442a1ff3d97eb9f063479718811046197c0a75d03929c545f2f30fc", + "0x00ad499c2c077902bb44cb36cba5f9619dcaae391b52075d84f846a463bfe2f9", + "0x00b90be8d5bc7f0b91a86ca0a28b402fd84d38258aa061301daa5982d534f0fd", + "0x00121228edff23042c9873ee4c161b0a106245bbbe02acaf11f4c1e881e21629", + "0x008281ba44e9b4aec225ef730db3b3513725739b002377dde0398a66e90858b0", + "0x003e67e6fed8cb267f61826d10802b76d174015be4da448ef6d289a08bd719d3", + "0x001e47926407e2b02a96ac26662902ac8b2d0cffdc456712ac23e744ba148ac1", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -4413,19 +4413,19 @@ contract_class_log_fields = [ ] [inputs.hiding_kernel_proof_data.public_inputs] - expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff1b30" + expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c70e7" [inputs.hiding_kernel_proof_data.public_inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x2ad6fde853521717c1ca3718c050ed1bba49a6d75f58f6f226df5f9280a79f69" + total_fees = "0x00000000000000000000000000000000000000000000000002449f1e83b9af00" + total_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" + root = "0x2d7278322ae3f2f02196f7b5eb323c037067b5a8bb27bb36e5936e01618b922e" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.state.l1_to_l2_message_tree] @@ -4433,26 +4433,26 @@ root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" +root = "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2d77" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.hiding_kernel_proof_data.public_inputs.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -4463,7 +4463,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hiding_kernel_proof_data.public_inputs.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [inputs.hiding_kernel_proof_data.public_inputs.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -4483,8 +4483,8 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 [inputs.hiding_kernel_proof_data.public_inputs.end] note_hashes = [ - "0x2295fa9f079bf362a4f01c3b07d9f912f9b484e5ee527ad7a528025a165b9352", - "0x27f0738f58cf7f88e6845175913245e6f82475f464578de70619eceaff66402e", + "0x21c7e2027864f293ff502b26ca73419fb7de391a18467849bba3e7debd669312", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -4549,9 +4549,9 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000" ] nullifiers = [ - "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c", - "0x1567c8c1ff81dda9727361df23c92849c46772567aa0bf3723db03c3751e9d2e", - "0x1cb96ed0bfe97ed05e23f013062425e5ce6599fb6430b162e69edfc317d5bf82", + "0x15664292cc693dcb31f3638ce704a65d0776e3d3a3a0138517913a429ea63c4b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -4697,66 +4697,66 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.hiding_kernel_proof_data.public_inputs.end.private_logs]] fields = [ - "0x2c3715409dc4762ec9a9a602d199ea9932d61edd3fd32c9891fe5ea5a722acde", - "0x10433733db106ed8336b9b799ec2debee9fe2da75f114f567eefde5abf9f74d3", - "0x17440c522b009a136c2207db86790b05464774690523c7fbf949ad381664d0ea", - "0x0a5e8928a4d74ad3256e8a697cfdf84b7baae32abad67b2de7c36ffd67acb665", - "0x0b1200621e156c6d79f463e17e81b96f11d18d716ca5222e7276e07d45845a26", - "0x04b2b64d09e487d10d557106046a94a97f2c40f4316e6667a2c2d9a99db05385", - "0x193da3d713c24b85e1c8f22dd8ef575e88d19c6732f8fd17e370cf64e65b3e04", - "0x08569203e8f3d028234ed200df77bca848c9b4b015ad8797c37669a5e5d1ee0c", - "0x13a9b2003409ad3d4f38caba797acc77092ddd431af25a955a83dc6f5b92cc93", - "0x16fece01bc0b0205bcbaca2904d5674d10573bfef038f94d3e5d526596da2ae9", - "0x0a438177a05071eaeb1862f154b187315de4dc804e275b0f2258baf4700c6d64", - "0x0959244a76e5e861ce5b8833101b91e19d758109d68cc174a6f9eec9c7afa008", - "0x03533d18a1c3ebcf22f820a243be161c9798ea59a506572e32e125c53b7aee7e", - "0x1e2b22ea302597bfcbcfdefcda48b60e35fce9c70f46c6cb90fa6db6e8d4dc6d", - "0x28fab93b8cd28d8d2a993badc3d1a080902feecfab019dc7c00af0ea9f6f403d", - "0x104c4c81c135af94af35a1eeb49b1262e5c53e25ee513731ddeb9f6496eea2ab" + "0x2e6635123c11ea371de1f0de5f7297edba9bd1ee4419a2baa9017834545196cf", + "0x22d45c5ecf33caca73655293c9c044de949350fbeb99751edee46bff7266df18", + "0x00aca686dd1494b88f1e99b9e0bf383beca6e79ee2fee64787081f71b3b55667", + "0x1c314fd1d2ed42ff85cc036bea4bd2fb15d110b6faa48ed8b0669dc30c94dbbd", + "0x2df45aed68ae9a8905fbe509e7f8d23f2fb5e9762f55c254e7f88c49b0506ff0", + "0x1195fd070cbaeed0ceb7aa9e8a9e5fee29e5ed025d288c9a56324d21601de372", + "0x001e27b9bc0a61e287574cfaeb9ea8a875daeaa683218bb33d95706d602269ba", + "0x0f4d2a7c2cdd6d3437522a159d3cbdda6402e5a5d7a9a1ac24f82727330bdbdf", + "0x2c2c768c42de26d71a1fa968c89abd1759a227ea1d15c124f45b20debc4320ea", + "0x1310ad0816e6c567cc27b94659907153bf9da9325a909ec25551a80f11b1bcea", + "0x0172c17ffcac570994c8a7f61065d71781221f210cf9931696a8acd553e68995", + "0x23e5bacd81360b2de450b8e39300120dc63d6312a525b0ebf2dea8f312d27fb3", + "0x1fba8519bacf0550c03873c8575c9f820db6d1b877e27f4e1adcaa0471394f95", + "0x03550ee6245d89cb2586fbcccd88e8052c64379c7e19103dff6bc53bb7a72aa5", + "0x2f530df6da91d1a2a47cb71cf6cb966b5253f4b412a454dd87bdd6a141eeca71", + "0x139da0492d7abf2cc4f359067e959399a31cb8b685c447eeb85ebfdb4faaddbf" ] length = "0x0000000000000000000000000000000000000000000000000000000000000010" [[inputs.hiding_kernel_proof_data.public_inputs.end.private_logs]] fields = [ - "0x1b7f52b7a346b47077bab6835a0810e5d75e977fc3f3fbb0436055bcdaa167ee", - "0x2320e89fb76918e7dc48b13861302dbf78af5ba8d5a20da77d19781ac32b9bc2", - "0x2a99619c0d4d380dbc3d53d03ed35011aa9c296a507fabcf712f43a0e5a10850", - "0x02e5d98e7dfbe7653dafb14afddd7e00f403b5a60816d7ab961823bd3cc4b628", - "0x223b37d6caffe87e91cddafdf65c4f641a609ff13350d02654b0fed1443088ab", - "0x2846b9aa4544f8f8851554f5d0c189c188756d734112e1eedd6840c8aeb0e66f", - "0x21cda3f228d55fb1b37f2b7c7a5d42066007143db17645669521ff58956fa7bf", - "0x1d8d79951d7389e5f9dfa963f93e399aebaa346e9ce3b3a5da1b45e4600a1553", - "0x15eabc8ed921f60621fa4fa35214748a7593f1c06a1e66b76092f789b4960bc5", - "0x16babb28d68725cb64d6d7558d49fb921c480359488fcdfb5292019239a50563", - "0x015e561b49da425d081b87bac01336defa1e29ee50d01b7be798ac28e05b24d6", - "0x04bf1a23807cb0711511a6140caf195df55fcf029842652243034ae2ca740648", - "0x2789cc422a86395739004c513cf6a15024e3adf5f2e238b18e1b4f1211a9383a", - "0x00c4e950cfe804e8a3623fe768c82b7340b0216f93c00351c53e2144364cfb51", - "0x2fd9827b4118b7ef401dff1727785e46fdd31947d2e733f4b39076f43652c18a", - "0x158ca7fba6e7fa7b3eb7c062751182d93b4e36b5c77d2e609e246b810650e59e" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.hiding_kernel_proof_data.public_inputs.end.private_logs]] fields = [ - "0x07d20bd951900d3094f2894e3c76c117114e3150dc3197e9e325e42b4487c6e2", - "0x127157561e774918ba656738fb61ad37f92086431bd4f1e4842ab11928b0f8d2", - "0x2e5cf59c8f2eee7a06d14cdedb8fe58945357cb16f4c792094325909a12924b2", - "0x0e29376c31f2aa7a156c6ce6d1fc9529998251d8500604658f173ff86adffa98", - "0x20761b8be9a186cf6a1730b8a1e99049a07e45c005e66d27b6e0ef15a2833e2f", - "0x1adf679b2441cf3535241924a35164cf8309256721e3f9fcb860bc2acc462b46", - "0x06a613741497b7b7ee978a495bfed7d19bbf76c462d268cee17a3920b1b1abe0", - "0x10ade06e253c1cfd65f24246211fb703c157fd9b563ffaf6ab01b6fba4635155", - "0x2311c6b104555d4d9afc7d66be6b47a41f8aa96eb77f613a75fc952da5975ccf", - "0x08431c3838d7ad6198c1d33ff138953ace3520551bd95b69692609ee11ded216", - "0x1822c33cf8097138c896bb9f7aad7def909a6859d5e640919fd16ebcf153a0db", - "0x11203b31ef49d39fb85a5ea474116c334c156091ab468493a480f13ad1ec1849", - "0x207a4712bacadd2f631fe253cb62932a7acb586dd6dd1b10e0fbe733f61a8f11", - "0x2c862b0eb14b1325a0ca63dda4570f718541d998fb4aba96339b7913b80757c9", - "0x1bf17ee7d3cf2487dcf1eb7a3647b0920c9e68aacc0a33c9a424d4ee6601ded3", - "0x2c70c9b7da7d7df78fcae182d124d7041209070f76d920e5d5c2d7590c385ea1" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - length = "0x0000000000000000000000000000000000000000000000000000000000000010" + length = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.hiding_kernel_proof_data.public_inputs.end.private_logs]] fields = [ @@ -6048,22 +6048,22 @@ length = "0x0000000000000000000000000000000000000000000000000000000000000000" inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hiding_kernel_proof_data.public_inputs.gas_used] - da_gas = "0x0000000000000000000000000000000000000000000000000000000000000760" - l2_gas = "0x000000000000000000000000000000000000000000000000000000000007d76c" + da_gas = "0x00000000000000000000000000000000000000000000000000000000000002c0" + l2_gas = "0x00000000000000000000000000000000000000000000000000000000000722f4" [inputs.hiding_kernel_proof_data.public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.hiding_kernel_proof_data.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" sibling_path = [ "0x242211eb4067563a1667c912cfa2492c7b8bcf5e2b97fde4d26fd9bef12ee5f8", - "0x0e20194c2fc70cf5d2006345608c9f5abc7cdaf2cebe11870301359962bf326e", - "0x08c3364c5142d8fe956b12902940b54a7be36a42ce00cfc5831385a9d55cbe99", - "0x166399703d23a5c22febc6185f8eb93c72b65906eefef226e643c35fa0022adb", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x0bd0a68a914cc9453fa207323a819e6b1f4f432a1ea1e3185a55ef85fd1d4e68", + "0x1c3b50ab3c647b6d36f1830308d4542ce50afddf32694ad04eb0cd74c3745ac8", + "0x09ef85eaa102507d30f8dd98ca7ac4118e672d857aa409ddcbfcd5ead95566f9", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.hiding_kernel_proof_data.vk_data.vk] @@ -6215,16 +6215,16 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" hash = "0x0adf07f9ae6efe161812ba23ef36c864880bc3b0a8461ffaf756f4400c7e9f80" [inputs.start_tree_snapshots.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" +root = "0x1ebd1f6284edfa586309202f29d58f8211b22ad55f0913e7a61e37e8f558c52b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" [inputs.start_tree_snapshots.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" +root = "0x1e42767e9c9083af802ea9f53b7957180260f8a4cd73a99b61551c292f090fbe" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" [inputs.start_tree_snapshots.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x24d209b2c68b99743e478e8ff0ffe01bf8b627abb2c72b2d74253277ffbe26a0" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6249,7 +6249,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", - "0x1b250005eb96ff625256d16bb83fedca81f8952f06c2d3031636c0e1d8c9fecd", + "0x096edd31a317c6cc09d90028076aa45ef130565dd27e9d6bb76ede7390bb505c", "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", @@ -6284,9 +6284,9 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x08c286d5f8584ac20b64b63f763d4ec37d3fa13244234a3280f34bbc70a32d53" ] sorted_nullifiers = [ - "0x282b555a2f009837bd02f744ae119250934c991464481b5613f7f2112a615f7c", - "0x1cb96ed0bfe97ed05e23f013062425e5ce6599fb6430b162e69edfc317d5bf82", - "0x1567c8c1ff81dda9727361df23c92849c46772567aa0bf3723db03c3751e9d2e", + "0x15664292cc693dcb31f3638ce704a65d0776e3d3a3a0138517913a429ea63c4b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -6351,8 +6351,8 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] sorted_nullifier_indexes = [ "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", @@ -6417,9 +6417,9 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] nullifier_subtree_root_sibling_path = [ "0x09166b559c0f096e897bb202971954b6c576adc978e55de25b96e97269f0e461", - "0x0362ef192033d8dd7561fb3d5599ffef50988df3dfb2d2a62db522b4dd468396", + "0x0e60bad1964713fbdd46c647c5eac792cc80a557602143931b895d1cd0367840", "0x2e5d15ff444e6868f293419113070aae8ce133e2ab4d2705a6a696caf2a17e21", - "0x11b6672806903af07ce5206700433633952804bd3668e15fac8868f0695bed72", + "0x2e7e6d33d178e492419788f2c1939a32602095f55adab3b2c2a8862f6d5a2981", "0x2842a7e5a723d69a6f6c088fcc7b2e289173ca583987359c712c15ee44806960", "0x2bc8d89815dcd02215ab5a89956f9743a205a7fd71e002096d7c250ffc3544bf", "0x01d2012039a4d9492bb83367eead0282083ff9011b9c3884c96022f90dcf7432", @@ -6455,19 +6455,19 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_preimages]] - nullifier = "0x20847724d5be09ca0af6e9b36ec5ce1147d557c6a4a2c61bb2aa4d62bdc08e66" - next_nullifier = "0x2bd24d9521cfcd8b14bb5f749a761545f4fe94dcc56618d57bcfea385a5db168" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000145" + nullifier = "0x14a78fd09108f21352c459933d7249a29259439d15d464562ffdd3e76d9c8a60" + next_nullifier = "0x190fcbb9384f74f5537b08d81102312ba13fea5a3bbfa55589497863ca3c05d4" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_preimages]] - nullifier = "0x1b292354acb3ba526050467dbc93d2d505c80e73a41b7d2fb0c09cd32d03875f" - next_nullifier = "0x1ceec3511b2489568c8344be81e970a769044dd97be95562536c6867e09b8677" - next_index = "0x00000000000000000000000000000000000000000000000000000000000000c1" + nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_preimages]] - nullifier = "0x1546bc72fd1c9f595cc29ec322397f0c1306a17f5de02a12ae937e48b30f316d" - next_nullifier = "0x16c07a80d3d164d5d8082a5dda9fb5d5f0de35fc2bc4ac2fa36182ed91ce381f" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000146" + nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_preimages]] nullifier = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -6775,18 +6775,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 next_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_membership_witnesses]] - leaf_index = "449" + leaf_index = "327" sibling_path = [ - "0x2941a7272bf49125b7e5c8f9c8a06939064d366f933f8ebfcbe4257716243dad", - "0x19b8970c3845d2244da0851d0f9b631fae6156a9846a5598a0216fb537fb37d9", - "0x1fca8e5d48b8e1a70cb333a4f5ca28a3355ec77b582acf926a4a17d42c31f776", + "0x11e4524abf621361d914b2e2a9c620e31e8c611d5c9e2dae20810eb13fcb4d3f", + "0x0ab52f1e5cd20bd58359a914345e5aa1c07f92b3ff66c9549637a8029eb7c875", + "0x0b1235834e142a7ca83f6c68a977e24e5101e53b2288fc95dd63456f0d3c3724", "0x218d6b91b3a210e878d135aab2560fb2801db442dbd439ff2efd1fdfdfeeaad0", "0x0b926aa38fc854f094d02c0b719a75e50a7d4a0ef11685217c6568095b41fccc", "0x09c18d449a07bd072b1eb2b042e466fde1f82f740d57ab0ecb3ff368b3868abd", - "0x0df0ef1adc3691e5553b5304a971c203841eabef3423142e2e3c0bb4cfb01a82", - "0x233e166aa2a44dc5f9bcfbba514493bab8b8a00e3dd56e0d813888f5d06203f8", - "0x24bd80edafc13493c1edb17a018f34698eca5bed3b768dee95961dc577560e4e", - "0x29dbd0f2b5aec42761b1d801d1f899352dbb3b8c358abbf17c97069b6827de9e", + "0x130e440f3661265e95d02c65c164bca11f068700d185c854e8d8d249c88ff343", + "0x23777262752a110196cfb8aea4336fcf72709e5aa223ecdd70026cdced152de2", + "0x022583491e3efb346bd1c50a927a25b3cbcd82418dda6780c05be0e5654cdca5", + "0x2d8d44b58b661a6bf00468c07860bc5742006d7e6b1749d9a049a18376e80500", "0x2842a7e5a723d69a6f6c088fcc7b2e289173ca583987359c712c15ee44806960", "0x2bc8d89815dcd02215ab5a89956f9743a205a7fd71e002096d7c250ffc3544bf", "0x01d2012039a4d9492bb83367eead0282083ff9011b9c3884c96022f90dcf7432", @@ -6822,97 +6822,97 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_membership_witnesses]] - leaf_index = "327" + leaf_index = "0" sibling_path = [ - "0x10ef06a0c859785e8d7fcbbf7d1a624f045c1544816d195838405eaacd740010", - "0x2573a0e9cf295372545c619b8c9329e46b01b7ab974cec3bd12def9098d16620", - "0x08db730f7a5e1eed62556f1a919321b5e4f5ab9cf68cd8982fd80e1cadc6369f", - "0x218d6b91b3a210e878d135aab2560fb2801db442dbd439ff2efd1fdfdfeeaad0", - "0x0b926aa38fc854f094d02c0b719a75e50a7d4a0ef11685217c6568095b41fccc", - "0x09c18d449a07bd072b1eb2b042e466fde1f82f740d57ab0ecb3ff368b3868abd", - "0x259490a13493a82580afd12e91ff42f23d398b46827e29d819e2a64dfa907c47", - "0x20b151f51c25e2fbf0e6eb3c22eddd39b87ca1836592ed50d5d8fd3b489ee69d", - "0x24bd80edafc13493c1edb17a018f34698eca5bed3b768dee95961dc577560e4e", - "0x29dbd0f2b5aec42761b1d801d1f899352dbb3b8c358abbf17c97069b6827de9e", - "0x2842a7e5a723d69a6f6c088fcc7b2e289173ca583987359c712c15ee44806960", - "0x2bc8d89815dcd02215ab5a89956f9743a205a7fd71e002096d7c250ffc3544bf", - "0x01d2012039a4d9492bb83367eead0282083ff9011b9c3884c96022f90dcf7432", - "0x1778f17c8e296c4932de3439ce9789f59b83d5d3b856937f72a288ae1bc374af", - "0x095c78afebf8964a4900d8fd66177a0984fb2edc4f356630aa51f907c85e84a7", - "0x046adaf8a40ea8887051610d6ab46dd6b048b5d9c53059df80986b5bef657f6d", - "0x1e11d1859ad659a0335c8fd61dc426014864e5a55bcaeb257f9d227feae35f6c", - "0x0d5672a31f96065cfd886a178fb8a68f39359e072cc46059f829646a54bd5fea", - "0x002d4f87866c996c7cf08f9f2586b9352c6cb232f63f1f409442e79544ed1fea", - "0x1ae0d30f052aa078af8db1a19c5b29221eede6254d8456d4cfee32c7a1b65478", - "0x1081707dd8a7f5c1a530083104d13fea9af029da4d2e61245362c1f3ecf48196", - "0x15e1c98c82aa0a3259bb22b05652d09fd002a68bf0e1d7653bf43e362fd9ba1f", - "0x27f95c7a4ac6c88c7de9875b118e512b5e2d37a2831fc024f8a19b8bdc93fdf7", - "0x2554df241c43f2f76d7a85046a677f6d9427a26ac0cd46ac0b50c4ed838a674b", - "0x2f195708750d44098049e52b6adfde393658f69efea5a667ffee73f6cc80aa50", - "0x0b7a6d34dcaea7f093ac0b9772051418f48daae9bf84cf17f70a296aef62ecdc", - "0x1b653bd3cc2dfcf3f3b3afb2d217a9b88780027696d7768efd448c49a19f8224", - "0x2df1dcfeb9b7af5dcb96a8b534dd71ef3d552a4137be5614178cc1495f7f75f5", - "0x0f0331f8536e68b278f5de7801c132c4147fdfaf87315d527d151ae390381ece", - "0x2f2d601c41f429882eba885efe4ce645282a3637cbd0ee792e1ac739039330b6", - "0x0d516d0b39971ef19fe22dd4ec75c46671f4565bfb058d2680822b9553744dee", - "0x2f2b3594d5c121e620d1c673958d592972294602c0f3e4fe3492b49fc8ee9b0b", - "0x16d9a5f4522dfbf3ffd8faa23855178b54891fa521cf64dc8b2ce9870443cb08", - "0x248a6f54e4dc5bd76713782a6b65b972110f1892ef8c95cbf20105b6f12f207e", - "0x08b23d0504724cba951bcc67ba6181d9a4fd3a8b214095edaffb0d7c8db16dd9", - "0x12660ba2b4cee62a89cbf769915ebdeded1f9b6e6ebb843944ec836659c9528b", - "0x0eb5f9c7ca6420724b0fc9b01a3662e3fe6f51c54d3978a61171326bf3ee92e3", - "0x0fbea79b7a5d8b5e9d1177db2431cb7882995d5ef59bbf97e0e20b5ae3288c40", - "0x05b719cf2bc233946ac8066663c68c9fe008f7fe6c22711946861ddbd61ab5ac", - "0x05fe8d565aede597081b80f58cac87763f6c9ee43a7ab0a5f2b6baa3a97802d2", - "0x2fca418f250f4226d90e9c46b86a7fde2b88532fd817811a5de8b9c5bcac7298", - "0x06c52a2b4d052ab23fd5106d1e8b198fb13c934bd5a27f7e06bce496e1c6c205" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_membership_witnesses]] - leaf_index = "448" + leaf_index = "0" sibling_path = [ - "0x09828dd1f15420f5ae235412b7e16ecbce1b932812b73b7564e762bfd566f9a5", - "0x19b8970c3845d2244da0851d0f9b631fae6156a9846a5598a0216fb537fb37d9", - "0x1fca8e5d48b8e1a70cb333a4f5ca28a3355ec77b582acf926a4a17d42c31f776", - "0x218d6b91b3a210e878d135aab2560fb2801db442dbd439ff2efd1fdfdfeeaad0", - "0x0b926aa38fc854f094d02c0b719a75e50a7d4a0ef11685217c6568095b41fccc", - "0x09c18d449a07bd072b1eb2b042e466fde1f82f740d57ab0ecb3ff368b3868abd", - "0x0df0ef1adc3691e5553b5304a971c203841eabef3423142e2e3c0bb4cfb01a82", - "0x1cf8e3ee3a38d1b5aa62577b1820cc6a13b2bd9af440383c958fb833e05e831a", - "0x24bd80edafc13493c1edb17a018f34698eca5bed3b768dee95961dc577560e4e", - "0x29dbd0f2b5aec42761b1d801d1f899352dbb3b8c358abbf17c97069b6827de9e", - "0x2842a7e5a723d69a6f6c088fcc7b2e289173ca583987359c712c15ee44806960", - "0x2bc8d89815dcd02215ab5a89956f9743a205a7fd71e002096d7c250ffc3544bf", - "0x01d2012039a4d9492bb83367eead0282083ff9011b9c3884c96022f90dcf7432", - "0x1778f17c8e296c4932de3439ce9789f59b83d5d3b856937f72a288ae1bc374af", - "0x095c78afebf8964a4900d8fd66177a0984fb2edc4f356630aa51f907c85e84a7", - "0x046adaf8a40ea8887051610d6ab46dd6b048b5d9c53059df80986b5bef657f6d", - "0x1e11d1859ad659a0335c8fd61dc426014864e5a55bcaeb257f9d227feae35f6c", - "0x0d5672a31f96065cfd886a178fb8a68f39359e072cc46059f829646a54bd5fea", - "0x002d4f87866c996c7cf08f9f2586b9352c6cb232f63f1f409442e79544ed1fea", - "0x1ae0d30f052aa078af8db1a19c5b29221eede6254d8456d4cfee32c7a1b65478", - "0x1081707dd8a7f5c1a530083104d13fea9af029da4d2e61245362c1f3ecf48196", - "0x15e1c98c82aa0a3259bb22b05652d09fd002a68bf0e1d7653bf43e362fd9ba1f", - "0x27f95c7a4ac6c88c7de9875b118e512b5e2d37a2831fc024f8a19b8bdc93fdf7", - "0x2554df241c43f2f76d7a85046a677f6d9427a26ac0cd46ac0b50c4ed838a674b", - "0x2f195708750d44098049e52b6adfde393658f69efea5a667ffee73f6cc80aa50", - "0x0b7a6d34dcaea7f093ac0b9772051418f48daae9bf84cf17f70a296aef62ecdc", - "0x1b653bd3cc2dfcf3f3b3afb2d217a9b88780027696d7768efd448c49a19f8224", - "0x2df1dcfeb9b7af5dcb96a8b534dd71ef3d552a4137be5614178cc1495f7f75f5", - "0x0f0331f8536e68b278f5de7801c132c4147fdfaf87315d527d151ae390381ece", - "0x2f2d601c41f429882eba885efe4ce645282a3637cbd0ee792e1ac739039330b6", - "0x0d516d0b39971ef19fe22dd4ec75c46671f4565bfb058d2680822b9553744dee", - "0x2f2b3594d5c121e620d1c673958d592972294602c0f3e4fe3492b49fc8ee9b0b", - "0x16d9a5f4522dfbf3ffd8faa23855178b54891fa521cf64dc8b2ce9870443cb08", - "0x248a6f54e4dc5bd76713782a6b65b972110f1892ef8c95cbf20105b6f12f207e", - "0x08b23d0504724cba951bcc67ba6181d9a4fd3a8b214095edaffb0d7c8db16dd9", - "0x12660ba2b4cee62a89cbf769915ebdeded1f9b6e6ebb843944ec836659c9528b", - "0x0eb5f9c7ca6420724b0fc9b01a3662e3fe6f51c54d3978a61171326bf3ee92e3", - "0x0fbea79b7a5d8b5e9d1177db2431cb7882995d5ef59bbf97e0e20b5ae3288c40", - "0x05b719cf2bc233946ac8066663c68c9fe008f7fe6c22711946861ddbd61ab5ac", - "0x05fe8d565aede597081b80f58cac87763f6c9ee43a7ab0a5f2b6baa3a97802d2", - "0x2fca418f250f4226d90e9c46b86a7fde2b88532fd817811a5de8b9c5bcac7298", - "0x06c52a2b4d052ab23fd5106d1e8b198fb13c934bd5a27f7e06bce496e1c6c205" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] [[inputs.tree_snapshot_diff_hints.nullifier_predecessor_membership_witnesses]] @@ -9783,16 +9783,16 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [inputs.tree_snapshot_diff_hints.fee_payer_balance_membership_witness] - leaf_index = "120" + leaf_index = "118" sibling_path = [ - "0x13d5c2f78d433c774b2f9be7bb5d666fb8fd80452d0896af987365d04f9f681b", - "0x25f3536c3eb76fd96d5ccdde3cbbe50f5548e23683bf9f2cbad67f53d10537bc", - "0x2835a744c1a26d89fca8be670b7b8d7a2473a3eb7fd72bf533a007d6cc443772", - "0x2d0726c97dd7add62ef5c3e71e02ff90e76079e2650f2217ec0fe5e678b0bb8c", + "0x013c095d61087adcef13cfdeb887287dba3806baf73093ee460023cfb7730f22", + "0x060b5c8a3d6c10c09c2c4ef7897592f838ac2433c4ca664adc73ae6bf507aff4", + "0x2523970382de270c1acd87f98b4ed454353257f9c689dc608f7dc1b6ca23741a", + "0x12bef12e0e192e65178ebf9707e29797e5afdace0a42a17d796d1c40e5b7501c", "0x2edd4e68944dac758244213037fbe9d622c7c28d6070f16862b3e8986090bee4", "0x1d5ea1a288ff1ff4cabceaaa2f93eda378a5fb0a2a55423f4d4d205969181931", "0x23b80d0ef13d744a52faabf5651164d28f7faf902653e41a35472eea87936e6e", - "0x27c696ad87d2ae17e4005225c67d015eaca8a9c6e97dec181f97f15e2c1ff894", + "0x1ff2ba9f5f44162476e89f994a79debf4b9af550a887b5b484d18f5997553566", "0x16c8aff52f0422f4bfc502620fe15dd6a4de67637563b7a8175f2d5727d268a4", "0x1c76b6744bc3d6b1cd4b53459a08b4959643c0768fde657299fcc82e2732f744", "0x12a6fac0fdfbd7897d8fe955f454cdb309ce8597d647ebfd0ba614c4eb215581", @@ -9828,18 +9828,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [inputs.fee_payer_balance_leaf_preimage] - slot = "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3" - value = "0x00000000000000000000000000000000000000000000021e01deb310ea6e1140" - next_slot = "0x133d35b9030a815b221f9205ef080f220fd8ba968e9bd88b60033b4854e100ad" - next_index = "0x0000000000000000000000000000000000000000000000000000000000000085" + slot = "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969" + value = "0x00000000000000000000000000000000000000000000021e0219674fdaa32380" + next_slot = "0x07e3196f3e5be886c078da1e359a784f0451f3b454344a3c6482a090708f2547" + next_index = "0x0000000000000000000000000000000000000000000000000000000000000087" [inputs.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.constants.last_archive] - root = "0x00f30d99838de8d9e0b40bb5f19c53ebd2cea2e4e324a6b48a4db2655906ad63" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [inputs.constants.l1_to_l2_tree_snapshot] @@ -9848,13 +9848,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000041" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde078" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [inputs.constants.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-public/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-public/Prover.toml index d2414328ae1d..41eca05ca9e8 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-public/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-tx-base-public/Prover.toml @@ -1,9 +1,9 @@ [inputs] anchor_block_archive_sibling_path = [ - "0x1444237c68ff756b5bcab6ef4b010657fbc4911b8a806638579f1df27f6e43f0", - "0x048c76bde3b9047f9f34f7fe8811109eafa422f663c1825d2399df06f4f11689", + "0x09ae38c4bdd7cdbfee06b35cc61272ed229c502820948e040a4acf7081f149e0", + "0x162a8906e43df2f5e1ea3d0d32a2ccdcd0d4581e5307025f0796d0b64f937d13", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x2b3b2f80ea4227dfe7ab4edec33942ff08b95b023d6d15efb0abde90594c993b", + "0x08ead7d93a6e0ab74b47c029605a16640557a4c3e830a2f6294aea4559e5325d", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -3547,57 +3547,57 @@ contract_class_log_fields = [ prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail] - expiration_timestamp = "0x0000000000000000000000000000000000000000000000000000000069ff1b30" + expiration_timestamp = "0x000000000000000000000000000000000000000000000000000000006a0c712f" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants] - vk_tree_root = "0x0c16448b65c4b3f83f9db3bebf635bd38957c74c9c1ea36036cbda16432cf558" - protocol_contracts_hash = "0x0333160f082dfc02e255c756febac14dc42c4c88b882e0403d44710c1f0bb80f" + vk_tree_root = "0x17276f417e92c8fbe3f6b33784b982b5f9616034e7b092140f1d53bf11e7b27f" + protocol_contracts_hash = "0x2947d6ab285fab4b2cde4c027aa22c2146ab8470fe246c99c958116105ad615e" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header] - sponge_blob_hash = "0x13a1bf44c19e7c2eb7fc1a96527d072cf424bc99c760e392f4abcecc1fc597f8" - total_fees = "0x00000000000000000000000000000000000000000000000002b26ec5db7a7140" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3979" + sponge_blob_hash = "0x07b265010fd2cc21c16b1d2594ca99672e2cfff5ca81945b3a0831755b42379f" + total_fees = "0x0000000000000000000000000000000000000000000000000035dd7429a09780" + total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000722f4" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.last_archive] - root = "0x0d18996e508e8c1e51f6a56652cc5d71169450ff16c25de9af7f79af5385e334" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x24b436e53660fa0ce7ece2c6a741d91157cbb61a10885ac29d14d58cd3180af8" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002000" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002400" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.state.partial.note_hash_tree] -root = "0x1c223e428d6faa36822890e3b99417ddf73ffb069bf4c44b6ae9d7fc741733f6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2ec6c12dea917fa19ec74a89fa547c25e2894a67f1d0f6b816fb105662287c8d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.state.partial.nullifier_tree] -root = "0x01c778a6b3dcb1245bb0aee174252dd95256e67309f952e5d2f8cbafffe20d0f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000280" +root = "0x144143122fcbe95a5aab0c5c25ba91279b425eb8f5dff6ff7fcc2fd9eb65aa64" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.state.partial.public_data_tree] -root = "0x134e44df49ddb89525046d19bcfc2734c78e419994de9d6f7467eb84d02d1060" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x19208383914fedc1cee3bbbda84965791ab30ab104aca7d2f9131dd853eba7db" +next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008a" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000022" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fdd7c0" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000023" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2dbf" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.anchor_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000004386faeb40" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.tx_context] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.constants.tx_context.gas_settings.gas_limits] da_gas = "0x0000000000000000000000000000000000000000000000000000000000030000" @@ -3683,7 +3683,7 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000" ] nullifiers = [ - "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef", + "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -7069,13 +7069,13 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.revertible_accumulated_data.public_call_requests]] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x00a5e40cab902df3efe088094577e83eb92103581c990f351edf1dfba3778905" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.revertible_accumulated_data.public_call_requests.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.revertible_accumulated_data.public_call_requests.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x1be490a4b344f41827e94113f628fb311efc1abac19bc1e84b08fd578708964a" [[inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.revertible_accumulated_data.public_call_requests]] is_static_call = false @@ -7402,18 +7402,18 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" l2_gas = "0x00000000000000000000000000000000000000000000000000000000000903d0" [inputs.public_chonk_verifier_proof_data.public_inputs.private_tail.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.public_chonk_verifier_proof_data.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" sibling_path = [ - "0x1b3bb563a5febae9302424bc9b80841523b8773b3e521fb20de577a64e78bc9e", + "0x0a7fb889325f39bec13ee8f853c529ad8458c39c703cf4277c5b066d8d2eee15", "0x0a2d5d1c88992fa153310bc96af4c750c81353526f8c7dfe2b069ed57136e696", - "0x08c3364c5142d8fe956b12902940b54a7be36a42ce00cfc5831385a9d55cbe99", - "0x166399703d23a5c22febc6185f8eb93c72b65906eefef226e643c35fa0022adb", - "0x25f6f5fc25ee815cef59a1889f1e39db3d431d01b01ee1554f9492afec9d41d6", - "0x28650667b92be48b116289119fa4794a5fe8fe5792a49d89b9977feae7f685a6", - "0x2aa74c20807e8cbb3e32a86ad29472c42a3fb7021dcfaad112a6b68eb0eca98e" + "0x1c3b50ab3c647b6d36f1830308d4542ce50afddf32694ad04eb0cd74c3745ac8", + "0x09ef85eaa102507d30f8dd98ca7ac4118e672d857aa409ddcbfcd5ead95566f9", + "0x1256e2d7faae3069ab6b6eeecdd2ca57f968531ba26c9523d7873d1c01d8a712", + "0x130ead05bf8609707d66dc246899574c8d5f3f60fdc65b3affa4dfdd50c9c602", + "0x175bb0190a44c00aa0f83b47bd63259e980f01e24e9518b9bb8abd2c25e49a02" ] [inputs.public_chonk_verifier_proof_data.vk_data.vk] @@ -7421,94 +7421,94 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" "0x0000000000000000000000000000000000000000000000000000000000000015", "0x0000000000000000000000000000000000000000000000000000000000000aef", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000001a8ea793d4cdae748667e6cdeb797ade65", - "0x00000000000000000000000000000000001cdf44a19565682df1db9105c2cd50", - "0x0000000000000000000000000000007d45bf53693d1e5f8c726b3b9090a3bdba", - "0x00000000000000000000000000000000002ddd08200eb9544a216dd19a8b59c9", - "0x00000000000000000000000000000096b0edfeb3ee3338c818b6e462ae496f95", - "0x00000000000000000000000000000000001bb979e3cd7d8111d021237de30bb7", - "0x000000000000000000000000000000e785a70c5bc29de6993bcd63514b5b856f", - "0x00000000000000000000000000000000001b6701a1a9de0c4e25c2eee81fbfc5", - "0x000000000000000000000000000000ccad5e1b43ec3cad430d126196ed4b784f", - "0x000000000000000000000000000000000026c8cfeea88730a069f9f8aae45eff", - "0x000000000000000000000000000000f25307bf7ae8166628fb8ca2aa186d80cc", - "0x000000000000000000000000000000000022a312b7a1b12f670d059924fde061", - "0x000000000000000000000000000000cfa8bf07d4dd07bd309194ad43dcf460aa", - "0x0000000000000000000000000000000000167ca0ccc32845025c5a76273b1b08", - "0x0000000000000000000000000000002a2f6be8e93ea920cd14a7b043ef6ed5d1", - "0x0000000000000000000000000000000000277ea66800e42f0b7078688718305a", - "0x0000000000000000000000000000007f88f1687491d3f3326c737061282c2e20", - "0x000000000000000000000000000000000019f0c295284fc42024aacbd46f9ae9", - "0x0000000000000000000000000000008a6e059479dbef05407682d018e1d7fd0d", - "0x0000000000000000000000000000000000276f6c02388d41b068d36f0e4082b0", - "0x0000000000000000000000000000006fe39d9df6859556bc04a2847a62aad7ff", - "0x00000000000000000000000000000000000faecf34f51e503f9c5bdf6f57aca8", - "0x0000000000000000000000000000004b4587deb70388b513862ba57de24e4596", - "0x0000000000000000000000000000000000167c35f16800e5924b66b6c395c2e1", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000351e060c59f2f13ceb5c631381e110552b", - "0x00000000000000000000000000000000002eeb2d2cba09260a9e138d0d24555c", - "0x000000000000000000000000000000d3bae05ebcb86c7b4921f00e4c579e9c5f", - "0x00000000000000000000000000000000002d4be8ae9ebbf085739d2c52d2ab93", - "0x000000000000000000000000000000940377e34f17c5ad22102cca865bb574a1", - "0x00000000000000000000000000000000000a723717bfcee9dcb71e21b6de10f8", - "0x000000000000000000000000000000991a4b02291df9c14b77e2473315d673b3", - "0x00000000000000000000000000000000001e89b95cf6b2ad2506d684fc7b7a30", - "0x0000000000000000000000000000004022b331528bfac4bdb04464fc89ff83fb", - "0x0000000000000000000000000000000000196330867786a8c08738881b739ce0", - "0x0000000000000000000000000000009df8b221819ebf22dc413d730b0c8a1e31", - "0x0000000000000000000000000000000000276ed9c7e725f586bf3b0f7d5f1594", - "0x0000000000000000000000000000008eb30c526734ef3a740aea96282908f962", - "0x00000000000000000000000000000000001624f456603c219b9f79b39960c61b", - "0x000000000000000000000000000000b9e9ead3a80d73be248eb82b65a23dbaf9", - "0x000000000000000000000000000000000022e03caaedc42d8b4b100610f33723", - "0x00000000000000000000000000000004914aab219c2e5c1388d1c5b276006436", - "0x00000000000000000000000000000000002426e1277a7907df8ec2e0e609f0a6", - "0x000000000000000000000000000000508e79b26489525bf5386a5c910dca5a5d", - "0x00000000000000000000000000000000003063b87ddf8ff817e547fe4ac149dc", - "0x000000000000000000000000000000f106fc4afe6bda7761c0d4ed7ded72ce1c", - "0x00000000000000000000000000000000002547059f6e3ae71ef9efe2be7dc5c0", - "0x0000000000000000000000000000001c8589cec2b200eed912f3e76cf5562b2b", - "0x0000000000000000000000000000000000154c96e49bb18fdd1aed7abd315822", - "0x0000000000000000000000000000009c4fcdf6541a1a4fd3d01630e1bba3fad8", - "0x00000000000000000000000000000000000e2b7c9dabb30e63d6cb909551d6d8", - "0x0000000000000000000000000000003e17757fa84eda964303f6fea5cca55ef1", - "0x00000000000000000000000000000000001efc4c896804eb95a3b76060ee5db8", - "0x000000000000000000000000000000514fabf9f6c618a2c084e1e9e64393459d", - "0x00000000000000000000000000000000000e851da603a179ea88a694100ed72e", - "0x00000000000000000000000000000081c7f92e6390c9fbe0627a879ecbd8f8e4", - "0x00000000000000000000000000000000002378d597dead1c2952534dc50aa04f", - "0x00000000000000000000000000000033435458f18b0436847ac2652e1aab3a81", - "0x000000000000000000000000000000000010f0f995d2e1ddfc2e2820abac64f5", - "0x000000000000000000000000000000cdc9c148beeb2652667b2a4be097432e98", - "0x00000000000000000000000000000000001790fa444ce77b0f17ced05ac77644", - "0x000000000000000000000000000000b4e0fa181577e0fce2a73e33cb1c7ef76a", - "0x00000000000000000000000000000000001248979a0b4c713d52467ef1091214", - "0x00000000000000000000000000000078b68a818812e294d27ed5173181eca67b", - "0x00000000000000000000000000000000001202f015e527e07bc8aa3b29bfc68a", - "0x0000000000000000000000000000002e37c769468f1d3bd64860032eeec60c95", - "0x000000000000000000000000000000000013a9a82892cb1b4ba982fa96f6fe5f", - "0x000000000000000000000000000000a4f97445c3ce77b60a4f89e090ed25f90d", - "0x00000000000000000000000000000000001bfe48767b9d9852929fd6c6ef7489", - "0x000000000000000000000000000000009788ffc458269e32c68d8529122209c6", - "0x00000000000000000000000000000000001ad94133da104b491b0533c283058d", - "0x00000000000000000000000000000082943f7e3e8277c5573c7bc01ee756e08e", - "0x0000000000000000000000000000000000093e0b3b3b286763d72202e7d89bd3", - "0x000000000000000000000000000000661e1803122d810a714ede90be3cff69ed", - "0x00000000000000000000000000000000000d11450f56fe63fe8dc9c9bcf5e0cd", - "0x0000000000000000000000000000003bbb3abba3a132e8d8f45f371281a8162a", - "0x000000000000000000000000000000000022484ddb85caad7259d40a2feaf9f0", - "0x000000000000000000000000000000d5c60aad9d3206ac85c01b2bbe07bb882c", - "0x0000000000000000000000000000000000064dbab19fabf630e0a01c9c644f28", - "0x0000000000000000000000000000000c6d39a6cc1814cb9c474639a2c85d7696", - "0x0000000000000000000000000000000000052e9746024ad3039b28344dff0160", - "0x00000000000000000000000000000082d5e3a922fab44e31d4948721b4c26f6a", - "0x00000000000000000000000000000000000209322634f0a5d2a3bd73f1e3eefa", - "0x000000000000000000000000000000ae542b5e28179ea83bd48b32d82857e6ce", - "0x00000000000000000000000000000000002e46a1b641046cc74f095ebc925043", + "0x000000000000000000000000000000b684f3822d696c3ecf484a7fe34791f63b", + "0x00000000000000000000000000000000002e9cd7590551679f2745acc9a6166b", + "0x000000000000000000000000000000c0fa18a8ea0c5477840072169c70c27083", + "0x000000000000000000000000000000000006fed68edbd8843dd0ab879a772fc6", + "0x00000000000000000000000000000026e7b1ee3942c1a107eb829a4a1fa2804d", + "0x000000000000000000000000000000000009789bf7546013a4f03234c7cf7806", + "0x00000000000000000000000000000008b9a37ec6fc3442e0c17c53d3e10b0b85", + "0x00000000000000000000000000000000001ec5dc87962d6200825abf3d662edc", + "0x0000000000000000000000000000007d544b6605780427b276080dcba2d3a6b1", + "0x00000000000000000000000000000000000e462e18915af1093432e4b54d56b5", + "0x0000000000000000000000000000002d05ce754d8790322afa554bb538c82ce7", + "0x0000000000000000000000000000000000217fb463fb96af6e79b1a94df4de2b", + "0x000000000000000000000000000000988e396bb90b6bb7bdbf004d58ee206dc7", + "0x00000000000000000000000000000000000ba1855ea83b7c95ca53b8080e4d9a", + "0x0000000000000000000000000000000542d08371517becedf53f97ab311ed352", + "0x00000000000000000000000000000000001da797344377e013d7ace7bd0b582a", + "0x00000000000000000000000000000020166ea9997b1c239d34547f165b8d5982", + "0x00000000000000000000000000000000001850619eba2054f9f41324786599c0", + "0x0000000000000000000000000000007b9e1bf48be054d6a7281d9aef57fa66c6", + "0x00000000000000000000000000000000002a965ef9ba89270efb7a138db9f3a5", + "0x000000000000000000000000000000b8eaa90b65a792f984baa676b46045473b", + "0x00000000000000000000000000000000002bdf1ff1c21dbc118d6b878d504e6d", + "0x0000000000000000000000000000001ff7882b2fdd2ca32c857c77a380501a10", + "0x000000000000000000000000000000000005d51203c3526df0478a7275d46c7b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000598c8acc7fbfa779ed23372aba38bee64e", + "0x000000000000000000000000000000000001984ff4c3c19be7573bd5bb20b210", + "0x000000000000000000000000000000cd57f43bdf29875704dbb8e152f13aa037", + "0x00000000000000000000000000000000000dd55c58c84f3d5e854644f37177e4", + "0x0000000000000000000000000000001f02ca88c525a96b8563b48a7aabfc6b24", + "0x000000000000000000000000000000000002c93e0923d1b6d1e60d43a3928487", + "0x0000000000000000000000000000003c44cb74e2b6818ca4c75759ea23191cdb", + "0x00000000000000000000000000000000000e4db22c7616ee8c3c75b705bc7668", + "0x000000000000000000000000000000cabb69affcf99d1cc46c03c4140cb33f47", + "0x00000000000000000000000000000000001c15d7c93bbec9b2c897220b1c1420", + "0x000000000000000000000000000000090d5378c110fa9fd29af632a34cf84470", + "0x00000000000000000000000000000000001c8f5e33fd9b7841bda781b9a1a2af", + "0x000000000000000000000000000000b268933977ad81d4b2a90d89d86fef1cd6", + "0x00000000000000000000000000000000002f05ee0ba26ee4625875220a4e9f51", + "0x000000000000000000000000000000b79359439c800d1ff8759390cf8e9877b8", + "0x00000000000000000000000000000000000907e60e1332a9c7d1543b5429af59", + "0x00000000000000000000000000000084be3aaaa5d4b2ce869b94d84b180886c8", + "0x00000000000000000000000000000000002bf2641799eea22ca7c17fcd0170bd", + "0x000000000000000000000000000000ffd7944bc577de67a10fa61e563e39a199", + "0x000000000000000000000000000000000018ee5274d9d59c7a4e6ea4e9086857", + "0x000000000000000000000000000000913cedb17e467b5ec128fcd30a5d8f45a4", + "0x00000000000000000000000000000000000c36352a17ffaa1baa9f6f4ab990f0", + "0x000000000000000000000000000000d1d15826519e7557e9252e25cca7b68234", + "0x00000000000000000000000000000000002d8d82a0d2a2dafaa5c30e4fd0beca", + "0x000000000000000000000000000000f366069eb603ece7d5dbe351d3a7f8cb99", + "0x00000000000000000000000000000000000119a645221fedcdd2f0ccc55659aa", + "0x000000000000000000000000000000d4c5aa8f13dc73d1efb124730021df3c0d", + "0x0000000000000000000000000000000000173a91d164168b2a104f8a445923e3", + "0x0000000000000000000000000000001e0da0a289c24c20d61d63757e40d52e9e", + "0x00000000000000000000000000000000000873f2a70e71f36a677fac98b0f223", + "0x0000000000000000000000000000006363e418625d1a87b6c793a3fa67b62c8a", + "0x00000000000000000000000000000000001ad07fff2f60d183c6bbb52a88a076", + "0x000000000000000000000000000000602ed6d6e8441b84b20d5cf2eefe2b5730", + "0x0000000000000000000000000000000000011db44c3dd41d17fd5a5da5841ab1", + "0x000000000000000000000000000000ef6dbd36e70930ca9ecea70731b3ae2952", + "0x000000000000000000000000000000000012198e0151358cf72269f25d98a7d6", + "0x000000000000000000000000000000a9c62bc5e4859d84a6b71f0eb9ae002076", + "0x0000000000000000000000000000000000146b4d83228248fb4daeceb484a5cf", + "0x00000000000000000000000000000024272119fa5ea3659f5cc93e6906346041", + "0x00000000000000000000000000000000000e6f203351dc3d501e96deeacd1745", + "0x00000000000000000000000000000042723ba67f449f887a257cff0077f60df2", + "0x00000000000000000000000000000000000d5d772ba32d8ea22a4a0ca387da7c", + "0x0000000000000000000000000000008768ff19c1d3a20e9d334a1dfc81d182a6", + "0x00000000000000000000000000000000001f094f6d1eb8ebb46d7095f5cc262d", + "0x0000000000000000000000000000000efeb2b7db33a990c506e101c73afeed1c", + "0x00000000000000000000000000000000001381f886e9f8fd1aaf0824301d7f8e", + "0x00000000000000000000000000000026555700b99ad174e75f4fb2d54779813b", + "0x00000000000000000000000000000000001c184192b5ddd9b083ea27a2d01025", + "0x000000000000000000000000000000182a4013ec7ec4cabe96b2bd1a6ab6430f", + "0x0000000000000000000000000000000000266cf97a9846e58c82026b73f6be09", + "0x000000000000000000000000000000a0520688f4f47af3d195d4177dea4f6e70", + "0x000000000000000000000000000000000006dc9cef5b50392a5b25ffcd69e751", + "0x000000000000000000000000000000527d7c6049997c4de9bee2ace160dfd14a", + "0x000000000000000000000000000000000015e9a964515f16d454fb7d7e2e565e", + "0x000000000000000000000000000000cbf8b366a6c9c4395540c30f766a303cb9", + "0x00000000000000000000000000000000000fbb75e876fd119e954d22ceeea95c", + "0x000000000000000000000000000000922cfb797e0ee95d7bb31ceeeeb4d433c7", + "0x00000000000000000000000000000000000f2223f49c2f01718041ba6c8ff4e5", + "0x000000000000000000000000000000a0d4ea1e1c31cb33177efc4f9a6e1652ca", + "0x000000000000000000000000000000000017d878dd102598b8a90d658d650bba", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -7529,12 +7529,12 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000b2cda22d682b80465a610820a455ccfe00", - "0x000000000000000000000000000000000014dbf65b57cd412e5a4e51e2e8fcb1", - "0x0000000000000000000000000000009324a599f7e39fa876752e4178e66cf056", - "0x000000000000000000000000000000000012a5445413899397985b2de3535efa" + "0x000000000000000000000000000000a353727eecbeb2708a0ba7438c9f67ac9f", + "0x000000000000000000000000000000000016d8906c48c640faac59aa0947b8bd", + "0x000000000000000000000000000000c14d66a59de329aabcfb5715846504a4e4", + "0x000000000000000000000000000000000009a577481460dded82d652c6abc7f8" ] - hash = "0x0c77683b8fb3dbb3c652ec7c75c7edab0f9597a4763fa388ed23a1a7dc7d4ba0" + hash = "0x1ef80142d10a45fb61f3a4192d352f1d813530777b10ca6db9613ccf5d025640" [inputs.avm_proof_data] proof = [ @@ -23942,43 +23942,43 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.avm_proof_data.public_inputs] prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" - transaction_fee = "0x0000000000000000000000000000000000000000000000000022e452ad469ea0" + transaction_fee = "0x000000000000000000000000000000000000000000000000004d2c208a4b8060" reverted = false [inputs.avm_proof_data.public_inputs.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x00000000000000000000000000000000000000000000000000000000ad49d7cd" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000b" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000043" - timestamp = "0x0000000000000000000000000000000000000000000000000000000069fde108" + version = "0x000000000000000000000000000000000000000000000000000000007597d4fd" + block_number = "0x000000000000000000000000000000000000000000000000000000000000000c" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000026" + timestamp = "0x000000000000000000000000000000000000000000000000000000006a0b2e97" [inputs.avm_proof_data.public_inputs.global_variables.coinbase] - inner = "0x000000000000000000000000fde0805eba75f23cd30a3bb4f0e567a356075904" + inner = "0x0000000000000000000000000058eeb4a1d899caaeae3694cae1527237e4f56c" [inputs.avm_proof_data.public_inputs.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.avm_proof_data.public_inputs.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000003699e8ba0" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x1520f4bb11a3a1d2248a03d8472e9af4bb8324eb1d2d8c83bce61894383464b9" +inner = "0x2c78cadfe08eabbb0e2a15b62eefd07a08cbc1631fa2be7962fd219308d9f1e3" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x26a43bf066852a7b1ec3c5b454f41735fea12e2ffbefed471058124b91d94018" +inner = "0x0d6429ccd33eeec2a03a7b2f78d6c901ad9406bf2058231382147de5014303fd" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x1bd26c6831ebc53674b13ac69a0c534563c37e46c2cbb36f2deca107a26515fa" +inner = "0x0b286a1c928fbe1ca3be78fe2f2bd25a2eec7f5f15c2757a2db53b2a8d499358" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x06870c63132d2a4e3356a76d773240efe729e7d9b9380a7a3cf1798fc9031aed" +inner = "0x1cef6885d1ace5a36534202d1f593b94ac0876ff4933745085ad62da062a3b5e" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x0083c4dfb922796f1086d399f8f3d021159d1a87ba3b833dcdf9863c630ba643" +inner = "0x2ccc3471349063b3b0c5a6362e0dbfc3c21b534f84fc963483667b32840e259a" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] -inner = "0x0b4d3a9a7a3caf83f9c2060347e48cc28c7f04d2560d1cbf5bf08d4832128a97" +inner = "0x0ad78bd90b0e2e0887928b98b621517d04a6bddebf6b20bdb76ddd8aec6f05fd" [[inputs.avm_proof_data.public_inputs.protocol_contracts.derived_addresses]] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -23997,18 +23997,18 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.avm_proof_data.public_inputs.start_tree_snapshots.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000003000" [inputs.avm_proof_data.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" [inputs.avm_proof_data.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x0e8d32952999631ff527d706426177bdb3208db1d3b8dd4e74ba883610dc37e5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x1cfed5fd7ef032befae488393236dfabcdca928fd71b5775b02eeeca5952b149" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" [inputs.avm_proof_data.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x0d21d4944ca04ad548057c7362ba76b7370e29929fe9cdd32ec1d04c07e21179" +root = "0x17809078aea757181529cc251693b3402311164785b07da22da983ca02d24ffa" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" [inputs.avm_proof_data.public_inputs.start_gas_used] @@ -24033,10 +24033,10 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 [inputs.avm_proof_data.public_inputs.effective_gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000003699e8ba0" + fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000078c3bcb60" [inputs.avm_proof_data.public_inputs.fee_payer] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.avm_proof_data.public_inputs.public_call_request_array_lengths] setup_calls = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -24365,13 +24365,13 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 [[inputs.avm_proof_data.public_inputs.public_app_logic_call_requests]] is_static_call = false - calldata_hash = "0x16acf8ee72d77f214e5286307ed2710fda25445374c38debbef546a746b679ce" + calldata_hash = "0x00a5e40cab902df3efe088094577e83eb92103581c990f351edf1dfba3778905" [inputs.avm_proof_data.public_inputs.public_app_logic_call_requests.msg_sender] - inner = "0x0635e757a5f05ba5322db37d6930525b43c2e055ed7c4600559a07fc38ab09ec" + inner = "0x2d56768ff7de67ad18e8f657deb90e0e541d951a204fb19910831c2021c1dca2" [inputs.avm_proof_data.public_inputs.public_app_logic_call_requests.contract_address] - inner = "0x16fc6ad8c94527d45832bb8631b0c1dedf3218fe7c3ca04e01850a3eff6a511a" + inner = "0x1be490a4b344f41827e94113f628fb311efc1abac19bc1e84b08fd578708964a" [[inputs.avm_proof_data.public_inputs.public_app_logic_call_requests]] is_static_call = false @@ -24771,7 +24771,7 @@ fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000" ] nullifiers = [ - "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef", + "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -25133,18 +25133,18 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.avm_proof_data.public_inputs.end_tree_snapshots.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000003000" [inputs.avm_proof_data.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2126a6e400b3fae90b44b74482d5b59dc707ba8f044c90a5f0e06ff48029f19f" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x17220b63d32aab917a748a18b8074aff52332c70604bcad27008d4867e2feea8" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" [inputs.avm_proof_data.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x28f8d2b1f0315d8539c1e4ff651e2eaac034de0a2271cd6f198f557ecf449cb1" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000003c0" +root = "0x1b9b13fad9b8c5689ecb8b3449c932a2d4ce5b1bb6c66b151c74151b7a909287" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" [inputs.avm_proof_data.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x1a010e7a4312757d9349e0058c907064764c9836de016199dbd957ca46fefc3b" +root = "0x042e24ca2f4d3cda89d63c923672cba1d069fd15c9575270effd23fb306ee5b1" next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" [inputs.avm_proof_data.public_inputs.end_gas_used] @@ -25225,7 +25225,7 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000" ] nullifiers = [ - "0x09fac458f9e079d0117ef63746c55ce66b3e5d95c8420974d9c69f369b0d77ef", + "0x233e95769f6a7d3be5b0c68b13431ad2214bcede52ae9c10e340ac57871b65fb", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -29473,16 +29473,16 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" ] [[inputs.avm_proof_data.public_inputs.accumulated_data.public_data_writes]] - leaf_slot = "0x2935995b8343928a25acdb09654bdc27aeef345ec185caa48fb0048bd475fbcb" - value = "0x0000000000000000000000000000000000000000000000000000000000001c20" + leaf_slot = "0x1e116153847a288031b32de76feba5606af7f48ea6844ed7f788cb4937c97651" + value = "0x0000000000000000000000000000000000000000000000000000000000001f40" [[inputs.avm_proof_data.public_inputs.accumulated_data.public_data_writes]] - leaf_slot = "0x0dc02e099550676b3dcfd522010d4db9d2c47a4556dfa28aa20a4a0eb35c54a4" - value = "0x0000000000000000000000000000000000000000000000000000000000000af0" + leaf_slot = "0x22d51324ad539ea879ef28ac3e794fc1fa95103211f0d355b7edbf0795a37e5a" + value = "0x00000000000000000000000000000000000000000000000000000000000007d0" [[inputs.avm_proof_data.public_inputs.accumulated_data.public_data_writes]] - leaf_slot = "0x12d1296a2643b832fbd1d6d3ed3678833fce770084efd75adfd517de8214ccf3" - value = "0x00000000000000000000000000000000000000000000021e00afaeb15ed67ca0" + leaf_slot = "0x041ecbe21bbbbefd34a95c40b18be9f5fca1323072eeea3a6f5d0136c2a71969" + value = "0x00000000000000000000000000000000000000000000021e008a3dae486615a0" [[inputs.avm_proof_data.public_inputs.accumulated_data.public_data_writes]] leaf_slot = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -29747,5 +29747,5 @@ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" squeeze_mode = false [inputs.last_archive] - root = "0x24f3d6261780561e8ede638edf15d34d9f93372572631856307c57a08dfb9cb1" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" + root = "0x2d4409306059501fce0434d5913ad345e014fc870961be182b636a307b3d06d8" + next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000c" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml index 9181896a6389..a86acdd36df9 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml @@ -489,8 +489,8 @@ proof = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] @@ -570,10 +570,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7d1b34e" ] state = [ - "0x0dbad51bb440650e97a5db6945e0b816676a7c99a97b61f7575f7ebb0302cb74", - "0x153f707b3f374da7de4e7558dd131ca1b276367234300e2061ebb6a80c9321cd", - "0x301693101ecf5431e14201ddc3e55cb8715203dcc3e3d159df5c63bdbde17381", - "0x223072f1c5ac6c338cf08c7043aa64605f2ba6feec29f658343ec4db85070b27" + "0x28ceaed15a6167592482697da06ac405557958a88659e8a294d4a863e97f8cbe", + "0x16710e00e80f40036d0a39c58a3269bf0e03b7c095b904499bdab6f3ef5ccd71", + "0x25a44adf4bb8ea266cd5398139a046115f57ab3cbbf9827ae3edb4dca94d8fd1", + "0x13551db592560b9a6d2ffed579ee3530d463b8baa035312dccd664e01e077a66" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -581,134 +581,134 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000008580b9a8c85e4a3c1e7b1089bd79f3bc28", - "0x000000000000000000000000000000000022dc01e3ed0e1b10bdcff9d093431a", - "0x00000000000000000000000000000054f9950035e8ffae852707e9d1a9032e59", - "0x0000000000000000000000000000000000276c56cb94e0545b3bfd85919a8ce8", - "0x0000000000000000000000000000009352ff9d82645804416a2b338260fa235d", - "0x000000000000000000000000000000000010a253776d2bdcb7129acfa2e91ac5", - "0x00000000000000000000000000000095babbbc4a6d5a9b68707c3a8e1e9508e2", - "0x000000000000000000000000000000000030157ca77e90f7ee9155c1009b06a1", - "0x000000000000000000000000000000068047e82e283284235befaa9cc7a1838d", - "0x00000000000000000000000000000000000bcd70cc5042e81e440b1ea5ef3c3f", - "0x0000000000000000000000000000007702a95c1bf5e2923ca69f26cc2d7efe0f", - "0x00000000000000000000000000000000000adeb0e8b1074c68de2b2172f21c5e", - "0x000000000000000000000000000000520354133ccbbccfc69be0c01b92abdf0f", - "0x00000000000000000000000000000000002dea248e3c2fe054c698a861bf4c27", - "0x000000000000000000000000000000f93b6112b7de5c27298a81c68d502b7beb", - "0x00000000000000000000000000000000002be3a33fc9502b0cc8b9427fcfe50f", - "0x000000000000000000000000000000168f01ff83f4a014a90db19e5d882a0a0a", - "0x000000000000000000000000000000000008876edc3cc7e3825dc194e21cb011", - "0x0000000000000000000000000000006d1df389f06e514e1829af3744dc64294a", - "0x000000000000000000000000000000000022e86ef68622bd107e5080cc062a4f", - "0x000000000000000000000000000000d137fc89e86049cb1b141b67b3361b6298", - "0x00000000000000000000000000000000001d7ad7d0634dc08d7d9816b5b6814c", - "0x000000000000000000000000000000defd2454e2c3a75ec8e0730bd3640b9408", - "0x00000000000000000000000000000000000b189f6ee9395b1ca5771c361501d7", - "0x00000000000000000000000000000001fccf755f5b30a7d544b2f78ce075cb5d", - "0x000000000000000000000000000000000026f5423942948047e155a519b195e8", - "0x000000000000000000000000000000a9efc76daffb8dfe2a39570b2d5d046767", - "0x000000000000000000000000000000000026e7dd89fe96952a4603c2b5555538", - "0x00000000000000000000000000000008262b430328dcaab242dd8acc504e8ac9", - "0x000000000000000000000000000000000015f3ab1410f0e5dd3e00f03b9f563b", - "0x0000000000000000000000000000008fca5ff8ed9a5d41fe9b451f02502dd1c9", - "0x0000000000000000000000000000000000266aa6e4947434ef18adeba3700713", - "0x000000000000000000000000000000d93cecd04341f5da304f3c92f0670afc43", - "0x000000000000000000000000000000000020165b3fd2bfb72a4de3dc68f66eed", - "0x000000000000000000000000000000094a6d376eb3cc1ba94b4da00dea583eac", - "0x00000000000000000000000000000000001caf7742d251b04f3517f0f1e5a625", - "0x0000000000000000000000000000003be5647cd472ad0b06a48f632997e3eea2", - "0x000000000000000000000000000000000015fb4d9ecb8125b3243cee37698c48", - "0x0000000000000000000000000000000854a3ab5bcbca1e86d4949b1b7c5f4b0e", - "0x000000000000000000000000000000000015450314fbf315448dc3379dc82214", - "0x0000000000000000000000000000009c2c55d2ea5bdf5fc5e28f1a78b1d29625", - "0x000000000000000000000000000000000020b36a8406ec64352600587cf04194", - "0x000000000000000000000000000000f14d08d9dab6a54412d741166146188ae6", - "0x00000000000000000000000000000000001b5a34ccd7eaf5cd09ab920011552f", - "0x00000000000000000000000000000074b7827a59faf701f7f41df26e5476c40c", - "0x00000000000000000000000000000000002decbab1c87b933da1625951860793", - "0x000000000000000000000000000000751aab48a0e01094128242ea0aaab63ff7", - "0x00000000000000000000000000000000001a2a334289adf8d23d4d52caf4cfe6", - "0x000000000000000000000000000000f6a41261290460b25e1e7d7bf69b564ae6", - "0x00000000000000000000000000000000000296925feaed4585bb03319f126d96", - "0x00000000000000000000000000000055b70d653ebd7df04f720951e76a27369b", - "0x000000000000000000000000000000000019744937a687edc9f46fb8323a46d9", - "0x00000000000000000000000000000047978fda5b64d8fc4571f09da3e8ccc7de", - "0x0000000000000000000000000000000000139de6a387109f47ecbacc74e03742", - "0x0000000000000000000000000000007f5afdfcb7bcd85aa293676e18e899a03e", - "0x000000000000000000000000000000000006a2971c1c947f4cadb07ebc9bc980", - "0x0000000000000000000000000000006cdb69a57b7f7a25b99e18fc0f83c1bc70", - "0x000000000000000000000000000000000028f2a76a01dc3cc927cdba29383e9b", - "0x0000000000000000000000000000001bbc4d6033de44907975ce473bc0f4f148", - "0x00000000000000000000000000000000002642f26fc1850c4b9b7fc4cd860ab9", - "0x000000000000000000000000000000ac996074e35eb268f6ebbe99e9c7d26c47", - "0x00000000000000000000000000000000002262620617978a01f75646f1909969", - "0x000000000000000000000000000000e63aa32bcc098428f407b5e07d9cb26118", - "0x000000000000000000000000000000000022b294b6a7dc4c17319f9a91a1b443", - "0x000000000000000000000000000000649d9ce9147431632893f55d3c6bbc158e", - "0x000000000000000000000000000000000020698c9b0787f14aa66a57bc232ec1", - "0x000000000000000000000000000000b4fde29f9bde909609d70bf9862dd65cf1", - "0x000000000000000000000000000000000005fcac9b75cac50d87ca827678c070", - "0x00000000000000000000000000000071e27b0a0dd0e2180985072f4a949f0c1d", - "0x000000000000000000000000000000000025d2d1388eddcf016213f1cadc763f", - "0x000000000000000000000000000000b216bad715cdfa7c382d30d7a368cc1346", - "0x0000000000000000000000000000000000302dbbf78b13a6d71d1978b5607145", - "0x00000000000000000000000000000002ebdec49969d2ff9220240bbcb8730617", - "0x000000000000000000000000000000000027f41cad8540e47008c1da90340ef6", - "0x000000000000000000000000000000e8259148321315cc34166a206fe910c6cb", - "0x000000000000000000000000000000000013444efc30c7688d961f36de252af6", - "0x0000000000000000000000000000005b7c7ad432291e9dff1dfad51159e50dbf", - "0x0000000000000000000000000000000000205ec973a0d1c898c1def7852353b3", - "0x0000000000000000000000000000007940a7e88fe5ce47af688975c92be1b62a", - "0x000000000000000000000000000000000015bdab44fe41eec6ee62ed58f55ff5", - "0x0000000000000000000000000000003693b90aedcd664eede665df6f376cf526", - "0x0000000000000000000000000000000000207c38fd6851d1568fe18a83585f31", - "0x000000000000000000000000000000f1a8a60975b9b092aab1421166be08c2f5", - "0x000000000000000000000000000000000015450d2e8ea17db209302582b886f1", - "0x000000000000000000000000000000526e857040a344bd434bfdbf94d3a49196", - "0x00000000000000000000000000000000000d0112b922a852c4754ab3929d6d02", - "0x000000000000000000000000000000d88041fa28c8118a58ceacbcc8780844b5", - "0x00000000000000000000000000000000002584170ebef150b71c5e6aa93e2fbb", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a2c4fbcbebac01e208127093cbf44780d4", - "0x00000000000000000000000000000000001ca34545a074b1cb689aa0b343402d", - "0x000000000000000000000000000000a58c28598055d8818a6dbadd0018904386", - "0x0000000000000000000000000000000000152154cbc213630f5c7ec1ee37751b" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000f944590031f1d3b251c3dc90ea2821c71d", + "0x00000000000000000000000000000000000d31fd1a4942efade625e012c77df1", + "0x0000000000000000000000000000001e9acd89b92c18e3d89b881b26312bb12b", + "0x000000000000000000000000000000000000736f00a23cbea07da614d8b767e4", + "0x00000000000000000000000000000012167fb1f0d3b9afea7d534404e3b36b53", + "0x0000000000000000000000000000000000021e6d056d0d40c720927abd39c872", + "0x0000000000000000000000000000004ea3f0c21ee1056b3e2ad9c082242e5a2e", + "0x00000000000000000000000000000000000c574204fd079871ae599e192d72c8", + "0x0000000000000000000000000000002654c5b2b175f95fdb2ab405dcc4220545", + "0x00000000000000000000000000000000001fd13a35df71290c2354c6c5f610de", + "0x000000000000000000000000000000d5e3b3464d67c82f035b33016912264b04", + "0x000000000000000000000000000000000009fcdab45c12d2f313f95b94a1dcb8", + "0x000000000000000000000000000000768c5a9d8ca0081f67ff3171a7ffe3ba49", + "0x00000000000000000000000000000000001cd676b8d32bb0bb898d83a9f49a2b", + "0x00000000000000000000000000000028650bc3473de217fbfec1e9fb10e4e999", + "0x0000000000000000000000000000000000260c000ea0ebc3db3ba672328007a5", + "0x000000000000000000000000000000f1948fbf68599bf0628f118156de61f57f", + "0x00000000000000000000000000000000000033e796d200425f6a499de18dbfeb", + "0x00000000000000000000000000000016a35cf8fc5f017037adf860723e6346e5", + "0x0000000000000000000000000000000000088cf6d72197800bb1300677f734a7", + "0x00000000000000000000000000000047169c153b6cc24bbac1e4126410779ccb", + "0x000000000000000000000000000000000022b70bfb92e8c7944ae65a49b7effa", + "0x000000000000000000000000000000425c661c37104ad33c2054f3cfde9954d0", + "0x000000000000000000000000000000000000c36b8ecc5963bef022dea4dfadcc", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", + "0x000000000000000000000000000000862e0c485b99696417d296ecc2b2bac316", + "0x00000000000000000000000000000000000ae46fcce211297d2d7fcab27fc041", + "0x000000000000000000000000000000551700c158e12cb40d8ea4ef2563b6fb43", + "0x00000000000000000000000000000000000b515d88939b250a4a4758e4e2ea53", + "0x000000000000000000000000000000f4bae0ad0baeb9d42c7fe2ae3d18c98fad", + "0x00000000000000000000000000000000002a20d66bd435a17fdf1eaf345d5933", + "0x000000000000000000000000000000ed8a8ba528c7088b1ae4730572e1ec32c8", + "0x000000000000000000000000000000000009506de430d6b9f9863e6f10cd35fb", + "0x000000000000000000000000000000682b627744ce0319f4d9191675057282fb", + "0x000000000000000000000000000000000017de059961f8c12752abd299396f86", + "0x000000000000000000000000000000b975958ec262178729e94350c0e7543fb0", + "0x0000000000000000000000000000000000220ce50e394560e53f025e094d17aa", + "0x0000000000000000000000000000001fca3a68a28d438e85e9dc955856752779", + "0x000000000000000000000000000000000028f8f3400bb3b9d19b02ec709e2ee4", + "0x0000000000000000000000000000004e35d073460b0634ebe216d49a3dca9b36", + "0x00000000000000000000000000000000000cb0f5827b08075c405353f10ba632", + "0x0000000000000000000000000000001ece860550ce14fae74eda0123ded56a74", + "0x00000000000000000000000000000000000a34b258bd3daaf8f9edd201c25ed3", + "0x0000000000000000000000000000008cb28ae85d58a75302229585a9ad114c2b", + "0x000000000000000000000000000000000014aac1da344ad32659c3036510fcc1", + "0x000000000000000000000000000000822b45036d5c2befa8a20df910513570c4", + "0x000000000000000000000000000000000011244b388e709fbcb7f54658cfac43", + "0x000000000000000000000000000000389de9951eb8fad7e25e4ad0a9229d2275", + "0x0000000000000000000000000000000000136e6eb0ee251f9b12336cb7bb46ee", + "0x00000000000000000000000000000088f21d9f6c7c54ce4e9a4c103a91b54a58", + "0x0000000000000000000000000000000000187f2beab9a05ca29d2137ee7cbc19", + "0x0000000000000000000000000000009c703a5eb43dcef0686e08fa57ef452f68", + "0x000000000000000000000000000000000012caebb183f1490d3e4f2a2c583ab6", + "0x0000000000000000000000000000009dab4a0aa8d4954a8e1761db3da148a746", + "0x0000000000000000000000000000000000230a08da3b62fd6479b4230760b686", + "0x00000000000000000000000000000081a00a1e38bbd5212603f18ef982a5189d", + "0x000000000000000000000000000000000021ae0f9df38f1e70fa3c26867f4ee8", + "0x0000000000000000000000000000001a722dbd34f841b4823cd055149fce642f", + "0x000000000000000000000000000000000002df2693a9b134670cfe72bf29b363", + "0x00000000000000000000000000000007c906c328630b844b0797e34cedccd1ec", + "0x00000000000000000000000000000000002ab2ae39dd9c0259f7dfb1dda47e81", + "0x000000000000000000000000000000ac6642a4923aa2df07a00a9d3e462b0ed1", + "0x000000000000000000000000000000000015afb7af6c0fc23a24457aa887df9c", + "0x0000000000000000000000000000004d916ec23ef29c0b6134f208e3535671d4", + "0x00000000000000000000000000000000000d37c6c25852903d79475133d414e8", + "0x00000000000000000000000000000029ad212431ba1972de7ee0ba9f12113be3", + "0x000000000000000000000000000000000005c2393db23155844d4f71bead84d0", + "0x000000000000000000000000000000c69074efa82a4910eaf8ab8689d7aafcad", + "0x000000000000000000000000000000000029f3d77437006a0eacf1a149c4b8a0", + "0x00000000000000000000000000000030926853da69d4016eca2f1f0df5e5316f", + "0x000000000000000000000000000000000014841d3291aecd45ea0e05657dbed2", + "0x00000000000000000000000000000052fdb060fe666a3f686088f1f6996a1cf9", + "0x00000000000000000000000000000000002be878eb09939603b391aa9ee0393a", + "0x000000000000000000000000000000d99de3b49476e64c0138037838cfc63803", + "0x0000000000000000000000000000000000260874b43f32c373783efe7ef200a2", + "0x0000000000000000000000000000004951edbb25e9c6b65d446e3418b2b3f16e", + "0x00000000000000000000000000000000002300fac13ab48d40a91114d1ff9627", + "0x00000000000000000000000000000090b8d216da73861ee276dddb17428d8c09", + "0x000000000000000000000000000000000028f906106984e5fa78812869cc1aee", + "0x000000000000000000000000000000ce2aff6eda49d5b8be6ee42104d2aa21e0", + "0x000000000000000000000000000000000002833f671993d2b772b5dec0e12056", + "0x0000000000000000000000000000008be4e7cfb1fdf317a33b7bc3530625e6b8", + "0x000000000000000000000000000000000023404bed8e224a350755410e5c96b2", + "0x000000000000000000000000000000cd9a812fad3fe3a89983e416b70529445b", + "0x00000000000000000000000000000000000b66296ff191a2cf6dbe6ca03dcd0c", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003e895e3756deb16393c59a6a9d3669ce0f", + "0x0000000000000000000000000000000000262d7f27b9058ca9bd2e0620f9a3d3", + "0x000000000000000000000000000000b98c4ce00d755cb57daf4bc1b860536fc3", + "0x0000000000000000000000000000000000017137ecc6753555f49859a34eeb62" ] - hash = "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6" + hash = "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead" [[inputs.previous_rollups]] proof = [ @@ -1201,8 +1201,8 @@ proof = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x0141caf6779674bc31225636c4cc4259a731835c52fc462f2dcbfabf7de01a1d" - protocol_contracts_hash = "0x01af64239167dcc8333e25456aab71348f66d9f6de731a8b62181d16cf0818c1" + vk_tree_root = "0x0b701ee3d1002ca8a5a73a81bcb2e0d84e6c30222be65f508574f182569b718f" + protocol_contracts_hash = "0x0fcccdf7958e813bb1d24f764ae13ff08a999008434c2e4dec55f4401564b05e" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] @@ -1264,10 +1264,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7d1b34e" ] state = [ - "0x0dbad51bb440650e97a5db6945e0b816676a7c99a97b61f7575f7ebb0302cb74", - "0x153f707b3f374da7de4e7558dd131ca1b276367234300e2061ebb6a80c9321cd", - "0x301693101ecf5431e14201ddc3e55cb8715203dcc3e3d159df5c63bdbde17381", - "0x223072f1c5ac6c338cf08c7043aa64605f2ba6feec29f658343ec4db85070b27" + "0x28ceaed15a6167592482697da06ac405557958a88659e8a294d4a863e97f8cbe", + "0x16710e00e80f40036d0a39c58a3269bf0e03b7c095b904499bdab6f3ef5ccd71", + "0x25a44adf4bb8ea266cd5398139a046115f57ab3cbbf9827ae3edb4dca94d8fd1", + "0x13551db592560b9a6d2ffed579ee3530d463b8baa035312dccd664e01e077a66" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false @@ -1282,10 +1282,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x095ff6c475ee1af84257c77b73b727e6ebf0cc7015e0318ea5ceb14044e637a8", - "0x28810b36811d26c3700f0c7867fc191986df3ef57ea3a195b396ae8e1516b1a7", - "0x0d0d075374c48ade348ced65280060db0bfe6c16752688a5d65a07afc55cf16c", - "0x0b29f6eee3031f85d7f5ce02982c80e8fc06b552319a441c5b0fc3521d9c801c" + "0x019c8b37514a1a54433fb4ee411ccaf6da8c99234b4e5d11cc5f6b95c3989bb5", + "0x026875d420939d38c5495ee684f0a31efd5cab908193ae929d1c426d68bb9409", + "0x1a8c7e8add3b6e5ee547b84164a1d59756426ff82c71128c0627a7c01c830220", + "0x081d1fadf8d9a49f296a172486009b0c5f64d52de31142cfc01bc2b08387210a" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1293,131 +1293,131 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x0f8f726e833df2994b5e4f7236bb20b770b92eeddaa5e11c229e396b784aac56", - "0x24d3d34d155de7ba76e941299ef9b12edeb7de094e758c30ab32f54a32954ae5", - "0x234d319aa3526e9e00d76d9b5b9b18b435756035ad00d8d716e1be50ac82ead3", - "0x2648004ca39ab2f7f01e8733c2de2d035675568a1c98d1410ce90ac2512e72e2", - "0x15313312ac8ca4825afd3891479fbb14626ca65499d939e23b1f653cd7d018ea", - "0x19de2a32662702dd872e529ad89836e16b013012f910daf2bc7c2a67356dd107", - "0x1f07bca7a14f9a969539c0afd388affa18926689f431fc541841a2a7604d388c" + "0x09b4bb0061881fc354c5fadf8dc55f36b0c67dc3b2f58a18406363dfa0b079fa", + "0x2136af42d41c58f3fd528f4e88c2de5152c2bb251a3c4d8950d4401a0c8ae6ff", + "0x02d4017a1d1c142d1fdf34bf701748bd9db29906e0114ac657648a51d10b6799", + "0x146274c75e0cce377b1764ae8c0ba9167cfb0632d9453ac4c5b521f5d45cee4c", + "0x10fa882cccd67cfee268da2a5d99ed42a34302ecebc26f4b3254e41507b3ee42", + "0x133dc174ef877c42d59ac5fe87733ce13f9355587db788e3b490832c7afbcfd2", + "0x13482b383bc59a6da6ab4e998b0986c23166d0aba121fc0789e9f14605af653b" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000008580b9a8c85e4a3c1e7b1089bd79f3bc28", - "0x000000000000000000000000000000000022dc01e3ed0e1b10bdcff9d093431a", - "0x00000000000000000000000000000054f9950035e8ffae852707e9d1a9032e59", - "0x0000000000000000000000000000000000276c56cb94e0545b3bfd85919a8ce8", - "0x0000000000000000000000000000009352ff9d82645804416a2b338260fa235d", - "0x000000000000000000000000000000000010a253776d2bdcb7129acfa2e91ac5", - "0x00000000000000000000000000000095babbbc4a6d5a9b68707c3a8e1e9508e2", - "0x000000000000000000000000000000000030157ca77e90f7ee9155c1009b06a1", - "0x000000000000000000000000000000068047e82e283284235befaa9cc7a1838d", - "0x00000000000000000000000000000000000bcd70cc5042e81e440b1ea5ef3c3f", - "0x0000000000000000000000000000007702a95c1bf5e2923ca69f26cc2d7efe0f", - "0x00000000000000000000000000000000000adeb0e8b1074c68de2b2172f21c5e", - "0x000000000000000000000000000000520354133ccbbccfc69be0c01b92abdf0f", - "0x00000000000000000000000000000000002dea248e3c2fe054c698a861bf4c27", - "0x000000000000000000000000000000f93b6112b7de5c27298a81c68d502b7beb", - "0x00000000000000000000000000000000002be3a33fc9502b0cc8b9427fcfe50f", - "0x000000000000000000000000000000168f01ff83f4a014a90db19e5d882a0a0a", - "0x000000000000000000000000000000000008876edc3cc7e3825dc194e21cb011", - "0x0000000000000000000000000000006d1df389f06e514e1829af3744dc64294a", - "0x000000000000000000000000000000000022e86ef68622bd107e5080cc062a4f", - "0x000000000000000000000000000000d137fc89e86049cb1b141b67b3361b6298", - "0x00000000000000000000000000000000001d7ad7d0634dc08d7d9816b5b6814c", - "0x000000000000000000000000000000defd2454e2c3a75ec8e0730bd3640b9408", - "0x00000000000000000000000000000000000b189f6ee9395b1ca5771c361501d7", - "0x00000000000000000000000000000001fccf755f5b30a7d544b2f78ce075cb5d", - "0x000000000000000000000000000000000026f5423942948047e155a519b195e8", - "0x000000000000000000000000000000a9efc76daffb8dfe2a39570b2d5d046767", - "0x000000000000000000000000000000000026e7dd89fe96952a4603c2b5555538", - "0x00000000000000000000000000000008262b430328dcaab242dd8acc504e8ac9", - "0x000000000000000000000000000000000015f3ab1410f0e5dd3e00f03b9f563b", - "0x0000000000000000000000000000008fca5ff8ed9a5d41fe9b451f02502dd1c9", - "0x0000000000000000000000000000000000266aa6e4947434ef18adeba3700713", - "0x000000000000000000000000000000d93cecd04341f5da304f3c92f0670afc43", - "0x000000000000000000000000000000000020165b3fd2bfb72a4de3dc68f66eed", - "0x000000000000000000000000000000094a6d376eb3cc1ba94b4da00dea583eac", - "0x00000000000000000000000000000000001caf7742d251b04f3517f0f1e5a625", - "0x0000000000000000000000000000003be5647cd472ad0b06a48f632997e3eea2", - "0x000000000000000000000000000000000015fb4d9ecb8125b3243cee37698c48", - "0x0000000000000000000000000000000854a3ab5bcbca1e86d4949b1b7c5f4b0e", - "0x000000000000000000000000000000000015450314fbf315448dc3379dc82214", - "0x0000000000000000000000000000009c2c55d2ea5bdf5fc5e28f1a78b1d29625", - "0x000000000000000000000000000000000020b36a8406ec64352600587cf04194", - "0x000000000000000000000000000000f14d08d9dab6a54412d741166146188ae6", - "0x00000000000000000000000000000000001b5a34ccd7eaf5cd09ab920011552f", - "0x00000000000000000000000000000074b7827a59faf701f7f41df26e5476c40c", - "0x00000000000000000000000000000000002decbab1c87b933da1625951860793", - "0x000000000000000000000000000000751aab48a0e01094128242ea0aaab63ff7", - "0x00000000000000000000000000000000001a2a334289adf8d23d4d52caf4cfe6", - "0x000000000000000000000000000000f6a41261290460b25e1e7d7bf69b564ae6", - "0x00000000000000000000000000000000000296925feaed4585bb03319f126d96", - "0x00000000000000000000000000000055b70d653ebd7df04f720951e76a27369b", - "0x000000000000000000000000000000000019744937a687edc9f46fb8323a46d9", - "0x00000000000000000000000000000047978fda5b64d8fc4571f09da3e8ccc7de", - "0x0000000000000000000000000000000000139de6a387109f47ecbacc74e03742", - "0x0000000000000000000000000000007f5afdfcb7bcd85aa293676e18e899a03e", - "0x000000000000000000000000000000000006a2971c1c947f4cadb07ebc9bc980", - "0x0000000000000000000000000000006cdb69a57b7f7a25b99e18fc0f83c1bc70", - "0x000000000000000000000000000000000028f2a76a01dc3cc927cdba29383e9b", - "0x0000000000000000000000000000001bbc4d6033de44907975ce473bc0f4f148", - "0x00000000000000000000000000000000002642f26fc1850c4b9b7fc4cd860ab9", - "0x000000000000000000000000000000ac996074e35eb268f6ebbe99e9c7d26c47", - "0x00000000000000000000000000000000002262620617978a01f75646f1909969", - "0x000000000000000000000000000000e63aa32bcc098428f407b5e07d9cb26118", - "0x000000000000000000000000000000000022b294b6a7dc4c17319f9a91a1b443", - "0x000000000000000000000000000000649d9ce9147431632893f55d3c6bbc158e", - "0x000000000000000000000000000000000020698c9b0787f14aa66a57bc232ec1", - "0x000000000000000000000000000000b4fde29f9bde909609d70bf9862dd65cf1", - "0x000000000000000000000000000000000005fcac9b75cac50d87ca827678c070", - "0x00000000000000000000000000000071e27b0a0dd0e2180985072f4a949f0c1d", - "0x000000000000000000000000000000000025d2d1388eddcf016213f1cadc763f", - "0x000000000000000000000000000000b216bad715cdfa7c382d30d7a368cc1346", - "0x0000000000000000000000000000000000302dbbf78b13a6d71d1978b5607145", - "0x00000000000000000000000000000002ebdec49969d2ff9220240bbcb8730617", - "0x000000000000000000000000000000000027f41cad8540e47008c1da90340ef6", - "0x000000000000000000000000000000e8259148321315cc34166a206fe910c6cb", - "0x000000000000000000000000000000000013444efc30c7688d961f36de252af6", - "0x0000000000000000000000000000005b7c7ad432291e9dff1dfad51159e50dbf", - "0x0000000000000000000000000000000000205ec973a0d1c898c1def7852353b3", - "0x0000000000000000000000000000007940a7e88fe5ce47af688975c92be1b62a", - "0x000000000000000000000000000000000015bdab44fe41eec6ee62ed58f55ff5", - "0x0000000000000000000000000000003693b90aedcd664eede665df6f376cf526", - "0x0000000000000000000000000000000000207c38fd6851d1568fe18a83585f31", - "0x000000000000000000000000000000f1a8a60975b9b092aab1421166be08c2f5", - "0x000000000000000000000000000000000015450d2e8ea17db209302582b886f1", - "0x000000000000000000000000000000526e857040a344bd434bfdbf94d3a49196", - "0x00000000000000000000000000000000000d0112b922a852c4754ab3929d6d02", - "0x000000000000000000000000000000d88041fa28c8118a58ceacbcc8780844b5", - "0x00000000000000000000000000000000002584170ebef150b71c5e6aa93e2fbb", - "0x0000000000000000000000000000006363c23486d6a7a313beac4e2d9611968a", - "0x0000000000000000000000000000000000085acee4523161ab1e268a4f0c1b0f", - "0x000000000000000000000000000000b250d5a528a555d96d498fc9af4f8cc5c2", - "0x000000000000000000000000000000000017080f8d1d21b541de1c64d8b794df", - "0x000000000000000000000000000000621557759a0775ea5575adc9c6fbd96d56", - "0x00000000000000000000000000000000001cd60c23a37c42d7e46e1e19e966ae", - "0x0000000000000000000000000000000d52081b2311a7e9bf52407cf3d2c336b3", - "0x0000000000000000000000000000000000003b2312f2f2f419434a1440d40c69", - "0x000000000000000000000000000000d26082083660d6ac8bffb639994e4500e7", - "0x000000000000000000000000000000000019d6ef8ce569e7fa55b8aab7f5eea6", - "0x00000000000000000000000000000078d8a04f7b6c536d3a8a35c790b4dc7ddc", - "0x00000000000000000000000000000000001111470a41156a530334d2c08511a5", - "0x0000000000000000000000000000008ab4119a5478448b7ec3573de2cdfd8e56", - "0x0000000000000000000000000000000000263c7bd4cde5591308156c458d2989", - "0x0000000000000000000000000000004a676142c9eca140ac96ab9ca49633e141", - "0x00000000000000000000000000000000001de62520faa095ad7513f753e0a73e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000a2c4fbcbebac01e208127093cbf44780d4", - "0x00000000000000000000000000000000001ca34545a074b1cb689aa0b343402d", - "0x000000000000000000000000000000a58c28598055d8818a6dbadd0018904386", - "0x0000000000000000000000000000000000152154cbc213630f5c7ec1ee37751b" + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000f944590031f1d3b251c3dc90ea2821c71d", + "0x00000000000000000000000000000000000d31fd1a4942efade625e012c77df1", + "0x0000000000000000000000000000001e9acd89b92c18e3d89b881b26312bb12b", + "0x000000000000000000000000000000000000736f00a23cbea07da614d8b767e4", + "0x00000000000000000000000000000012167fb1f0d3b9afea7d534404e3b36b53", + "0x0000000000000000000000000000000000021e6d056d0d40c720927abd39c872", + "0x0000000000000000000000000000004ea3f0c21ee1056b3e2ad9c082242e5a2e", + "0x00000000000000000000000000000000000c574204fd079871ae599e192d72c8", + "0x0000000000000000000000000000002654c5b2b175f95fdb2ab405dcc4220545", + "0x00000000000000000000000000000000001fd13a35df71290c2354c6c5f610de", + "0x000000000000000000000000000000d5e3b3464d67c82f035b33016912264b04", + "0x000000000000000000000000000000000009fcdab45c12d2f313f95b94a1dcb8", + "0x000000000000000000000000000000768c5a9d8ca0081f67ff3171a7ffe3ba49", + "0x00000000000000000000000000000000001cd676b8d32bb0bb898d83a9f49a2b", + "0x00000000000000000000000000000028650bc3473de217fbfec1e9fb10e4e999", + "0x0000000000000000000000000000000000260c000ea0ebc3db3ba672328007a5", + "0x000000000000000000000000000000f1948fbf68599bf0628f118156de61f57f", + "0x00000000000000000000000000000000000033e796d200425f6a499de18dbfeb", + "0x00000000000000000000000000000016a35cf8fc5f017037adf860723e6346e5", + "0x0000000000000000000000000000000000088cf6d72197800bb1300677f734a7", + "0x00000000000000000000000000000047169c153b6cc24bbac1e4126410779ccb", + "0x000000000000000000000000000000000022b70bfb92e8c7944ae65a49b7effa", + "0x000000000000000000000000000000425c661c37104ad33c2054f3cfde9954d0", + "0x000000000000000000000000000000000000c36b8ecc5963bef022dea4dfadcc", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", + "0x000000000000000000000000000000862e0c485b99696417d296ecc2b2bac316", + "0x00000000000000000000000000000000000ae46fcce211297d2d7fcab27fc041", + "0x000000000000000000000000000000551700c158e12cb40d8ea4ef2563b6fb43", + "0x00000000000000000000000000000000000b515d88939b250a4a4758e4e2ea53", + "0x000000000000000000000000000000f4bae0ad0baeb9d42c7fe2ae3d18c98fad", + "0x00000000000000000000000000000000002a20d66bd435a17fdf1eaf345d5933", + "0x000000000000000000000000000000ed8a8ba528c7088b1ae4730572e1ec32c8", + "0x000000000000000000000000000000000009506de430d6b9f9863e6f10cd35fb", + "0x000000000000000000000000000000682b627744ce0319f4d9191675057282fb", + "0x000000000000000000000000000000000017de059961f8c12752abd299396f86", + "0x000000000000000000000000000000b975958ec262178729e94350c0e7543fb0", + "0x0000000000000000000000000000000000220ce50e394560e53f025e094d17aa", + "0x0000000000000000000000000000001fca3a68a28d438e85e9dc955856752779", + "0x000000000000000000000000000000000028f8f3400bb3b9d19b02ec709e2ee4", + "0x0000000000000000000000000000004e35d073460b0634ebe216d49a3dca9b36", + "0x00000000000000000000000000000000000cb0f5827b08075c405353f10ba632", + "0x0000000000000000000000000000001ece860550ce14fae74eda0123ded56a74", + "0x00000000000000000000000000000000000a34b258bd3daaf8f9edd201c25ed3", + "0x0000000000000000000000000000008cb28ae85d58a75302229585a9ad114c2b", + "0x000000000000000000000000000000000014aac1da344ad32659c3036510fcc1", + "0x000000000000000000000000000000822b45036d5c2befa8a20df910513570c4", + "0x000000000000000000000000000000000011244b388e709fbcb7f54658cfac43", + "0x000000000000000000000000000000389de9951eb8fad7e25e4ad0a9229d2275", + "0x0000000000000000000000000000000000136e6eb0ee251f9b12336cb7bb46ee", + "0x00000000000000000000000000000088f21d9f6c7c54ce4e9a4c103a91b54a58", + "0x0000000000000000000000000000000000187f2beab9a05ca29d2137ee7cbc19", + "0x0000000000000000000000000000009c703a5eb43dcef0686e08fa57ef452f68", + "0x000000000000000000000000000000000012caebb183f1490d3e4f2a2c583ab6", + "0x0000000000000000000000000000009dab4a0aa8d4954a8e1761db3da148a746", + "0x0000000000000000000000000000000000230a08da3b62fd6479b4230760b686", + "0x00000000000000000000000000000081a00a1e38bbd5212603f18ef982a5189d", + "0x000000000000000000000000000000000021ae0f9df38f1e70fa3c26867f4ee8", + "0x0000000000000000000000000000001a722dbd34f841b4823cd055149fce642f", + "0x000000000000000000000000000000000002df2693a9b134670cfe72bf29b363", + "0x00000000000000000000000000000007c906c328630b844b0797e34cedccd1ec", + "0x00000000000000000000000000000000002ab2ae39dd9c0259f7dfb1dda47e81", + "0x000000000000000000000000000000ac6642a4923aa2df07a00a9d3e462b0ed1", + "0x000000000000000000000000000000000015afb7af6c0fc23a24457aa887df9c", + "0x0000000000000000000000000000004d916ec23ef29c0b6134f208e3535671d4", + "0x00000000000000000000000000000000000d37c6c25852903d79475133d414e8", + "0x00000000000000000000000000000029ad212431ba1972de7ee0ba9f12113be3", + "0x000000000000000000000000000000000005c2393db23155844d4f71bead84d0", + "0x000000000000000000000000000000c69074efa82a4910eaf8ab8689d7aafcad", + "0x000000000000000000000000000000000029f3d77437006a0eacf1a149c4b8a0", + "0x00000000000000000000000000000030926853da69d4016eca2f1f0df5e5316f", + "0x000000000000000000000000000000000014841d3291aecd45ea0e05657dbed2", + "0x00000000000000000000000000000052fdb060fe666a3f686088f1f6996a1cf9", + "0x00000000000000000000000000000000002be878eb09939603b391aa9ee0393a", + "0x000000000000000000000000000000d99de3b49476e64c0138037838cfc63803", + "0x0000000000000000000000000000000000260874b43f32c373783efe7ef200a2", + "0x0000000000000000000000000000004951edbb25e9c6b65d446e3418b2b3f16e", + "0x00000000000000000000000000000000002300fac13ab48d40a91114d1ff9627", + "0x00000000000000000000000000000090b8d216da73861ee276dddb17428d8c09", + "0x000000000000000000000000000000000028f906106984e5fa78812869cc1aee", + "0x000000000000000000000000000000ce2aff6eda49d5b8be6ee42104d2aa21e0", + "0x000000000000000000000000000000000002833f671993d2b772b5dec0e12056", + "0x0000000000000000000000000000008be4e7cfb1fdf317a33b7bc3530625e6b8", + "0x000000000000000000000000000000000023404bed8e224a350755410e5c96b2", + "0x000000000000000000000000000000cd9a812fad3fe3a89983e416b70529445b", + "0x00000000000000000000000000000000000b66296ff191a2cf6dbe6ca03dcd0c", + "0x0000000000000000000000000000005eefcb3c6f69064ed55425945fcc74c2bc", + "0x00000000000000000000000000000000001613278bd29c20c182e6f3b5e367ce", + "0x0000000000000000000000000000006c39d4dd8c65752b9bc2628fcc3dbf415c", + "0x00000000000000000000000000000000000d4b721e385647b57de3efbc9952db", + "0x000000000000000000000000000000e26e87fb5ad793c153110c1e55129d9ee7", + "0x00000000000000000000000000000000001986fe851f46fd25818f580f9d55f1", + "0x0000000000000000000000000000007a7eb895f6f2419aafb58de3f81b3f6739", + "0x00000000000000000000000000000000000d1289085013119c588fbcdbb11f5e", + "0x00000000000000000000000000000061358ce9820bc7ced39ca91d017f767cfa", + "0x000000000000000000000000000000000018a26c04d92048605adf6b40fbe696", + "0x000000000000000000000000000000924ee754d49e43f0991a540ece79958ad1", + "0x00000000000000000000000000000000001faa0f64d400addf955b2f4a8181ec", + "0x0000000000000000000000000000000c13651a87f101a4d0bf32619d4326c45b", + "0x000000000000000000000000000000000002809feb719732fbf341dd249e671d", + "0x0000000000000000000000000000003523e8c751d17a4dcd30540a4f9261403b", + "0x00000000000000000000000000000000001466cc1bd7c1743fca0477c4ea4481", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003e895e3756deb16393c59a6a9d3669ce0f", + "0x0000000000000000000000000000000000262d7f27b9058ca9bd2e0620f9a3d3", + "0x000000000000000000000000000000b98c4ce00d755cb57daf4bc1b860536fc3", + "0x0000000000000000000000000000000000017137ecc6753555f49859a34eeb62" ] - hash = "0x0c9b0fab06de495eb1835dc184eb51d6584a970a90bb9c9dba17ab97e9b6dee6" + hash = "0x05df4d5edfe80160c2f684f683ed1ef5fb3a539be4cfb97957b2d7f5c3ab9ead" diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr index 58b47bf68d13..00910d1f1907 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr @@ -1,15 +1,20 @@ -use crate::{point::Point, traits::{Deserialize, Empty, Serialize}}; +use crate::traits::{Deserialize, Empty, Serialize}; use std::meta::derive; +/// A request from an app circuit to the kernel for validation of a siloed app secret key. +/// +/// The master public key is exposed only as its [`hash_public_key`](crate::public_keys::hash_public_key) digest -- apps +/// must not see the raw point. The kernel reset circuit derives the point from the master secret +/// key hint, hashes it, and asserts equality with `pk_m_hash`. #[derive(Deserialize, Eq, Serialize)] pub struct KeyValidationRequest { - pub pk_m: Point, + pub pk_m_hash: Field, pub sk_app: Field, // not a grumpkin scalar because it's output of poseidon2 } impl Empty for KeyValidationRequest { fn empty() -> Self { - KeyValidationRequest { pk_m: Point::empty(), sk_app: 0 } + KeyValidationRequest { pk_m_hash: 0, sk_app: 0 } } } @@ -17,15 +22,12 @@ mod test { use crate::{ abis::validation_requests::key_validation_request::KeyValidationRequest, constants::KEY_VALIDATION_REQUEST_LENGTH, - point::Point, traits::{Deserialize, Serialize}, }; #[test] fn serialization_of_key_validation_request() { - let item = KeyValidationRequest { pk_m: Point::deserialize([123, 456, 0]), sk_app: 789 }; - // We use the KEY_VALIDATION_REQUEST_LENGTH constant to ensure that there is a match between the derived trait - // implementation and the constant. + let item = KeyValidationRequest { pk_m_hash: 123, sk_app: 789 }; let serialized: [Field; KEY_VALIDATION_REQUEST_LENGTH] = item.serialize(); let deserialized = KeyValidationRequest::deserialize(serialized); assert_eq(item, deserialized); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_separator.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_separator.nr index 55cdaa6a4b1e..ca4f7e1b93b2 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_separator.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_separator.nr @@ -34,14 +34,13 @@ mod test { key_validation_request_and_separator::KeyValidationRequestAndSeparator, }, constants::KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH, - point::Point, traits::{Deserialize, Serialize}, }; #[test] fn serialization_of_key_validation_request_and_separator() { let non_empty_item = KeyValidationRequestAndSeparator { - request: KeyValidationRequest { pk_m: Point::deserialize([123, 456, 0]), sk_app: 789 }, + request: KeyValidationRequest { pk_m_hash: 123, sk_app: 789 }, key_type_domain_separator: 789, }; let serialized: [Field; KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH] = diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr index 312ae5bb5c58..fc6063570354 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr @@ -2,15 +2,15 @@ use crate::{ address::{ partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash, }, - constants::{AZTEC_ADDRESS_LENGTH, DOM_SEP__CONTRACT_ADDRESS_V1, MAX_FIELD_VALUE}, + constants::{AZTEC_ADDRESS_LENGTH, DOM_SEP__CONTRACT_ADDRESS_V2, MAX_FIELD_VALUE}, contract_class_id::ContractClassId, hash::poseidon2_hash_with_separator, - public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, ToPoint, TpkM}, + public_keys::{hash_public_key, IvpkM, PublicKeys, ToPoint}, traits::{Deserialize, Empty, FromField, Packable, Serialize, ToField}, utils::field::sqrt, }; -use crate::point::Point; +use crate::point::EmbeddedCurvePoint; use crate::public_keys::AddressPoint; use std::{ @@ -66,7 +66,7 @@ impl AztecAddress { // positive one (where y <= (r - 1) / 2) by negating it. let final_y = if Self::is_positive(y) { y } else { -y }; - AddressPoint { inner: Point { x: self.inner, y: final_y, is_infinite: false } } + AddressPoint { inner: EmbeddedCurvePoint { x: self.inner, y: final_y } } }) } @@ -112,15 +112,15 @@ impl AztecAddress { // / \ . // / \ . // partial_address public_keys_hash . - // / \ / / \ \ . - // / \ Npk_m Ivpk_m Ovpk_m Tpk_m . + // / \ / / \ \ . + // / \ npk_m_hash Ivpk_m ovpk_m_hash tpk_m_hash // contract_class_id \ |................... // / | \ \ - // artifact_hash | public_bytecode_commitment salted_initialization_hash - // | / / \ - // private_function_tree_root deployer_address salt initialization_hash - // / \ / \ - // ... ... constructor_fn_selector constructor_args_hash + // artifact_hash | public_bytecode_commitment salted_initialization_hash + // | / / \ \ + // private_function_tree_root salt initialization_hash deployer_address immutables_hash + // / \ / \ + // ... ... constructor_fn_selector constructor_args_hash // / \ // / \ / \ // leaf leaf leaf leaf @@ -134,15 +134,13 @@ impl AztecAddress { let pre_address = poseidon2_hash_with_separator( [public_keys_hash.to_field(), partial_address.to_field()], - DOM_SEP__CONTRACT_ADDRESS_V1, + DOM_SEP__CONTRACT_ADDRESS_V2, ); // Note: `.add()` will fail within the blackbox fn if either of the points are not on the curve. (See tests below). - // TODO(F-553): Drop the `.to_embedded()` / `.into()` round-trip once the custom `Point` wrapper is removed and - // we use `EmbeddedCurvePoint` directly. - let address_point: Point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)) - .add(public_keys.ivpk_m.to_point().to_embedded()) - .into(); + let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add( + public_keys.ivpk_m.to_point(), + ); // 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 // 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. @@ -195,73 +193,55 @@ fn check_is_positive() { // because the blackbox function does this check for us. #[test(should_fail_with = "is not on curve")] fn check_embedded_curve_point_add() { - // Choose a point not on the curve: - let p1 = Point { x: 1, y: 1, is_infinite: false }; - let p2 = Point::generator(); - let _ = p1 + p2; -} - -// Gives us confidence that we don't need to manually check that the input public keys need to be on the curve for `add`, -// because the blackbox function does this check for us. -#[test(should_fail_with = "is not on curve")] -fn check_embedded_curve_point_add_2() { // Choose a point not on the curve in the 2nd position. - let p1 = Point::generator(); - let p2 = Point { x: 1, y: 1, is_infinite: false }; - let _ = p1 + p2; + let p1 = EmbeddedCurvePoint::generator(); + let key = IvpkM { inner: EmbeddedCurvePoint { x: 1, y: 1 } }; + let _ = p1 + key.to_point(); } #[test] fn compute_address_from_partial_and_pub_keys() { + let npk_m_point = EmbeddedCurvePoint { + x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab, + y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7, + }; + let ovpk_m_point = EmbeddedCurvePoint { + x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484, + y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b, + }; + let tpk_m_point = EmbeddedCurvePoint { + x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762, + y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a, + }; + let public_keys = PublicKeys { - npk_m: NpkM { - inner: Point { - x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab, - y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7, - is_infinite: false, - }, - }, + npk_m_hash: hash_public_key(npk_m_point), ivpk_m: IvpkM { - inner: Point { + inner: EmbeddedCurvePoint { x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e, y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95, - is_infinite: false, - }, - }, - ovpk_m: OvpkM { - inner: Point { - x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484, - y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b, - is_infinite: false, - }, - }, - tpk_m: TpkM { - inner: Point { - x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762, - y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a, - is_infinite: false, }, }, + ovpk_m_hash: hash_public_key(ovpk_m_point), + tpk_m_hash: hash_public_key(tpk_m_point), }; let partial_address = PartialAddress::from_field( 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de, ); - let address = AztecAddress::compute(public_keys, partial_address); + let address = AztecAddress::compute(public_keys, partial_address).to_field(); - // The following value was generated by `derivation.test.ts`. - // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data. let expected_computed_address_from_partial_and_pubkeys = - 0x2f66081d4bb077fbe8e8abe96a3516a713a3d7e34360b4e985da0da95092b37d; - assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys); + 0x05f9c48c02e4dbd18d7e165f999c3b8426abb1911476f48e68deef42475d6145; + assert_eq(address, expected_computed_address_from_partial_and_pubkeys); } #[test] fn compute_preaddress_from_partial_and_pub_keys() { - let pre_address = poseidon2_hash_with_separator([1, 2], DOM_SEP__CONTRACT_ADDRESS_V1); + let pre_address = poseidon2_hash_with_separator([1, 2], DOM_SEP__CONTRACT_ADDRESS_V2); let expected_computed_preaddress_from_partial_and_pubkey = - 0x286c7755f2924b1e53b00bcaf1adaffe7287bd74bba7a02f4ab867e3892d28da; + 0x0fa1c698858df1a99170cd39d5f4bfad6d0d60f1f8afa3dc92281ee60b36f3bb; assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr index e2698c8475e7..cd5f1f9fb95f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr @@ -35,10 +35,11 @@ impl PartialAddress { salt: Field, initialization_hash: Field, deployer: AztecAddress, + immutables_hash: Field, ) -> Self { PartialAddress::compute_from_salted_initialization_hash( contract_class_id, - SaltedInitializationHash::compute(salt, initialization_hash, deployer), + SaltedInitializationHash::compute(salt, initialization_hash, deployer, immutables_hash), ) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr index 4f09babab178..8b50410bfabd 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr @@ -20,9 +20,14 @@ impl SaltedInitializationHash { Self { inner: field } } - pub fn compute(salt: Field, initialization_hash: Field, deployer: AztecAddress) -> Self { + pub fn compute( + salt: Field, + initialization_hash: Field, + deployer: AztecAddress, + immutables_hash: Field, + ) -> Self { SaltedInitializationHash::from_field(poseidon2_hash_with_separator( - [salt, initialization_hash, deployer.to_field()], + [salt, initialization_hash, deployer.to_field(), immutables_hash], DOM_SEP__SALTED_INITIALIZATION_HASH, )) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 027f1e7ef243..d204616a106b 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -291,6 +291,16 @@ pub global DEFAULT_TPK_M_X: Field = pub global DEFAULT_TPK_M_Y: Field = 0x2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f; +// Precomputed `hash_public_key(Point { DEFAULT_*_X, DEFAULT_*_Y })` for each non-ivpk key. +// Used by `PublicKeys::default()` and the matching TS `PublicKeys.default()`. Verified by the +// `compute_default_hash` test in public_keys.nr. +pub global DEFAULT_NPK_M_HASH: Field = + 0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26; +pub global DEFAULT_OVPK_M_HASH: Field = + 0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b; +pub global DEFAULT_TPK_M_HASH: Field = + 0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0; + // LENGTH OF STRUCTS SERIALIZED TO FIELDS // TODO: figure out whether Noir is sophisticated enough to derive these for us, these days. pub global AZTEC_ADDRESS_LENGTH: u32 = 1; @@ -301,7 +311,7 @@ pub global GAS_SETTINGS_LENGTH: u32 = GAS_LENGTH /* gas_limits */ + GAS_FEES_LENGTH /* max_fees_per_gas */ + GAS_FEES_LENGTH /* max_priority_fees_per_gas */; pub global CALL_CONTEXT_LENGTH: u32 = 4; -pub global CONTRACT_INSTANCE_LENGTH: u32 = 16; +pub global CONTRACT_INSTANCE_LENGTH: u32 = 10; pub global CONTRACT_STORAGE_READ_LENGTH: u32 = 3; pub global CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: u32 = 3; pub global ETH_ADDRESS_LENGTH: u32 = 1; @@ -329,7 +339,7 @@ pub global L2_TO_L1_MESSAGE_LENGTH: u32 = 1 /* recipient */ + 1 /* content */; pub global COUNTED_L2_TO_L1_MESSAGE_LENGTH: u32 = L2_TO_L1_MESSAGE_LENGTH + 1; pub global SCOPED_L2_TO_L1_MESSAGE_LENGTH: u32 = L2_TO_L1_MESSAGE_LENGTH + 1; pub global SCOPED_COUNTED_L2_TO_L1_MESSAGE_LENGTH: u32 = COUNTED_L2_TO_L1_MESSAGE_LENGTH + 1; -pub global KEY_VALIDATION_REQUEST_LENGTH: u32 = 4; +pub global KEY_VALIDATION_REQUEST_LENGTH: u32 = 2; pub global KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = KEY_VALIDATION_REQUEST_LENGTH + 1; pub global SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH + 1; @@ -748,11 +758,12 @@ pub global DOM_SEP__IVSK_M: u32 = 2747825907; pub global DOM_SEP__OVSK_M: u32 = 4272201051; pub global DOM_SEP__TSK_M: u32 = 1546190975; pub global DOM_SEP__PUBLIC_KEYS_HASH: u32 = 777457226; +pub global DOM_SEP__SINGLE_PUBLIC_KEY_HASH: u32 = 3452068255; // Address pub global DOM_SEP__PARTIAL_ADDRESS: u32 = 2103633018; -pub global DOM_SEP__CONTRACT_ADDRESS_V1: u32 = 1788365517; +pub global DOM_SEP__CONTRACT_ADDRESS_V2: u32 = 4099338721; // --------------------------------------------------------------- @@ -1240,7 +1251,7 @@ pub global AVM_DEBUGLOG_BASE_L2_GAS: u32 = 9; pub global AVM_POSEIDON2_BASE_L2_GAS: u32 = 24 * 15; // SLOW_SIM_MUL = 15 pub global AVM_SHA256COMPRESSION_BASE_L2_GAS: u32 = 12288; pub global AVM_KECCAKF1600_BASE_L2_GAS: u32 = 58176; -pub global AVM_ECADD_BASE_L2_GAS: u32 = 27 * 10; // SLOW_SIM_MUL = 10 +pub global AVM_ECADD_BASE_L2_GAS: u32 = 18 * 10; // SLOW_SIM_MUL = 10 pub global AVM_TORADIXBE_BASE_L2_GAS: u32 = 24; // Dynamic L2 GAS diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr index e4415d7b4b95..24f79b64b047 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -9,11 +9,11 @@ use crate::{ DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_NULLIFIER, DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOB_CHALLENGE_Z, DOM_SEP__BLOB_GAMMA_ACC, DOM_SEP__BLOB_GAMMA_FINAL, DOM_SEP__BLOB_HASHED_Y_LIMBS, DOM_SEP__BLOB_Z_ACC, - DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONTRACT_ADDRESS_V1, + DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONTRACT_ADDRESS_V2, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FUNCTION_ARGS, - DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, - DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, + DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, DOM_SEP__IVSK_M, + DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, @@ -25,9 +25,10 @@ use crate::{ DOM_SEP__PUBLIC_LEAF_SLOT, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, DOM_SEP__PUBLIC_TX_HASH, DOM_SEP__RETRIEVED_BYTECODES_MERKLE, DOM_SEP__SALTED_INITIALIZATION_HASH, DOM_SEP__SECRET_HASH, DOM_SEP__SIGNATURE_PAYLOAD, DOM_SEP__SILOED_NOTE_HASH, - DOM_SEP__SILOED_NULLIFIER, DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, DOM_SEP__TSK_M, - DOM_SEP__TX_NULLIFIER, DOM_SEP__TX_REQUEST, DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, - DOM_SEP__UNIQUE_NOTE_HASH, DOM_SEP__WRITTEN_SLOTS_MERKLE, NULL_MSG_SENDER_CONTRACT_ADDRESS, + DOM_SEP__SILOED_NULLIFIER, DOM_SEP__SINGLE_PUBLIC_KEY_HASH, + DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, DOM_SEP__TSK_M, DOM_SEP__TX_NULLIFIER, + DOM_SEP__TX_REQUEST, DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, DOM_SEP__UNIQUE_NOTE_HASH, + DOM_SEP__WRITTEN_SLOTS_MERKLE, NULL_MSG_SENDER_CONTRACT_ADDRESS, SIDE_EFFECT_MASKING_ADDRESS, TX_START_PREFIX, }, hash::poseidon2_hash_bytes, @@ -142,7 +143,7 @@ impl HashedValueTester::new(); + let mut tester = HashedValueTester::<71, 64>::new(); // ----------------- // Domain separators @@ -193,8 +194,9 @@ fn hashed_values_match_derived() { tester.assert_dom_sep_matches_derived(DOM_SEP__OVSK_M, "ovsk_m"); tester.assert_dom_sep_matches_derived(DOM_SEP__TSK_M, "tsk_m"); tester.assert_dom_sep_matches_derived(DOM_SEP__PUBLIC_KEYS_HASH, "public_keys_hash"); + tester.assert_dom_sep_matches_derived(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, "single_public_key_hash"); tester.assert_dom_sep_matches_derived(DOM_SEP__PARTIAL_ADDRESS, "partial_address"); - tester.assert_dom_sep_matches_derived(DOM_SEP__CONTRACT_ADDRESS_V1, "contract_address_v1"); + tester.assert_dom_sep_matches_derived(DOM_SEP__CONTRACT_ADDRESS_V2, "contract_address_v2"); tester.assert_dom_sep_matches_derived(DOM_SEP__BLOCK_HEADER_HASH, "block_header_hash"); tester.assert_dom_sep_matches_derived(DOM_SEP__TX_REQUEST, "tx_request"); tester.assert_dom_sep_matches_derived(DOM_SEP__PUBLIC_TX_HASH, "public_tx_hash"); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr b/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr index fa2ce232d0a3..f96851c0d0a1 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr @@ -12,6 +12,7 @@ pub struct ContractInstance { pub deployer: AztecAddress, pub contract_class_id: ContractClassId, pub initialization_hash: Field, + pub immutables_hash: Field, pub public_keys: PublicKeys, } @@ -30,6 +31,7 @@ impl ContractInstance { self.salt, self.initialization_hash, self.deployer, + self.immutables_hash, ), ) } @@ -52,6 +54,7 @@ mod test { deployer: AztecAddress::from_field(12), contract_class_id: ContractClassId::from_field(13), initialization_hash: 156, + immutables_hash: 789, public_keys: PublicKeys::default(), }; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/point.nr b/noir-projects/noir-protocol-circuits/crates/types/src/point.nr index 289ee5fcb2b1..c5ea3b076b2c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/point.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/point.nr @@ -1,174 +1,12 @@ -use crate::{ - hash::poseidon2_hash, - traits::{Deserialize, Empty, Hash, Packable, Serialize}, - utils::{reader::Reader, writer::Writer}, -}; -use std::embedded_curve_ops::EmbeddedCurvePoint; +pub use std::embedded_curve_ops::EmbeddedCurvePoint; -pub global POINT_LENGTH: u32 = 3; - -// TODO(F-553): This custom `Point` struct is a temporary workaround. A newer version of Noir dropped the `is_infinite` -// field from `EmbeddedCurvePoint` and changed its serialization from 3 fields to 2. To preserve backwards compatibility -// of our onchain serialization format we re-introduced our own `Point` that wraps `EmbeddedCurvePoint` and keeps the -// old 3-field layout. Once we're ready to take the breaking change (e.g. alongside the v5 oracle changes), delete this -// struct, use `EmbeddedCurvePoint` directly and reduce `POINT_LENGTH` to 2. -pub struct Point { - pub x: Field, - pub y: Field, - pub is_infinite: bool, -} - -impl Point { - pub fn generator() -> Self { - let g = EmbeddedCurvePoint::generator(); - Point { x: g.x, y: g.y, is_infinite: false } - } - - pub fn point_at_infinity() -> Self { - Point { x: 0, y: 0, is_infinite: true } - } - - pub fn double(self) -> Self { - self.to_embedded().double().into() - } - - pub fn to_embedded(self) -> EmbeddedCurvePoint { - EmbeddedCurvePoint { x: self.x, y: self.y } - } -} - -impl From for Point { - fn from(p: EmbeddedCurvePoint) -> Self { - Point { x: p.x, y: p.y, is_infinite: p.is_infinite() } - } -} - -impl std::ops::Add for Point { - fn add(self, other: Point) -> Point { - (self.to_embedded() + other.to_embedded()).into() - } -} - -impl std::ops::Sub for Point { - fn sub(self, other: Point) -> Point { - (self.to_embedded() - other.to_embedded()).into() - } -} - -impl std::ops::Neg for Point { - fn neg(self) -> Point { - Point { x: self.x, y: -self.y, is_infinite: self.is_infinite } - } -} - -impl Eq for Point { - fn eq(self, other: Point) -> bool { - (self.x == other.x) & (self.y == other.y) & (self.is_infinite == other.is_infinite) - } -} - -impl Hash for Point { - fn hash(self) -> Field { - poseidon2_hash(self.serialize()) - } -} - -impl Empty for Point { - /// Note: Does not return a valid point on curve - instead represents an empty/"unpopulated" point struct (e.g. - /// empty/unpopulated value in an array of points). - fn empty() -> Self { - Point { x: 0, y: 0, is_infinite: false } - } -} - -impl Serialize for Point { - let N: u32 = POINT_LENGTH; - - fn serialize(self) -> [Field; Self::N] { - [self.x, self.y, self.is_infinite as Field] - } - - fn stream_serialize(self, writer: &mut Writer) { - writer.write(self.x); - writer.write(self.y); - writer.write(self.is_infinite as Field); - } -} - -impl Deserialize for Point { - let N: u32 = POINT_LENGTH; - - fn deserialize(fields: [Field; Self::N]) -> Self { - Point { x: fields[0], y: fields[1], is_infinite: fields[2] != 0 } - } - - #[inline_always] - fn stream_deserialize(reader: &mut Reader) -> Self { - Point { x: reader.read(), y: reader.read(), is_infinite: reader.read_bool() } - } -} - -pub fn validate_on_curve(p: Point) { +/// Validates that the given point exists on the Grumpkin curve. +pub fn validate_on_curve(p: EmbeddedCurvePoint) { // y^2 == x^3 - 17 let x = p.x; let y = p.y; - if p.is_infinite { - // Assert the canonical representation of infinity - assert_eq(x, 0, "Point at infinity should have canonical representation (0 0)"); - assert_eq(y, 0, "Point at infinity should have canonical representation (0 0)"); - } else { + // p.is_infinite() <==> x == y == 0, considered on the curve: + if !p.is_infinite() { assert_eq(y * y, x * x * x - 17, "Point not on curve"); } } - -// TODO(#11356): use compact representation here. -impl Packable for Point { - let N: u32 = POINT_LENGTH; - - fn pack(self) -> [Field; Self::N] { - self.serialize() - } - - fn unpack(packed: [Field; Self::N]) -> Self { - Self::deserialize(packed) - } -} - -mod tests { - use super::{Point, validate_on_curve}; - - #[test] - unconstrained fn test_validate_on_curve_generator() { - // The generator point should be on the curve - let generator = Point::generator(); - validate_on_curve(generator); - } - - #[test] - unconstrained fn test_validate_on_curve_infinity() { - // Canonical infinite point (x=0, y=0) should pass - let infinity = Point { x: 0, y: 0, is_infinite: true }; - validate_on_curve(infinity); - } - - #[test(should_fail_with = "Point not on curve")] - unconstrained fn test_validate_on_curve_invalid_point() { - // A point not on the curve should fail - let invalid = Point { x: 1, y: 1, is_infinite: false }; - validate_on_curve(invalid); - } - - #[test(should_fail_with = "Point at infinity should have canonical representation (0 0)")] - unconstrained fn test_validate_on_curve_infinity_non_canonical_x() { - // Infinite point with non-zero x should fail - let invalid_infinity = Point { x: 1, y: 0, is_infinite: true }; - validate_on_curve(invalid_infinity); - } - - #[test(should_fail_with = "Point at infinity should have canonical representation (0 0)")] - unconstrained fn test_validate_on_curve_infinity_non_canonical_y() { - // Infinite point with non-zero y should fail - let invalid_infinity = Point { x: 0, y: 1, is_infinite: true }; - validate_on_curve(invalid_infinity); - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr b/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr index 4aa7bdd77d45..c312b1a557f8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr @@ -1,101 +1,67 @@ use crate::{ address::public_keys_hash::PublicKeysHash, constants::{ - DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, DEFAULT_NPK_M_X, DEFAULT_NPK_M_Y, DEFAULT_OVPK_M_X, - DEFAULT_OVPK_M_Y, DEFAULT_TPK_M_X, DEFAULT_TPK_M_Y, DOM_SEP__PUBLIC_KEYS_HASH, + DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, DEFAULT_NPK_M_HASH, DEFAULT_OVPK_M_HASH, + DEFAULT_TPK_M_HASH, DOM_SEP__PUBLIC_KEYS_HASH, DOM_SEP__SINGLE_PUBLIC_KEY_HASH, }, hash::poseidon2_hash_with_separator, - point::validate_on_curve, + point::{EmbeddedCurvePoint, validate_on_curve}, traits::{Deserialize, Hash, Serialize}, }; -use crate::point::Point; use std::{default::Default, meta::derive}; pub trait ToPoint { - fn to_point(self) -> Point; + fn to_point(self) -> EmbeddedCurvePoint; } -#[derive(Deserialize, Eq, Serialize)] -pub struct NpkM { - pub inner: Point, -} - -impl ToPoint for NpkM { - fn to_point(self) -> Point { - self.inner - } -} - -// Note: If we store npk_m_hash directly we can remove this trait implementation. See #8091 -impl Hash for NpkM { - fn hash(self) -> Field { - self.inner.hash() - } +/// Hashes a public key point under the canonical single-public-key domain separator. +/// +/// Defined as `Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, x, y)`. +pub fn hash_public_key(p: EmbeddedCurvePoint) -> Field { + poseidon2_hash_with_separator([p.x, p.y], DOM_SEP__SINGLE_PUBLIC_KEY_HASH as Field) } #[derive(Deserialize, Eq, Serialize)] pub struct IvpkM { - pub inner: Point, + pub inner: EmbeddedCurvePoint, } impl ToPoint for IvpkM { - fn to_point(self) -> Point { + fn to_point(self) -> EmbeddedCurvePoint { self.inner } } -#[derive(Deserialize, Eq, Serialize)] -pub struct OvpkM { - pub inner: Point, -} - -impl Hash for OvpkM { +impl Hash for IvpkM { fn hash(self) -> Field { - self.inner.hash() - } -} - -impl ToPoint for OvpkM { - fn to_point(self) -> Point { - self.inner - } -} - -#[derive(Deserialize, Eq, Serialize)] -pub struct TpkM { - pub inner: Point, -} - -impl ToPoint for TpkM { - fn to_point(self) -> Point { - self.inner + hash_public_key(self.inner) } } +/// A non-owner's view of an account's master public keys. +/// +/// `npk_m_hash`, `ovpk_m_hash`, and `tpk_m_hash` are the [`hash_public_key`] digests of the +/// underlying points. The points themselves are not exposed here -- they are only known to the +/// owner. `ivpk_m` remains a point because address derivation (encrypt-to-address) requires the +/// raw point in-circuit. #[derive(Deserialize, Eq, Serialize)] pub struct PublicKeys { - pub npk_m: NpkM, + pub npk_m_hash: Field, pub ivpk_m: IvpkM, - pub ovpk_m: OvpkM, - pub tpk_m: TpkM, + pub ovpk_m_hash: Field, + pub tpk_m_hash: Field, } impl Default for PublicKeys { fn default() -> Self { PublicKeys { - npk_m: NpkM { - inner: Point { x: DEFAULT_NPK_M_X, y: DEFAULT_NPK_M_Y, is_infinite: false }, - }, + npk_m_hash: DEFAULT_NPK_M_HASH, ivpk_m: IvpkM { - inner: Point { x: DEFAULT_IVPK_M_X, y: DEFAULT_IVPK_M_Y, is_infinite: false }, - }, - ovpk_m: OvpkM { - inner: Point { x: DEFAULT_OVPK_M_X, y: DEFAULT_OVPK_M_Y, is_infinite: false }, - }, - tpk_m: TpkM { - inner: Point { x: DEFAULT_TPK_M_X, y: DEFAULT_TPK_M_Y, is_infinite: false }, + inner: EmbeddedCurvePoint { x: DEFAULT_IVPK_M_X, y: DEFAULT_IVPK_M_Y }, }, + ovpk_m_hash: DEFAULT_OVPK_M_HASH, + tpk_m_hash: DEFAULT_TPK_M_HASH, } } } @@ -103,70 +69,97 @@ impl Default for PublicKeys { impl PublicKeys { pub fn hash(self) -> PublicKeysHash { PublicKeysHash::from_field(poseidon2_hash_with_separator( - self.serialize(), + [self.npk_m_hash, self.ivpk_m.hash(), self.ovpk_m_hash, self.tpk_m_hash], DOM_SEP__PUBLIC_KEYS_HASH as Field, )) } + /// Validates that the (only) point-form key, `ivpk_m`, lies on the Grumpkin curve. + /// + /// The other three keys are exposed only as hashes and are unverifiable on-circuit; the PXE + /// is responsible for ensuring they were derived from on-curve points before persistence. pub fn validate_on_curve(self) { - validate_on_curve(self.npk_m.inner); validate_on_curve(self.ivpk_m.inner); - validate_on_curve(self.ovpk_m.inner); - validate_on_curve(self.tpk_m.inner); } + /// Validates that `ivpk_m` is not the point at infinity. + /// + /// As with [`Self::validate_on_curve`], the other three keys are now exposed only as hashes + /// and this property must be enforced PXE-side. pub fn validate_non_infinity(self) { - assert_eq(self.npk_m.inner.is_infinite, false, "NpkM is the point at infinity"); - assert_eq(self.ivpk_m.inner.is_infinite, false, "IvpkM is the point at infinity"); - assert_eq(self.ovpk_m.inner.is_infinite, false, "OvpkM is the point at infinity"); - assert_eq(self.tpk_m.inner.is_infinite, false, "TpkM is the point at infinity"); + assert_eq(self.ivpk_m.inner.is_infinite(), false, "IvpkM is the point at infinity"); } } pub struct AddressPoint { - pub inner: Point, + pub inner: EmbeddedCurvePoint, } impl ToPoint for AddressPoint { - fn to_point(self) -> Point { + fn to_point(self) -> EmbeddedCurvePoint { self.inner } } mod test { - use crate::point::Point; + use crate::constants::{ + DEFAULT_NPK_M_HASH, DEFAULT_NPK_M_X, DEFAULT_NPK_M_Y, DEFAULT_OVPK_M_HASH, DEFAULT_OVPK_M_X, + DEFAULT_OVPK_M_Y, DEFAULT_TPK_M_HASH, DEFAULT_TPK_M_X, DEFAULT_TPK_M_Y, + }; use crate::{ - point::POINT_LENGTH, - public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, TpkM}, + point::EmbeddedCurvePoint, + public_keys::{hash_public_key, IvpkM, PublicKeys}, traits::{Deserialize, Serialize}, }; - use std::ops::Neg; + + global PUBLIC_KEYS_LENGTH: u32 = 5; + + /// Catches drift between the precomputed `DEFAULT_*_M_HASH` constants and the + /// `DEFAULT_*_M_X/Y` curve points they're derived from. If anyone updates the X/Y + /// constants (or the hashing primitive) without also updating the *_HASH constants, + /// this test fails and `PublicKeys::default()` would silently produce a stale value. + #[test] + unconstrained fn default_hashes_match_default_points() { + let npk = hash_public_key( + EmbeddedCurvePoint { x: DEFAULT_NPK_M_X, y: DEFAULT_NPK_M_Y }, + ); + assert_eq(npk, DEFAULT_NPK_M_HASH); + + let ovpk = hash_public_key( + EmbeddedCurvePoint { x: DEFAULT_OVPK_M_X, y: DEFAULT_OVPK_M_Y }, + ); + assert_eq(ovpk, DEFAULT_OVPK_M_HASH); + + let tpk = hash_public_key( + EmbeddedCurvePoint { x: DEFAULT_TPK_M_X, y: DEFAULT_TPK_M_Y }, + ); + assert_eq(tpk, DEFAULT_TPK_M_HASH); + } #[test] unconstrained fn compute_public_keys_hash() { let keys = PublicKeys { - npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } }, - ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } }, - ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } }, - tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } }, + npk_m_hash: 11, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } }, + ovpk_m_hash: 22, + tpk_m_hash: 33, }; - let actual = keys.hash(); + let actual = keys.hash().to_field(); - // The following value was generated by `public_keys.test.ts`. let expected_public_keys_hash = - 0x056998309f6c119e4d753e404f94fef859dddfa530a9379634ceb0854b29bf7a; + 0x0b8c7b67576d3ac859a7fab578b2b2e305c67eba9e133b0fa46af8d19a50b8fc; - assert(actual.to_field() == expected_public_keys_hash); + assert_eq(actual, expected_public_keys_hash); } #[test] unconstrained fn test_validate_on_curve() { let keys = PublicKeys { - npk_m: NpkM { inner: Point::generator() }, - ivpk_m: IvpkM { inner: Point::generator().double() }, - ovpk_m: OvpkM { inner: Point::generator().neg() }, - tpk_m: TpkM { inner: Point::generator() + Point::generator().double() }, + npk_m_hash: 0, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint::generator().double() }, + ovpk_m_hash: 0, + tpk_m_hash: 0, }; keys.validate_on_curve(); @@ -175,10 +168,10 @@ mod test { #[test(should_fail_with = "Point not on curve")] unconstrained fn test_validate_not_on_curve() { let keys = PublicKeys { - npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } }, - ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } }, - ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } }, - tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } }, + npk_m_hash: 0, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } }, + ovpk_m_hash: 0, + tpk_m_hash: 0, }; keys.validate_on_curve(); @@ -187,22 +180,22 @@ mod test { #[test] unconstrained fn test_validate_non_infinity() { let keys = PublicKeys { - npk_m: NpkM { inner: Point::generator() }, - ivpk_m: IvpkM { inner: Point::generator().double() }, - ovpk_m: OvpkM { inner: Point::generator().neg() }, - tpk_m: TpkM { inner: Point::generator() + Point::generator().double() }, + npk_m_hash: 0, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint::generator().double() }, + ovpk_m_hash: 0, + tpk_m_hash: 0, }; keys.validate_non_infinity(); } - #[test(should_fail_with = "TpkM is the point at infinity")] + #[test(should_fail_with = "IvpkM is the point at infinity")] unconstrained fn test_validate_infinity() { let keys = PublicKeys { - npk_m: NpkM { inner: Point::generator() }, - ivpk_m: IvpkM { inner: Point::generator().double() }, - ovpk_m: OvpkM { inner: Point::generator().neg() }, - tpk_m: TpkM { inner: Point::point_at_infinity() }, + npk_m_hash: 0, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint::point_at_infinity() }, + ovpk_m_hash: 0, + tpk_m_hash: 0, }; keys.validate_non_infinity(); @@ -212,26 +205,24 @@ mod test { unconstrained fn compute_default_hash() { let keys = PublicKeys::default(); - let actual = keys.hash(); + let actual = keys.hash().to_field(); - // The following value was generated by `public_keys.test.ts`. let test_data_default_hash = - 0x023547e676dba19784188825b901a0e70d8ad978300d21d6185a54281b734da0; + 0x147a900f3e1abdfcc56355d65ab9bebb1016400cb9d81ee1c977d0df16bb198c; - assert(actual.to_field() == test_data_default_hash); + assert_eq(actual, test_data_default_hash); } #[test] unconstrained fn serde() { let keys = PublicKeys { - npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } }, - ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } }, - ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } }, - tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } }, + npk_m_hash: 11, + ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } }, + ovpk_m_hash: 22, + tpk_m_hash: 33, }; - // We use the PUBLIC_KEYS_LENGTH constant to ensure that there is a match between the derived trait - let serialized: [Field; POINT_LENGTH * 4] = keys.serialize(); + let serialized: [Field; PUBLIC_KEYS_LENGTH] = keys.serialize(); let deserialized = PublicKeys::deserialize(serialized); assert_eq(keys, deserialized); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr b/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr index bee6737454fd..932691b0b577 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr @@ -1,4 +1,4 @@ -use crate::traits::Packable; +use crate::traits::{Deserialize, Packable, Serialize}; global BOOL_PACKED_LEN: u32 = 1; global U8_PACKED_LEN: u32 = 1; @@ -11,6 +11,7 @@ global I8_PACKED_LEN: u32 = 1; global I16_PACKED_LEN: u32 = 1; global I32_PACKED_LEN: u32 = 1; global I64_PACKED_LEN: u32 = 1; +global POINT_PACKED_LEN: u32 = 2; impl Packable for bool { let N: u32 = BOOL_PACKED_LEN; @@ -166,6 +167,17 @@ impl Packable for i64 { } } +impl Packable for super::point::EmbeddedCurvePoint { + let N: u32 = POINT_PACKED_LEN; + fn pack(self) -> [Field; Self::N] { + self.serialize() + } + + fn unpack(packed: [Field; Self::N]) -> Self { + Self::deserialize(packed) + } +} + impl Packable for [T; M] where T: Packable, diff --git a/noir/noir-repo b/noir/noir-repo index 4f77d904a259..f1a4575adac5 160000 --- a/noir/noir-repo +++ b/noir/noir-repo @@ -1 +1 @@ -Subproject commit 4f77d904a259301b1784dbb1e1e7b82e5e0e2260 +Subproject commit f1a4575adac59af0a86b036cf73ff5883d142a91 diff --git a/playground/docker-compose.yml b/playground/docker-compose.yml index d48663150b0d..7d86f4bd03ba 100644 --- a/playground/docker-compose.yml +++ b/playground/docker-compose.yml @@ -27,6 +27,7 @@ services: WS_BLOCK_CHECK_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 P2P_MIN_TX_POOL_AGE_MS: 0 + SEQ_ENABLE_PROPOSER_PIPELINING: 'true' healthcheck: test: ['CMD', 'curl', '-fSs', 'http://127.0.0.1:8080/status'] interval: 3s diff --git a/spartan/aztec-node/templates/_pod-template.yaml b/spartan/aztec-node/templates/_pod-template.yaml index 67bfaec31a23..bfeb7e899cf9 100644 --- a/spartan/aztec-node/templates/_pod-template.yaml +++ b/spartan/aztec-node/templates/_pod-template.yaml @@ -217,14 +217,14 @@ spec: - name: SLASH_VALIDATORS_NEVER value: {{ join "," .Values.node.slash.validatorsNever | quote }} {{- end }} - {{- if .Values.node.slash.prunePenalty }} - - name: SLASH_PRUNE_PENALTY - value: {{ .Values.node.slash.prunePenalty | quote }} - {{- end }} {{- if .Values.node.slash.dataWithholdingPenalty }} - name: SLASH_DATA_WITHHOLDING_PENALTY value: {{ .Values.node.slash.dataWithholdingPenalty | quote }} {{- end }} + {{- if .Values.node.slash.dataWithholdingToleranceSlots }} + - name: SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS + value: {{ .Values.node.slash.dataWithholdingToleranceSlots | quote }} + {{- end }} {{- if .Values.node.slash.inactivityPenalty }} - name: SLASH_INACTIVITY_PENALTY value: {{ .Values.node.slash.inactivityPenalty | quote }} @@ -237,6 +237,10 @@ spec: - name: SLASH_INVALID_BLOCK_PENALTY value: {{ .Values.node.slash.invalidBlockPenalty | quote }} {{- end }} + {{- if .Values.node.slash.invalidCheckpointProposalPenalty }} + - name: SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY + value: {{ .Values.node.slash.invalidCheckpointProposalPenalty | quote }} + {{- end }} {{- if .Values.node.slash.proposeInvalidAttestationsPenalty }} - name: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY value: {{ .Values.node.slash.proposeInvalidAttestationsPenalty | quote }} @@ -249,9 +253,9 @@ spec: - name: SLASH_DUPLICATE_ATTESTATION_PENALTY value: {{ .Values.node.slash.duplicateAttestationPenalty | quote }} {{- end }} - {{- if .Values.node.slash.attestDescendantOfInvalidPenalty }} - - name: SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY - value: {{ .Values.node.slash.attestDescendantOfInvalidPenalty | quote }} + {{- if .Values.node.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty }} + - name: SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY + value: {{ .Values.node.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty | quote }} {{- end }} {{- if .Values.node.slash.attestInvalidCheckpointProposalPenalty }} - name: SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY diff --git a/spartan/aztec-node/values.yaml b/spartan/aztec-node/values.yaml index c16fb422b64c..b9d8732f434d 100644 --- a/spartan/aztec-node/values.yaml +++ b/spartan/aztec-node/values.yaml @@ -147,13 +147,14 @@ node: validatorsAlways: [] validatorsNever: [] # Penalty amounts for different offense types - prunePenalty: "" dataWithholdingPenalty: "" + dataWithholdingToleranceSlots: "" inactivityPenalty: "" inactivityTargetPercentage: "" invalidBlockPenalty: "" + invalidCheckpointProposalPenalty: "" proposeInvalidAttestationsPenalty: "" - attestDescendantOfInvalidPenalty: "" + proposeDescendantOfCheckpointWithInvalidAttestationsPenalty: "" attestInvalidCheckpointProposalPenalty: "" unknownPenalty: "" # Slasher behavior configuration diff --git a/spartan/bootstrap.sh b/spartan/bootstrap.sh index 15d908e4409b..4a4a19db9d69 100755 --- a/spartan/bootstrap.sh +++ b/spartan/bootstrap.sh @@ -183,8 +183,12 @@ function block_capacity_bench_cmds { } function bench_10tps_cmds { - local high_value_tps=10 - local low_value_tps=0 + # Mix: 1 tps of high-value + 9 tps of low-value, total still 10 tps. The + # high-value lane is what we measure for the headline client-observed + # inclusion latency (low-value txs pay near-network-min and are allowed to + # fail fee checks, so they would skew the headline if measured). + local high_value_tps=1 + local low_value_tps=9 local test_duration=${TEST_DURATION_SECONDS:-600} # 10 mins local timeout=${BENCH_TIMEOUT_SECONDS:-7200} # account for initial committee formation echo "$(hash):TIMEOUT=${timeout} BENCH_RUN_ID=${BENCH_RUN_ID:-} BENCH_OUTPUT=bench-out/n_tps.10tps.bench.json BENCH_SCENARIO=10tps LOW_VALUE_TPS=${low_value_tps} HIGH_VALUE_TPS=${high_value_tps} TEST_DURATION_SECONDS=${test_duration} $root/yarn-project/end-to-end/scripts/run_test.sh simple n_tps.test.ts" @@ -259,6 +263,7 @@ function bench_10tps { --target-tps 10 \ --workload sha256_hash_1024 \ --output "$run_json" \ + --inclusion-records "$metadata" \ --wait-for-pending-zero \ --max-pending-wait-seconds "${BENCH_SCRAPE_MAX_PENDING_WAIT_SECONDS:-3600}" \ || echo "[bench_10tps] scraper failed (non-fatal)" @@ -399,6 +404,13 @@ case "$cmd" in fi fi ;; + "wait_for_l2_block") + env_file="$1" + source_env_basic "$env_file" + gcp_auth + source_network_env "$env_file" + ./scripts/wait_for_l2_block.sh "$NAMESPACE" + ;; "single_test") run_network_tests "$1" "$2" ;; diff --git a/spartan/environments/alpha-net.env b/spartan/environments/alpha-net.env deleted file mode 100644 index 563054a0f9bb..000000000000 --- a/spartan/environments/alpha-net.env +++ /dev/null @@ -1,91 +0,0 @@ -NAMESPACE=${NAMESPACE:-alpha-net} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=8 -AZTEC_SLOT_DURATION=72 -AZTEC_PROOF_SUBMISSION_EPOCHS=2 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -# Install chaos mesh peer isolation after Aztec infra deploys. Validators, -# RPC nodes, and prover nodes can only peer with full-nodes, not each other. -# Requires P2P_PUBLIC_IP=false so P2P uses pod IPs that iptables rules can match. -P2P_PUBLIC_IP=false -CHAOS_MESH_SCENARIOS_FILE=network-requirements.yaml - -AZTEC_MANA_TARGET=2147483647 - -P2P_TX_POOL_DELETE_TXS_AFTER_REORG=true - -# For mbps -SEQ_BUILD_CHECKPOINT_IF_EMPTY=true -SEQ_BLOCK_DURATION_MS=6000 -SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT=5 - -CREATE_ROLLUP_CONTRACTS=true -REDEPLOY_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=128 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=5 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 -SPONSORED_FPC=true - -SEQ_MAX_TX_PER_CHECKPOINT=72 -SEQ_MIN_TX_PER_BLOCK=1 -SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/bench-10tps.env b/spartan/environments/bench-10tps.env index b4782d9e35e8..e7bedf0d9e58 100644 --- a/spartan/environments/bench-10tps.env +++ b/spartan/environments/bench-10tps.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-bench-10tps} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a DESTROY_NAMESPACE=true DESTROY_AZTEC_INFRA=true @@ -30,7 +31,7 @@ VALIDATOR_REPLICAS=3 VALIDATORS_PER_NODE=20 VALIDATOR_PUBLISHERS_PER_REPLICA=4 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" VALIDATOR_HA_REPLICAS=1 SEQ_BLOCK_DURATION_MS=6000 @@ -47,11 +48,11 @@ RPC_RESOURCE_PROFILE="prod" RPC_INGRESS_ENABLED=false FULL_NODE_REPLICAS=5 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" +FULL_NODE_RESOURCE_PROFILE="prod" REAL_VERIFIER=false PROVER_REPLICAS=10 -PROVER_RESOURCE_PROFILE="hi-tps" +PROVER_RESOURCE_PROFILE="dev-hi-tps" PUBLISHERS_PER_PROVER=1 PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 PROVER_AGENT_POLL_INTERVAL_MS=10000 diff --git a/spartan/environments/block-capacity.env b/spartan/environments/block-capacity.env index bc98dfd21cc2..8e24f24be61a 100644 --- a/spartan/environments/block-capacity.env +++ b/spartan/environments/block-capacity.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-block-capacity} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a AZTEC_EPOCH_DURATION=8 @@ -23,7 +24,7 @@ OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET VALIDATOR_REPLICAS=1 VALIDATORS_PER_NODE=48 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="prod-hi-tps" +VALIDATOR_RESOURCE_PROFILE="prod" REAL_VERIFIER=false diff --git a/spartan/environments/devnet.env b/spartan/environments/devnet.env index e78d04742203..0741b4751f7e 100644 --- a/spartan/environments/devnet.env +++ b/spartan/environments/devnet.env @@ -1,5 +1,6 @@ GCP_REGION=us-west1-a CLUSTER=aztec-gke-private +RESOURCE_PROFILE=dev NETWORK="devnet" NAMESPACE=${NAMESPACE:-devnet} diff --git a/spartan/environments/five-tps-long-epoch.env b/spartan/environments/five-tps-long-epoch.env deleted file mode 100644 index b8ed75aa4346..000000000000 --- a/spartan/environments/five-tps-long-epoch.env +++ /dev/null @@ -1,75 +0,0 @@ -NAMESPACE=${NAMESPACE:-five-tps} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=32 -AZTEC_SLOT_DURATION=36 -AZTEC_PROOF_SUBMISSION_EPOCHS=2 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -AZTEC_MANA_TARGET=2147483647 - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=64 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=20 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 - -SEQ_MAX_TX_PER_CHECKPOINT=180 -SEQ_MIN_TX_PER_BLOCK=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/five-tps-short-epoch.env b/spartan/environments/five-tps-short-epoch.env deleted file mode 100644 index e78badea2365..000000000000 --- a/spartan/environments/five-tps-short-epoch.env +++ /dev/null @@ -1,75 +0,0 @@ -NAMESPACE=${NAMESPACE:-five-tps} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=8 -AZTEC_SLOT_DURATION=36 -AZTEC_PROOF_SUBMISSION_EPOCHS=10 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -AZTEC_MANA_TARGET=2147483647 - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=64 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=5 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 - -SEQ_MAX_TX_PER_CHECKPOINT=180 -SEQ_MIN_TX_PER_BLOCK=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/kind-minimal.env b/spartan/environments/kind-minimal.env index c70b55aede50..e3d5ab2901fc 100644 --- a/spartan/environments/kind-minimal.env +++ b/spartan/environments/kind-minimal.env @@ -3,6 +3,7 @@ NAMESPACE=${NAMESPACE:-kind} CLUSTER=kind +RESOURCE_PROFILE=dev CREATE_ETH_DEVNET=true CREATE_ROLLUP_CONTRACTS=true CREATE_AZTEC_INFRA=true diff --git a/spartan/environments/kind-provers.env b/spartan/environments/kind-provers.env index f6e0482d7e1a..e74d5a25e0b8 100644 --- a/spartan/environments/kind-provers.env +++ b/spartan/environments/kind-provers.env @@ -3,6 +3,7 @@ NAMESPACE=${NAMESPACE:-kind} CLUSTER=kind +RESOURCE_PROFILE=dev CREATE_ETH_DEVNET=true CREATE_ROLLUP_CONTRACTS=true CREATE_AZTEC_INFRA=true diff --git a/spartan/environments/mainnet.env b/spartan/environments/mainnet.env index 2315e53d29d0..97d6b69748f5 100644 --- a/spartan/environments/mainnet.env +++ b/spartan/environments/mainnet.env @@ -4,6 +4,7 @@ ETHEREUM_CHAIN_ID=${ETHEREUM_CHAIN_ID:-1} GCP_REGION=us-west1-a CLUSTER=aztec-gke-public +RESOURCE_PROFILE=prod NAMESPACE=${NAMESPACE:-mainnet} CREATE_ROLLUP_CONTRACTS=false @@ -24,9 +25,9 @@ FISHERMAN_REPLICAS=1 FISHERMAN_MNEMONIC_START_INDEX=1 PROVER_NODE_DISABLE_PROOF_PUBLISH=true -RPC_RESOURCE_PROFILE=mainnet -BLOB_SINK_RESOURCE_PROFILE=mainnet -PROVER_RESOURCE_PROFILE=mainnet +RPC_RESOURCE_PROFILE=prod +BLOB_SINK_RESOURCE_PROFILE=prod +PROVER_RESOURCE_PROFILE=prod LOG_LEVEL=info FISHERMAN_LOG_LEVEL=info diff --git a/spartan/environments/mbps-net.env b/spartan/environments/mbps-net.env deleted file mode 100644 index 4357bf8fc037..000000000000 --- a/spartan/environments/mbps-net.env +++ /dev/null @@ -1,68 +0,0 @@ -CREATE_ETH_DEVNET=false -GCP_REGION=us-west1-a -CLUSTER=aztec-gke-private -NETWORK=next-net -NAMESPACE=mbps-net -DESTROY_NAMESPACE=true -ETHEREUM_CHAIN_ID=11155111 -ETHEREUM_RPC_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEYS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEY_HEADERS=REPLACE_WITH_GCP_SECRET -FUNDING_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -LABS_INFRA_MNEMONIC=REPLACE_WITH_GCP_SECRET -ROLLUP_DEPLOYMENT_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET -VERIFY_CONTRACTS=false -ETHERSCAN_API_KEY=REPLACE_WITH_GCP_SECRET -DEPLOY_INTERNAL_BOOTNODE=true -STORE_SNAPSHOT_URL= -BLOB_BUCKET_DIRECTORY=${BLOB_BUCKET_DIRECTORY:-next-net/blobs} -R2_ACCESS_KEY_ID=REPLACE_WITH_GCP_SECRET -R2_SECRET_ACCESS_KEY=REPLACE_WITH_GCP_SECRET -PROVER_FAILED_PROOF_STORE=gs://aztec-develop/next-net/failed-proofs -TEST_ACCOUNTS=true -SPONSORED_FPC=true -SEQ_MIN_TX_PER_BLOCK=0 -SEQ_MAX_TX_PER_BLOCK=8 -AZTEC_EPOCH_DURATION=8 -REAL_VERIFIER=false -PROVER_REAL_PROOFS=false - -SEQ_BUILD_CHECKPOINT_IF_EMPTY=true -SEQ_BLOCK_DURATION_MS=6000 -LOG_LEVEL=verbose - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 - -BOT_TRANSFERS_REPLICAS=1 -BOT_TRANSFERS_TX_INTERVAL_SECONDS=4 -BOT_TRANSFERS_FOLLOW_CHAIN=PROPOSED -BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP=proposed - -BOT_SWAPS_REPLICAS=1 -BOT_SWAPS_TX_INTERVAL_SECONDS=4 -BOT_SWAPS_FOLLOW_CHAIN=PROPOSED -BOT_SWAPS_PXE_SYNC_CHAIN_TIP=proposed - -BOT_CROSS_CHAIN_REPLICAS=1 -BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS=8 -BOT_CROSS_CHAIN_FOLLOW_CHAIN=PROPOSED -BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP=proposed - -REDEPLOY_ROLLUP_CONTRACTS=true - -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" - diff --git a/spartan/environments/mbps-pipeline.env b/spartan/environments/mbps-pipeline.env deleted file mode 100644 index fa00ac5c9f88..000000000000 --- a/spartan/environments/mbps-pipeline.env +++ /dev/null @@ -1,69 +0,0 @@ -CREATE_ETH_DEVNET=true -GCP_REGION=us-west1-a -CLUSTER=aztec-gke-private -NETWORK=next-net -NAMESPACE=mbps-pipe -DESTROY_NAMESPACE=true -ETHEREUM_CHAIN_ID=1337 -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -DEPLOY_INTERNAL_BOOTNODE=true -TEST_ACCOUNTS=true -SPONSORED_FPC=true -SEQ_MIN_TX_PER_BLOCK=0 -SEQ_MAX_TX_PER_BLOCK=8 -AZTEC_EPOCH_DURATION=8 -REAL_VERIFIER=false -PROVER_REAL_PROOFS=false - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -SEQ_BUILD_CHECKPOINT_IF_EMPTY=true -SEQ_BLOCK_DURATION_MS=5500 -SEQ_MAX_TX_PER_CHECKPOINT=96 -SEQ_ENABLE_PROPOSER_PIPELINING=true -SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER=1 -LOG_LEVEL=verbose - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -AZTEC_INBOX_LAG=2 - -AZTEC_TARGET_COMMITTEE_SIZE=24 - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 - -BOT_TRANSFERS_REPLICAS=1 -BOT_TRANSFERS_TX_INTERVAL_SECONDS=4 -BOT_TRANSFERS_FOLLOW_CHAIN=PROPOSED -BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP=proposed - -BOT_SWAPS_REPLICAS=1 -BOT_SWAPS_TX_INTERVAL_SECONDS=4 -BOT_SWAPS_FOLLOW_CHAIN=PROPOSED -BOT_SWAPS_PXE_SYNC_CHAIN_TIP=proposed - -BOT_CROSS_CHAIN_REPLICAS=1 -BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS=8 -BOT_CROSS_CHAIN_FOLLOW_CHAIN=PROPOSED -BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP=proposed - -REDEPLOY_ROLLUP_CONTRACTS=true - -DEBUG_P2P_INSTRUMENT_MESSAGES=true -OTEL_COLLECT_INTERVAL_MS=10000 -OTEL_EXPORT_TIMEOUT_MS=5000 - -VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" - diff --git a/spartan/environments/network-defaults.yml b/spartan/environments/network-defaults.yml index 3bfe0cd37aaa..c918dcddc515 100644 --- a/spartan/environments/network-defaults.yml +++ b/spartan/environments/network-defaults.yml @@ -119,10 +119,10 @@ slasher: &slasher SLASH_MAX_PAYLOAD_SIZE: 80 # Rounds to look back when executing slashes. SLASH_EXECUTE_ROUNDS_LOOK_BACK: 4 - # Penalty for slashing validators of a valid pruned epoch. - SLASH_PRUNE_PENALTY: 10e18 # Penalty for data withholding. SLASH_DATA_WITHHOLDING_PENALTY: 10e18 + # Number of full L2 slots to wait after a checkpoint's slot before declaring its txs missing. + SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS: 3 # Missed attestation percentage to trigger inactivity slash (0, 1]. SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9 # Consecutive epochs a validator must be inactive before slashing. @@ -131,8 +131,8 @@ slasher: &slasher SLASH_INACTIVITY_PENALTY: 10e18 # Penalty for proposing invalid attestations. SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 - # Penalty for attesting to a descendant of an invalid block. - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + # Penalty for proposing a checkpoint that builds on an invalid checkpoint. + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 # Penalty for attesting to an invalid checkpoint proposal. SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 # Penalty for proposing two different block or checkpoint proposal for the same position. @@ -143,6 +143,8 @@ slasher: &slasher SLASH_UNKNOWN_PENALTY: 10e18 # Penalty for broadcasting an invalid block. SLASH_INVALID_BLOCK_PENALTY: 10e18 + # Penalty for broadcasting an invalid checkpoint proposal. + SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0 # L2 slots grace period before considering an offense expired. SLASH_GRACE_PERIOD_L2_SLOTS: 0 @@ -235,7 +237,6 @@ networks: PUBLIC_OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "" PUBLIC_OTEL_COLLECT_FROM: "" # Slasher penalties - SLASH_PRUNE_PENALTY: 10e18 SLASH_DATA_WITHHOLDING_PENALTY: 10e18 SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9 SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 1 @@ -243,10 +244,11 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 SLASH_UNKNOWN_PENALTY: 10e18 SLASH_INVALID_BLOCK_PENALTY: 10e18 + SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0 SLASH_GRACE_PERIOD_L2_SLOTS: 0 ENABLE_VERSION_CHECK: true @@ -281,7 +283,6 @@ networks: P2P_MAX_PENDING_TX_COUNT: 1000 P2P_TX_POOL_DELETE_TXS_AFTER_REORG: true # Slasher penalties - SLASH_PRUNE_PENALTY: 10e18 SLASH_DATA_WITHHOLDING_PENALTY: 10e18 SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9 SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 1 @@ -289,10 +290,11 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 SLASH_UNKNOWN_PENALTY: 10e18 SLASH_INVALID_BLOCK_PENALTY: 10e18 + SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0 SLASH_GRACE_PERIOD_L2_SLOTS: 64 ENABLE_VERSION_CHECK: true @@ -341,7 +343,6 @@ networks: PUBLIC_OTEL_COLLECT_FROM: "" ENABLE_VERSION_CHECK: false # Slasher penalties - more lenient initially - SLASH_PRUNE_PENALTY: 0 SLASH_DATA_WITHHOLDING_PENALTY: 0 SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.8 SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 2 @@ -349,8 +350,9 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 2000e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 2000e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 2000e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 2000e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 2000e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 2000e18 SLASH_UNKNOWN_PENALTY: 2000e18 SLASH_INVALID_BLOCK_PENALTY: 2000e18 + SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0 SLASH_GRACE_PERIOD_L2_SLOTS: 1200 diff --git a/spartan/environments/next-net-clone.env b/spartan/environments/next-net-clone.env deleted file mode 100644 index b159feccf9c1..000000000000 --- a/spartan/environments/next-net-clone.env +++ /dev/null @@ -1,79 +0,0 @@ -CREATE_ETH_DEVNET=false -GCP_REGION=us-west1-a -CLUSTER=aztec-gke-private -NETWORK=next-net -NAMESPACE=${NAMESPACE:-next-net-clone} -DESTROY_NAMESPACE=true -ETHEREUM_CHAIN_ID=11155111 -ETHEREUM_RPC_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEYS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEY_HEADERS=REPLACE_WITH_GCP_SECRET -FUNDING_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -LABS_INFRA_MNEMONIC=REPLACE_WITH_GCP_SECRET -ROLLUP_DEPLOYMENT_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET -VERIFY_CONTRACTS=false -ETHERSCAN_API_KEY=REPLACE_WITH_GCP_SECRET -DEPLOY_INTERNAL_BOOTNODE=true -STORE_SNAPSHOT_URL= -#BLOB_BUCKET_DIRECTORY=${BLOB_BUCKET_DIRECTORY:-next-net/blobs} -#BLOB_FILE_STORE_URLS="," -#TX_FILE_STORE_ENABLED=true -#TX_FILE_STORE_BUCKET_DIRECTORY=${TX_FILE_STORE_BUCKET_DIRECTORY:-next-net/txs} -#TX_COLLECTION_FILE_STORE_URLS="https://aztec-labs-snapshots.com/${TX_FILE_STORE_BUCKET_DIRECTORY}" -R2_ACCESS_KEY_ID=REPLACE_WITH_GCP_SECRET -R2_SECRET_ACCESS_KEY=REPLACE_WITH_GCP_SECRET -#PROVER_FAILED_PROOF_STORE=gs://aztec-develop/next-net/failed-proofs -#L1_TX_FAILED_STORE=gs://aztec-develop/next-net/failed-l1-txs -TEST_ACCOUNTS=true -SPONSORED_FPC=true - -SEQ_ENABLE_PROPOSER_PIPELINING=true -SEQ_MIN_TX_PER_BLOCK=1 -SEQ_MAX_TX_PER_CHECKPOINT=12 - -# Build checkpoint even if block is empty. -SEQ_BUILD_CHECKPOINT_IF_EMPTY=true -SEQ_BLOCK_DURATION_MS=5500 - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -AZTEC_INBOX_LAG=2 - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 - -BOT_TRANSFERS_REPLICAS=1 -BOT_TRANSFERS_TX_INTERVAL_SECONDS=250 -BOT_TRANSFERS_FOLLOW_CHAIN=PENDING - -BOT_SWAPS_REPLICAS=1 -BOT_SWAPS_FOLLOW_CHAIN=PENDING -BOT_SWAPS_TX_INTERVAL_SECONDS=350 - -CREATE_ROLLUP_CONTRACTS=true - -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -RPC_INGRESS_ENABLED=false -#RPC_INGRESS_HOSTS='["nextnet.aztec-labs.com"]' -#RPC_INGRESS_STATIC_IP_NAME=nextnet-rpc-ip -#RPC_INGRESS_SSL_CERT_NAMES='["nextnet-rpc-cert"]' - -VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" - -REAL_VERIFIER=true -AZTEC_SLOT_DURATION=72 -AZTEC_EPOCH_DURATION=32 -AZTEC_TARGET_COMMITTEE_SIZE=48 -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -AZTEC_PROOF_SUBMISSION_EPOCHS=1 - diff --git a/spartan/environments/next-net.env b/spartan/environments/next-net.env index 7ecf1b28b7e6..f8541c8b5229 100644 --- a/spartan/environments/next-net.env +++ b/spartan/environments/next-net.env @@ -1,6 +1,7 @@ CREATE_ETH_DEVNET=false GCP_REGION=us-west1-a CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod NETWORK=next-net NAMESPACE=${NAMESPACE:-next-net} DESTROY_NAMESPACE=true @@ -29,7 +30,7 @@ L1_TX_FAILED_STORE=gs://aztec-develop/next-net/failed-l1-txs TEST_ACCOUNTS=true SPONSORED_FPC=true -LOG_LEVEL=debug +LOG_LEVEL="debug; info: json-rpc, simulator" SEQ_ENABLE_PROPOSER_PIPELINING=true SEQ_MIN_TX_PER_BLOCK=1 @@ -69,7 +70,7 @@ RPC_INGRESS_STATIC_IP_NAME=nextnet-rpc-ip RPC_INGRESS_SSL_CERT_NAMES='["nextnet-rpc-cert"]' VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" REAL_VERIFIER=true AZTEC_SLOT_DURATION=72 diff --git a/spartan/environments/next-scenario.env b/spartan/environments/next-scenario.env index e11caa65025e..efc9f2dd15bf 100644 --- a/spartan/environments/next-scenario.env +++ b/spartan/environments/next-scenario.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-scenario} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a DESTROY_NAMESPACE=true DESTROY_ETH_DEVNET=true @@ -52,4 +53,4 @@ PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 SEQ_MIN_TX_PER_BLOCK=0 VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" diff --git a/spartan/environments/prove-n-tps-fake.env b/spartan/environments/prove-n-tps-fake.env index 553ab562dac7..9aa4fc5f6359 100644 --- a/spartan/environments/prove-n-tps-fake.env +++ b/spartan/environments/prove-n-tps-fake.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-prove-n-tps-fake} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a AZTEC_EPOCH_DURATION=32 @@ -32,7 +33,7 @@ RPC_REPLICAS=1 RPC_INGRESS_ENABLED=false PROVER_REPLICAS=10 -PROVER_RESOURCE_PROFILE="hi-tps" +PROVER_RESOURCE_PROFILE="dev-hi-tps" PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 PROVER_AGENT_POLL_INTERVAL_MS=10000 PUBLISHERS_PER_PROVER=1 diff --git a/spartan/environments/prove-n-tps-real.env b/spartan/environments/prove-n-tps-real.env index 41357530292a..16e0548e91e9 100644 --- a/spartan/environments/prove-n-tps-real.env +++ b/spartan/environments/prove-n-tps-real.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-prove-n-tps-real} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a AZTEC_EPOCH_DURATION=32 diff --git a/spartan/environments/scenario.local.env b/spartan/environments/scenario.local.env index 8fcc338a7183..5059489633de 100644 --- a/spartan/environments/scenario.local.env +++ b/spartan/environments/scenario.local.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-scenario} CLUSTER=kind +RESOURCE_PROFILE=dev CREATE_ETH_DEVNET=true LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" L1_ACCOUNT_MNEMONIC="test test test test test test test test test test test junk" diff --git a/spartan/environments/staging-ignition.env b/spartan/environments/staging-ignition.env deleted file mode 100644 index f1d267365995..000000000000 --- a/spartan/environments/staging-ignition.env +++ /dev/null @@ -1,42 +0,0 @@ -CREATE_ETH_DEVNET=false -GCP_REGION=us-west1-a -CLUSTER=aztec-gke-private -NAMESPACE=${NAMESPACE:-staging-ignition} -TRANSACTIONS_DISABLED=true -TEST_ACCOUNTS=false -SPONSORED_FPC=false -SEQ_MIN_TX_PER_BLOCK=0 -SEQ_MAX_TX_PER_BLOCK=0 -NETWORK=staging-ignition - -ETHEREUM_CHAIN_ID=11155111 -ETHEREUM_RPC_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_URLS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEYS=REPLACE_WITH_GCP_SECRET -ETHEREUM_CONSENSUS_HOST_API_KEY_HEADERS=REPLACE_WITH_GCP_SECRET -FUNDING_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -LABS_INFRA_MNEMONIC=REPLACE_WITH_GCP_SECRET -LABS_INFRA_MNEMONIC_SECRET_NAME=sepolia-labs-staging-ignition-mnemonic -ROLLUP_DEPLOYMENT_PRIVATE_KEY=REPLACE_WITH_GCP_SECRET -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET -VERIFY_CONTRACTS=true -ETHERSCAN_API_KEY=REPLACE_WITH_GCP_SECRET -SNAPSHOT_BUCKET_DIRECTORY=${SNAPSHOT_BUCKET_DIRECTORY:-staging-ignition} -BLOB_BUCKET_DIRECTORY=${BLOB_BUCKET_DIRECTORY:-staging-ignition/blobs} -BLOB_FILE_STORE_URLS="," -R2_ACCESS_KEY_ID=REPLACE_WITH_GCP_SECRET -R2_SECRET_ACCESS_KEY=REPLACE_WITH_GCP_SECRET -BOT_TRANSFERS_REPLICAS=0 -BOT_SWAPS_REPLICAS=0 -DEPLOY_INTERNAL_BOOTNODE=false - -CREATE_ROLLUP_CONTRACTS=${CREATE_ROLLUP_CONTRACTS:-false} - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -USE_NETWORK_CONFIG=true diff --git a/spartan/environments/staging-public.env b/spartan/environments/staging-public.env index cbc41af5d589..b3f8b318c4a4 100644 --- a/spartan/environments/staging-public.env +++ b/spartan/environments/staging-public.env @@ -1,6 +1,7 @@ CREATE_ETH_DEVNET=false GCP_REGION=us-west1-a CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod NETWORK=staging-public NAMESPACE=${NAMESPACE:-staging-public} ETHEREUM_CHAIN_ID=11155111 @@ -51,7 +52,7 @@ VALIDATOR_PUBLISHERS_PER_REPLICA=4 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 VALIDATOR_HA_REPLICAS=1 VALIDATOR_HA_REPLICA_COUNT=4 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" PROVER_FAILED_PROOF_STORE=gs://aztec-develop/staging-public/failed-proofs L1_TX_FAILED_STORE=gs://aztec-develop/staging-public/failed-l1-txs diff --git a/spartan/environments/staging.local.env b/spartan/environments/staging.local.env deleted file mode 100644 index 99054b7b87b1..000000000000 --- a/spartan/environments/staging.local.env +++ /dev/null @@ -1,21 +0,0 @@ -NAMESPACE=${NAMESPACE:-staging} -CLUSTER=kind -CREATE_ETH_DEVNET=false -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - -# The following need to be set manually -# AZTEC_DOCKER_IMAGE=aztecprotocol/aztec:whatever -# ETHEREUM_RPC_URLS='[""]' -# ETHEREUM_CONSENSUS_HOST_URLS='[""]' -# ETHEREUM_CONSENSUS_HOST_API_KEYS='[""]' -# ETHEREUM_CONSENSUS_HOST_API_KEY_HEADERS='[""]' - -VALIDATOR_REPLICAS=4 -VALIDATORS_PER_NODE=12 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 diff --git a/spartan/environments/ten-tps-long-epoch.env b/spartan/environments/ten-tps-long-epoch.env deleted file mode 100644 index 297e2cd55f96..000000000000 --- a/spartan/environments/ten-tps-long-epoch.env +++ /dev/null @@ -1,76 +0,0 @@ -NAMESPACE=${NAMESPACE:-ten-tps} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=32 -AZTEC_SLOT_DURATION=36 -AZTEC_PROOF_SUBMISSION_EPOCHS=2 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -AZTEC_MANA_TARGET=2147483647 - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 -SPONSORED_FPC=true - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=128 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=20 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 - -SEQ_MAX_TX_PER_CHECKPOINT=360 -SEQ_MIN_TX_PER_BLOCK=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/ten-tps-short-epoch.env b/spartan/environments/ten-tps-short-epoch.env deleted file mode 100644 index 56518164d2ab..000000000000 --- a/spartan/environments/ten-tps-short-epoch.env +++ /dev/null @@ -1,76 +0,0 @@ -NAMESPACE=${NAMESPACE:-ten-tps} -CLUSTER=aztec-gke-private -GCP_REGION=us-west1-a -DESTROY_NAMESPACE=true -DESTROY_ETH_DEVNET=true -CREATE_ETH_DEVNET=${CREATE_ETH_DEVNET:-true} -AZTEC_EPOCH_DURATION=8 -AZTEC_SLOT_DURATION=36 -AZTEC_PROOF_SUBMISSION_EPOCHS=2 -ETHEREUM_CHAIN_ID=1337 -LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" -FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -# CREATE_CHAOS_MESH=true - -AZTEC_MANA_TARGET=2147483647 - -CREATE_ROLLUP_CONTRACTS=true -VERIFY_CONTRACTS=false -DESTROY_AZTEC_INFRA=true - -AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 -AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 -SPONSORED_FPC=true - -OTEL_COLLECTOR_ENDPOINT=REPLACE_WITH_GCP_SECRET - -VALIDATOR_REPLICAS=12 -VALIDATORS_PER_NODE=4 -VALIDATOR_PUBLISHERS_PER_REPLICA=4 -VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" - -REAL_VERIFIER=false - -RPC_REPLICAS=12 -RPC_INGRESS_ENABLED=false - -FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" - -PUBLISHERS_PER_PROVER=2 -PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 -PROVER_REPLICAS=128 -PROVER_RESOURCE_PROFILE="hi-tps" -PROVER_AGENT_POLL_INTERVAL_MS=10000 - -RUN_TESTS=false - -PROVER_TEST_DELAY_TYPE=fixed - -AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 -AZTEC_SLASHING_QUORUM=5 -AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS=0 -AZTEC_SLASHING_OFFSET_IN_ROUNDS=1 -AZTEC_LOCAL_EJECTION_THRESHOLD=90000000000000000000 - -SEQ_MAX_TX_PER_CHECKPOINT=360 -SEQ_MIN_TX_PER_BLOCK=1 - -# Override L1 tx utils bump percentages for scenario tests -VALIDATOR_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -VALIDATOR_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_BUMP_PERCENTAGE=0 -PROVER_L1_PRIORITY_FEE_RETRY_BUMP_PERCENTAGE=0 - -# Enable latency mesaruement for p2p messages -DEBUG_P2P_INSTRUMENT_MESSAGES=true - -# Inject artificial delay of proof verification for all nodes -PROVER_TEST_VERIFICATION_DELAY_MS=250 - -# Reduce the amount of metrics produced by prover agents and full nodes -PROVER_AGENT_INCLUDE_METRICS="aztec.circuit" -FULL_NODE_INCLUDE_METRICS="aztec.p2p.gossip.agg_" -LOG_LEVEL=info - diff --git a/spartan/environments/testnet.env b/spartan/environments/testnet.env index 2a88fb1e1826..10cf468f1341 100644 --- a/spartan/environments/testnet.env +++ b/spartan/environments/testnet.env @@ -1,6 +1,7 @@ CREATE_ETH_DEVNET=false GCP_REGION=us-west1-a CLUSTER=aztec-gke-public +RESOURCE_PROFILE=prod NAMESPACE=${NAMESPACE:-testnet} NETWORK=testnet @@ -80,7 +81,7 @@ VALIDATORS_PER_NODE=64 VALIDATOR_PUBLISHERS_PER_REPLICA=8 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 VALIDATOR_HA_REPLICAS=1 -VALIDATOR_RESOURCE_PROFILE="prod-spot" +VALIDATOR_RESOURCE_PROFILE="prod" PUBLISHERS_PER_PROVER=2 PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 diff --git a/spartan/environments/tps-scenario.env b/spartan/environments/tps-scenario.env index fc3893282c6c..4a1f08e156e2 100644 --- a/spartan/environments/tps-scenario.env +++ b/spartan/environments/tps-scenario.env @@ -1,5 +1,6 @@ NAMESPACE=${NAMESPACE:-tps-scenario} CLUSTER=aztec-gke-private +RESOURCE_PROFILE=prod GCP_REGION=us-west1-a AZTEC_EPOCH_DURATION=8 @@ -37,7 +38,7 @@ VALIDATOR_REPLICAS=12 VALIDATORS_PER_NODE=4 VALIDATOR_PUBLISHERS_PER_REPLICA=4 VALIDATOR_PUBLISHER_MNEMONIC_START_INDEX=5000 -VALIDATOR_RESOURCE_PROFILE="2-core-dedicated" +VALIDATOR_RESOURCE_PROFILE="prod" REAL_VERIFIER=false @@ -45,12 +46,12 @@ RPC_REPLICAS=10 RPC_INGRESS_ENABLED=false FULL_NODE_REPLICAS=500 -FULL_NODE_RESOURCE_PROFILE="2-core-spot" +FULL_NODE_RESOURCE_PROFILE="prod" PUBLISHERS_PER_PROVER=2 PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000 PROVER_REPLICAS=20 -PROVER_RESOURCE_PROFILE="hi-tps" +PROVER_RESOURCE_PROFILE="dev-hi-tps" PROVER_AGENT_POLL_INTERVAL_MS=10000 WAIT_FOR_PROVER_DEPLOY=false diff --git a/spartan/metrics/grafana/alerts/policies.yaml b/spartan/metrics/grafana/alerts/policies.yaml index 1de335ec919e..de2ca357a81e 100644 --- a/spartan/metrics/grafana/alerts/policies.yaml +++ b/spartan/metrics/grafana/alerts/policies.yaml @@ -19,18 +19,6 @@ policies: - =~ - $STAGING_PUBLIC_REGEX - # Staging Ignition - by namespace - - receiver: "Slack #alerts-staging-ignition by namespace" - object_matchers: - - - k8s_namespace_name - - =~ - - $STAGING_IGNITION_REGEX - # Staging Ignition - by network label - - receiver: "Slack #alerts-staging-ignition by network" - object_matchers: - - - network - - =~ - - $STAGING_IGNITION_REGEX # Next Scenario - by namespace - receiver: "Slack #alerts-next-scenario by namespace" diff --git a/spartan/metrics/grafana/dashboards/aztec_network.json b/spartan/metrics/grafana/dashboards/aztec_network.json index e6fae556a5e7..ebc2b85ea31d 100644 --- a/spartan/metrics/grafana/dashboards/aztec_network.json +++ b/spartan/metrics/grafana/dashboards/aztec_network.json @@ -248,11 +248,11 @@ { "datasource": { "type": "prometheus", - "uid": "prometheus" + "uid": "${data_source}" }, "editorMode": "code", "exemplar": false, - "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"\"}, \"aztec_status\", \"Pending chain\", \"aztec_status\", \"^$\"))", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"proposed\"}, \"aztec_status\", \"Proposed chain\", \"aztec_status\", \"^proposed$\")) or max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"\"}, \"aztec_status\", \"Proposed chain\", \"aztec_status\", \"^$\"))", "instant": true, "legendFormat": "{{aztec_status}}", "range": false, @@ -261,16 +261,16 @@ { "datasource": { "type": "prometheus", - "uid": "prometheus" + "uid": "${data_source}" }, "editorMode": "code", "exemplar": false, - "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"proven\"}, \"aztec_status\", \"Proven chain\", \"aztec_status\", \"^proven$\"))", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"checkpointed\"}, \"aztec_status\", \"Checkpointed chain\", \"aztec_status\", \"^checkpointed$\")) or max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"\"}, \"aztec_status\", \"Checkpointed chain\", \"aztec_status\", \"^$\"))", "hide": false, "instant": true, "legendFormat": "{{aztec_status}}", "range": false, - "refId": "E" + "refId": "B" }, { "datasource": { @@ -279,38 +279,12 @@ }, "editorMode": "code", "exemplar": false, - "expr": "max by (aztec_status) (label_replace(aztec_archiver_l1_block_height{k8s_namespace_name=\"$namespace\"}, \"aztec_status\", \"l1\", \"aztec_status\", \"^$\"))", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\",aztec_status=\"proven\"}, \"aztec_status\", \"Proven chain\", \"aztec_status\", \"^proven$\"))", "hide": false, "instant": true, - "legendFormat": "L1", + "legendFormat": "{{aztec_status}}", "range": false, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${data_source}" - }, - "editorMode": "code", - "expr": "max(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\", aztec_status=\"\"}) - max(aztec_archiver_block_height{k8s_namespace_name=\"$namespace\", aztec_status=\"proven\"})", - "hide": false, - "instant": false, - "legendFormat": "Pending chain depth", - "range": true, "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${data_source}" - }, - "editorMode": "code", - "expr": "max(aztec_archiver_prune_count{k8s_namespace_name=\"$namespace\"}) or vector(0)", - "hide": false, - "instant": false, - "legendFormat": "Total re-orgs", - "range": true, - "refId": "D" } ], "title": "Current Block Heights", @@ -2592,15 +2566,47 @@ "uid": "${data_source}" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "max by(service_name, aztec_status) (aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=~\"proposed|proven\"})", + "editorMode": "code", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"proposed\"}, \"aztec_status\", \"Proposed chain\", \"aztec_status\", \"^proposed$\")) or max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"\"}, \"aztec_status\", \"Proposed chain\", \"aztec_status\", \"^$\"))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "__auto", + "legendFormat": "{{aztec_status}}", "range": true, "refId": "A", "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"checkpointed\"}, \"aztec_status\", \"Checkpointed chain\", \"aztec_status\", \"^checkpointed$\")) or max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"\"}, \"aztec_status\", \"Checkpointed chain\", \"aztec_status\", \"^$\"))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{aztec_status}}", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "max by (aztec_status) (label_replace(aztec_archiver_block_height{service_namespace=\"$namespace\", aztec_status=\"proven\"}, \"aztec_status\", \"Proven chain\", \"aztec_status\", \"^proven$\"))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{aztec_status}}", + "range": true, + "refId": "C", + "useBackend": false } ], "title": "Block height", @@ -2669,8 +2675,8 @@ "gridPos": { "h": 8, "w": 12, - "x": 12, - "y": 75 + "x": 0, + "y": 83 }, "id": 11, "options": { @@ -2774,7 +2780,7 @@ "gridPos": { "h": 8, "w": 12, - "x": 0, + "x": 12, "y": 83 }, "id": 24, @@ -2814,6 +2820,107 @@ ], "title": "Archiver Sync Duration (P95)", "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "${data_source}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 8, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 75 + }, + "id": 41, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "editorMode": "code", + "expr": "max by(k8s_pod_name) (aztec_archiver_block_height{k8s_namespace_name=\"$namespace\", aztec_status=\"proposed\"}) or max by(k8s_pod_name) (aztec_archiver_block_height{k8s_namespace_name=\"$namespace\", aztec_status=\"\"})", + "instant": false, + "legendFormat": "{{k8s_pod_name}}", + "range": true, + "refId": "A" + } + ], + "title": "Proposed Chains by Pod", + "type": "timeseries" } ], "preload": false, diff --git a/spartan/metrics/grafana/dashboards/bootnodes.json b/spartan/metrics/grafana/dashboards/bootnodes.json index 296ded8850ea..dbccf99dc15f 100644 --- a/spartan/metrics/grafana/dashboards/bootnodes.json +++ b/spartan/metrics/grafana/dashboards/bootnodes.json @@ -554,8 +554,8 @@ { "current": { "selected": false, - "text": "staging-ignition", - "value": "staging-ignition" + "text": "staging-public", + "value": "staging-public" }, "datasource": { "type": "prometheus", diff --git a/spartan/metrics/irm-monitor/alerting/alert-rules.yml b/spartan/metrics/irm-monitor/alerting/alert-rules.yml index 82983b498810..a6a08f77633e 100644 --- a/spartan/metrics/irm-monitor/alerting/alert-rules.yml +++ b/spartan/metrics/irm-monitor/alerting/alert-rules.yml @@ -16,7 +16,7 @@ groups: datasourceUid: grafanacloud-prom model: editorMode: code - expr: changes(rollup_pending_block_number{network!="staging-ignition"}[40m]) + expr: changes(rollup_pending_block_number[40m]) instant: true intervalMs: 1000 legendFormat: __auto @@ -33,7 +33,7 @@ groups: type: prometheus uid: grafanacloud-prom editorMode: code - expr: rollup_pending_block_number{network!="staging-ignition"} + expr: rollup_pending_block_number instant: true intervalMs: 1000 legendFormat: __auto diff --git a/spartan/metrics/values.yaml b/spartan/metrics/values.yaml index 5919fc8c34b9..18ffe1d86c77 100644 --- a/spartan/metrics/values.yaml +++ b/spartan/metrics/values.yaml @@ -119,9 +119,8 @@ grafana: server: domain: env: - PRODUCTION_NAMESPACES_REGEX: "v2-testnet|staging-public|staging-ignition" + PRODUCTION_NAMESPACES_REGEX: "v2-testnet|staging-public" STAGING_PUBLIC_REGEX: "staging-public" - STAGING_IGNITION_REGEX: "staging-ignition|ignition-fisherman-sepolia" NEXT_SCENARIO_REGEX: "v[0-9]+-scenario|next-scenario" NEXT_NET_REGEX: "next-net" TESTNET_NAMESPACES_REGEX: "testnet|v[0-9]+-testnet" diff --git a/spartan/scripts/bench_10tps/bench_output.schema.json b/spartan/scripts/bench_10tps/bench_output.schema.json index a6c57437fd06..3685c72960d8 100644 --- a/spartan/scripts/bench_10tps/bench_output.schema.json +++ b/spartan/scripts/bench_10tps/bench_output.schema.json @@ -19,7 +19,9 @@ "const": "3", "description": "Bump when breaking the schema. Old JSONs keep their previous version so the dashboard can render them side-by-side. v3: timeSeries entries carry `series: [{labels, points}]` instead of bare `points` to support per-pod / per-label data." }, - "run": { "$ref": "#/$defs/runMeta" }, + "run": { + "$ref": "#/$defs/runMeta" + }, "summary": { "$ref": "#/$defs/summary", "description": "Scalar reductions — one number per run. Shown on the dashboard trend page and duplicated into index.json so the index can render headline numbers without fetching every run." @@ -31,30 +33,42 @@ "blocks": { "type": "array", "description": "Per-block records parsed from structured logs (each block emits one `Processed N successful txs and M failed txs ...` info line). Authoritative for per-block facts — Prometheus histograms cannot recover per-block samples.", - "items": { "$ref": "#/$defs/blockRecord" } + "items": { + "$ref": "#/$defs/blockRecord" + } }, "events": { "type": "array", "description": "Discrete occurrences during the run (currently just chain prunes). Typically rendered as annotations on charts.", - "items": { "$ref": "#/$defs/event" } + "items": { + "$ref": "#/$defs/event" + } }, "sequencerStateSlots": { "type": "array", "description": "Per-slot sequencer state time budget reconstructed from structured state-transition logs. Optional for older runs and empty when sequencer debug logs were not enabled.", - "items": { "$ref": "#/$defs/sequencerStateSlot" } + "items": { + "$ref": "#/$defs/sequencerStateSlot" + } }, "notes": { "type": "array", - "items": { "type": "string" }, + "items": { + "type": "string" + }, "description": "Free-form operator notes (e.g. 'ran with doubled prover agents'). Optional." } }, - "$defs": { "runMeta": { "type": "object", "additionalProperties": false, - "required": ["runId", "startedAt", "endedAt", "namespace"], + "required": [ + "runId", + "startedAt", + "endedAt", + "namespace" + ], "properties": { "runId": { "type": "string", @@ -80,7 +94,12 @@ "format": "date-time", "description": "Wall-clock time the scraper began querying Prometheus. Typically endedAt + ~90s to let the OTel batch push (60s default) and one Prom scrape (15s) settle." }, - "namespace": { "type": "string", "examples": ["bench-10tps"] }, + "namespace": { + "type": "string", + "examples": [ + "bench-10tps" + ] + }, "gcpProject": { "type": "string", "description": "GCP project containing the GKE container logs." @@ -97,12 +116,25 @@ "type": "string", "description": "Aztec image tag or digest the validators ran." }, - "targetTps": { "type": "number", "minimum": 0 }, - "testDurationSeconds": { "type": "integer", "minimum": 0 }, - "workload": { "type": "string", "examples": ["sha256_hash_1024"] }, + "targetTps": { + "type": "number", + "minimum": 0 + }, + "testDurationSeconds": { + "type": "integer", + "minimum": 0 + }, + "workload": { + "type": "string", + "examples": [ + "sha256_hash_1024" + ] + }, "aztecConfig": { "type": "object", - "additionalProperties": { "type": "string" }, + "additionalProperties": { + "type": "string" + }, "description": "Curated subset of Aztec config env vars captured from a running validator pod. Keys include SEQ_MAX_TX_PER_BLOCK, P2P_MAX_PENDING_TX_COUNT, AZTEC_MANA_TARGET, etc. Lets the dashboard show 'pool=20k vs pool=1000' alongside compared runs." }, "infrastructure": { @@ -118,12 +150,16 @@ "properties": { "instanceTypes": { "type": "array", - "items": { "type": "string" }, + "items": { + "type": "string" + }, "description": "Distinct Kubernetes node instance types used by this role." }, "nodePools": { "type": "array", - "items": { "type": "string" }, + "items": { + "type": "string" + }, "description": "Distinct node pools used by this role, when exposed as node labels." }, "nodes": { @@ -131,13 +167,27 @@ "items": { "type": "object", "additionalProperties": false, - "required": ["role", "podName", "nodeName"], + "required": [ + "role", + "podName", + "nodeName" + ], "properties": { - "role": { "type": "string" }, - "podName": { "type": "string" }, - "nodeName": { "type": "string" }, - "instanceType": { "type": "string" }, - "nodePool": { "type": "string" } + "role": { + "type": "string" + }, + "podName": { + "type": "string" + }, + "nodeName": { + "type": "string" + }, + "instanceType": { + "type": "string" + }, + "nodePool": { + "type": "string" + } } } } @@ -150,10 +200,14 @@ "type": "object", "additionalProperties": false, "properties": { - "enabled": { "type": "boolean" }, + "enabled": { + "type": "boolean" + }, "profile": { "type": "string", - "examples": ["network-requirements"] + "examples": [ + "network-requirements" + ] } } }, @@ -172,7 +226,9 @@ "minimum": 1, "description": "PromQL range-query step." }, - "promUrl": { "type": "string" }, + "promUrl": { + "type": "string" + }, "waitForPendingZero": { "type": "boolean", "description": "Whether live scraping waited for validator pending TxPool depth to reach zero before querying." @@ -183,18 +239,42 @@ "description": "Maximum time the scraper was allowed to wait for validator pending TxPool depth to reach zero." }, "pendingAtScrape": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "minimum": 0, "description": "Validator pending TxPool depth observed when scraping started, or null when the pending drain gate was disabled." }, "pendingByRoleAtScrape": { - "type": ["object", "null"], + "type": [ + "object", + "null" + ], "description": "Pending TxPool depth by pod role at scrape start. RPC/full-node pending can remain non-zero after validators drain, which indicates load that did not propagate to proposers before expiry.", "additionalProperties": false, "properties": { - "rpc": { "type": ["number", "null"], "minimum": 0 }, - "validator": { "type": ["number", "null"], "minimum": 0 }, - "fullNode": { "type": ["number", "null"], "minimum": 0 } + "rpc": { + "type": [ + "number", + "null" + ], + "minimum": 0 + }, + "validator": { + "type": [ + "number", + "null" + ], + "minimum": 0 + }, + "fullNode": { + "type": [ + "number", + "null" + ], + "minimum": 0 + } } }, "pendingWaitTimedOut": { @@ -205,103 +285,239 @@ } } }, - "summary": { "type": "object", "additionalProperties": false, - "required": ["headlineKpi", "inclusionTpsMean", "targetTps"], + "required": [ + "headlineKpi", + "inclusionTpsMean", + "targetTps" + ], "properties": { "headlineKpi": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "description": "inclusionTpsMean / targetTps. The single number on the dashboard top strip." }, - "targetTps": { "type": "number" }, + "targetTps": { + "type": "number" + }, "inclusionTpsMean": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "description": "Inclusion throughput over the observed inclusion window. Uses exact block-log throughput when block records are available, otherwise falls back to the Prometheus inclusionTps mean." }, "inclusionTpsPeak": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "description": "Peak sampled Prometheus rolling inclusion rate over the observed scrape window." }, - "inclusionLatencyP50Ms": { "type": ["number", "null"] }, - "inclusionLatencyP95Ms": { "type": ["number", "null"] }, - "inclusionLatencyP99Ms": { "type": ["number", "null"] }, - "blockBuildDurationP50Ms": { "type": ["number", "null"] }, - "blockBuildDurationP95Ms": { "type": ["number", "null"] }, - "publicProcessorTxDurationP50Ms": { "type": ["number", "null"] }, - "publicProcessorTxDurationP95Ms": { "type": ["number", "null"] }, + "inclusionLatencyP50Ms": { + "type": [ + "number", + "null" + ] + }, + "inclusionLatencyP95Ms": { + "type": [ + "number", + "null" + ] + }, + "inclusionLatencyP99Ms": { + "type": [ + "number", + "null" + ] + }, + "blockBuildDurationP50Ms": { + "type": [ + "number", + "null" + ] + }, + "blockBuildDurationP95Ms": { + "type": [ + "number", + "null" + ] + }, + "publicProcessorTxDurationP50Ms": { + "type": [ + "number", + "null" + ] + }, + "publicProcessorTxDurationP95Ms": { + "type": [ + "number", + "null" + ] + }, "totalTxsMined": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Exact sum from per-block logs. Null when block logs were unavailable and inclusionTpsMean came from Prometheus." }, "totalTxsFailed": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Exact sum from per-block logs. Null when block logs were unavailable." }, "totalSilentSkipCount": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Sum of per-block silentlySkippedCount. > 0 means the post-process blob-field revert path fired during the run." }, "totalSilentSkipDurationMs": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Sum of per-block silentlySkippedDurationMs. Wall-clock 'wasted' on silently-skipped txs across the run." }, "reorgCount": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Count of `Chain pruned` events during the run." }, "deepestReorgBlocks": { - "type": ["integer", "null"], + "type": [ + "integer", + "null" + ], "description": "Max (fromBlock - toBlock) across reorg events. 0 if no reorgs." } } }, - "timeSeriesSection": { "type": "object", "description": "Key = stable slug (used by the dashboard to look up series); value = a series. Slugs decouple the display name from Prometheus metric names (which may be renamed across Aztec versions).", - "additionalProperties": { "$ref": "#/$defs/timeSeries" }, + "additionalProperties": { + "$ref": "#/$defs/timeSeries" + }, "properties": { - "inclusionTps": { "$ref": "#/$defs/timeSeries" }, - "ingressTps": { "$ref": "#/$defs/timeSeries" }, - "mempoolSizeRpc": { "$ref": "#/$defs/timeSeries" }, - "mempoolSizeValidator": { "$ref": "#/$defs/timeSeries" }, - "mempoolSizeFullNode": { "$ref": "#/$defs/timeSeries" }, - "mempoolMinedMax": { "$ref": "#/$defs/timeSeries" }, - "mempoolEvictedByReasonRate": { "$ref": "#/$defs/timeSeries" }, - "mempoolRejectedByReasonRate": { "$ref": "#/$defs/timeSeries" }, - "blockBuildDurationP95": { "$ref": "#/$defs/timeSeries" }, - "blockBuildDurationP50": { "$ref": "#/$defs/timeSeries" }, - "publicProcessorTxDurationP95": { "$ref": "#/$defs/timeSeries" }, - "publicProcessorTxDurationP50": { "$ref": "#/$defs/timeSeries" }, - "publicProcessorGasRate": { "$ref": "#/$defs/timeSeries" }, - "checkpointLastBlockToBroadcastP95": { "$ref": "#/$defs/timeSeries" }, - "checkpointBlockCountMean": { "$ref": "#/$defs/timeSeries" }, - "checkpointTxCountMean": { "$ref": "#/$defs/timeSeries" }, - "l1InclusionDelayP95": { "$ref": "#/$defs/timeSeries" }, - "gossipLatencyP95": { "$ref": "#/$defs/timeSeries" }, + "inclusionTps": { + "$ref": "#/$defs/timeSeries" + }, + "ingressTps": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolSizeRpc": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolSizeValidator": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolSizeFullNode": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolMinedMax": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolEvictedByReasonRate": { + "$ref": "#/$defs/timeSeries" + }, + "mempoolRejectedByReasonRate": { + "$ref": "#/$defs/timeSeries" + }, + "blockBuildDurationP95": { + "$ref": "#/$defs/timeSeries" + }, + "blockBuildDurationP50": { + "$ref": "#/$defs/timeSeries" + }, + "publicProcessorTxDurationP95": { + "$ref": "#/$defs/timeSeries" + }, + "publicProcessorTxDurationP50": { + "$ref": "#/$defs/timeSeries" + }, + "txMinedDelayP50": { + "$ref": "#/$defs/timeSeries" + }, + "txMinedDelayP95": { + "$ref": "#/$defs/timeSeries" + }, + "txMinedDelayP99": { + "$ref": "#/$defs/timeSeries" + }, + "publicProcessorGasRate": { + "$ref": "#/$defs/timeSeries" + }, + "checkpointLastBlockToBroadcastP95": { + "$ref": "#/$defs/timeSeries" + }, + "checkpointBlockCountMean": { + "$ref": "#/$defs/timeSeries" + }, + "checkpointTxCountMean": { + "$ref": "#/$defs/timeSeries" + }, + "l1InclusionDelayP95": { + "$ref": "#/$defs/timeSeries" + }, + "gossipLatencyP95": { + "$ref": "#/$defs/timeSeries" + }, "peerCountMean": { "$ref": "#/$defs/timeSeries", "description": "Legacy aggregate peer-count series kept for older run JSONs." }, - "peerCountByRole": { "$ref": "#/$defs/timeSeries" }, - "peerCountByValidator": { "$ref": "#/$defs/timeSeries" }, - "attestationsCollectDurationMean": { "$ref": "#/$defs/timeSeries" }, - "attestationsCollectAllowanceMean": { "$ref": "#/$defs/timeSeries" }, - "txCollectorTxsFromMempoolRate": { "$ref": "#/$defs/timeSeries" }, - "txCollectorTxsFromP2pRate": { "$ref": "#/$defs/timeSeries" }, - "txCollectorMissingRate": { "$ref": "#/$defs/timeSeries" }, - "txCollectorRequestedFractionMean": { "$ref": "#/$defs/timeSeries" }, - "txCollectorRequestDelayP95": { "$ref": "#/$defs/timeSeries" }, - "sequencerStateDurationP95": { "$ref": "#/$defs/timeSeries" } + "peerCountByRole": { + "$ref": "#/$defs/timeSeries" + }, + "peerCountByValidator": { + "$ref": "#/$defs/timeSeries" + }, + "attestationsCollectDurationMean": { + "$ref": "#/$defs/timeSeries" + }, + "attestationsCollectAllowanceMean": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorTxsFromMempoolRate": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorTxsFromP2pRate": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorMissingRate": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorRequestedFractionMean": { + "$ref": "#/$defs/timeSeries" + }, + "txCollectorRequestDelayP95": { + "$ref": "#/$defs/timeSeries" + }, + "sequencerStateDurationP95": { + "$ref": "#/$defs/timeSeries" + } } }, - "timeSeries": { "type": "object", "additionalProperties": false, - "required": ["metric", "source", "series"], + "required": [ + "metric", + "source", + "series" + ], "properties": { "metric": { "type": "string", @@ -309,73 +525,112 @@ }, "unit": { "type": "string", - "examples": ["ms", "tps", "mana/s", "count"] + "examples": [ + "ms", + "tps", + "mana/s", + "count" + ] }, "source": { "type": "string", - "const": "promql", - "description": "Future-proofing: other series sources may exist (e.g. 'log-aggregated') with different provenance semantics." + "enum": [ + "promql", + "client_observed" + ], + "description": "Provenance: 'promql' = scraped via PromQL from cluster Prometheus; 'client_observed' = computed in this scraper from per-tx records emitted by n_tps.test.ts (e.g. headline tx_mined_delay)." }, "query": { "type": "string", - "description": "Exact PromQL used. Kept for audit: if a value looks wrong, the query is the first thing to check." + "description": "For source=promql: exact PromQL used. For source=client_observed: a human-readable description of the computation. Kept for audit: if a value looks wrong, the query is the first thing to check." + }, + "stepSeconds": { + "type": "integer", + "minimum": 1 }, - "stepSeconds": { "type": "integer", "minimum": 1 }, "series": { "type": "array", "description": "One entry per Prometheus series returned by the query. Single-series queries (e.g. inclusionTps) emit one entry with empty labels. Multi-series queries (per-pod, per-topic, per-rejection-reason, etc.) emit one entry per label combination.", - "items": { "$ref": "#/$defs/seriesEntry" } + "items": { + "$ref": "#/$defs/seriesEntry" + } } } }, - "seriesEntry": { "type": "object", "additionalProperties": false, - "required": ["labels", "points"], + "required": [ + "labels", + "points" + ], "properties": { "labels": { "type": "object", - "additionalProperties": { "type": "string" }, + "additionalProperties": { + "type": "string" + }, "description": "Prometheus labels that disambiguate this series. Empty {} for single-series queries. Common keys: k8s_pod_name, aztec_gossip_topic_name, rejection_reason, aztec_sequencer_state." }, "points": { "type": "array", "description": "Samples ordered by unixEpoch ascending. Missing samples (Prom didn't scrape in that window) are omitted rather than interpolated — consumers decide how to handle gaps.", - "items": { "$ref": "#/$defs/tsPoint" } + "items": { + "$ref": "#/$defs/tsPoint" + } } } }, - "tsPoint": { "type": "object", "additionalProperties": false, - "required": ["unixEpoch", "value"], + "required": [ + "unixEpoch", + "value" + ], "properties": { "unixEpoch": { "type": "integer", "description": "Seconds since unix epoch for this sample. Dashboards normalise to time-within-run via unixEpoch - run.startedAt at render time." }, "value": { - "type": ["number", "null"], + "type": [ + "number", + "null" + ], "description": "Metric value. null if Prom returned NaN / no data for this step." } } }, - "blockRecord": { "type": "object", "additionalProperties": false, - "required": ["blockNumber", "blockNumberInTest", "minedAt"], + "required": [ + "blockNumber", + "blockNumberInTest", + "minedAt" + ], "properties": { - "blockNumber": { "type": "integer", "minimum": 0 }, + "blockNumber": { + "type": "integer", + "minimum": 0 + }, "blockNumberInTest": { "type": "integer", "description": "blockNumber - firstBlockInTest. First block mined after run.startedAt is 0." }, - "minedAt": { "type": "string", "format": "date-time" }, - "successfulCount": { "type": "integer", "minimum": 0 }, - "failedCount": { "type": "integer", "minimum": 0 }, + "minedAt": { + "type": "string", + "format": "date-time" + }, + "successfulCount": { + "type": "integer", + "minimum": 0 + }, + "failedCount": { + "type": "integer", + "minimum": 0 + }, "silentlySkippedCount": { "type": "integer", "minimum": 0, @@ -386,16 +641,26 @@ "minimum": 0, "description": "Wall-clock time spent on silently-skipped txs in this block. Added 2026-04-22." }, - "buildDurationSeconds": { "type": "number", "minimum": 0 }, + "buildDurationSeconds": { + "type": "number", + "minimum": 0 + }, "totalPublicGas": { "type": "object", "additionalProperties": false, "properties": { - "daGas": { "type": "integer" }, - "l2Gas": { "type": "integer" } + "daGas": { + "type": "integer" + }, + "l2Gas": { + "type": "integer" + } } }, - "totalSizeInBytes": { "type": "integer", "minimum": 0 }, + "totalSizeInBytes": { + "type": "integer", + "minimum": 0 + }, "source": { "type": "string", "const": "log", @@ -403,15 +668,29 @@ } } }, - "event": { "type": "object", "additionalProperties": false, - "required": ["at", "type"], + "required": [ + "at", + "type" + ], "properties": { - "at": { "type": "string", "format": "date-time" }, - "type": { "type": "string", "enum": ["chainPruned", "slotSummary"] }, - "source": { "type": "string", "const": "log" }, + "at": { + "type": "string", + "format": "date-time" + }, + "type": { + "type": "string", + "enum": [ + "chainPruned", + "slotSummary" + ] + }, + "source": { + "type": "string", + "const": "log" + }, "fromBlock": { "type": "integer", "description": "For chainPruned: the pre-prune tip." @@ -428,20 +707,40 @@ "type": "integer", "description": "For slotSummary: wall-clock slot in which the checkpoint was built." }, - "checkpointNumber": { "type": "integer" }, - "sourcePod": { "type": "string" }, + "checkpointNumber": { + "type": "integer" + }, + "sourcePod": { + "type": "string" + }, "proposer": { "type": "string", "description": "Validator/proposer address selected for this slot." }, - "attestorAddress": { "type": "string" }, - "publisherAddress": { "type": "string" }, - "blocksBuilt": { "type": "number", "minimum": 0 }, - "txCount": { "type": "number", "minimum": 0 }, - "totalMana": { "type": "number", "minimum": 0 }, + "attestorAddress": { + "type": "string" + }, + "publisherAddress": { + "type": "string" + }, + "blocksBuilt": { + "type": "number", + "minimum": 0 + }, + "txCount": { + "type": "number", + "minimum": 0 + }, + "totalMana": { + "type": "number", + "minimum": 0 + }, "blockBuildFailures": { "type": "array", - "items": { "type": "object", "additionalProperties": true } + "items": { + "type": "object", + "additionalProperties": true + } }, "checkpointBuildFailure": { "type": "object", @@ -459,11 +758,16 @@ } } }, - "sequencerStateSlot": { "type": "object", "additionalProperties": false, - "required": ["slotNumber", "startedAt", "endedAt", "totalMs", "states"], + "required": [ + "slotNumber", + "startedAt", + "endedAt", + "totalMs", + "states" + ], "properties": { "slotNumber": { "type": "integer", @@ -490,10 +794,13 @@ }, "states": { "type": "object", - "additionalProperties": { "type": "number", "minimum": 0 }, + "additionalProperties": { + "type": "number", + "minimum": 0 + }, "description": "Map from SequencerState name to total milliseconds spent in that state during this slot." } } } } -} +} \ No newline at end of file diff --git a/spartan/scripts/bench_10tps/bench_scrape.ts b/spartan/scripts/bench_10tps/bench_scrape.ts index 3f819585bcfd..f2bfdc301a39 100755 --- a/spartan/scripts/bench_10tps/bench_scrape.ts +++ b/spartan/scripts/bench_10tps/bench_scrape.ts @@ -53,6 +53,7 @@ type Args = { targetTps: number; workload: string; output: string | undefined; + inclusionRecords: string | undefined; waitForPendingZero: boolean; maxPendingWaitSeconds: number; }; @@ -78,6 +79,10 @@ function parseArgs(): Args { argv.indexOf("--output") === -1 ? undefined : argv[argv.indexOf("--output") + 1], + inclusionRecords: + argv.indexOf("--inclusion-records") === -1 + ? undefined + : argv[argv.indexOf("--inclusion-records") + 1], waitForPendingZero: !argv.includes("--no-wait-for-pending-zero") && (argv.includes("--wait-for-pending-zero") || @@ -134,6 +139,128 @@ type SeriesEntry = { points: TsPoint[]; }; +// --- Inclusion records (client-observed per-tx timing from n_tps.test.ts) --- + +// Subset of TxInclusionData (yarn-project/.../tx_metrics.ts) that we care +// about. Records are emitted into /tmp/n_tps_timing_data.json under the +// `inclusionRecords` key, filtered to the high-value group, so this is the +// authoritative client-observed inclusion-latency dataset for the run. +type InclusionRecord = { + txHash: string; + sentAtMs: number; + minedAtMs: number; + blocknumber: number; +}; + +async function loadInclusionRecords( + path: string | undefined, +): Promise { + if (!path) return []; + try { + const raw = await readFile(path, "utf8"); + const parsed = JSON.parse(raw) as { + inclusionRecords?: InclusionRecord[]; + }; + const records = parsed.inclusionRecords ?? []; + log(`Loaded ${records.length} inclusion records`, { path }); + return records; + } catch (err) { + log("inclusion records load failed", { + path, + err: err instanceof Error ? err.message : String(err), + }); + return []; + } +} + +// Nearest-rank quantile. Returns null on empty input. +function quantile(sorted: number[], p: number): number | null { + if (sorted.length === 0) return null; + const idx = Math.min(sorted.length - 1, Math.floor(p * sorted.length)); + return sorted[idx]; +} + +function deltasMs(records: InclusionRecord[]): number[] { + const out: number[] = []; + for (const r of records) { + if (r.sentAtMs > 0 && r.minedAtMs > 0) { + const d = r.minedAtMs - r.sentAtMs; + if (d > 0) out.push(d); + } + } + return out; +} + +function inclusionLatencyScalarMs( + records: InclusionRecord[], + p: number, +): number | null { + const sorted = deltasMs(records).sort((a, b) => a - b); + return quantile(sorted, p); +} + +// Bin records by sentAt minute, compute per-bin quantile. Matches the +// `[1m]` window semantics the old Prom-based tx_mined_delay queries used. +function inclusionLatencyTimeSeriesPoints( + records: InclusionRecord[], + startedAtEpoch: number, + endedAtEpoch: number, + p: number, + bucketSec = 60, +): TsPoint[] { + const bins = new Map(); + for (const r of records) { + if (r.sentAtMs <= 0 || r.minedAtMs <= 0) continue; + const sentSec = Math.floor(r.sentAtMs / 1000); + if (sentSec < startedAtEpoch || sentSec > endedAtEpoch) continue; + const d = r.minedAtMs - r.sentAtMs; + if (d <= 0) continue; + const bin = Math.floor(sentSec / bucketSec) * bucketSec; + const arr = bins.get(bin) ?? []; + arr.push(d); + bins.set(bin, arr); + } + const points: TsPoint[] = []; + for (const bin of [...bins.keys()].sort((a, b) => a - b)) { + const arr = bins.get(bin)!.sort((a, b) => a - b); + points.push({ unixEpoch: bin, value: quantile(arr, p) }); + } + return points; +} + +function buildInclusionLatencyTimeSeries( + records: InclusionRecord[], + startedAtEpoch: number, + endedAtEpoch: number, + p: number, +): { + metric: string; + unit: string; + source: string; + query: string; + stepSeconds: number; + series: SeriesEntry[]; +} { + return { + metric: "n_tps_test.tx_inclusion_time", + unit: "ms", + source: "client_observed", + query: `n_tps.test.ts inclusionRecords (group=tx_inclusion_time), quantile=${p}, 60s bins by sentAtMs`, + stepSeconds: 60, + series: [ + { + labels: {}, + points: inclusionLatencyTimeSeriesPoints( + records, + startedAtEpoch, + endedAtEpoch, + p, + ), + }, + ], + }; +} + const parseValue = (v: string | undefined): number | null => v === undefined || v === "NaN" ? null : Number(v); @@ -1408,6 +1535,7 @@ type SummaryArgs = { timeSeries: Record; blocks: BlockRecord[]; events: Event[]; + inclusionRecords: InclusionRecord[]; }; async function buildSummary(a: SummaryArgs): Promise> { @@ -1463,24 +1591,17 @@ async function buildSummary(a: SummaryArgs): Promise> { const oneShotQuantile = (q: number, bucket: string) => `histogram_quantile(${q}, sum by (le)(rate(${bucket}${NS}[${windowSpec}])))`; - const [ - inclLatP50, - inclLatP95, - inclLatP99, - buildP50, - buildP95, - ppTxP50, - ppTxP95, - ] = await Promise.all([ - safeInstant( - oneShotQuantile(0.5, "aztec_mempool_tx_mined_delay_milliseconds_bucket"), - ), - safeInstant( - oneShotQuantile(0.95, "aztec_mempool_tx_mined_delay_milliseconds_bucket"), - ), - safeInstant( - oneShotQuantile(0.99, "aztec_mempool_tx_mined_delay_milliseconds_bucket"), - ), + // Inclusion-latency quantiles are now computed from per-tx client-observed + // records emitted by n_tps.test.ts (high-value group only). The other + // histogram-based scalars below still come from Prometheus. + const inclLatP50 = inclusionLatencyScalarMs(a.inclusionRecords, 0.5); + const inclLatP95 = inclusionLatencyScalarMs(a.inclusionRecords, 0.95); + const inclLatP99 = inclusionLatencyScalarMs(a.inclusionRecords, 0.99); + if (a.inclusionRecords.length === 0) { + log("No inclusion records loaded; summary.inclusionLatencyP* will be null"); + } + + const [buildP50, buildP95, ppTxP50, ppTxP95] = await Promise.all([ safeInstant( oneShotQuantile( 0.5, @@ -1794,6 +1915,34 @@ async function main(): Promise { log("Scraping Prometheus time-series"); const timeSeries = await scrapeTimeSeries(startedAtEpoch, promEndEpoch); + log("Loading client-observed inclusion records"); + const inclusionRecords = await loadInclusionRecords(args.inclusionRecords); + // Compute the headline inclusion-latency time series from per-tx records + // and inject under the same slugs the dashboard reads. No Prometheus + // dependency for these — they reflect the true client → block-visible + // wall-clock latency for high-value txs only. + (timeSeries as Record).txMinedDelayP50 = + buildInclusionLatencyTimeSeries( + inclusionRecords, + startedAtEpoch, + promEndEpoch, + 0.5, + ); + (timeSeries as Record).txMinedDelayP95 = + buildInclusionLatencyTimeSeries( + inclusionRecords, + startedAtEpoch, + promEndEpoch, + 0.95, + ); + (timeSeries as Record).txMinedDelayP99 = + buildInclusionLatencyTimeSeries( + inclusionRecords, + startedAtEpoch, + promEndEpoch, + 0.99, + ); + log("Scraping per-block logs from gcloud"); // Extend the log window by the drain buffer too — some blocks near endedAt // arrive in gcloud after the test stops sending. @@ -1848,6 +1997,7 @@ async function main(): Promise { timeSeries: timeSeries as Record, blocks, events, + inclusionRecords, }); const payload = { diff --git a/spartan/scripts/check_env_vars.sh b/spartan/scripts/check_env_vars.sh index 4622a51757f1..7976030a21f3 100755 --- a/spartan/scripts/check_env_vars.sh +++ b/spartan/scripts/check_env_vars.sh @@ -157,7 +157,6 @@ EXCLUDED_VARS_ARRAY=( "SERVICE" "SLACK_WEBHOOK_SECRET_NAME" "SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME" - "SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME" "SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME" "SLACK_WEBHOOK_NEXT_NET_SECRET_NAME" "SLACK_WEBHOOK_TESTNET_SECRET_NAME" diff --git a/spartan/scripts/deploy_network.sh b/spartan/scripts/deploy_network.sh index edd3526eb4b8..9ef173dfdacd 100755 --- a/spartan/scripts/deploy_network.sh +++ b/spartan/scripts/deploy_network.sh @@ -43,7 +43,7 @@ declare -A STAGE_TIMINGS ######################## NAMESPACE=${NAMESPACE} # required CLUSTER=${CLUSTER:-kind} -RESOURCE_PROFILE=${RESOURCE_PROFILE:-$([[ "${CLUSTER}" == "kind" ]] && echo "dev" || echo "prod")} +RESOURCE_PROFILE=${RESOURCE_PROFILE:?RESOURCE_PROFILE must be set by the environment} BASE_STATE_PATH="${CLUSTER}/${NAMESPACE}" # Don't try and retrieve contract addresses, instead allow deployed infra to read from network config @@ -586,15 +586,16 @@ PROVER_PUBLISHERS_PER_PROVER = ${PUBLISHERS_PER_PROVER} SENTINEL_ENABLED = ${SENTINEL_ENABLED:-null} SLASH_INACTIVITY_TARGET_PERCENTAGE = ${SLASH_INACTIVITY_TARGET_PERCENTAGE:-null} SLASH_INACTIVITY_PENALTY = ${SLASH_INACTIVITY_PENALTY:-null} -SLASH_PRUNE_PENALTY = ${SLASH_PRUNE_PENALTY:-null} SLASH_DATA_WITHHOLDING_PENALTY = ${SLASH_DATA_WITHHOLDING_PENALTY:-null} +SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS = ${SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS:-null} SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY = ${SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY:-null} SLASH_DUPLICATE_PROPOSAL_PENALTY = ${SLASH_DUPLICATE_PROPOSAL_PENALTY:-null} SLASH_DUPLICATE_ATTESTATION_PENALTY = ${SLASH_DUPLICATE_ATTESTATION_PENALTY:-null} -SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY = ${SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY:-null} +SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY = ${SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY:-null} SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY = ${SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY:-null} SLASH_UNKNOWN_PENALTY = ${SLASH_UNKNOWN_PENALTY:-null} SLASH_INVALID_BLOCK_PENALTY = ${SLASH_INVALID_BLOCK_PENALTY:-null} +SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY = ${SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY:-null} SLASH_OFFENSE_EXPIRATION_ROUNDS = ${SLASH_OFFENSE_EXPIRATION_ROUNDS:-null} SLASH_MAX_PAYLOAD_SIZE = ${SLASH_MAX_PAYLOAD_SIZE:-null} OTEL_COLLECTOR_ENDPOINT = "${OTEL_COLLECTOR_ENDPOINT}" diff --git a/spartan/scripts/network_pause.sh b/spartan/scripts/network_pause.sh index 706b9553b911..8cf0b2f02fd7 100755 --- a/spartan/scripts/network_pause.sh +++ b/spartan/scripts/network_pause.sh @@ -44,7 +44,7 @@ if kubectl get cronjob "$SNAPSHOT_CRONJOB" -n "$NAMESPACE" &>/dev/null; then log "Snapshotting $NAMESPACE" $scripts_dir/manual_snapshot.sh $NAMESPACE log "Waiting for snapshot upload" - sleep 60 # staging-ignition takes 28s + sleep 60 else log "Snapshot cronjob not found ($SNAPSHOT_CRONJOB), skipping snapshot" fi diff --git a/spartan/scripts/wait_for_l2_block.sh b/spartan/scripts/wait_for_l2_block.sh index f3b9278c4177..19f238234111 100755 --- a/spartan/scripts/wait_for_l2_block.sh +++ b/spartan/scripts/wait_for_l2_block.sh @@ -6,6 +6,7 @@ # AZTEC_SLOT_DURATION - seconds per L2 slot # AZTEC_EPOCH_DURATION - slots per epoch # AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET - epochs to wait for validator set +# AZTEC_LAG_IN_EPOCHS_FOR_RANDAO - epochs to wait for RANDAO seed set -euo pipefail @@ -13,25 +14,36 @@ namespace="${1:?namespace is required}" slot_duration="${AZTEC_SLOT_DURATION:?AZTEC_SLOT_DURATION must be set}" epoch_duration="${AZTEC_EPOCH_DURATION:?AZTEC_EPOCH_DURATION must be set}" -lag_epochs="${AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET:?AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET must be set}" +validator_lag_epochs="${AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET:?AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET must be set}" +randao_lag_epochs="${AZTEC_LAG_IN_EPOCHS_FOR_RANDAO:-$validator_lag_epochs}" -# Time to first block = lag_epochs * epoch_duration * slot_duration + buffer -# Add 2x buffer for deployment overhead, validator registration, etc. -expected_wait=$((lag_epochs * epoch_duration * slot_duration)) -max_wait=$((expected_wait * 2 + 120)) # 2x expected + 2min buffer +if [ "$validator_lag_epochs" -gt "$randao_lag_epochs" ]; then + lag_epochs="$validator_lag_epochs" +else + lag_epochs="$randao_lag_epochs" +fi + +# A fresh rollup needs lag + 1 complete epochs before the first committee-backed +# block can be proposed. Add half an epoch plus 5m for deployment and RPC jitter. +warmup_epochs=$((lag_epochs + 1)) +expected_wait=$((warmup_epochs * epoch_duration * slot_duration)) +buffer=$((epoch_duration * slot_duration / 2 + 300)) +max_wait="${L2_BLOCK_WAIT_TIMEOUT_SECONDS:-$((expected_wait + buffer))}" poll_interval=10 -echo "Waiting for L2 blocks (slot=${slot_duration}s, epoch=${epoch_duration} slots, lag=${lag_epochs} epochs)" -echo "Expected first block in ~${expected_wait}s, max wait ${max_wait}s" +echo "Waiting for L2 blocks (slot=${slot_duration}s, epoch=${epoch_duration} slots, validator_lag=${validator_lag_epochs}, randao_lag=${randao_lag_epochs})" +echo "Expected first block after ~${expected_wait}s from genesis, max wait ${max_wait}s from now" rpc_pod="${namespace}-rpc-aztec-node-0" +block_number_request="{\"jsonrpc\":\"2.0\",\"method\":\"node_getBlockNumber\",\"params\":[],\"id\":1}" elapsed=0 while [ $elapsed -lt $max_wait ]; do - block_number=$(kubectl exec -n "$namespace" "$rpc_pod" -- \ - curl -s -X POST http://localhost:8080 \ - -H "Content-Type: application/json" \ - -d '{"jsonrpc":"2.0","method":"node_getBlockNumber","params":[],"id":1}' 2>/dev/null \ - | grep -o '"result":[0-9]*' | grep -o '[0-9]*' || echo "0") + block_number=$(kubectl --request-timeout=10s exec -n "$namespace" "$rpc_pod" -- \ + sh -c "curl --max-time 5 -s -X POST http://localhost:8080 \ + -H \"Content-Type: application/json\" \ + -d \"\$1\" \ + | jq -r \".result // 0\"" \ + sh "$block_number_request" 2>/dev/null || echo "0") if [ "$block_number" -ge 1 ] 2>/dev/null; then echo "L2 block $block_number mined after ${elapsed}s" @@ -39,8 +51,16 @@ while [ $elapsed -lt $max_wait ]; do fi echo "Waiting for L2 blocks... (${elapsed}s/${max_wait}s, block: ${block_number:-0})" - sleep $poll_interval - elapsed=$((elapsed + poll_interval)) + sleep_for=$poll_interval + remaining=$((max_wait - elapsed)) + if [ "$remaining" -lt "$sleep_for" ]; then + sleep_for=$remaining + fi + if [ "$sleep_for" -le 0 ]; then + break + fi + sleep "$sleep_for" + elapsed=$((elapsed + sleep_for)) done echo "Warning: No L2 blocks mined after ${max_wait}s" diff --git a/spartan/terraform/deploy-aztec-infra/main.tf b/spartan/terraform/deploy-aztec-infra/main.tf index 13ea3870380f..46583be5f6fc 100644 --- a/spartan/terraform/deploy-aztec-infra/main.tf +++ b/spartan/terraform/deploy-aztec-infra/main.tf @@ -157,11 +157,11 @@ locals { validator_base_config = { chart = "aztec-validator" timeout = 1800 - values = [ + values = concat([ "common.yaml", "validator.yaml", "validator-resources-${var.VALIDATOR_RESOURCE_PROFILE}.yaml" - ] + ], var.VALIDATOR_HA_REPLICAS > 0 ? ["validator-resources-spot.yaml", "validator-resources-ha.yaml"] : []) inline_values = [yamlencode({ validator = { service = { @@ -170,18 +170,6 @@ locals { node = { logLevel = var.LOG_LEVEL } - # spread validator pods to different nodes to avoid having two validators with the same attester keys on the same physical node - topologySpreadConstraints = [{ - maxSkew = 1 - topologyKey = "kubernetes.io/hostname" - whenUnsatisfiable = "ScheduleAnyway" # soft constraint - labelSelector = { - matchLabels = { - "app.kubernetes.io/component" = "sequencer-node" - } - } - matchLabelKeys = ["apps.kubernetes.io/pod-index"] - }] } })] boot_node_host_path = "validator.node.env.BOOT_NODE_HOST" @@ -200,15 +188,16 @@ locals { "validator.sentinel.enabled" = var.SENTINEL_ENABLED "validator.slash.inactivityTargetPercentage" = var.SLASH_INACTIVITY_TARGET_PERCENTAGE "validator.slash.inactivityPenalty" = var.SLASH_INACTIVITY_PENALTY - "validator.slash.prunePenalty" = var.SLASH_PRUNE_PENALTY "validator.slash.dataWithholdingPenalty" = var.SLASH_DATA_WITHHOLDING_PENALTY + "validator.slash.dataWithholdingToleranceSlots" = var.SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS "validator.slash.proposeInvalidAttestationsPenalty" = var.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY "validator.slash.duplicateProposalPenalty" = var.SLASH_DUPLICATE_PROPOSAL_PENALTY "validator.slash.duplicateAttestationPenalty" = var.SLASH_DUPLICATE_ATTESTATION_PENALTY - "validator.slash.attestDescendantOfInvalidPenalty" = var.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY + "validator.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty" = var.SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY "validator.slash.attestInvalidCheckpointProposalPenalty" = var.SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY "validator.slash.unknownPenalty" = var.SLASH_UNKNOWN_PENALTY "validator.slash.invalidBlockPenalty" = var.SLASH_INVALID_BLOCK_PENALTY + "validator.slash.invalidCheckpointProposalPenalty" = var.SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY "validator.slash.offenseExpirationRounds" = var.SLASH_OFFENSE_EXPIRATION_ROUNDS "validator.slash.maxPayloadSize" = var.SLASH_MAX_PAYLOAD_SIZE "validator.node.env.TRANSACTIONS_DISABLED" = var.TRANSACTIONS_DISABLED diff --git a/spartan/terraform/deploy-aztec-infra/values/blob-sink-resources-mainnet.yaml b/spartan/terraform/deploy-aztec-infra/values/blob-sink-resources-mainnet.yaml deleted file mode 100644 index 17a98678a4b3..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/blob-sink-resources-mainnet.yaml +++ /dev/null @@ -1,41 +0,0 @@ -nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "4" - -replicaCount: 1 - -node: - nodeJsOptions: - - "--max-old-space-size=12288" - resources: - requests: - cpu: "2" - memory: "8Gi" - limits: - cpu: "3.5" - memory: "14Gi" - -persistence: - enabled: true - -statefulSet: - enabled: true - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi - -service: - type: ClusterIP - p2p: - enabled: true - nodePortEnabled: false - admin: - enabled: false - headless: - enabled: false diff --git a/spartan/terraform/deploy-aztec-infra/values/bot-resources-dev.yaml b/spartan/terraform/deploy-aztec-infra/values/bot-resources-dev.yaml index 435afd48a65d..8f555ff021e4 100644 --- a/spartan/terraform/deploy-aztec-infra/values/bot-resources-dev.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/bot-resources-dev.yaml @@ -1,4 +1,24 @@ bot: + nodeSelector: + local-ssd: "false" + node-type: "network" + cores: "2" + pool: "spot" + + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-spot + operator: Exists + + tolerations: + - key: "cloud.google.com/gke-spot" + operator: "Equal" + value: "true" + effect: "NoSchedule" + node: resources: requests: @@ -7,4 +27,3 @@ bot: limits: cpu: "0.5" memory: "2Gi" - diff --git a/spartan/terraform/deploy-aztec-infra/values/bot-resources-prod.yaml b/spartan/terraform/deploy-aztec-infra/values/bot-resources-prod.yaml index 6feb5f1183cf..66da7f06194a 100644 --- a/spartan/terraform/deploy-aztec-infra/values/bot-resources-prod.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/bot-resources-prod.yaml @@ -2,7 +2,8 @@ bot: nodeSelector: local-ssd: "false" node-type: "network" - cores: "8" + cores: "2" + pool: "spot" affinity: nodeAffinity: @@ -21,5 +22,8 @@ bot: node: resources: requests: - cpu: "7" - memory: "16Gi" + cpu: "0.5" + memory: "1Gi" + limits: + cpu: "2" + memory: "4Gi" diff --git a/spartan/terraform/deploy-aztec-infra/values/full-node-resources-2-core-spot.yaml b/spartan/terraform/deploy-aztec-infra/values/full-node-resources-2-core-spot.yaml deleted file mode 100644 index 63577f7db2c9..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/full-node-resources-2-core-spot.yaml +++ /dev/null @@ -1,52 +0,0 @@ -nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "2" - pool: "spot" - -affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: cloud.google.com/gke-spot - operator: Exists - -tolerations: - - key: "cloud.google.com/gke-spot" - operator: "Equal" - value: "true" - effect: "NoSchedule" - -replicaCount: 1 - -node: - resources: - requests: - cpu: "0.5" - memory: "2Gi" - limits: - cpu: "1.5" - memory: "6Gi" -persistence: - enabled: true - -statefulSet: - enabled: true - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 10Gi - -service: - p2p: - enabled: true - nodePortEnabled: false - admin: - enabled: true - headless: - enabled: false diff --git a/spartan/terraform/deploy-aztec-infra/values/full-node-resources-prod.yaml b/spartan/terraform/deploy-aztec-infra/values/full-node-resources-prod.yaml index f98197846110..841620706871 100644 --- a/spartan/terraform/deploy-aztec-infra/values/full-node-resources-prod.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/full-node-resources-prod.yaml @@ -2,19 +2,6 @@ nodeSelector: local-ssd: "false" node-type: "network" cores: "2" - -affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - node - topologyKey: "kubernetes.io/hostname" - namespaceSelector: {} - replicaCount: 1 node: diff --git a/spartan/terraform/deploy-aztec-infra/values/prover-resources-hi-tps.yaml b/spartan/terraform/deploy-aztec-infra/values/prover-resources-dev-hi-tps.yaml similarity index 82% rename from spartan/terraform/deploy-aztec-infra/values/prover-resources-hi-tps.yaml rename to spartan/terraform/deploy-aztec-infra/values/prover-resources-dev-hi-tps.yaml index 586e22a37d7b..dfb893b64230 100644 --- a/spartan/terraform/deploy-aztec-infra/values/prover-resources-hi-tps.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/prover-resources-dev-hi-tps.yaml @@ -14,18 +14,6 @@ node: cores: "8" hi-mem: "true" - affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - node - topologyKey: "kubernetes.io/hostname" - namespaceSelector: {} - persistence: enabled: true statefulSet: @@ -64,7 +52,6 @@ broker: - "--max-old-space-size=65536" resources: requests: - # should land on a 8-core node cpu: "5" memory: "54Gi" diff --git a/spartan/terraform/deploy-aztec-infra/values/prover-resources-mainnet.yaml b/spartan/terraform/deploy-aztec-infra/values/prover-resources-mainnet.yaml deleted file mode 100644 index d1f078b792a4..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/prover-resources-mainnet.yaml +++ /dev/null @@ -1,83 +0,0 @@ -node: - node: - nodeJsOptions: - - "--max-old-space-size=12288" - resources: - requests: - cpu: "2" - memory: "8Gi" - limits: - cpu: "3.5" - memory: "14Gi" - - nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "4" - - persistence: - enabled: true - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi - -broker: - replicaCount: 1 - - nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "4" - - persistence: - enabled: true - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 8Gi - node: - nodeJsOptions: - - "--max-old-space-size=12288" - resources: - requests: - cpu: "2" - memory: "8Gi" - limits: - cpu: "3.5" - memory: "14Gi" - -agent: - replicaCount: 4 - - node: - env: - HARDWARE_CONCURRENCY: "32" - resources: - requests: - memory: "115Gi" - cpu: "31" - - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: cloud.google.com/gke-spot - operator: Exists - - tolerations: - - key: "cloud.google.com/gke-spot" - operator: "Equal" - value: "true" - effect: "NoSchedule" diff --git a/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod-hi-tps.yaml b/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod-hi-tps.yaml index ffd0347086cc..0c8afe9bf385 100644 --- a/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod-hi-tps.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod-hi-tps.yaml @@ -1,12 +1,12 @@ node: node: + enableInspector: true + nodeJsOptions: + - "--max-old-space-size=65536" resources: requests: - cpu: "7.5" - memory: "55Gi" - - nodeJsOptions: - - "--max-old-space-size=61440" + cpu: "6" + memory: "54Gi" nodeSelector: local-ssd: "false" @@ -29,15 +29,6 @@ node: broker: replicaCount: 1 - node: - resources: - requests: - cpu: "7.5" - memory: "55Gi" - - nodeJsOptions: - - "--max-old-space-size=61440" - nodeSelector: local-ssd: "false" node-type: "network" @@ -54,18 +45,32 @@ broker: accessModes: [ReadWriteOnce] resources: requests: - storage: 64Gi + storage: 32Gi + node: + enableInspector: true + nodeJsOptions: + - "--max-old-space-size=65536" + resources: + requests: + cpu: "5" + memory: "54Gi" + agent: replicaCount: 4 node: env: - # the pod will be scheduled on a 32-core VM - HARDWARE_CONCURRENCY: "32" + HARDWARE_CONCURRENCY: "16" resources: requests: - memory: "115Gi" - cpu: "31" + cpu: "4" + memory: "16Gi" + limits: + cpu: "16" + memory: "64Gi" + + nodeSelector: + pool: "spot" affinity: nodeAffinity: diff --git a/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod.yaml b/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod.yaml index b1175d43bae1..91710c0e321c 100644 --- a/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/prover-resources-prod.yaml @@ -58,12 +58,17 @@ agent: node: env: - # the pod will be scheduled on a 32-core VM - HARDWARE_CONCURRENCY: "32" + HARDWARE_CONCURRENCY: "16" resources: requests: - memory: "115Gi" - cpu: "31" + cpu: "4" + memory: "16Gi" + limits: + cpu: "16" + memory: "64Gi" + + nodeSelector: + pool: "spot" affinity: nodeAffinity: diff --git a/spartan/terraform/deploy-aztec-infra/values/rpc-resources-mainnet.yaml b/spartan/terraform/deploy-aztec-infra/values/rpc-resources-mainnet.yaml deleted file mode 100644 index 0a421fae62c4..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/rpc-resources-mainnet.yaml +++ /dev/null @@ -1,39 +0,0 @@ -nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "4" - -replicaCount: 1 - -node: - nodeJsOptions: - - "--max-old-space-size=12288" - resources: - requests: - cpu: "2" - memory: "8Gi" - limits: - cpu: "3.5" - memory: "14Gi" -persistence: - enabled: true - -statefulSet: - enabled: true - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi - -service: - p2p: - enabled: true - nodePortEnabled: false - admin: - enabled: true - headless: - enabled: false diff --git a/spartan/terraform/deploy-aztec-infra/values/validator-resources-2-core-dedicated.yaml b/spartan/terraform/deploy-aztec-infra/values/validator-resources-2-core-dedicated.yaml deleted file mode 100644 index 52b309cb781a..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/validator-resources-2-core-dedicated.yaml +++ /dev/null @@ -1,22 +0,0 @@ -validator: - nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "2" - node: - resources: - requests: - cpu: "1.5" - memory: "4Gi" - limits: - cpu: "1.5" - memory: "6Gi" - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi diff --git a/spartan/terraform/deploy-aztec-infra/values/validator-resources-ha.yaml b/spartan/terraform/deploy-aztec-infra/values/validator-resources-ha.yaml new file mode 100644 index 000000000000..738996c3c859 --- /dev/null +++ b/spartan/terraform/deploy-aztec-infra/values/validator-resources-ha.yaml @@ -0,0 +1,10 @@ +validator: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + matchLabelKeys: + - apps.kubernetes.io/pod-index + labelSelector: + matchLabels: + app.kubernetes.io/component: sequencer-node diff --git a/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-hi-tps.yaml b/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-hi-tps.yaml deleted file mode 100644 index ea5ef92f5b67..000000000000 --- a/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-hi-tps.yaml +++ /dev/null @@ -1,23 +0,0 @@ -validator: - nodeSelector: - local-ssd: "false" - node-type: "network" - cores: "8" - hi-mem: "true" - node: - resources: - requests: - cpu: "7.5" - memory: "55Gi" - - nodeJsOptions: - - "--max-old-space-size=61440" - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi diff --git a/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-spot.yaml b/spartan/terraform/deploy-aztec-infra/values/validator-resources-spot.yaml similarity index 57% rename from spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-spot.yaml rename to spartan/terraform/deploy-aztec-infra/values/validator-resources-spot.yaml index 0c573f3ff06f..2699f98765f9 100644 --- a/spartan/terraform/deploy-aztec-infra/values/validator-resources-prod-spot.yaml +++ b/spartan/terraform/deploy-aztec-infra/values/validator-resources-spot.yaml @@ -18,22 +18,3 @@ validator: operator: "Equal" value: "true" effect: "NoSchedule" - - node: - resources: - requests: - cpu: "0.5" - memory: "2Gi" - limits: - cpu: "1.5" - memory: "6Gi" - - statefulSet: - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 16Gi diff --git a/spartan/terraform/deploy-aztec-infra/variables.tf b/spartan/terraform/deploy-aztec-infra/variables.tf index 538f37fd0b23..189ec5309838 100644 --- a/spartan/terraform/deploy-aztec-infra/variables.tf +++ b/spartan/terraform/deploy-aztec-infra/variables.tf @@ -24,49 +24,41 @@ variable "GCP_REGION" { variable "FULL_NODE_RESOURCE_PROFILE" { description = "Resource profile to use for the full node" type = string - default = "prod" } variable "P2P_BOOTSTRAP_RESOURCE_PROFILE" { description = "Resource profile to use for the p2p bootstrap" type = string - default = "prod" } variable "VALIDATOR_RESOURCE_PROFILE" { description = "Resource profile to use for the validator" type = string - default = "prod" } variable "PROVER_RESOURCE_PROFILE" { description = "Resource profile to use for the prover" type = string - default = "prod" } variable "RPC_RESOURCE_PROFILE" { description = "Resource profile to use for the rpc" type = string - default = "prod" } variable "BOT_RESOURCE_PROFILE" { description = "Resource profile to use for the bots" type = string - default = "prod" } variable "ARCHIVE_RESOURCE_PROFILE" { description = "Resource profile to use for the archive node" type = string - default = "prod" } variable "BLOB_SINK_RESOURCE_PROFILE" { description = "Resource profile to use for the blob sink" type = string - default = "prod" } variable "DEBUG_P2P_INSTRUMENT_MESSAGES" { @@ -466,14 +458,14 @@ variable "SLASH_INACTIVITY_PENALTY" { nullable = true } -variable "SLASH_PRUNE_PENALTY" { - description = "The slash prune penalty" +variable "SLASH_DATA_WITHHOLDING_PENALTY" { + description = "The slash data withholding penalty" type = string nullable = true } -variable "SLASH_DATA_WITHHOLDING_PENALTY" { - description = "The slash data withholding penalty" +variable "SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS" { + description = "L2 slots to wait after a checkpoint slot before slashing for data withholding" type = string nullable = true } @@ -496,8 +488,8 @@ variable "SLASH_DUPLICATE_ATTESTATION_PENALTY" { nullable = true } -variable "SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY" { - description = "The slash attest descendant of invalid penalty" +variable "SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY" { + description = "The slash propose descendant of invalid penalty" type = string nullable = true } @@ -520,6 +512,12 @@ variable "SLASH_INVALID_BLOCK_PENALTY" { nullable = true } +variable "SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY" { + description = "The slash invalid checkpoint proposal penalty" + type = string + nullable = true +} + variable "SLASH_OFFENSE_EXPIRATION_ROUNDS" { description = "The slash offense expiration rounds" type = string diff --git a/spartan/terraform/deploy-metrics/main.tf b/spartan/terraform/deploy-metrics/main.tf index 57467ee59855..bf30ce3d59ac 100644 --- a/spartan/terraform/deploy-metrics/main.tf +++ b/spartan/terraform/deploy-metrics/main.tf @@ -181,7 +181,6 @@ resource "helm_release" "aztec-gke-cluster" { data = [ { secretKey = "SLACK_WEBHOOK_URL", remoteRef = { key = var.SLACK_WEBHOOK_SECRET_NAME } }, { secretKey = "SLACK_WEBHOOK_STAGING_PUBLIC_URL", remoteRef = { key = var.SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME } }, - { secretKey = "SLACK_WEBHOOK_STAGING_IGNITION_URL", remoteRef = { key = var.SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME } }, { secretKey = "SLACK_WEBHOOK_NEXT_SCENARIO_URL", remoteRef = { key = var.SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME } }, { secretKey = "SLACK_WEBHOOK_NEXT_NET_URL", remoteRef = { key = var.SLACK_WEBHOOK_NEXT_NET_SECRET_NAME } }, { secretKey = "SLACK_WEBHOOK_DEVNET_URL", remoteRef = { key = var.SLACK_WEBHOOK_DEVNET_SECRET_NAME } }, diff --git a/spartan/terraform/deploy-metrics/variables.tf b/spartan/terraform/deploy-metrics/variables.tf index f7327e84877e..0745367539a5 100644 --- a/spartan/terraform/deploy-metrics/variables.tf +++ b/spartan/terraform/deploy-metrics/variables.tf @@ -34,12 +34,6 @@ variable "SLACK_WEBHOOK_STAGING_PUBLIC_SECRET_NAME" { default = "slack-webhook-staging-public-url" } -variable "SLACK_WEBHOOK_STAGING_IGNITION_SECRET_NAME" { - description = "Webhook for staging-ignition alerts" - type = string - default = "slack-webhook-staging-ignition-url" -} - variable "SLACK_WEBHOOK_NEXT_SCENARIO_SECRET_NAME" { description = "Webhook for next-scenario alerts" type = string diff --git a/spartan/testnet-runbook.md b/spartan/testnet-runbook.md index 44eb1f265e59..dbd68a76d6d7 100644 --- a/spartan/testnet-runbook.md +++ b/spartan/testnet-runbook.md @@ -39,7 +39,7 @@ After cutting a release, deploy a public testnet using the new Docker containers Verbose logging on Aztec nodes should be enabled by default using the following `ENV VARS`: - `LOG_JSON=1` -- `LOG_LEVEL=debug` +- `LOG_LEVEL="debug; info: json-rpc, simulator"` Deployments are initiated from CI by manually running the (_name pending_) workflow. diff --git a/yarn-project/BRANCHING.md b/yarn-project/BRANCHING.md index 371c44da4a22..b5b414b1f398 100644 --- a/yarn-project/BRANCHING.md +++ b/yarn-project/BRANCHING.md @@ -58,13 +58,12 @@ Functionally, it is `v1`. It deploys the following networks: - staging-public, which is used to test changes before releasing to testnet -- staging-ignition, which is use to test changes before releasing to mainnet Release-please has been configured on `v2`. When the release-please PR is merged, it creates a clean tag at the next minor version. For example, at the time of writing, we are at `v2.0.3-rc.4`. When the release please PR is merged, it will create a tag `v2.0.4`. -This will cause ci3.yml to run a release, and then deploy-staging-networks.yml to run and deploy the two networks mentioned above as well as `testnet`. +This will cause ci3.yml to run a release, and then deploy-staging-networks.yml to run and deploy the staging network mentioned above as well as `testnet`. #### hotfixes diff --git a/yarn-project/CLAUDE.md b/yarn-project/CLAUDE.md index 070a5398537a..d83eb0b1dc68 100644 --- a/yarn-project/CLAUDE.md +++ b/yarn-project/CLAUDE.md @@ -118,7 +118,7 @@ yarn workspace @aztec/ test --runInBand ```bash LOG_LEVEL=verbose yarn workspace @aztec/ test src/file.test.ts # Recommended -LOG_LEVEL=debug yarn workspace @aztec/ test src/file.test.ts # More detail +LOG_LEVEL="debug; info: json-rpc, simulator" yarn workspace @aztec/ test src/file.test.ts # More detail # Available levels: trace, debug, verbose, info, warn # Module-specific logging @@ -131,7 +131,7 @@ LOG_LEVEL='info; debug:sequencer,archiver' yarn workspace @aztec/ ### Style -- **Line width**: 120 characters (`printWidth: 120` in `.prettierrc.json`). Wrap comments and code at 120, not 80. +- **Line width**: 120 characters (`printWidth: 120` in `.prettierrc.json`). Wrap **everything** at 120 — code, inline comments, and JSDoc/block comments alike. Do not wrap at 80, 90, or 100 out of habit. Prettier does not reflow comment bodies, so an under-wrapped JSDoc paragraph will sit at ~90 chars forever unless you wrote it at 120 to begin with. ### Format diff --git a/yarn-project/archiver/src/index.ts b/yarn-project/archiver/src/index.ts index 78587150a24b..d5a4868892af 100644 --- a/yarn-project/archiver/src/index.ts +++ b/yarn-project/archiver/src/index.ts @@ -4,6 +4,7 @@ export * from './archiver.js'; export * from './modules/data_source_base.js'; export * from './modules/data_store_updater.js'; export * from './config.js'; +export * from './errors.js'; export { type L1PublishedData } from './structs/published.js'; export { diff --git a/yarn-project/archiver/src/modules/data_store_updater.test.ts b/yarn-project/archiver/src/modules/data_store_updater.test.ts index 6316a16d5198..fa3a8ec9be60 100644 --- a/yarn-project/archiver/src/modules/data_store_updater.test.ts +++ b/yarn-project/archiver/src/modules/data_store_updater.test.ts @@ -6,6 +6,7 @@ import { ContractInstancePublishedEvent } from '@aztec/protocol-contracts/instan import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { L2Block } from '@aztec/stdlib/block'; import { ContractClassLog, PrivateLog } from '@aztec/stdlib/logs'; +import { CheckpointHeader } from '@aztec/stdlib/rollup'; import '@aztec/stdlib/testing/jest'; import { BlockHeader } from '@aztec/stdlib/tx'; @@ -122,6 +123,134 @@ describe('ArchiverDataStoreUpdater', () => { expect(await store.contractInstances.getContractInstance(instanceAddress, timestamp)).toBeUndefined(); }); + it('reconciles a local proposed block with an L1 checkpoint at the same block number but different slot', async () => { + // Regression for issue fixed at https://github.com/AztecProtocol/aztec-packages/pull/23461 + // Local proposed block 1 at slot 125, containing a deployed contract instance. + const localBlock = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(125), + }); + localBlock.body.txEffects[0].contractClassLogs = [contractClassLog]; + localBlock.body.txEffects[0].privateLogs = [ + PrivateLog.fromBuffer(getSampleContractInstancePublishedEventPayload()), + ]; + await updater.addProposedBlock(localBlock); + + const timestamp = localBlock.header.globalVariables.timestamp + 1n; + expect(await store.contractInstances.getContractInstance(instanceAddress, timestamp)).toBeDefined(); + + // L1 confirmed a different block 1 at slot 124, containing the SAME deployed contract instance + // (the same user tx ended up on chain, just signed by a different proposer at a different slot). + // Without the fix the prune step misses the conflict because the slot does not match, and + // re-applying the L1 block's contract data throws "Contract instance ... already exists". + const l1Block = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(124), + }); + l1Block.body.txEffects[0].contractClassLogs = [contractClassLog]; + l1Block.body.txEffects[0].privateLogs = [PrivateLog.fromBuffer(getSampleContractInstancePublishedEventPayload())]; + expect(l1Block.archive.root.equals(localBlock.archive.root)).toBe(false); + + const published = makePublishedCheckpoint(makeCheckpoint([l1Block]), 10); + + await expect(updater.addCheckpoints([published])).resolves.not.toThrow(); + + // The L1 block must end up persisted, with its contract instance reachable. + const storedBlock = await store.blocks.getBlock({ number: BlockNumber(1) }); + expect(storedBlock?.archive.root.equals(l1Block.archive.root)).toBe(true); + expect(await store.contractInstances.getContractInstance(instanceAddress, timestamp)).toBeDefined(); + }); + + it('evicts higher-numbered proposed checkpoints that chain off pruned blocks on conflict', async () => { + // Local builds: block 1 (slot 125, checkpoint 1) → proposed checkpoint 1 + // block 2 (slot 126, checkpoint 2) → proposed checkpoint 2 + // block_store.addCheckpoints already deletes the proposed entry at the same number it stores, + // so the eviction code matters specifically for higher-numbered proposed checkpoints whose + // referenced blocks were pruned by the conflict. + const localBlock1 = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(125), + }); + await updater.addProposedBlock(localBlock1); + await store.blocks.addProposedCheckpoint({ + checkpointNumber: CheckpointNumber(1), + header: CheckpointHeader.empty(), + startBlock: BlockNumber(1), + blockCount: 1, + totalManaUsed: 0n, + feeAssetPriceModifier: 0n, + }); + + const localBlock2 = await L2Block.random(BlockNumber(2), { + checkpointNumber: CheckpointNumber(2), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(126), + lastArchive: localBlock1.archive, + }); + await updater.addProposedBlock(localBlock2); + await store.blocks.addProposedCheckpoint({ + checkpointNumber: CheckpointNumber(2), + header: CheckpointHeader.empty(), + startBlock: BlockNumber(2), + blockCount: 1, + totalManaUsed: 0n, + feeAssetPriceModifier: 0n, + }); + + expect(await store.blocks.getProposedCheckpointNumber()).toBe(2); + + // L1 publishes a conflicting block 1. Pruning takes out both local blocks; both proposed + // checkpoints must be evicted (proposed 1 by block_store.addCheckpoints, proposed 2 by us). + const l1Block = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(124), + }); + expect(l1Block.archive.root.equals(localBlock1.archive.root)).toBe(false); + + await updater.addCheckpoints([makePublishedCheckpoint(makeCheckpoint([l1Block]), 10)]); + + expect(await store.blocks.getLastProposedCheckpoint()).toBeUndefined(); + }); + + it('preserves a speculative local block at a later slot when L1 confirms the matching previous block', async () => { + // Local proposes block 1 at slot 100 and a speculative block 2 at slot 101 built atop it. + // Pipelining: block 2 is the start of proposed checkpoint 2 and must not be pruned just + // because L1 confirmed a checkpoint that only contains block 1. + const localBlock1 = await L2Block.random(BlockNumber(1), { + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(100), + }); + await updater.addProposedBlock(localBlock1); + + await store.blocks.addProposedCheckpoint({ + checkpointNumber: CheckpointNumber(1), + header: CheckpointHeader.empty(), + startBlock: BlockNumber(1), + blockCount: 1, + totalManaUsed: 0n, + feeAssetPriceModifier: 0n, + }); + + const localBlock2 = await L2Block.random(BlockNumber(2), { + checkpointNumber: CheckpointNumber(2), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + slotNumber: SlotNumber(101), + lastArchive: localBlock1.archive, + }); + await updater.addProposedBlock(localBlock2); + + // L1 confirms checkpoint 1 with the same block 1 as local. Speculative block 2 must survive. + await updater.addCheckpoints([makePublishedCheckpoint(makeCheckpoint([localBlock1]), 10)]); + + const storedBlock2 = await store.blocks.getBlock({ number: BlockNumber(2) }); + expect(storedBlock2?.archive.root.equals(localBlock2.archive.root)).toBe(true); + }); + it('removes contract data when checkpoints are unwound', async () => { // Create block with contract data and add it as a checkpoint const block = await L2Block.random(BlockNumber(1), { diff --git a/yarn-project/archiver/src/modules/data_store_updater.ts b/yarn-project/archiver/src/modules/data_store_updater.ts index 2fb394c497a4..56a1369201f9 100644 --- a/yarn-project/archiver/src/modules/data_store_updater.ts +++ b/yarn-project/archiver/src/modules/data_store_updater.ts @@ -160,9 +160,17 @@ export class ArchiverDataStoreUpdater { /** * Checks for local proposed blocks that do not match the ones to be checkpointed and prunes them. - * This method handles multiple checkpoints but returns after pruning the first conflict found. - * This is correct because pruning from the first conflict point removes all subsequent blocks, - * and when checkpoints are added afterward, they include all the correct blocks. + * Conflict detection is keyed on `blockNumber`: when a local proposed block and an L1 + * checkpointed block share a block number but live at different slots (e.g. a different proposer + * mined the same block number one slot earlier), we still treat them as a conflict and prune. + * The trailing per-checkpoint prune that handles "local has extra trailing blocks within the + * same slot as the published checkpoint" remains scoped by slot to preserve pipelining: local + * blocks that live at a later slot than the checkpoint being processed represent speculation + * atop the just-confirmed tip (and may be referenced by a pending proposed checkpoint), so we + * leave them in place. This method handles multiple checkpoints but returns after pruning the + * first conflict found. This is correct because pruning from the first conflict point removes + * all subsequent blocks, and when checkpoints are added afterward, they include all the correct + * blocks. */ private async pruneMismatchingLocalBlocks(checkpoints: PublishedCheckpoint[]): Promise { const [lastCheckpointedBlockNumber, lastBlockNumber] = await Promise.all([ @@ -176,7 +184,7 @@ export class ArchiverDataStoreUpdater { } // Get all uncheckpointed local blocks - const uncheckpointedLocalBlocks = await this.stores.blocks.getBlocks({ + const uncheckpointedLocalBlocks = await this.stores.blocks.getBlocksData({ from: BlockNumber.add(lastCheckpointedBlockNumber, 1), limit: lastBlockNumber - lastCheckpointedBlockNumber, }); @@ -186,19 +194,19 @@ export class ArchiverDataStoreUpdater { for (const publishedCheckpoint of checkpoints) { const checkpointBlocks = publishedCheckpoint.checkpoint.blocks; const slot = publishedCheckpoint.checkpoint.slot; - const localBlocksInSlot = uncheckpointedLocalBlocks.filter(b => b.slot === slot); if (checkpointBlocks.length === 0) { this.log.warn(`Checkpoint ${publishedCheckpoint.checkpoint.number} for slot ${slot} has no blocks`); continue; } - // Find the first checkpoint block that conflicts with an existing local block and prune local afterwards + // Find the first checkpoint block that conflicts with an existing local block and prune local afterwards. + // Conflict detection joins on block number only — same block number at a different slot is still a conflict. for (const checkpointBlock of checkpointBlocks) { const blockNumber = checkpointBlock.number; - const existingBlock = localBlocksInSlot.find(b => b.number === blockNumber); + const existingBlock = uncheckpointedLocalBlocks.find(b => b.header.getBlockNumber() === blockNumber); const blockInfos = { - existingBlock: existingBlock?.toBlockInfo(), + existingBlock: existingBlock?.header.toInspect(), checkpointBlock: checkpointBlock.toBlockInfo(), }; @@ -210,20 +218,24 @@ export class ArchiverDataStoreUpdater { } else { this.log.info(`Conflict detected at block ${blockNumber} between checkpointed and local block`, blockInfos); const prunedBlocks = await this.removeBlocksAfter(BlockNumber(blockNumber - 1)); + await this.evictProposedCheckpointsForPrunedBlocks(prunedBlocks); return { prunedBlocks, lastAlreadyInsertedBlockNumber }; } } - // If local has more blocks than the checkpoint (e.g., local has [2,3,4] but checkpoint has [2,3]), - // we need to prune the extra local blocks so they match what was checkpointed + // If the sequencer locally proposed extra blocks within this checkpoint's slot (e.g. local has + // [N, N+1] but L1 confirmed just [N]), prune the extras. Scoped to the checkpoint's slot so we + // do not throw away speculative blocks at later slots that belong to a pending proposed checkpoint. const lastCheckpointBlockNumber = checkpointBlocks.at(-1)!.number; - const lastLocalBlockNumber = localBlocksInSlot.at(-1)?.number; + const localBlocksInSlot = uncheckpointedLocalBlocks.filter(b => b.header.getSlot() === slot); + const lastLocalBlockNumber = localBlocksInSlot.at(-1)?.header.getBlockNumber(); if (lastLocalBlockNumber !== undefined && lastLocalBlockNumber > lastCheckpointBlockNumber) { this.log.warn( `Local chain for slot ${slot} ends at block ${lastLocalBlockNumber} but checkpoint ends at ${lastCheckpointBlockNumber}. Pruning blocks after block ${lastCheckpointBlockNumber}.`, ); const prunedBlocks = await this.removeBlocksAfter(lastCheckpointBlockNumber); + await this.evictProposedCheckpointsForPrunedBlocks(prunedBlocks); return { prunedBlocks, lastAlreadyInsertedBlockNumber }; } } @@ -261,6 +273,19 @@ export class ArchiverDataStoreUpdater { return result; } + /** + * Evicts pending proposed checkpoints that referenced any of the just-pruned blocks. Pruned + * blocks invalidate all proposed checkpoints from the lowest pruned block's checkpoint number + * onwards: those checkpoints either reference the pruned blocks directly or chain off them. + */ + private async evictProposedCheckpointsForPrunedBlocks(prunedBlocks: L2Block[]): Promise { + if (prunedBlocks.length === 0) { + return; + } + const fromCheckpointNumber = prunedBlocks[0].checkpointNumber; + await this.stores.blocks.evictProposedCheckpointsFrom(fromCheckpointNumber); + } + /** * Removes all blocks strictly after the given block number along with any logs and contract data. * Does not remove their checkpoints. diff --git a/yarn-project/archiver/src/modules/l1_synchronizer.ts b/yarn-project/archiver/src/modules/l1_synchronizer.ts index fe0f07a812bc..a0daa21d7c83 100644 --- a/yarn-project/archiver/src/modules/l1_synchronizer.ts +++ b/yarn-project/archiver/src/modules/l1_synchronizer.ts @@ -1076,6 +1076,19 @@ export class ArchiverL1Synchronizer implements Traceable { calldataArchiveRoot: calldataCheckpoint.archiveRoot.toString(), }, ); + // Both the locally-proposed checkpoint and the L1-confirmed one are signed by the + // slot proposer; emit a divergence event so the slasher can attribute equivocation. + // Only emit when the slots match — uncheckpointed entries are pruned above so this + // should always hold, but guard defensively to avoid mis-attributing a slash. + if (proposed.header.slotNumber === calldataCheckpoint.header.slotNumber) { + this.events.emit(L2BlockSourceEvents.CheckpointEquivocationDetected, { + type: L2BlockSourceEvents.CheckpointEquivocationDetected, + slotNumber: calldataCheckpoint.header.slotNumber, + checkpointNumber: calldataCheckpoint.checkpointNumber, + l1ArchiveRoot: calldataCheckpoint.archiveRoot, + proposedArchiveRoot: proposed.archive.root, + }); + } // Return a divergence signal so the caller can evict pending >= this number return { diverged: true, fromCheckpointNumber: proposed.checkpointNumber }; } diff --git a/yarn-project/archiver/src/store/block_store.ts b/yarn-project/archiver/src/store/block_store.ts index 46490f35bd77..6e68cd2e41c8 100644 --- a/yarn-project/archiver/src/store/block_store.ts +++ b/yarn-project/archiver/src/store/block_store.ts @@ -13,7 +13,10 @@ import { BlockHash, Body, CommitteeAttestation, + GENESIS_CHECKPOINT_HEADER_HASH, L2Block, + type L2TipId, + type L2Tips, type ValidateCheckpointResult, deserializeValidateCheckpointResult, serializeValidateCheckpointResult, @@ -1129,6 +1132,174 @@ export class BlockStore { return typeof lastBlockNumber === 'number' ? BlockNumber(lastBlockNumber) : BlockNumber(INITIAL_L2_BLOCK_NUM - 1); } + /** + * Resolves all five L2 chain tips (proposed, proposedCheckpoint, checkpointed, proven, finalized) + * in a single read-only transaction so the snapshot is internally consistent. Each underlying + * record is read at most once: latest block, latest confirmed checkpoint, and latest pending + * checkpoint are each loaded directly (no separate "find the number, then look up data" hop), + * the proven/finalized checkpoint singletons are read once and their storage entries are + * reused if they coincide with the latest checkpoint, and per-tip block hashes are deduped + * when two tips land on the same block (e.g. finalized == proven, or proposedCheckpoint falls + * back to checkpointed when no pending checkpoint exists). + * + * The result is guaranteed to satisfy `finalized <= proven <= checkpointed <= proposed` (by + * block number). Genesis is represented by `(INITIAL_L2_BLOCK_NUM - 1)` and the supplied + * `genesisBlockHash`, paired with the synthetic genesis checkpoint id. + * + * @param genesisBlockHash - Block hash to report for the synthetic pre-initial block (used when + * a tip is still at genesis). + */ + async getL2TipsData(genesisBlockHash: BlockHash): Promise { + return await this.db.transactionAsync(async () => { + // Define genesis tips + const genesisBlockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1); + const genesisCheckpointNumber = CheckpointNumber(INITIAL_CHECKPOINT_NUMBER - 1); + const genesisBlockId = { number: genesisBlockNumber, hash: genesisBlockHash.toString() }; + const genesisCheckpointId = { + number: genesisCheckpointNumber, + hash: GENESIS_CHECKPOINT_HEADER_HASH.toString(), + }; + const genesisTip: L2TipId = { block: genesisBlockId, checkpoint: genesisCheckpointId }; + + // Load latest block and checkpoint entries + const [latestBlockEntry] = await toArray(this.#blocks.entriesAsync({ reverse: true, limit: 1 })); + const [proposedCheckpointEntry] = await toArray( + this.#proposedCheckpoints.entriesAsync({ reverse: true, limit: 1 }), + ); + const [latestCheckpointEntry] = await toArray(this.#checkpoints.entriesAsync({ reverse: true, limit: 1 })); + const latestCheckpointNumber = latestCheckpointEntry + ? CheckpointNumber(latestCheckpointEntry[0]) + : genesisCheckpointNumber; + + // Load proven and finalized checkpoint number pointers + const [provenRaw, finalizedRaw] = await Promise.all([ + this.#lastProvenCheckpoint.getAsync(), + this.#lastFinalizedCheckpoint.getAsync(), + ]); + + // Clamp to enforce finalized <= proven <= checkpointed. + const provenCheckpointNumber = CheckpointNumber(Math.min(provenRaw ?? 0, latestCheckpointNumber)); + const finalizedCheckpointNumber = CheckpointNumber(Math.min(finalizedRaw ?? 0, provenCheckpointNumber)); + + // Avoid loading the same checkpoint more than once + const checkpointStorageCache = new Map(); + if (latestCheckpointEntry) { + checkpointStorageCache.set(CheckpointNumber(latestCheckpointEntry[0]), latestCheckpointEntry[1]); + } + const loadCheckpointStorage = async (n: CheckpointNumber): Promise => { + if (n === 0) { + return undefined; + } + if (!checkpointStorageCache.has(n)) { + const checkpointStorage = await this.#checkpoints.getAsync(n); + if (!checkpointStorage) { + throw new CheckpointNotFoundError(n); + } + checkpointStorageCache.set(n, checkpointStorage); + } + return checkpointStorageCache.get(n)!; + }; + + // Load proven and finalized checkpoint storage entries + const provenCheckpoint = await loadCheckpointStorage(provenCheckpointNumber); + const finalizedCheckpoint = await loadCheckpointStorage(finalizedCheckpointNumber); + + // Avoid loading the same block hash multiple times when tips land on the same block + const blockHashCache = new Map(); + blockHashCache.set(genesisBlockNumber, genesisBlockHash.toString()); + if (latestBlockEntry) { + blockHashCache.set(latestBlockEntry[0], BlockHash.fromBuffer(latestBlockEntry[1].blockHash).toString()); + } + const loadBlockHash = async (n: BlockNumber): Promise => { + if (!blockHashCache.has(n)) { + const blockStorage = await this.#blocks.getAsync(n); + if (!blockStorage) { + throw new BlockNotFoundError(n); + } + const blockHash = BlockHash.fromBuffer(blockStorage.blockHash).toString(); + blockHashCache.set(n, blockHash); + } + return blockHashCache.get(n)!; + }; + + // Build proposed chain tip (this one has block only, no checkpoint) + const proposedBlockId = + latestBlockEntry === undefined + ? genesisBlockId + : { + number: BlockNumber(latestBlockEntry[0]), + hash: BlockHash.fromBuffer(latestBlockEntry[1].blockHash).toString(), + }; + + // Build other tips from checkpoint data, reading corresponding block data from the cache + const buildTipFromCheckpoint = async ( + stored: ProposedCheckpointStorage | CheckpointStorage | undefined, + ): Promise => { + if (!stored) { + return genesisTip; + } + const blockNumber = BlockNumber(stored.startBlock + stored.blockCount - 1); + const blockHash = await loadBlockHash(blockNumber); + const header = CheckpointHeader.fromBuffer(stored.header); + return { + block: { number: blockNumber, hash: blockHash }, + checkpoint: { number: CheckpointNumber(stored.checkpointNumber), hash: header.hash().toString() }, + }; + }; + + const checkpointedTip = await buildTipFromCheckpoint(latestCheckpointEntry?.[1]); + const provenTip = await buildTipFromCheckpoint(provenCheckpoint); + const finalizedTip = await buildTipFromCheckpoint(finalizedCheckpoint); + + // Proposed checkpoint falls back to the checkpoint tip if it's not set. And if local storage is + // inconsistent and the proposed checkpoint is behind the checkpointed tip, we patch that and + // report the checkpointed tip as the proposed checkpoint to maintain the invariant. + const proposedCheckpointTip = + proposedCheckpointEntry === undefined || proposedCheckpointEntry[0] <= latestCheckpointNumber + ? checkpointedTip + : await buildTipFromCheckpoint(proposedCheckpointEntry[1]); + + // A checkpointed block past the latest stored block would mean a checkpoint + // references blocks that aren't in blocks. + if (proposedBlockId.number < checkpointedTip.block.number) { + throw new Error( + `Inconsistent block store: latest block ${proposedBlockId.number} is behind checkpointed block ${checkpointedTip.block.number}`, + ); + } + + // Assert that checkpoint numbers are increasing + if ( + finalizedTip.checkpoint.number > provenTip.checkpoint.number || + provenTip.checkpoint.number > checkpointedTip.checkpoint.number || + checkpointedTip.checkpoint.number > proposedCheckpointTip.checkpoint.number + ) { + throw new Error( + `Inconsistent checkpoint numbers in chain tips: finalized=${finalizedTip.checkpoint.number} proven=${provenTip.checkpoint.number} checkpointed=${checkpointedTip.checkpoint.number} proposed=${proposedCheckpointTip.checkpoint.number}`, + ); + } + + // Assert block numbers are increasing + if ( + finalizedTip.block.number > provenTip.block.number || + provenTip.block.number > checkpointedTip.block.number || + checkpointedTip.block.number > proposedCheckpointTip.block.number || + proposedCheckpointTip.block.number > proposedBlockId.number + ) { + throw new Error( + `Inconsistent block numbers in chain tips: finalized=${finalizedTip.block.number} proven=${provenTip.block.number} checkpointed=${checkpointedTip.block.number} proposedCheckpoint=${proposedCheckpointTip.block.number} proposed=${proposedBlockId.number}`, + ); + } + + return { + proposed: proposedBlockId, + proposedCheckpoint: proposedCheckpointTip, + checkpointed: checkpointedTip, + proven: provenTip, + finalized: finalizedTip, + }; + }); + } + /** * Gets the most recent L1 block processed. * @returns The L1 block that published the latest L2 block @@ -1188,13 +1359,15 @@ export class BlockStore { } async getProvenCheckpointNumber(): Promise { - const [latestCheckpointNumber, provenCheckpointNumber] = await Promise.all([ - this.getLatestCheckpointNumber(), - this.#lastProvenCheckpoint.getAsync(), - ]); - return (provenCheckpointNumber ?? 0) > latestCheckpointNumber - ? latestCheckpointNumber - : CheckpointNumber(provenCheckpointNumber ?? 0); + return await this.db.transactionAsync(async () => { + const [latestCheckpointNumber, provenCheckpointNumber] = await Promise.all([ + this.getLatestCheckpointNumber(), + this.#lastProvenCheckpoint.getAsync(), + ]); + return (provenCheckpointNumber ?? 0) > latestCheckpointNumber + ? latestCheckpointNumber + : CheckpointNumber(provenCheckpointNumber ?? 0); + }); } async setProvenCheckpointNumber(checkpointNumber: CheckpointNumber) { @@ -1203,13 +1376,15 @@ export class BlockStore { } async getFinalizedCheckpointNumber(): Promise { - const [latestCheckpointNumber, finalizedCheckpointNumber] = await Promise.all([ - this.getLatestCheckpointNumber(), - this.#lastFinalizedCheckpoint.getAsync(), - ]); - return (finalizedCheckpointNumber ?? 0) > latestCheckpointNumber - ? latestCheckpointNumber - : CheckpointNumber(finalizedCheckpointNumber ?? 0); + return await this.db.transactionAsync(async () => { + const [provenCheckpointNumber, finalizedCheckpointNumber] = await Promise.all([ + this.getProvenCheckpointNumber(), + this.#lastFinalizedCheckpoint.getAsync(), + ]); + return (finalizedCheckpointNumber ?? 0) > provenCheckpointNumber + ? provenCheckpointNumber + : CheckpointNumber(finalizedCheckpointNumber ?? 0); + }); } setFinalizedCheckpointNumber(checkpointNumber: CheckpointNumber) { diff --git a/yarn-project/archiver/src/store/l2_tips_cache.ts b/yarn-project/archiver/src/store/l2_tips_cache.ts index bc69983fc722..68fa309a005b 100644 --- a/yarn-project/archiver/src/store/l2_tips_cache.ts +++ b/yarn-project/archiver/src/store/l2_tips_cache.ts @@ -1,12 +1,4 @@ -import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants'; -import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; -import { - type BlockData, - type BlockHash, - type CheckpointId, - GENESIS_CHECKPOINT_HEADER_HASH, - type L2Tips, -} from '@aztec/stdlib/block'; +import type { BlockHash, L2Tips } from '@aztec/stdlib/block'; import type { BlockStore } from './block_store.js'; @@ -20,10 +12,10 @@ export class L2TipsCache { #tipsPromise: Promise | undefined; /** - * Asymmetric by design: the genesis block hash is dynamic — derived from the injected initial header, - * which depends on `genesisTimestamp` and any prefilled state. The genesis checkpoint hash is static — - * checkpoint 0 is fully synthetic (no real checkpoint header exists at 0), so it stays at the protocol - * constant `GENESIS_CHECKPOINT_HEADER_HASH`. + * The genesis block hash is dynamic — derived from the injected initial header, which depends on + * `genesisTimestamp` and any prefilled state — so it is supplied here rather than read from store. + * The genesis checkpoint hash, by contrast, is the static protocol constant and is resolved + * inside the block store. */ constructor( private blockStore: BlockStore, @@ -32,115 +24,12 @@ export class L2TipsCache { /** Returns the cached L2 tips. Loads from the block store on first call. */ public getL2Tips(): Promise { - return (this.#tipsPromise ??= this.loadFromStore()); + return (this.#tipsPromise ??= this.blockStore.getL2TipsData(this.initialBlockHash)); } /** Reloads the L2 tips from the block store. Should be called after the writer transaction has committed. */ public async refresh(): Promise { - this.#tipsPromise = this.loadFromStore(); + this.#tipsPromise = this.blockStore.getL2TipsData(this.initialBlockHash); await this.#tipsPromise; } - - private async loadFromStore(): Promise { - const [ - latestBlockNumber, - provenBlockNumber, - proposedCheckpointBlockNumber, - checkpointedBlockNumber, - finalizedBlockNumber, - ] = await Promise.all([ - this.blockStore.getLatestL2BlockNumber(), - this.blockStore.getProvenBlockNumber(), - this.blockStore.getProposedCheckpointL2BlockNumber(), - this.blockStore.getCheckpointedL2BlockNumber(), - this.blockStore.getFinalizedL2BlockNumber(), - ]); - - const genesisBlockHeader = { - blockHash: this.initialBlockHash, - checkpointNumber: CheckpointNumber.ZERO, - } as const; - const beforeInitialBlockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1); - - const getBlockData = (blockNumber: BlockNumber) => - blockNumber > beforeInitialBlockNumber - ? this.blockStore.getBlockData({ number: blockNumber }) - : genesisBlockHeader; - - const [latestBlockData, provenBlockData, proposedCheckpointBlockData, checkpointedBlockData, finalizedBlockData] = - await Promise.all( - [ - latestBlockNumber, - provenBlockNumber, - proposedCheckpointBlockNumber, - checkpointedBlockNumber, - finalizedBlockNumber, - ].map(getBlockData), - ); - - if ( - !latestBlockData || - !provenBlockData || - !finalizedBlockData || - !checkpointedBlockData || - !proposedCheckpointBlockData - ) { - throw new Error('Failed to load block data for L2 tips'); - } - - const [provenCheckpointId, finalizedCheckpointId, proposedCheckpointId, checkpointedCheckpointId] = - await Promise.all([ - this.getCheckpointIdForBlock(provenBlockData), - this.getCheckpointIdForBlock(finalizedBlockData), - this.getCheckpointIdForProposedCheckpoint(checkpointedBlockData), - this.getCheckpointIdForBlock(checkpointedBlockData), - ]); - - return { - proposed: { number: latestBlockNumber, hash: latestBlockData.blockHash.toString() }, - proven: { - block: { number: provenBlockNumber, hash: provenBlockData.blockHash.toString() }, - checkpoint: provenCheckpointId, - }, - proposedCheckpoint: { - block: { number: proposedCheckpointBlockNumber, hash: proposedCheckpointBlockData.blockHash.toString() }, - checkpoint: proposedCheckpointId, - }, - finalized: { - block: { number: finalizedBlockNumber, hash: finalizedBlockData.blockHash.toString() }, - checkpoint: finalizedCheckpointId, - }, - checkpointed: { - block: { number: checkpointedBlockNumber, hash: checkpointedBlockData.blockHash.toString() }, - checkpoint: checkpointedCheckpointId, - }, - }; - } - - private async getCheckpointIdForProposedCheckpoint( - checkpointedBlockData: Pick, - ): Promise { - const checkpointData = await this.blockStore.getLastProposedCheckpoint(); - if (!checkpointData) { - return this.getCheckpointIdForBlock(checkpointedBlockData); - } - return { - number: checkpointData.checkpointNumber, - hash: checkpointData.header.hash().toString(), - }; - } - - private async getCheckpointIdForBlock(blockData: Pick): Promise { - const checkpointData = await this.blockStore.getCheckpointData(blockData.checkpointNumber); - if (!checkpointData) { - return { - number: CheckpointNumber.ZERO, - hash: GENESIS_CHECKPOINT_HEADER_HASH.toString(), - }; - } - return { - number: checkpointData.checkpointNumber, - hash: checkpointData.header.hash().toString(), - }; - } } diff --git a/yarn-project/aztec-node/src/aztec-node/config.ts b/yarn-project/aztec-node/src/aztec-node/config.ts index e279494485dc..9d59920335ac 100644 --- a/yarn-project/aztec-node/src/aztec-node/config.ts +++ b/yarn-project/aztec-node/src/aztec-node/config.ts @@ -60,6 +60,12 @@ export type AztecNodeConfig = ArchiverConfig & debugForceTxProofVerification: boolean; /** Whether to enable the prover node as a subsystem. */ enableProverNode: boolean; + /** + * Test-only: use the deterministic AutomineSequencer instead of the production Sequencer. + * Requires `aztecTargetCommitteeSize === 0` on the deployed rollup and anvil-backed L1. + * See `AUTOMINE_E2E_OPTS` in `end-to-end/src/fixtures/fixtures.ts`. + */ + useAutomineSequencer?: boolean; }; export const aztecNodeConfigMappings: ConfigMappingsType = { @@ -98,6 +104,11 @@ export const aztecNodeConfigMappings: ConfigMappingsType = { description: 'Whether to enable the prover node as a subsystem.', ...booleanConfigHelper(false), }, + useAutomineSequencer: { + env: 'USE_AUTOMINE_SEQUENCER', + description: 'Test-only: use AutomineSequencer instead of the production Sequencer.', + ...booleanConfigHelper(false), + }, }; /** diff --git a/yarn-project/aztec-node/src/aztec-node/server.test.ts b/yarn-project/aztec-node/src/aztec-node/server.test.ts index b4ca0084accd..462fa2cba60e 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.test.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.test.ts @@ -1031,6 +1031,81 @@ describe('aztec node', () => { }); }); + describe('pauseSequencer + setConfig', () => { + const INITIAL_MIN_TXS_PER_BLOCK = 2; + + let sequencerClient: MockProxy; + let nodeWithSequencer: AztecNodeService; + + beforeEach(() => { + const sequencer = mock(); + sequencer.getConfig.mockReturnValue({ minTxsPerBlock: INITIAL_MIN_TXS_PER_BLOCK } as any); + + sequencerClient = mock(); + sequencerClient.getSequencer.mockReturnValue(sequencer); + + nodeWithSequencer = new AztecNodeService( + nodeConfig, + p2p, + l2BlockSource, + mock(), + mock(), + mock(), + worldState, + sequencerClient, + undefined, + undefined, + undefined, + undefined, + undefined, + 12345, + rollupVersion.toNumber(), + globalVariablesBuilder, + mock(), + epochCache, + getPackageVersion(), + new TestCircuitVerifier(), + new TestCircuitVerifier(), + ); + }); + + it('keeps the sequencer frozen when setConfig updates minTxsPerBlock while paused', async () => { + await nodeWithSequencer.pauseSequencer(); + sequencerClient.updateConfig.mockClear(); + + await nodeWithSequencer.setConfig({ minTxsPerBlock: 1 }); + + // The sequencer must not receive the new minTxsPerBlock while paused; the freeze stays in place. + const updateCalls = sequencerClient.updateConfig.mock.calls; + const minTxsUpdates = updateCalls.filter(([cfg]) => 'minTxsPerBlock' in cfg); + expect(minTxsUpdates).toEqual([]); + }); + + it('resumeSequencer applies the value set via setConfig during pause (not the pre-pause value)', async () => { + await nodeWithSequencer.pauseSequencer(); + await nodeWithSequencer.setConfig({ minTxsPerBlock: 5 }); + sequencerClient.updateConfig.mockClear(); + + await nodeWithSequencer.resumeSequencer(); + + // Resume must use the test-supplied value (5), not the pre-pause snapshot (INITIAL_MIN_TXS_PER_BLOCK). + expect(sequencerClient.updateConfig).toHaveBeenCalledWith({ minTxsPerBlock: 5 }); + }); + + it('still forwards non-minTxsPerBlock config changes while paused', async () => { + await nodeWithSequencer.pauseSequencer(); + sequencerClient.updateConfig.mockClear(); + + const coinbase = EthAddress.random(); + await nodeWithSequencer.setConfig({ coinbase, minTxsPerBlock: 3 }); + + // coinbase still reaches the sequencer; only minTxsPerBlock is filtered. + const updateCalls = sequencerClient.updateConfig.mock.calls; + expect(updateCalls).toHaveLength(1); + expect(updateCalls[0][0]).toEqual({ coinbase }); + }); + }); + describe('getL2ToL1Messages', () => { const makeBlock = (slotNumber: number, l2ToL1MsgsByTx: Fr[][]): L2Block => { const block = L2Block.empty( diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 817ce3f0bf1d..edba020f1e27 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -1,4 +1,4 @@ -import { Archiver, createArchiver } from '@aztec/archiver'; +import { Archiver, L1ToL2MessagesNotReadyError, createArchiver } from '@aztec/archiver'; import { BBCircuitVerifier, BatchChonkVerifier, QueuedIVCVerifier } from '@aztec/bb-prover'; import { TestCircuitVerifier } from '@aztec/bb-prover/test'; import { type BlobClientInterface, createBlobClientWithFileStores } from '@aztec/blob-client/client'; @@ -20,6 +20,7 @@ import { retryUntil } from '@aztec/foundation/retry'; import { count } from '@aztec/foundation/string'; import { DateProvider, Timer } from '@aztec/foundation/timer'; import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees'; +import { isErrorClass } from '@aztec/foundation/types'; import { type KeyStore, KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore'; import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions'; import { createForwarderL1TxUtilsFromSigners, createL1TxUtilsFromSigners } from '@aztec/node-lib/factories'; @@ -34,15 +35,19 @@ import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { type ProverNode, type ProverNodeDeps, createProverNode } from '@aztec/prover-node'; import { createKeyStoreForProver } from '@aztec/prover-node/config'; import { + AutomineSequencer, FeeProviderImpl, GlobalVariableBuilder, SequencerClient, type SequencerPublisher, + createAutomineSequencer, } from '@aztec/sequencer-client'; import { PublicContractsDB, PublicProcessorFactory } from '@aztec/simulator/server'; import { AttestationsBlockWatcher, - EpochPruneWatcher, + BroadcastedInvalidCheckpointProposalWatcher, + CheckpointEquivocationWatcher, + DataWithholdingWatcher, type SlasherClientInterface, type Watcher, createSlasher, @@ -61,7 +66,12 @@ import { type NormalizedBlockParameter, inspectBlockParameter, } from '@aztec/stdlib/block'; -import { type CheckpointData, L1PublishedData, type PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import { + type CheckpointData, + CheckpointReexecutionTracker, + L1PublishedData, + type PublishedCheckpoint, +} from '@aztec/stdlib/checkpoint'; import type { ContractClassPublic, ContractDataSource, @@ -159,6 +169,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb private metrics: NodeMetrics; // Prevent two snapshot operations to happen simultaneously private isUploadingSnapshot = false; + // Saved minTxsPerBlock used by `pauseSequencer` to restore production-sequencer config on resume. + private sequencerPausedMinTxsPerBlock: number | undefined; public readonly tracer: Tracer; @@ -174,7 +186,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb protected readonly proverNode: ProverNode | undefined, protected readonly slasherClient: SlasherClientInterface | undefined, protected readonly validatorsSentinel: Sentinel | undefined, - protected readonly epochPruneWatcher: EpochPruneWatcher | undefined, + protected readonly dataWithholdingWatcher: DataWithholdingWatcher | undefined, protected readonly attestationsBlockWatcher: AttestationsBlockWatcher | undefined, protected readonly l1ChainId: number, protected readonly version: number, @@ -190,6 +202,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb private validatorClient?: ValidatorClient, private keyStoreManager?: KeystoreManager, private debugLogStore: DebugLogStore = new NullDebugLogStore(), + private readonly automineSequencer?: AutomineSequencer, ) { this.metrics = new NodeMetrics(telemetry, 'AztecNodeService'); this.tracer = telemetry.getTracer('AztecNodeService'); @@ -395,7 +408,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb /** Fetches checkpoint context for a set of blocks, deduplicating shared checkpoints. */ async #getCheckpointContextsForBlocks( blocks: { checkpointNumber: CheckpointNumber }[], - // TODO(palla): CheckpointNumber should be accepted by this lint rule ): Promise> { const unique = Array.from(new Set(blocks.map(b => b.checkpointNumber))); const entries = await Promise.all(unique.map(async n => [n, await this.#getCheckpointContext(n)] as const)); @@ -659,6 +671,9 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb let validatorClient: ValidatorClient | undefined; + // Tracks successful checkpoint re-execution by a checkpoint proposal handler. + const reexecutionTracker = new CheckpointReexecutionTracker(); + if (!config.disableValidator) { // Create validator client if required validatorClient = await createValidatorClient(config, { @@ -672,6 +687,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb l1ToL2MessageSource: archiver, keyStoreManager, blobClient, + reexecutionTracker, slashingProtectionDb: deps.slashingProtectionDb, }); @@ -708,6 +724,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb blobClient, dateProvider, telemetry, + reexecutionTracker, }).register(p2pClient, reexecute, archiver); } @@ -718,29 +735,50 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb await p2pClient.start(); let validatorsSentinel: Awaited> | undefined; - let epochPruneWatcher: EpochPruneWatcher | undefined; + let dataWithholdingWatcher: DataWithholdingWatcher | undefined; let attestationsBlockWatcher: AttestationsBlockWatcher | undefined; + let broadcastedInvalidCheckpointProposalWatcher: BroadcastedInvalidCheckpointProposalWatcher | undefined; + let checkpointEquivocationWatcher: CheckpointEquivocationWatcher | undefined; if (!proverOnly) { - validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, config); + validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, reexecutionTracker, config); if (validatorsSentinel && config.slashInactivityPenalty > 0n) { watchers.push(validatorsSentinel); } - if (config.slashPrunePenalty > 0n || config.slashDataWithholdingPenalty > 0n) { - epochPruneWatcher = new EpochPruneWatcher( + if (config.slashDataWithholdingPenalty > 0n) { + dataWithholdingWatcher = new DataWithholdingWatcher( + epochCache, archiver, + p2pClient.getTxProvider(), + p2pClient, + reexecutionTracker, + { chainId: config.l1ChainId, rollupAddress: config.rollupAddress }, + config, + ); + watchers.push(dataWithholdingWatcher); + } + + if (config.slashBroadcastedInvalidCheckpointProposalPenalty > 0n) { + broadcastedInvalidCheckpointProposalWatcher = new BroadcastedInvalidCheckpointProposalWatcher( + p2pClient, archiver, epochCache, - p2pClient.getTxProvider(), - validatorCheckpointsBuilder, config, ); - watchers.push(epochPruneWatcher); + watchers.push(broadcastedInvalidCheckpointProposalWatcher); + } + + if (config.slashDuplicateProposalPenalty > 0n) { + checkpointEquivocationWatcher = new CheckpointEquivocationWatcher(archiver, epochCache, config); + watchers.push(checkpointEquivocationWatcher); } // We assume we want to slash for invalid attestations unless all max penalties are set to 0 - if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashAttestDescendantOfInvalidPenalty > 0n) { + if ( + config.slashProposeInvalidAttestationsPenalty > 0n || + config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty > 0n + ) { attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config); watchers.push(attestationsBlockWatcher); } @@ -754,20 +792,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb await validatorsSentinel.start(); started.push(validatorsSentinel); } - if (epochPruneWatcher) { - await epochPruneWatcher.start(); - started.push(epochPruneWatcher); + if (dataWithholdingWatcher) { + await dataWithholdingWatcher.start(); + started.push(dataWithholdingWatcher); } if (attestationsBlockWatcher) { await attestationsBlockWatcher.start(); started.push(attestationsBlockWatcher); } + if (broadcastedInvalidCheckpointProposalWatcher) { + await broadcastedInvalidCheckpointProposalWatcher.start(); + started.push(broadcastedInvalidCheckpointProposalWatcher); + } + if (checkpointEquivocationWatcher) { + await checkpointEquivocationWatcher.start(); + started.push(checkpointEquivocationWatcher); + } log.info(`All p2p services started`); }) .catch(err => log.error('Failed to start p2p services after archiver sync', err)); // Validator enabled, create/start relevant service let sequencer: SequencerClient | undefined; + let automineSequencer: AutomineSequencer | undefined; let slasherClient: SlasherClientInterface | undefined; if (!config.disableValidator && validatorClient) { // We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher @@ -827,24 +874,54 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb debugLogStore, ); - sequencer = await SequencerClient.new(config, { - ...deps, - epochCache, - l1TxUtils, - funderL1TxUtils, - validatorClient, - p2pClient, - worldStateSynchronizer, - slasherClient, - checkpointsBuilder, - l2BlockSource: archiver, - l1ToL2MessageSource: archiver, - telemetry, - dateProvider, - blobClient, - nodeKeyStore: keyStoreManager!, - globalVariableBuilder, - }); + if (config.useAutomineSequencer) { + // Test-only path: deterministic, queue-driven sequencer for non-block-building e2e tests. + // See `AUTOMINE_E2E_OPTS` in `end-to-end/src/fixtures/fixtures.ts`. + automineSequencer = await createAutomineSequencer({ + config, + l1TxUtils, + funderL1TxUtils, + publicClient, + rollupContract, + epochCache, + blobClient, + telemetry, + dateProvider, + keyStoreManager: keyStoreManager!, + validatorClient, + checkpointsBuilder, + globalVariableBuilder, + worldStateSynchronizer, + archiver, + p2pClient, + l1Constants: { + l1GenesisTime, + slotDuration: Number(slotDuration), + ethereumSlotDuration: config.ethereumSlotDuration, + rollupManaLimit, + }, + log, + }); + } else { + sequencer = await SequencerClient.new(config, { + ...deps, + epochCache, + l1TxUtils, + funderL1TxUtils, + validatorClient, + p2pClient, + worldStateSynchronizer, + slasherClient, + checkpointsBuilder, + l2BlockSource: archiver, + l1ToL2MessageSource: archiver, + telemetry, + dateProvider, + blobClient, + nodeKeyStore: keyStoreManager!, + globalVariableBuilder, + }); + } } if (!options.dontStartSequencer && sequencer) { @@ -855,6 +932,14 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb log.warn(`Sequencer created but not started`); } + if (!options.dontStartSequencer && automineSequencer) { + await automineSequencer.start(); + started.push({ stop: () => automineSequencer!.stop() }); + log.verbose(`AutomineSequencer started`); + } else if (automineSequencer) { + log.warn(`AutomineSequencer created but not started`); + } + // Create prover node subsystem if enabled let proverNode: ProverNode | undefined; if (config.enableProverNode) { @@ -891,7 +976,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb proverNode, slasherClient, validatorsSentinel, - epochPruneWatcher, + dataWithholdingWatcher, attestationsBlockWatcher, ethereumChain.chainInfo.id, config.rollupVersion, @@ -907,6 +992,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb validatorClient, keyStoreManager, debugLogStore, + automineSequencer, ); return node; @@ -927,6 +1013,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb return this.sequencer; } + /** Test-only: returns the AutomineSequencer when wired via `useAutomineSequencer`. */ + public getAutomineSequencer(): AutomineSequencer | undefined { + return this.automineSequencer; + } + /** Returns the prover node subsystem, if enabled. */ public getProverNode(): ProverNode | undefined { return this.proverNode; @@ -1170,10 +1261,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb this.log.info(`Stopping Aztec Node`); await tryStop(this.attestationsBlockWatcher); await tryStop(this.validatorsSentinel); - await tryStop(this.epochPruneWatcher); + await tryStop(this.dataWithholdingWatcher); await tryStop(this.slasherClient); await Promise.all([tryStop(this.peerProofVerifier), tryStop(this.rpcProofVerifier)]); await tryStop(this.sequencer); + await tryStop(this.automineSequencer); await tryStop(this.proverNode); await tryStop(this.p2pClient); await tryStop(this.worldStateSynchronizer); @@ -1490,11 +1582,24 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb // the world state tree so simulation can take them into account. We detect if the next block would // start a new checkpoint by checking if the proposed checkpoint's block number matches the latest block number, // which means the next block would be the first block of the next checkpoint. + const targetCheckpoint = CheckpointNumber( + (l2Tips.proposedCheckpoint.checkpoint.number ?? CheckpointNumber.ZERO) + 1, + ); const nextCheckpointMessages: Fr[] | undefined = l2Tips.proposedCheckpoint.block.number === l2Tips.proposed.number - ? await this.l1ToL2MessageSource.getL1ToL2Messages( - CheckpointNumber((l2Tips.proposedCheckpoint.checkpoint.number ?? CheckpointNumber.ZERO) + 1), - ) + ? await this.l1ToL2MessageSource.getL1ToL2Messages(targetCheckpoint).catch(err => { + if (isErrorClass(err, L1ToL2MessagesNotReadyError)) { + this.log.warn( + `L1-to-L2 messages for checkpoint ${targetCheckpoint} are not ready yet (simulating without them)`, + ); + } else { + this.log.error( + `Failed to get L1-to-L2 messages for checkpoint ${targetCheckpoint} (simulating without them)`, + err, + ); + } + return undefined; + }) : undefined; // Request a new fork of the world state at the latest block number, and apply any overrides and next checkpoint messages to it before simulation @@ -1590,7 +1695,18 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb public async setConfig(config: Partial): Promise { const newConfig = { ...this.config, ...config }; - this.sequencer?.updateConfig(config); + // If the sequencer is currently paused via pauseSequencer(), record the caller's desired + // minTxsPerBlock as the restore value (so resumeSequencer applies it) and keep the freeze + // (MAX_SAFE_INTEGER) applied to the underlying sequencer. Without this guard, forwarding + // the new minTxsPerBlock to the sequencer would silently unpause block production while + // pauseSequencer() still considers it paused. + const sequencerUpdate = { ...config }; + if (this.sequencerPausedMinTxsPerBlock !== undefined && sequencerUpdate.minTxsPerBlock !== undefined) { + this.sequencerPausedMinTxsPerBlock = sequencerUpdate.minTxsPerBlock; + delete sequencerUpdate.minTxsPerBlock; + } + this.sequencer?.updateConfig(sequencerUpdate); + this.automineSequencer?.updateConfig(sequencerUpdate); this.slasherClient?.updateConfig(config); this.validatorsSentinel?.updateConfig(config); await this.p2pClient.updateP2PConfig(config); @@ -1735,6 +1851,41 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb return Promise.resolve(); } + public pauseSequencer(): Promise { + if (this.automineSequencer) { + this.automineSequencer.pause(); + return Promise.resolve(); + } + if (this.sequencer) { + if (this.sequencerPausedMinTxsPerBlock === undefined) { + this.sequencerPausedMinTxsPerBlock = this.sequencer.getSequencer().getConfig().minTxsPerBlock ?? 0; + this.sequencer.updateConfig({ minTxsPerBlock: Number.MAX_SAFE_INTEGER }); + this.log.info(`Sequencer paused (minTxsPerBlock set to MAX_SAFE_INTEGER)`, { + previousMinTxsPerBlock: this.sequencerPausedMinTxsPerBlock, + }); + } + return Promise.resolve(); + } + throw new BadRequestError('Cannot pause sequencer: no sequencer is running'); + } + + public resumeSequencer(): Promise { + if (this.automineSequencer) { + this.automineSequencer.resume(); + return Promise.resolve(); + } + if (this.sequencer) { + if (this.sequencerPausedMinTxsPerBlock !== undefined) { + const restored = this.sequencerPausedMinTxsPerBlock; + this.sequencerPausedMinTxsPerBlock = undefined; + this.sequencer.updateConfig({ minTxsPerBlock: restored }); + this.log.info(`Sequencer resumed (minTxsPerBlock restored)`, { minTxsPerBlock: restored }); + } + return Promise.resolve(); + } + throw new BadRequestError('Cannot resume sequencer: no sequencer is running'); + } + public getSlashOffenses(round: bigint | 'all' | 'current'): Promise { if (!this.slasherClient) { throw new Error(`Slasher client not enabled`); @@ -1835,6 +1986,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb } public async mineBlock(): Promise { + if (this.automineSequencer) { + await this.automineSequencer.buildEmptyBlock(); + return; + } if (!this.sequencer) { throw new BadRequestError('Cannot mine block: no sequencer is running'); } diff --git a/yarn-project/aztec-node/src/sentinel/README.md b/yarn-project/aztec-node/src/sentinel/README.md new file mode 100644 index 000000000000..5ab68d8d8cff --- /dev/null +++ b/yarn-project/aztec-node/src/sentinel/README.md @@ -0,0 +1,103 @@ +# Sentinel + +The Sentinel watches every committee member's behaviour each L2 slot, aggregates it into per-epoch performance once each epoch is fully observed, and emits inactivity slash payloads to the slasher. + +## Responsibilities + +- Classify per-slot proposer/attestor behaviour from local node observations. +- Persist a sliding window of per-slot history per validator. +- Roll up that history into per-epoch performance after each epoch ends. +- Decide which validators have been inactive for `slashInactivityConsecutiveEpochThreshold` consecutive epochs and emit `WANT_TO_SLASH_EVENT` with `OffenseType.INACTIVITY`. +- Expose validator stats to RPC consumers (`getValidatorStats`, `computeStats`). + +The sentinel is one of several watchers registered with the slasher; it does not vote or publish to L1 itself. + +## Inputs + +| Source | What it provides | +|---|---| +| `EpochCache` | Slot/epoch helpers, committee + proposer for a slot, escape-hatch state | +| `L2BlockSource` (archiver) | Synced slot, `chain-checkpointed` events, block headers | +| `P2PClient` | `getCheckpointAttestationsForSlot(slot, payloadHash)`, `hasBlockProposalsForSlot(slot)` | +| `CheckpointReexecutionTracker` | Local re-execution outcome for the proposal at each slot (`valid` / `invalid` / `unvalidated`) — populated by the validator client's `ProposalHandler` | +| L1-checkpointed events | `chain-checkpointed` populates `slotNumberToCheckpoint` with the canonical attestor set | + +## Two cadences + +`Sentinel.work()` runs every quarter L2 slot and drives two pipelines that operate independently: + +### 1. Per-slot recording (lag = 2 slots) + +`processSlot(currentSlot - 2)` runs once per slot. The 2-slot lag gives P2P attestations time to settle and lets the archiver catch up. It calls `getSlotActivity(slot, epoch, proposer, committee)` and writes per-validator statuses to `SentinelStore.historyMap`. History is a sliding window of `sentinelHistoryLengthInEpochs * epochDuration` slots (default 24 epochs). + +If `EpochCache.getCommittee(slot)` reports `isEscapeHatchOpen`, the slot is recorded as processed without writing any per-validator entries. + +### 2. Per-epoch evaluation (lag = `sentinelEpochEndBufferSlots` past the epoch's last slot) + +`processEpochEnds(currentSlot)` checks whether any epoch is now fully observable and not yet evaluated. An epoch is eligible once both: + +- the buffer has elapsed: `currentSlot − sentinelEpochEndBufferSlots ≥ lastSlotOfEpoch`, and +- per-slot recording has reached the epoch's last slot: `lastProcessedSlot ≥ lastSlotOfEpoch`. + +When eligible, `handleEpochEnd(epoch)` aggregates the slot-level statuses for that epoch into per-validator `{missed, total}`, persists the result to `SentinelStore.epochMap` (default 2000-epoch window), and runs the inactivity check. + +The aggregator catches up if multiple epochs become eligible at once (e.g. after a long backoff). + +## Six-case taxonomy + +For each slot, the proposer is assigned one of six statuses, ranked highest-confidence first: + +| # | Status | Trigger | Inactive party | +|---|---|---|---| +| 6 | `checkpoint-mined` | `slotNumberToCheckpoint.has(slot)` (a checkpoint covering this slot has landed on L1) | Attestors who didn't attest | +| 5 | `checkpoint-valid` | `tracker.getOutcomeForSlot(slot) === 'valid'` | Attestors who didn't attest | +| 4 | `checkpoint-invalid` | `tracker.getOutcomeForSlot(slot) === 'invalid'` (re-executed and rejected) | Proposer | +| 3 | `checkpoint-unvalidated` | `tracker.getOutcomeForSlot(slot) === 'unvalidated'` (validation aborted: missing data, timeout, etc.) | Proposer | +| 2 | `checkpoint-missed` | `p2p.hasBlockProposalsForSlot(slot)` true (blocks seen but no checkpoint proposal observed) | Proposer | +| 1 | `blocks-missed` | None of the above (no block proposals observed) | Proposer | + +Missing-attestor faults are only recorded in cases 5 and 6 — where the local node has positive evidence the checkpoint was valid or canonical. In cases 1–4 the proposer is at fault and no attestor penalty applies. + +Each non-proposer committee member is tagged: + +- `attestation-sent` — attestation seen on P2P (with valid signature) or in the L1 checkpoint's attestor set +- `attestation-missed` — only when proposer status is case 5 or 6 and the validator's attestation was not seen +- none — otherwise + +## Inactivity slashing + +`handleEpochPerformance(epoch, performance)`: + +1. Filter validators where `missed / total ≥ slashInactivityTargetPercentage`. +2. For each, call `checkPastInactivity` to require `slashInactivityConsecutiveEpochThreshold − 1` past epochs (from `SentinelStore.epochMap`) over the same threshold. Epochs where the validator was not on a committee are skipped, not counted against the streak. +3. Emit a single `WANT_TO_SLASH_EVENT` with one `WantToSlashArgs` per qualifying validator. + +`{missed, total}` only counts slots that had something happen (a proposal, an attestation, or a missed proposal opportunity). Slots where the validator was on the committee but no proposal occurred and they were not the proposer don't show up in either count — that prevents an offline validator from appearing as "5/10 missed" simply because half the epoch had no proposals. + +## Storage + +`SentinelStore` is an LMDB-backed KV store with two maps: + +- `historyMap` — validator address → serialized `[(slot, status)]` rolling window +- `epochMap` — validator address → serialized `[{epoch, missed, total}]` rolling window + +`SCHEMA_VERSION` controls on-disk compatibility; bumping it wipes the store on next open. The encoded status numbers live in `SentinelStore.statusToNumber`/`statusFromNumber`. + +## Configuration + +| Key | Env var | Default | Purpose | +|---|---|---|---| +| `sentinelEnabled` | `SENTINEL_ENABLED` | `false` | Master switch | +| `sentinelHistoryLengthInEpochs` | `SENTINEL_HISTORY_LENGTH_IN_EPOCHS` | `24` | Slot-history window, in epochs | +| `sentinelHistoricEpochPerformanceLengthInEpochs` | `SENTINEL_HISTORIC_EPOCH_PERFORMANCE_LENGTH_IN_EPOCHS` | `2000` | Per-epoch performance window | +| `sentinelEpochEndBufferSlots` | `SENTINEL_EPOCH_END_BUFFER_SLOTS` | `2` | Slots to wait past an epoch's last slot before evaluating it | + +The sentinel also reads slashing thresholds and L1 chain identifiers from `SentinelRuntimeConfig` (see `sentinel.ts`). + +## Files + +- `sentinel.ts` — main class +- `store.ts` — KV-backed persistence +- `config.ts` — `SentinelConfig` and env-var mappings +- `factory.ts` — `createSentinel` factory used by `AztecNodeService` +- `sentinel.test.ts` / `store.test.ts` — unit tests diff --git a/yarn-project/aztec-node/src/sentinel/config.ts b/yarn-project/aztec-node/src/sentinel/config.ts index 93fedeb6819e..163bbada989a 100644 --- a/yarn-project/aztec-node/src/sentinel/config.ts +++ b/yarn-project/aztec-node/src/sentinel/config.ts @@ -2,8 +2,9 @@ import { type ConfigMappingsType, booleanConfigHelper, numberConfigHelper } from export type SentinelConfig = { sentinelHistoryLengthInEpochs: number; - sentinelHistoricProvenPerformanceLengthInEpochs: number; + sentinelHistoricEpochPerformanceLengthInEpochs: number; sentinelEnabled: boolean; + sentinelEpochEndBufferSlots: number; }; export const sentinelConfigMappings: ConfigMappingsType = { @@ -13,8 +14,9 @@ export const sentinelConfigMappings: ConfigMappingsType = { ...numberConfigHelper(24), }, /** - * The number of L2 epochs kept of proven performance history for each validator. - * This value must be large enough so that we have proven performance for every validator + * The number of L2 epochs kept of per-epoch performance history for each validator. End-of-epoch + * activity is recorded here and used to decide consecutive-epoch inactivity slashing. + * This value must be large enough so that we have epoch performance for every validator * for at least slashInactivityConsecutiveEpochThreshold. Assuming this value is 3, * and the committee size is 48, and we have 10k validators, then we pick 48 out of 10k each draw. * For any fixed element, per-draw prob = 48/10000 = 0.0048. @@ -24,9 +26,9 @@ export const sentinelConfigMappings: ConfigMappingsType = { * - 95% chance: n = 1310 * - 99% chance: n = 1749 */ - sentinelHistoricProvenPerformanceLengthInEpochs: { - description: 'The number of L2 epochs kept of proven performance history for each validator.', - env: 'SENTINEL_HISTORIC_PROVEN_PERFORMANCE_LENGTH_IN_EPOCHS', + sentinelHistoricEpochPerformanceLengthInEpochs: { + description: 'The number of L2 epochs kept of per-epoch performance history for each validator.', + env: 'SENTINEL_HISTORIC_EPOCH_PERFORMANCE_LENGTH_IN_EPOCHS', ...numberConfigHelper(2000), }, sentinelEnabled: { @@ -34,4 +36,14 @@ export const sentinelConfigMappings: ConfigMappingsType = { env: 'SENTINEL_ENABLED', ...booleanConfigHelper(false), }, + /** + * Number of L2 slots to wait after the end of an epoch before computing the epoch's performance. + * The buffer allows P2P attestations and the local archiver to settle. Higher values reduce the + * risk of misjudging late-arriving activity at the cost of delayed slashing. + */ + sentinelEpochEndBufferSlots: { + description: 'Number of L2 slots after the end of an epoch before the sentinel evaluates it.', + env: 'SENTINEL_EPOCH_END_BUFFER_SLOTS', + ...numberConfigHelper(2), + }, }; diff --git a/yarn-project/aztec-node/src/sentinel/factory.ts b/yarn-project/aztec-node/src/sentinel/factory.ts index 0db6ac82874f..244d54a66a45 100644 --- a/yarn-project/aztec-node/src/sentinel/factory.ts +++ b/yarn-project/aztec-node/src/sentinel/factory.ts @@ -3,6 +3,7 @@ import { createLogger } from '@aztec/foundation/log'; import { createStore } from '@aztec/kv-store/lmdb-v2'; import type { P2PClient } from '@aztec/p2p'; import type { L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { ChainConfig } from '@aztec/stdlib/config'; import type { SlasherConfig } from '@aztec/stdlib/interfaces/server'; import type { DataStoreConfig } from '@aztec/stdlib/kv-store'; @@ -15,6 +16,7 @@ export async function createSentinel( epochCache: EpochCache, archiver: L2BlockSource, p2p: P2PClient, + reexecutionTracker: CheckpointReexecutionTracker, config: SentinelConfig & DataStoreConfig & SlasherConfig & Pick, logger = createLogger('node:sentinel'), ): Promise { @@ -23,10 +25,10 @@ export async function createSentinel( } const kvStore = await createStore('sentinel', SentinelStore.SCHEMA_VERSION, config, logger.getBindings()); const storeHistoryLength = config.sentinelHistoryLengthInEpochs * epochCache.getL1Constants().epochDuration; - const storeHistoricProvenPerformanceLength = config.sentinelHistoricProvenPerformanceLengthInEpochs; + const storeHistoricEpochPerformanceLength = config.sentinelHistoricEpochPerformanceLengthInEpochs; const sentinelStore = new SentinelStore(kvStore, { historyLength: storeHistoryLength, - historicProvenPerformanceLength: storeHistoricProvenPerformanceLength, + historicEpochPerformanceLength: storeHistoricEpochPerformanceLength, }); - return new Sentinel(epochCache, archiver, p2p, sentinelStore, config, logger); + return new Sentinel(epochCache, archiver, p2p, sentinelStore, reexecutionTracker, config, logger); } diff --git a/yarn-project/aztec-node/src/sentinel/sentinel.test.ts b/yarn-project/aztec-node/src/sentinel/sentinel.test.ts index 7bc4d050a71c..d28d49bc81a8 100644 --- a/yarn-project/aztec-node/src/sentinel/sentinel.test.ts +++ b/yarn-project/aztec-node/src/sentinel/sentinel.test.ts @@ -12,11 +12,15 @@ import { L2Block, type L2BlockSource, type L2BlockStream, - type L2BlockStreamEvent, getAttestationInfoFromPublishedCheckpoint, } from '@aztec/stdlib/block'; -import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; -import { type L1RollupConstants, getEpochAtSlot, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers'; +import { + Checkpoint, + CheckpointReexecutionTracker, + L1PublishedData, + PublishedCheckpoint, +} from '@aztec/stdlib/checkpoint'; +import { type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers'; import type { CheckpointAttestation } from '@aztec/stdlib/p2p'; import { TEST_COORDINATION_SIGNATURE_CONTEXT, @@ -41,6 +45,7 @@ describe('sentinel', () => { let archiver: MockProxy; let p2p: MockProxy; let blockStream: MockProxy; + let reexecutionTracker: CheckpointReexecutionTracker; let kvStore: AztecLMDBStoreV2; let store: SentinelStore; @@ -55,6 +60,7 @@ describe('sentinel', () => { slashInactivityPenalty: 100n, slashInactivityTargetPercentage: 0.8, slashInactivityConsecutiveEpochThreshold: 1, + sentinelEpochEndBufferSlots: 2, l1ChainId: TEST_COORDINATION_SIGNATURE_CONTEXT.chainId, rollupAddress: TEST_COORDINATION_SIGNATURE_CONTEXT.rollupAddress, }; @@ -65,9 +71,10 @@ describe('sentinel', () => { archiver.getGenesisBlockHash.mockReturnValue(GENESIS_BLOCK_HEADER_HASH); p2p = mock(); blockStream = mock(); + reexecutionTracker = new CheckpointReexecutionTracker(); kvStore = await openTmpStore('sentinel-test'); - store = new SentinelStore(kvStore, { historyLength: 10, historicProvenPerformanceLength: 5 }); + store = new SentinelStore(kvStore, { historyLength: 10, historicEpochPerformanceLength: 5 }); slot = SlotNumber(10); epoch = EpochNumber(0); @@ -94,13 +101,39 @@ describe('sentinel', () => { epochCache.isProposerPipeliningEnabled.mockReturnValue(false); epochCache.getL1Constants.mockReturnValue(l1Constants); - sentinel = new TestSentinel(epochCache, archiver, p2p, store, config, blockStream); + sentinel = new TestSentinel(epochCache, archiver, p2p, store, reexecutionTracker, config, blockStream); }); afterEach(async () => { await kvStore.close(); }); + describe('init', () => { + beforeEach(() => { + archiver.getBlockNumber.mockResolvedValue(BlockNumber(0)); + }); + + it('floors initialSlot at the archiver synced L2 slot when available', async () => { + const syncedSlot = SlotNumber(7); + epochCache.getSlotNow.mockReturnValue(SlotNumber(20)); + archiver.getSyncedL2SlotNumber.mockResolvedValue(syncedSlot); + + await sentinel.callProductionInit(); + + expect(sentinel.getInitialSlot()).toEqual(syncedSlot); + }); + + it('falls back to the wallclock slot when the archiver is not yet synced', async () => { + const wallclockSlot = SlotNumber(20); + epochCache.getSlotNow.mockReturnValue(wallclockSlot); + archiver.getSyncedL2SlotNumber.mockResolvedValue(undefined); + + await sentinel.callProductionInit(); + + expect(sentinel.getInitialSlot()).toEqual(wallclockSlot); + }); + }); + describe('getSlotActivity', () => { let signers: Secp256k1Signer[]; let validators: EthAddress[]; @@ -130,7 +163,7 @@ describe('sentinel', () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations); }); - it('flags checkpoint as mined', async () => { + it('flags checkpoint as mined when L1 has it (case 6)', async () => { // Create a checkpoint with a block at the target slot and emit chain-checkpointed event const checkpoint = await Checkpoint.random(CheckpointNumber(1), { numBlocks: 1, slotNumber: slot }); await emitCheckpointEvent(checkpoint); @@ -139,26 +172,49 @@ describe('sentinel', () => { expect(activity[proposer.toString()]).toEqual('checkpoint-mined'); }); - it('flags checkpoint as proposed when it is not mined but there are attestations', async () => { - p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations); + it('flags checkpoint as valid when tracker outcome is valid (case 5)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'valid', CheckpointNumber(1)); + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-valid'); + }); + + it('flags checkpoint as invalid when tracker outcome is invalid (case 4)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'invalid', CheckpointNumber(1)); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-invalid'); + }); + + it('flags checkpoint as unvalidated when tracker outcome is unvalidated (case 3)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'unvalidated'); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); - expect(activity[proposer.toString()]).toEqual('checkpoint-proposed'); + expect(activity[proposer.toString()]).toEqual('checkpoint-unvalidated'); }); - it('flags as blocks-missed when there are no attestations and no block proposals', async () => { + it('flags as blocks-missed when there is no tracker outcome and no block proposals (case 1)', async () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); p2p.hasBlockProposalsForSlot.mockResolvedValue(false); const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); expect(activity[proposer.toString()]).toEqual('blocks-missed'); }); - it('flags as checkpoint-missed when there are no attestations but block proposals exist', async () => { + it('flags as checkpoint-missed when block proposals exist but no checkpoint proposal (case 2)', async () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); p2p.hasBlockProposalsForSlot.mockResolvedValue(true); const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); expect(activity[proposer.toString()]).toEqual('checkpoint-missed'); }); + it('prefers L1-mined over tracker outcome', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'invalid', CheckpointNumber(1)); + const checkpoint = await Checkpoint.random(CheckpointNumber(1), { numBlocks: 1, slotNumber: slot }); + await emitCheckpointEvent(checkpoint); + + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-mined'); + }); + it('identifies attestors from p2p and archiver', async () => { // Create a checkpoint with a block at the target slot const checkpoint = await Checkpoint.random(CheckpointNumber(1), { numBlocks: 1, slotNumber: slot }); @@ -255,16 +311,18 @@ describe('sentinel', () => { expect(activity[committee[3].toString()]).toEqual('attestation-missed'); }); - it('identifies missed attestors if block is proposed', async () => { + it('identifies missed attestors when checkpoint proposal was re-executed valid', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'valid', CheckpointNumber(1)); p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations.slice(0, -1)); const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-valid'); expect(activity[committee[1].toString()]).toEqual('attestation-sent'); expect(activity[committee[2].toString()]).toEqual('attestation-sent'); expect(activity[committee[3].toString()]).toEqual('attestation-missed'); }); - it('does not tag attestors as missed if there was no block and no attestations', async () => { + it('does not tag attestors as missed if there was no block and no attestations (case 1)', async () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); p2p.hasBlockProposalsForSlot.mockResolvedValue(false); @@ -275,7 +333,7 @@ describe('sentinel', () => { expect(activity[committee[3].toString()]).not.toBeDefined(); }); - it('does not tag attestors as missed if blocks were proposed but checkpoint was missed', async () => { + it('does not tag attestors as missed if blocks were proposed but checkpoint was missed (case 2)', async () => { p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); p2p.hasBlockProposalsForSlot.mockResolvedValue(true); @@ -285,6 +343,25 @@ describe('sentinel', () => { expect(activity[committee[2].toString()]).not.toBeDefined(); expect(activity[committee[3].toString()]).not.toBeDefined(); }); + + it('does not tag attestors as missed when checkpoint is unvalidated (case 3)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'unvalidated'); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations.slice(0, -1)); + + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-unvalidated'); + // committee[1..3] should not be tagged as missed even though they didn't all attest + expect(activity[committee[3].toString()]).not.toBe('attestation-missed'); + }); + + it('does not tag attestors as missed when checkpoint is invalid (case 4)', async () => { + reexecutionTracker.recordOutcome(slot, block.archive.root, 'invalid', CheckpointNumber(1)); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue(attestations.slice(0, -1)); + + const activity = await sentinel.getSlotActivity(slot, epoch, proposer, committee); + expect(activity[proposer.toString()]).toEqual('checkpoint-invalid'); + expect(activity[committee[3].toString()]).not.toBe('attestation-missed'); + }); }); describe('computeStatsForValidator', () => { @@ -297,7 +374,7 @@ describe('sentinel', () => { it('computes stats correctly', () => { const stats = sentinel.computeStatsForValidator(validator, [ { slot: SlotNumber(1), status: 'checkpoint-mined' }, - { slot: SlotNumber(2), status: 'checkpoint-proposed' }, + { slot: SlotNumber(2), status: 'checkpoint-valid' }, { slot: SlotNumber(3), status: 'checkpoint-missed' }, { slot: SlotNumber(4), status: 'blocks-missed' }, { slot: SlotNumber(5), status: 'attestation-sent' }, @@ -316,6 +393,18 @@ describe('sentinel', () => { expect(stats.lastAttestation?.slot).toEqual(SlotNumber(5)); }); + it('counts checkpoint-invalid and checkpoint-unvalidated as missed proposals', () => { + const stats = sentinel.computeStatsForValidator(validator, [ + { slot: SlotNumber(1), status: 'checkpoint-mined' }, + { slot: SlotNumber(2), status: 'checkpoint-invalid' }, + { slot: SlotNumber(3), status: 'checkpoint-unvalidated' }, + { slot: SlotNumber(4), status: 'checkpoint-missed' }, + { slot: SlotNumber(5), status: 'blocks-missed' }, + ]); + expect(stats.missedProposals.count).toEqual(4); + expect(stats.missedProposals.total).toEqual(5); + }); + it('resets streaks correctly', () => { const stats = sentinel.computeStatsForValidator(validator, [ { slot: SlotNumber(1), status: 'checkpoint-mined' }, @@ -414,7 +503,7 @@ describe('sentinel', () => { ]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockProvenPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockProvenPerformance); jest.spyOn(sentinel, 'computeStatsForValidator').mockReturnValue({ address: validator, totalSlots: 2, @@ -433,7 +522,7 @@ describe('sentinel', () => { missedAttestations: { count: 0, currentStreak: 0, rate: 0, total: 0 }, history: mockHistory, }, - allTimeProvenPerformance: mockProvenPerformance, + allTimeEpochPerformance: mockProvenPerformance, lastProcessedSlot: sentinel.getLastProcessedSlot(), initialSlot: sentinel.getInitialSlot(), slotWindow: 10, @@ -443,7 +532,7 @@ describe('sentinel', () => { it('should call computeStatsForValidator with correct parameters', async () => { const mockHistory: ValidatorStatusHistory = [{ slot: SlotNumber(5), status: 'checkpoint-mined' }]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([]); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([]); const computeStatsSpy = jest.spyOn(sentinel, 'computeStatsForValidator').mockReturnValue({ address: validator, totalSlots: 1, @@ -460,7 +549,7 @@ describe('sentinel', () => { it('should use default slot range when not provided', async () => { const mockHistory: ValidatorStatusHistory = [{ slot: SlotNumber(5), status: 'checkpoint-mined' }]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([]); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([]); const computeStatsSpy = jest.spyOn(sentinel, 'computeStatsForValidator').mockReturnValue({ address: validator, totalSlots: 1, @@ -482,7 +571,7 @@ describe('sentinel', () => { it('should not produce negative slot numbers when historyLength exceeds lastProcessedSlot', async () => { const mockHistory: ValidatorStatusHistory = [{ slot: SlotNumber(2), status: 'checkpoint-mined' }]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([]); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([]); jest.spyOn(store, 'getHistoryLength').mockReturnValue(1000); // Large history length // Set lastProcessedSlot to a small value @@ -515,8 +604,8 @@ describe('sentinel', () => { ]; jest.spyOn(store, 'getHistory').mockResolvedValue(mockHistory); - const getProvenPerformanceSpy = jest - .spyOn(store, 'getProvenPerformance') + const getEpochPerformanceSpy = jest + .spyOn(store, 'getEpochPerformance') .mockResolvedValue(mockProvenPerformance); jest.spyOn(sentinel, 'computeStatsForValidator').mockReturnValue({ address: validator, @@ -528,8 +617,8 @@ describe('sentinel', () => { const result = await sentinel.getValidatorStats(validator); - expect(getProvenPerformanceSpy).toHaveBeenCalledWith(validator); - expect(result?.allTimeProvenPerformance).toEqual(mockProvenPerformance); + expect(getEpochPerformanceSpy).toHaveBeenCalledWith(validator); + expect(result?.allTimeEpochPerformance).toEqual(mockProvenPerformance); }); }); @@ -587,32 +676,14 @@ describe('sentinel', () => { }); }); - describe('handleChainProven', () => { + describe('handleEpochEnd', () => { it('calls inactivity watcher with performance data', async () => { - const blockNumber = BlockNumber(15); - const blockHash = '0xblockhash'; - const mockBlock = await L2Block.random(blockNumber); - const slot = mockBlock.header.getSlot(); - const epochNumber = getEpochAtSlot(slot, l1Constants); + const epochNumber = EpochNumber(2); const validator1 = EthAddress.random(); const validator2 = EthAddress.random(); const validator3 = EthAddress.random(); const [fromSlot, toSlot] = getSlotRangeForEpoch(epochNumber, l1Constants); - epochCache.getEpochAndSlotNow.mockReturnValue({ - epoch: epochNumber, - slot, - ts, - nowMs: ts * 1000n, - }); - epochCache.getSlotNow.mockReturnValue(slot); - epochCache.getTargetSlot.mockReturnValue(slot); - epochCache.getEpochNow.mockReturnValue(epochNumber); - epochCache.getTargetEpoch.mockReturnValue(epochNumber); - archiver.getBlockData.mockResolvedValue({ header: mockBlock.header } as any); - archiver.getL1Constants.mockResolvedValue(l1Constants); - epochCache.getL1Constants.mockReturnValue(l1Constants); - epochCache.getCommittee.mockResolvedValue({ committee: [validator1, validator2, validator3], seed: 0n, @@ -648,14 +719,14 @@ describe('sentinel', () => { history: [], }, }, - lastProcessedSlot: slot, + lastProcessedSlot: SlotNumber(toSlot), initialSlot: SlotNumber(0), slotWindow: 15, }; const computeStatsSpy = jest.spyOn(sentinel, 'computeStats').mockResolvedValue(statsResult); const emitSpy = jest.spyOn(sentinel, 'emit'); - await sentinel.handleChainProven({ type: 'chain-proven', block: { number: blockNumber, hash: blockHash } }); + await sentinel.handleEpochEnd(epochNumber); expect(computeStatsSpy).toHaveBeenCalledWith({ fromSlot, @@ -723,16 +794,10 @@ describe('sentinel', () => { expect(sentinel.getLastProcessedSlot()).toEqual(slot); }); - it('handleChainProven skips proven performance when escape hatch is open', async () => { - const blockNumber = BlockNumber(15); - const blockHash = '0xblockhash'; - const mockBlock = await L2Block.random(blockNumber); - const blockSlot = mockBlock.header.getSlot(); - const epochNumber = getEpochAtSlot(blockSlot, l1Constants); + it('handleEpochEnd skips epoch performance when escape hatch is open', async () => { + const epochNumber = EpochNumber(2); const validator1 = EthAddress.random(); - archiver.getBlockData.mockResolvedValue({ header: mockBlock.header } as any); - epochCache.getCommittee.mockResolvedValue({ committee: [validator1], seed: 0n, @@ -741,12 +806,12 @@ describe('sentinel', () => { }); const emitSpy = jest.spyOn(sentinel, 'emit'); - const updateProvenSpy = jest.spyOn(store, 'updateProvenPerformance'); + const updateEpochSpy = jest.spyOn(store, 'updateEpochPerformance'); - await sentinel.handleChainProven({ type: 'chain-proven', block: { number: blockNumber, hash: blockHash } }); + await sentinel.handleEpochEnd(epochNumber); // Should have stored empty performance (no offenses during escape hatch) - expect(updateProvenSpy).toHaveBeenCalledWith(epochNumber, {}); + expect(updateEpochSpy).toHaveBeenCalledWith(epochNumber, {}); // Should NOT have emitted any slash events expect(emitSpy).not.toHaveBeenCalled(); }); @@ -771,7 +836,7 @@ describe('sentinel', () => { { epoch: EpochNumber(2), missed: 5, total: 10 }, // 50% missed (active) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -787,7 +852,7 @@ describe('sentinel', () => { { epoch: EpochNumber(2), missed: 5, total: 10 }, // 50% missed (active) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -801,7 +866,7 @@ describe('sentinel', () => { { epoch: EpochNumber(4), missed: 9, total: 10 }, // 90% missed (inactive) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -814,7 +879,7 @@ describe('sentinel', () => { { epoch: EpochNumber(4), missed: 9, total: 10 }, // 90% missed (inactive) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); // We are checking at epoch 4, so no past epochs const result = await sentinel.checkPastInactivity(validator1, EpochNumber(4), 2); @@ -830,7 +895,7 @@ describe('sentinel', () => { { epoch: EpochNumber(2), missed: 8, total: 10 }, // 80% missed (inactive) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -838,7 +903,7 @@ describe('sentinel', () => { }); it('should work with threshold of 0 used when there are no past epochs to inspect', async () => { - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([]); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([]); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 0); expect(result).toBe(true); }); @@ -852,7 +917,7 @@ describe('sentinel', () => { { epoch: EpochNumber(2), missed: 5, total: 10 }, // 50% missed (active) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); // Query on epoch 5, so we only consider past ones and don't get to threshold const result = await sentinel.checkPastInactivity(validator1, EpochNumber(5), 3); @@ -867,7 +932,7 @@ describe('sentinel', () => { { epoch: EpochNumber(3), missed: 8, total: 10 }, // 80% missed (inactive) ]; - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue(mockPerformance); + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue(mockPerformance); const result = await sentinel.checkPastInactivity(validator1, EpochNumber(6), 3); @@ -876,13 +941,13 @@ describe('sentinel', () => { }); }); - describe('handleProvenPerformance with consecutive epochs', () => { + describe('handleEpochPerformance with consecutive epochs', () => { it('should slash validators only after consecutive epoch failures', async () => { // Update config to require 2 consecutive epochs sentinel.updateConfig({ slashInactivityConsecutiveEpochThreshold: 2 }); // Mock performance data for two validators - jest.spyOn(store, 'getProvenPerformance').mockImplementation(validator => { + jest.spyOn(store, 'getEpochPerformance').mockImplementation(validator => { if (validator.equals(validator1)) { // Validator1: inactive for 2+ consecutive epochs - should be slashed return Promise.resolve([ @@ -908,7 +973,7 @@ describe('sentinel', () => { [validator2.toString()]: { missed: 8, total: 10 }, // 80% missed }; - await sentinel.handleProvenPerformance(EpochNumber(5), currentEpochPerformance); + await sentinel.handleEpochPerformance(EpochNumber(5), currentEpochPerformance); // Should only slash validator1 (2 consecutive epochs), not validator2 (1 epoch) expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ @@ -926,7 +991,7 @@ describe('sentinel', () => { sentinel.updateConfig({ slashInactivityConsecutiveEpochThreshold: 3 }); // Mock performance data: validators only inactive for 2 epochs - jest.spyOn(store, 'getProvenPerformance').mockResolvedValue([ + jest.spyOn(store, 'getEpochPerformance').mockResolvedValue([ { epoch: EpochNumber(5), missed: 8, total: 10 }, // 80% missed (inactive) { epoch: EpochNumber(4), missed: 9, total: 10 }, // 90% missed (inactive) { epoch: EpochNumber(3), missed: 5, total: 10 }, // 50% missed (active) @@ -938,7 +1003,7 @@ describe('sentinel', () => { [validator1.toString()]: { missed: 8, total: 10 }, // 80% missed }; - await sentinel.handleProvenPerformance(EpochNumber(5), currentEpochPerformance); + await sentinel.handleEpochPerformance(EpochNumber(5), currentEpochPerformance); // Should not emit any slash events expect(emitSpy).not.toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, expect.anything()); @@ -953,10 +1018,11 @@ class TestSentinel extends Sentinel { archiver: L2BlockSource, p2p: P2PClient, store: SentinelStore, + reexecutionTracker: CheckpointReexecutionTracker, config: SentinelRuntimeConfig, protected override blockStream: L2BlockStream, ) { - super(epochCache, archiver, p2p, store, config); + super(epochCache, archiver, p2p, store, reexecutionTracker, config); } public override init() { @@ -964,6 +1030,11 @@ class TestSentinel extends Sentinel { return Promise.resolve(); } + /** Invokes the production Sentinel.init() so tests can assert its initialSlot logic. */ + public callProductionInit() { + return super.init(); + } + public override getSlotActivity(slot: SlotNumber, epoch: EpochNumber, proposer: EthAddress, committee: EthAddress[]) { return super.getSlotActivity(slot, epoch, proposer, committee); } @@ -977,16 +1048,16 @@ class TestSentinel extends Sentinel { return super.computeStatsForValidator(address, history, fromSlot, toSlot); } - public override handleChainProven(event: L2BlockStreamEvent) { - return super.handleChainProven(event); + public override handleEpochEnd(epoch: EpochNumber) { + return super.handleEpochEnd(epoch); } public override computeStats(opts: { fromSlot?: SlotNumber; toSlot?: SlotNumber }) { return super.computeStats(opts); } - public override handleProvenPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { - return super.handleProvenPerformance(epoch, performance); + public override handleEpochPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { + return super.handleEpochPerformance(epoch, performance); } public override getValidatorStats(validatorAddress: EthAddress, fromSlot?: SlotNumber, toSlot?: SlotNumber) { diff --git a/yarn-project/aztec-node/src/sentinel/sentinel.ts b/yarn-project/aztec-node/src/sentinel/sentinel.ts index e1d4c153169c..53d1dcc70099 100644 --- a/yarn-project/aztec-node/src/sentinel/sentinel.ts +++ b/yarn-project/aztec-node/src/sentinel/sentinel.ts @@ -27,6 +27,7 @@ import { type L2BlockStreamEventHandler, getAttestationInfoFromPublishedCheckpoint, } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { ChainConfig } from '@aztec/stdlib/config'; import { getEpochAtSlot, getSlotRangeForEpoch, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { ConsensusPayload, type CoordinationSignatureContext } from '@aztec/stdlib/p2p'; @@ -42,12 +43,14 @@ import type { import EventEmitter from 'node:events'; +import type { SentinelConfig } from './config.js'; import { SentinelStore } from './store.js'; export type SentinelRuntimeConfig = Pick< SlasherConfig, 'slashInactivityTargetPercentage' | 'slashInactivityPenalty' | 'slashInactivityConsecutiveEpochThreshold' > & + Pick & Pick; /** Maps a validator status to its category: proposer or attestation. */ @@ -61,6 +64,76 @@ function statusToCategory(status: ValidatorStatusInSlot): ValidatorStatusType { } } +/** + * The Sentinel observes validator behaviour every L2 slot, classifies it into a per-slot status, + * aggregates those statuses into per-epoch performance once each epoch is fully observed, and + * emits inactivity slash payloads when a validator has been inactive for the configured number + * of consecutive epochs. + * + * ## Two cadences + * + * The sentinel runs `work()` every quarter L2 slot and drives two independent pipelines: + * + * 1. **Per-slot activity recording.** `processSlot(currentSlot - 2)` runs once per slot, with a + * two-slot lag to let P2P attestations settle and the archiver catch up. It classifies each + * committee member's behaviour for that slot via `getSlotActivity` and persists the result to + * `SentinelStore.historyMap` (sliding window of `sentinelHistoryLengthInEpochs * epochDuration` + * slots, default 24 epochs). + * + * 2. **Per-epoch evaluation.** `processEpochEnds(currentSlot)` runs every tick too. Once + * `sentinelEpochEndBufferSlots` (default 2) has elapsed past an epoch's last slot AND the + * per-slot recorder has covered that last slot, the sentinel calls `handleEpochEnd(epoch)`. + * That aggregates the slot-level statuses for the epoch into per-validator `{missed, total}`, + * persists it to `SentinelStore.epochMap` (default 2000-epoch window), and runs the slashing + * decision. + * + * Triggering per-epoch evaluation off local L2 state — rather than waiting for L1 proof + * publication — decouples slashing from prover availability. + * + * ## Six-case taxonomy in `getSlotActivity` + * + * For each slot, the sentinel assigns the proposer one of six statuses, ranked highest-confidence + * first: + * + * - `checkpoint-mined` — a checkpoint covering this slot has landed on L1 + * (`slotNumberToCheckpoint` populated from `chain-checkpointed`). + * - `checkpoint-valid` — the local node re-executed a checkpoint proposal for this slot + * successfully (consulted via `CheckpointReexecutionTracker`). + * - `checkpoint-invalid` — the local node re-executed a checkpoint proposal for this slot + * and rejected it (e.g. header/archive/out-hash mismatch, limit + * breach). Proposer-fault. + * - `checkpoint-unvalidated` — the local node observed a checkpoint proposal but could not + * validate it (missing blocks/txs, timeouts). Treated as + * proposer-fault for slashing. + * - `checkpoint-missed` — block proposals seen on P2P but no checkpoint proposal at all. + * - `blocks-missed` — no block proposals seen for this slot. + * + * Missing-attestor faults are recorded only in `checkpoint-mined` and `checkpoint-valid`, where + * the local node has positive evidence the checkpoint was canonical or valid. In the other four + * cases the proposer is at fault and no attestor penalty applies. + * + * ## Re-execution tracker + * + * `CheckpointReexecutionTracker` is populated by the validator client's checkpoint proposal + * handler. Every early return in `validateCheckpointProposal` records an outcome + * (`valid` / `invalid` / `unvalidated`) keyed by slot. + * + * ## Inactivity slashing + * + * `handleEpochPerformance` filters the epoch's per-validator stats by + * `slashInactivityTargetPercentage` and then calls `checkPastInactivity` to require + * `slashInactivityConsecutiveEpochThreshold` consecutive past epochs over the same threshold + * (read from `SentinelStore.epochMap`). Only validators meeting both conditions are emitted as + * `WANT_TO_SLASH_EVENT` with `OffenseType.INACTIVITY`. The slot-level counters that feed this — + * `missedProposals` and `missedAttestations` — include the four proposer-fault statuses plus + * `attestation-missed`. + * + * ## Escape hatch + * + * If `epochCache.getCommittee(slot)` reports `isEscapeHatchOpen`, per-slot recording is skipped + * (no history entries for that slot) and per-epoch evaluation writes an empty performance map + * (no slashing). + */ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) implements L2BlockStreamEventHandler, Watcher { protected runningPromise: RunningPromise; protected blockStream!: L2BlockStream; @@ -68,6 +141,8 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme protected initialSlot: SlotNumber | undefined; protected lastProcessedSlot: SlotNumber | undefined; + /** Largest epoch number for which the end-of-epoch aggregator has run. */ + protected lastEvaluatedEpoch: EpochNumber | undefined; protected slotNumberToCheckpoint: Map< SlotNumber, { @@ -84,6 +159,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme protected archiver: L2BlockSource, protected p2p: P2PClient, protected store: SentinelStore, + protected reexecutionTracker: CheckpointReexecutionTracker, protected config: SentinelRuntimeConfig, protected logger = createLogger('node:sentinel'), ) { @@ -109,14 +185,31 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme this.runningPromise.start(); } - /** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */ + /** + * Loads initial slot and initializes blockstream. We will not process anything at or before + * the initial slot. Floors at the archiver's synced L2 slot so the sentinel keeps making + * forward progress when L1 is advancing but L2 has no activity (the synced slot is driven by + * L1 sync, not by L2 blocks). Falls back to the wallclock if the archiver isn't ready yet + * (cold start). + */ protected async init() { - this.initialSlot = this.epochCache.getSlotNow(); + this.initialSlot = await this.getCurrentSlot(); const startingBlock = BlockNumber(await this.archiver.getBlockNumber()); this.logger.info(`Starting validator sentinel with initial slot ${this.initialSlot} and block ${startingBlock}`); this.blockStream = new L2BlockStream(this.archiver, this.l2TipsStore, this, this.logger, { startingBlock }); } + /** + * Returns the L2 slot the sentinel should treat as "current": the archiver's last fully + * synced L2 slot, falling back to the wallclock slot when the archiver isn't ready yet + * (cold start). Anchoring to the synced slot keeps timing arithmetic (initial floor, + * per-slot lag, end-of-epoch buffer, stats-range fallback) from speculating ahead of where + * L1 actually is. + */ + protected async getCurrentSlot(): Promise { + return (await this.archiver.getSyncedL2SlotNumber()) ?? this.epochCache.getSlotNow(); + } + public stop() { return this.runningPromise.stop(); } @@ -125,8 +218,6 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme await this.l2TipsStore.handleBlockStreamEvent(event); if (event.type === 'chain-checkpointed') { this.handleCheckpoint(event); - } else if (event.type === 'chain-proven') { - await this.handleChainProven(event); } } @@ -163,33 +254,25 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme } } - protected async handleChainProven(event: L2BlockStreamEvent) { - if (event.type !== 'chain-proven') { - return; - } - const blockNumber = event.block.number; - const header = (await this.archiver.getBlockData({ number: blockNumber }))?.header; - if (!header) { - this.logger.error(`Failed to get block header ${blockNumber}`); - return; - } - - // TODO(palla/slash): We should only be computing proven performance if this is - // a full proof epoch and not a partial one, otherwise we'll end up with skewed stats. - const epoch = getEpochAtSlot(header.getSlot(), this.epochCache.getL1Constants()); - this.logger.debug(`Computing proven performance for epoch ${epoch}`); - const performance = await this.computeProvenPerformance(epoch); - this.logger.info(`Computed proven performance for epoch ${epoch}`, performance); + /** + * Called once per epoch, after the configured end-of-epoch buffer has elapsed beyond the + * epoch's last slot. Computes per-epoch performance from the slot-level history collected + * by `processSlot` and emits any inactivity slash payloads. + */ + protected async handleEpochEnd(epoch: EpochNumber) { + this.logger.debug(`Computing epoch performance for epoch ${epoch}`); + const performance = await this.computeEpochPerformance(epoch); + this.logger.info(`Computed epoch performance for epoch ${epoch}`, performance); - await this.store.updateProvenPerformance(epoch, performance); - await this.handleProvenPerformance(epoch, performance); + await this.store.updateEpochPerformance(epoch, performance); + await this.handleEpochPerformance(epoch, performance); } - protected async computeProvenPerformance(epoch: EpochNumber): Promise { + protected async computeEpochPerformance(epoch: EpochNumber): Promise { const [fromSlot, toSlot] = getSlotRangeForEpoch(epoch, this.epochCache.getL1Constants()); const { committee, isEscapeHatchOpen } = await this.epochCache.getCommittee(fromSlot); if (isEscapeHatchOpen) { - this.logger.info(`Skipping proven performance for epoch ${epoch} - escape hatch is open`); + this.logger.info(`Skipping epoch performance for epoch ${epoch} - escape hatch is open`); return {}; } if (!committee) { @@ -231,8 +314,8 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme return true; } - // Get all historical performance for this validator - const allPerformance = await this.store.getProvenPerformance(validator); + // Get all historical per-epoch performance for this validator + const allPerformance = await this.store.getEpochPerformance(validator); // Sort by epoch descending to get most recent first, keep only epochs strictly before the current one, and get the first N const pastEpochs = allPerformance.sort((a, b) => Number(b.epoch - a.epoch)).filter(p => p.epoch < currentEpoch); @@ -251,7 +334,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme .every(p => (p.total === 0 ? false : p.missed / p.total >= this.config.slashInactivityTargetPercentage)); } - protected async handleProvenPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { + protected async handleEpochPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { if (this.config.slashInactivityPenalty === 0n) { return; } @@ -291,26 +374,72 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme * Process data for two L2 slots ago. * Note that we do not process historical data, since we rely on p2p data for processing, * and we don't have that data if we were offline during the period. + * + * `currentSlot` is anchored to the archiver's last synced L2 slot rather than the wallclock, + * so the per-slot lag (`isReadyToProcess`) and the end-of-epoch buffer (`processEpochEnds`) + * advance with archiver. */ public async work() { - const currentSlot = this.epochCache.getSlotNow(); + const currentSlot = await this.getCurrentSlot(); try { // Manually sync the block stream to ensure we have the latest data. // Note we never `start` the blockstream, so it loops at the same pace as we do. await this.blockStream.sync(); - // Check if we are ready to process data for two L2 slots ago. + // Per-slot activity recording (lag = 2 slots for P2P attestation settlement). const targetSlot = await this.isReadyToProcess(currentSlot); - - // And process it if we are. if (targetSlot !== false) { await this.processSlot(targetSlot); } + + // End-of-epoch evaluation (lag = sentinelEpochEndBufferSlots beyond the epoch's last slot). + await this.processEpochEnds(currentSlot); } catch (err) { this.logger.error(`Failed to process slot ${currentSlot}`, err); } } + /** + * After the configured buffer has elapsed past an epoch's last slot, runs the end-of-epoch + * aggregator for that epoch. Catches up if multiple epochs become eligible at once. + */ + protected async processEpochEnds(currentSlot: SlotNumber) { + const constants = this.epochCache.getL1Constants(); + const buffer = this.config.sentinelEpochEndBufferSlots; + if (currentSlot < buffer) { + return; + } + if (this.initialSlot === undefined) { + return; + } + + // We can close epoch E iff: + // - the per-slot recorder has covered the epoch's last slot (lastProcessedSlot ≥ toSlot(E)) + // - the buffer has elapsed past the epoch's last slot (currentSlot − buffer ≥ toSlot(E)) + // - the epoch is not in the past relative to when the sentinel started (toSlot(E) > initialSlot) + if (this.lastProcessedSlot === undefined) { + return; + } + const slotForBuffer = SlotNumber(currentSlot - buffer); + + // First eligible epoch to close is the one after lastEvaluatedEpoch, or the epoch containing + // the initial slot if we haven't evaluated any yet (the initialSlot epoch may be partial — we + // don't try to evaluate it, we start from initialSlot's epoch + 1). + const startEpoch = + this.lastEvaluatedEpoch !== undefined + ? EpochNumber(this.lastEvaluatedEpoch + 1) + : EpochNumber(getEpochAtSlot(this.initialSlot, constants) + 1); + + for (let epoch = startEpoch; ; epoch = EpochNumber(epoch + 1)) { + const [, toSlot] = getSlotRangeForEpoch(epoch, constants); + if (toSlot > this.lastProcessedSlot || toSlot > slotForBuffer) { + break; + } + await this.handleEpochEnd(epoch); + this.lastEvaluatedEpoch = epoch; + } + } + /** * Check if we are ready to process data for two L2 slots ago, so we allow plenty of time for p2p to process all in-flight attestations. * We also don't move past the archiver last synced L2 slot, as we don't want to process data that is not yet available. @@ -379,49 +508,68 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme this.lastProcessedSlot = slot; } - /** Computes activity for a given slot. */ + /** + * Computes activity for a given slot using the six-case taxonomy. + * + * Proposer status: + * - case 6 `checkpoint-mined` — a checkpoint covering this slot has landed on L1. + * - case 5 `checkpoint-valid` — the local node re-executed a checkpoint proposal for this + * slot successfully. + * - case 4 `checkpoint-invalid` — the local node re-executed a checkpoint proposal for this + * slot and rejected it. + * - case 3 `checkpoint-unvalidated` — the local node observed a checkpoint proposal for this + * slot but could not validate it (missing data, timeouts). + * - case 2 `checkpoint-missed` — block proposals seen on P2P but no checkpoint proposal. + * - case 1 `blocks-missed` — no block proposals seen for this slot. + * + * Missing-attestor penalties apply only in cases 5 and 6, where the local node has positive + * evidence the checkpoint was valid or has been canonicalised on L1. + */ protected async getSlotActivity(slot: SlotNumber, epoch: EpochNumber, proposer: EthAddress, committee: EthAddress[]) { this.logger.debug(`Computing stats for slot ${slot} at epoch ${epoch}`, { slot, epoch, proposer, committee }); - // Check if there is an L2 block in L1 for this L2 slot - - // Here we get all checkpoint attestations for the checkpoint at the given slot, - // or all checkpoint attestations for all proposals in the slot if no checkpoint was mined. - // We gather from both p2p (contains the ones seen on the p2p layer) and archiver - // (contains the ones synced from mined checkpoints, which we may have missed from p2p). + // Gather attestors from both p2p (live attestations) and the archiver (signers on the + // checkpoint if one has landed on L1). Used regardless of which case applies. const checkpoint = this.slotNumberToCheckpoint.get(slot); const p2pAttested = await this.p2p.getCheckpointAttestationsForSlot(slot, checkpoint?.proposalPayloadHash); - // Filter out attestations with invalid signatures const p2pAttestors = p2pAttested.map(a => a.getSender()).filter((s): s is EthAddress => s !== undefined); const attestors = new Set( [...p2pAttestors.map(a => a.toString()), ...(checkpoint?.attestors.map(a => a.toString()) ?? [])].filter( - addr => proposer.toString() !== addr, // Exclude the proposer from the attestors + addr => proposer.toString() !== addr, ), ); - // We assume that there was a block proposal if at least one of the validators (other than the proposer) attested to it. - // It could be the case that every single validator failed, and we could differentiate it by having - // this node re-execute every block proposal it sees and storing it in the attestation pool. - // But we'll leave that corner case out to reduce pressure on the node. - // TODO(palla/slash): This breaks if a given node has more than one validator in the current committee, - // since they will attest to their own proposal it even if it's not re-executable. - let status: 'checkpoint-mined' | 'checkpoint-proposed' | 'checkpoint-missed' | 'blocks-missed'; + // Determine the proposer status from the six-case taxonomy. + const reexecutionOutcome = this.reexecutionTracker.getOutcomeForSlot(slot); + let status: + | 'checkpoint-mined' + | 'checkpoint-valid' + | 'checkpoint-invalid' + | 'checkpoint-unvalidated' + | 'checkpoint-missed' + | 'blocks-missed'; if (checkpoint) { status = 'checkpoint-mined'; - } else if (attestors.size > 0) { - status = 'checkpoint-proposed'; + } else if (reexecutionOutcome === 'valid') { + status = 'checkpoint-valid'; + } else if (reexecutionOutcome === 'invalid') { + status = 'checkpoint-invalid'; + } else if (reexecutionOutcome === 'unvalidated') { + status = 'checkpoint-unvalidated'; } else { - // No checkpoint on L1 and no checkpoint attestations seen. Check if block proposals were sent for this slot. + // No L1 checkpoint, no local re-execution outcome for this slot. Distinguish "proposer + // sent block proposals but never made a checkpoint" from "proposer sent nothing". const hasBlockProposals = await this.p2p.hasBlockProposalsForSlot(slot); status = hasBlockProposals ? 'checkpoint-missed' : 'blocks-missed'; } this.logger.debug(`Checkpoint status for slot ${slot}: ${status}`, { ...checkpoint, slot }); - // Get attestors that failed their checkpoint attestation duties, but only if there was a checkpoint proposed or mined + // Missing-attestor faults only apply when we have positive evidence the proposal was valid. + const attestorsExpected = status === 'checkpoint-mined' || status === 'checkpoint-valid'; const missedAttestors = new Set( - status === 'blocks-missed' || status === 'checkpoint-missed' - ? [] - : committee.filter(v => !attestors.has(v.toString()) && !proposer.equals(v)).map(v => v.toString()), + attestorsExpected + ? committee.filter(v => !attestors.has(v.toString()) && !proposer.equals(v)).map(v => v.toString()) + : [], ); this.logger.debug(`Retrieved ${attestors.size} attestors out of ${committee.length} for slot ${slot}`, { @@ -465,7 +613,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme ? fromEntries(await Promise.all(validators.map(async v => [v.toString(), await this.store.getHistory(v)]))) : await this.store.getHistories(); - const slotNow = this.epochCache.getSlotNow(); + const slotNow = await this.getCurrentSlot(); fromSlot ??= SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0)); toSlot ??= this.lastProcessedSlot ?? slotNow; @@ -493,7 +641,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme return undefined; } - const slotNow = this.epochCache.getSlotNow(); + const slotNow = await this.getCurrentSlot(); const effectiveFromSlot = fromSlot ?? SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0)); const effectiveToSlot = toSlot ?? this.lastProcessedSlot ?? slotNow; @@ -515,7 +663,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme return { validator, - allTimeProvenPerformance: await this.store.getProvenPerformance(validatorAddress), + allTimeEpochPerformance: await this.store.getEpochPerformance(validatorAddress), lastProcessedSlot: this.lastProcessedSlot, initialSlot: this.initialSlot, slotWindow: this.store.getHistoryLength(), @@ -530,16 +678,19 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme ): ValidatorStats { let history = fromSlot ? allHistory.filter(h => BigInt(h.slot) >= fromSlot) : allHistory; history = toSlot ? history.filter(h => BigInt(h.slot) <= toSlot) : history; - const lastProposal = history - .filter(h => h.status === 'checkpoint-proposed' || h.status === 'checkpoint-mined') - .at(-1); + const lastProposal = history.filter(h => h.status === 'checkpoint-valid' || h.status === 'checkpoint-mined').at(-1); const lastAttestation = history.filter(h => h.status === 'attestation-sent').at(-1); return { address: EthAddress.fromString(address), lastProposal: this.computeFromSlot(lastProposal?.slot), lastAttestation: this.computeFromSlot(lastAttestation?.slot), totalSlots: history.length, - missedProposals: this.computeMissed(history, 'proposer', ['checkpoint-missed', 'blocks-missed']), + missedProposals: this.computeMissed(history, 'proposer', [ + 'checkpoint-missed', + 'blocks-missed', + 'checkpoint-invalid', + 'checkpoint-unvalidated', + ]), missedAttestations: this.computeMissed(history, 'attestation', ['attestation-missed']), history, }; diff --git a/yarn-project/aztec-node/src/sentinel/store.test.ts b/yarn-project/aztec-node/src/sentinel/store.test.ts index 0c7babb7ce99..cd8adf3d352e 100644 --- a/yarn-project/aztec-node/src/sentinel/store.test.ts +++ b/yarn-project/aztec-node/src/sentinel/store.test.ts @@ -13,12 +13,12 @@ describe('sentinel-store', () => { let log: Logger; const historyLength = 4; - const historicProvenPerformanceLength = 3; + const historicEpochPerformanceLength = 3; beforeEach(async () => { log = createLogger('sentinel:store:test'); kvStore = await openTmpStore('sentinel-store-test'); - store = new SentinelStore(kvStore, { historyLength, historicProvenPerformanceLength }); + store = new SentinelStore(kvStore, { historyLength, historicEpochPerformanceLength }); }); afterEach(async () => { @@ -27,10 +27,12 @@ describe('sentinel-store', () => { it('inserts new validators with all statuses', async () => { const slot = SlotNumber(1); - const validators: `0x${string}`[] = times(6, () => EthAddress.random().toString()); + const validators: `0x${string}`[] = times(8, () => EthAddress.random().toString()); const statuses: ValidatorStatusInSlot[] = [ 'checkpoint-mined', - 'checkpoint-proposed', + 'checkpoint-valid', + 'checkpoint-invalid', + 'checkpoint-unvalidated', 'checkpoint-missed', 'blocks-missed', 'attestation-sent', @@ -66,7 +68,7 @@ describe('sentinel-store', () => { await store.updateValidators( SlotNumber(2), Object.fromEntries([ - ...newValidators.map(v => [v, 'checkpoint-proposed'] as const), + ...newValidators.map(v => [v, 'checkpoint-valid'] as const), ...existingValidators.map(v => [v, 'checkpoint-missed'] as const), ]), ); @@ -84,8 +86,8 @@ describe('sentinel-store', () => { { slot: SlotNumber(2), status: 'checkpoint-missed' }, ]); - expect(histories[newValidators[0]]).toEqual([{ slot: SlotNumber(2), status: 'checkpoint-proposed' }]); - expect(histories[newValidators[1]]).toEqual([{ slot: SlotNumber(2), status: 'checkpoint-proposed' }]); + expect(histories[newValidators[0]]).toEqual([{ slot: SlotNumber(2), status: 'checkpoint-valid' }]); + expect(histories[newValidators[1]]).toEqual([{ slot: SlotNumber(2), status: 'checkpoint-valid' }]); }); it('trims history to the specified length', async () => { @@ -106,52 +108,52 @@ describe('sentinel-store', () => { ]); }); - it('updates proven performance', async () => { + it('updates per-epoch performance', async () => { const validator = EthAddress.random(); - await store.updateProvenPerformance(EpochNumber(1), { [validator.toString()]: { missed: 2, total: 10 } }); - const provenPerformance = await store.getProvenPerformance(validator); - expect(provenPerformance).toEqual([{ epoch: EpochNumber(1), missed: 2, total: 10 }]); + await store.updateEpochPerformance(EpochNumber(1), { [validator.toString()]: { missed: 2, total: 10 } }); + const epochPerformance = await store.getEpochPerformance(validator); + expect(epochPerformance).toEqual([{ epoch: EpochNumber(1), missed: 2, total: 10 }]); - await store.updateProvenPerformance(EpochNumber(1), { [validator.toString()]: { missed: 3, total: 10 } }); - const provenPerformance2 = await store.getProvenPerformance(validator); - expect(provenPerformance2).toEqual([{ epoch: EpochNumber(1), missed: 3, total: 10 }]); + await store.updateEpochPerformance(EpochNumber(1), { [validator.toString()]: { missed: 3, total: 10 } }); + const epochPerformance2 = await store.getEpochPerformance(validator); + expect(epochPerformance2).toEqual([{ epoch: EpochNumber(1), missed: 3, total: 10 }]); - await store.updateProvenPerformance(EpochNumber(2), { [validator.toString()]: { missed: 4, total: 10 } }); - const provenPerformance3 = await store.getProvenPerformance(validator); - expect(provenPerformance3).toEqual([ + await store.updateEpochPerformance(EpochNumber(2), { [validator.toString()]: { missed: 4, total: 10 } }); + const epochPerformance3 = await store.getEpochPerformance(validator); + expect(epochPerformance3).toEqual([ { epoch: EpochNumber(1), missed: 3, total: 10 }, { epoch: EpochNumber(2), missed: 4, total: 10 }, ]); }); - it('trims proven performance to the specified historicProvenPerformanceLength', async () => { + it('trims per-epoch performance to the specified historicEpochPerformanceLength', async () => { const validator = EthAddress.random(); - // Add 5 epochs worth of proven performance data (more than historicProvenPerformanceLength = 3) + // Add 5 epochs worth of per-epoch performance data (more than historicEpochPerformanceLength = 3) for (let i = 1; i <= 5; i++) { - await store.updateProvenPerformance(EpochNumber(i), { [validator.toString()]: { missed: i, total: 10 } }); + await store.updateEpochPerformance(EpochNumber(i), { [validator.toString()]: { missed: i, total: 10 } }); } - const provenPerformance = await store.getProvenPerformance(validator); + const epochPerformance = await store.getEpochPerformance(validator); // Should only keep the most recent 3 entries (epochs 3, 4, 5) - expect(provenPerformance).toHaveLength(historicProvenPerformanceLength); - expect(provenPerformance).toEqual([ + expect(epochPerformance).toHaveLength(historicEpochPerformanceLength); + expect(epochPerformance).toEqual([ { epoch: EpochNumber(3), missed: 3, total: 10 }, { epoch: EpochNumber(4), missed: 4, total: 10 }, { epoch: EpochNumber(5), missed: 5, total: 10 }, ]); }); - it('getHistoricProvenPerformanceLength returns the correct value', () => { - expect(store.getHistoricProvenPerformanceLength()).toBe(historicProvenPerformanceLength); + it('getHistoricEpochPerformanceLength returns the correct value', () => { + expect(store.getHistoricEpochPerformanceLength()).toBe(historicEpochPerformanceLength); }); - it('proven performance with 2k entries', async () => { + it('per-epoch performance with 2k entries', async () => { const validator = EthAddress.random(); const totalEntries = 2000; - log.info(`Starting stress test with ${totalEntries} proven performance entries`); + log.info(`Starting stress test with ${totalEntries} per-epoch performance entries`); // Track timing for additions const addTimes: number[] = []; @@ -160,7 +162,7 @@ describe('sentinel-store', () => { // Add 2k entries for (let i = 1; i <= totalEntries; i++) { const addStart = Date.now(); - await store.updateProvenPerformance(EpochNumber(i), { + await store.updateEpochPerformance(EpochNumber(i), { [validator.toString()]: { missed: i % 10, total: 10 }, }); const addEnd = Date.now(); @@ -186,15 +188,15 @@ describe('sentinel-store', () => { for (let i = 0; i < numRetrievals; i++) { const retrievalStart = Date.now(); - const performance = await store.getProvenPerformance(validator); + const performance = await store.getEpochPerformance(validator); const retrievalEnd = Date.now(); retrievalTimes.push(retrievalEnd - retrievalStart); // Verify we only keep the configured number of entries - expect(performance).toHaveLength(historicProvenPerformanceLength); + expect(performance).toHaveLength(historicEpochPerformanceLength); // Verify we kept the most recent entries - const expectedStartEpoch = totalEntries - historicProvenPerformanceLength + 1; + const expectedStartEpoch = totalEntries - historicEpochPerformanceLength + 1; expect(performance[0].epoch).toBe(EpochNumber(expectedStartEpoch)); expect(performance[performance.length - 1].epoch).toBe(EpochNumber(totalEntries)); } @@ -206,7 +208,7 @@ describe('sentinel-store', () => { it('does not allow insertion of invalid validator addresses', async () => { const validator = '0x123'; await expect( - store.updateProvenPerformance(EpochNumber(1), { [validator]: { missed: 2, total: 10 } }), + store.updateEpochPerformance(EpochNumber(1), { [validator]: { missed: 2, total: 10 } }), ).rejects.toThrow(); await expect(store.updateValidators(SlotNumber(1), { [validator]: 'checkpoint-mined' })).rejects.toThrow(); }); diff --git a/yarn-project/aztec-node/src/sentinel/store.ts b/yarn-project/aztec-node/src/sentinel/store.ts index c06be27cb179..6f74c8c50a76 100644 --- a/yarn-project/aztec-node/src/sentinel/store.ts +++ b/yarn-project/aztec-node/src/sentinel/store.ts @@ -9,45 +9,45 @@ import type { } from '@aztec/stdlib/validators'; export class SentinelStore { - public static readonly SCHEMA_VERSION = 3; + public static readonly SCHEMA_VERSION = 4; // a map from validator address to their ValidatorStatusHistory private readonly historyMap: AztecAsyncMap<`0x${string}`, Buffer>; - // a map from validator address to their historical proven epoch performance + // a map from validator address to their historical epoch performance, evaluated at end-of-epoch. // e.g. { validator: [{ epoch: 1, missed: 1, total: 10 }, { epoch: 2, missed: 3, total: 7 }, ...] } - private readonly provenMap: AztecAsyncMap<`0x${string}`, Buffer>; + private readonly epochMap: AztecAsyncMap<`0x${string}`, Buffer>; constructor( private store: AztecAsyncKVStore, - private config: { historyLength: number; historicProvenPerformanceLength: number }, + private config: { historyLength: number; historicEpochPerformanceLength: number }, ) { this.historyMap = store.openMap('sentinel-validator-status'); - this.provenMap = store.openMap('sentinel-validator-proven'); + this.epochMap = store.openMap('sentinel-validator-epoch'); } public getHistoryLength() { return this.config.historyLength; } - public getHistoricProvenPerformanceLength() { - return this.config.historicProvenPerformanceLength; + public getHistoricEpochPerformanceLength() { + return this.config.historicEpochPerformanceLength; } - public async updateProvenPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { + public async updateEpochPerformance(epoch: EpochNumber, performance: ValidatorsEpochPerformance) { await this.store.transactionAsync(async () => { for (const [who, { missed, total }] of Object.entries(performance)) { - await this.pushValidatorProvenPerformanceForEpoch({ who: EthAddress.fromString(who), missed, total, epoch }); + await this.pushValidatorEpochPerformance({ who: EthAddress.fromString(who), missed, total, epoch }); } }); } - public async getProvenPerformance(who: EthAddress): Promise<{ missed: number; total: number; epoch: EpochNumber }[]> { - const currentPerformanceBuffer = await this.provenMap.getAsync(who.toString()); + public async getEpochPerformance(who: EthAddress): Promise<{ missed: number; total: number; epoch: EpochNumber }[]> { + const currentPerformanceBuffer = await this.epochMap.getAsync(who.toString()); return currentPerformanceBuffer ? this.deserializePerformance(currentPerformanceBuffer) : []; } - private async pushValidatorProvenPerformanceForEpoch({ + private async pushValidatorEpochPerformance({ who, missed, total, @@ -58,7 +58,7 @@ export class SentinelStore { total: number; epoch: EpochNumber; }) { - const currentPerformance = await this.getProvenPerformance(who); + const currentPerformance = await this.getEpochPerformance(who); const existingIndex = currentPerformance.findIndex(p => p.epoch === epoch); if (existingIndex !== -1) { currentPerformance[existingIndex] = { missed, total, epoch }; @@ -70,10 +70,10 @@ export class SentinelStore { // Since we keep the size small, this is not a big deal. currentPerformance.sort((a, b) => Number(a.epoch - b.epoch)); - // keep the most recent `historicProvenPerformanceLength` entries. - const performanceToKeep = currentPerformance.slice(-this.config.historicProvenPerformanceLength); + // keep the most recent `historicEpochPerformanceLength` entries. + const performanceToKeep = currentPerformance.slice(-this.config.historicEpochPerformanceLength); - await this.provenMap.set(who.toString(), this.serializePerformance(performanceToKeep)); + await this.epochMap.set(who.toString(), this.serializePerformance(performanceToKeep)); } public async updateValidators(slot: SlotNumber, statuses: Record<`0x${string}`, ValidatorStatusInSlot | undefined>) { @@ -147,7 +147,7 @@ export class SentinelStore { switch (status) { case 'checkpoint-mined': return 1; - case 'checkpoint-proposed': + case 'checkpoint-valid': return 2; case 'checkpoint-missed': return 3; @@ -157,6 +157,10 @@ export class SentinelStore { return 5; case 'blocks-missed': return 6; + case 'checkpoint-invalid': + return 7; + case 'checkpoint-unvalidated': + return 8; default: { const _exhaustive: never = status; throw new Error(`Unknown status: ${status}`); @@ -169,7 +173,7 @@ export class SentinelStore { case 1: return 'checkpoint-mined'; case 2: - return 'checkpoint-proposed'; + return 'checkpoint-valid'; case 3: return 'checkpoint-missed'; case 4: @@ -178,6 +182,10 @@ export class SentinelStore { return 'attestation-missed'; case 6: return 'blocks-missed'; + case 7: + return 'checkpoint-invalid'; + case 8: + return 'checkpoint-unvalidated'; default: throw new Error(`Unknown status: ${status}`); } diff --git a/yarn-project/aztec-node/src/test/index.ts b/yarn-project/aztec-node/src/test/index.ts index be390476ef21..22e12a224cef 100644 --- a/yarn-project/aztec-node/src/test/index.ts +++ b/yarn-project/aztec-node/src/test/index.ts @@ -1,7 +1,7 @@ import type { EpochCacheInterface } from '@aztec/epoch-cache'; import type { P2P } from '@aztec/p2p'; import { SequencerClient } from '@aztec/sequencer-client'; -import { EpochPruneWatcher, type SlasherClientInterface } from '@aztec/slasher'; +import { DataWithholdingWatcher, type SlasherClientInterface } from '@aztec/slasher'; import type { L2BlockSource } from '@aztec/stdlib/block'; import type { ContractDataSource } from '@aztec/stdlib/contract'; import type { L2LogsSource, Service, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; @@ -23,7 +23,7 @@ export declare class TestAztecNodeService extends AztecNodeService { declare public sequencer: SequencerClient | undefined; declare public slasherClient: SlasherClientInterface | undefined; declare public validatorsSentinel: Sentinel | undefined; - declare public epochPruneWatcher: EpochPruneWatcher | undefined; + declare public dataWithholdingWatcher: DataWithholdingWatcher | undefined; declare public l1ChainId: number; declare public version: number; declare public globalVariableBuilder: GlobalVariableBuilderInterface; diff --git a/yarn-project/aztec.js/src/deployment/publish_instance.ts b/yarn-project/aztec.js/src/deployment/publish_instance.ts index bb6db197f49c..69801363ed91 100644 --- a/yarn-project/aztec.js/src/deployment/publish_instance.ts +++ b/yarn-project/aztec.js/src/deployment/publish_instance.ts @@ -17,6 +17,7 @@ export function publishInstance(wallet: Wallet, instance: ContractInstanceWithAd salt, contractClassId, instance.initializationHash, + instance.immutablesHash, publicKeys, isUniversalDeploy, ); diff --git a/yarn-project/aztec.js/src/utils/node.test.ts b/yarn-project/aztec.js/src/utils/node.test.ts index 2bdfc8cc3699..7ae9528aae00 100644 --- a/yarn-project/aztec.js/src/utils/node.test.ts +++ b/yarn-project/aztec.js/src/utils/node.test.ts @@ -42,7 +42,7 @@ describe('waitForTx', () => { const revertedReceipt = new TxReceipt( txHash, TxStatus.CHECKPOINTED, - TxExecutionResult.APP_LOGIC_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, @@ -56,7 +56,7 @@ describe('waitForTx', () => { const revertedReceipt = new TxReceipt( txHash, TxStatus.CHECKPOINTED, - TxExecutionResult.APP_LOGIC_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, diff --git a/yarn-project/aztec.js/src/wallet/wallet.test.ts b/yarn-project/aztec.js/src/wallet/wallet.test.ts index cf96c2231cc2..344747a28a29 100644 --- a/yarn-project/aztec.js/src/wallet/wallet.test.ts +++ b/yarn-project/aztec.js/src/wallet/wallet.test.ts @@ -136,12 +136,13 @@ describe('WalletSchema', () => { }; const mockInstance: ContractInstanceWithAddress = { address: await AztecAddress.random(), - version: 1, + version: 2, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: PublicKeys.default(), }; const result = await context.client.registerContract(mockInstance, mockArtifact, Fr.random()); @@ -150,10 +151,11 @@ describe('WalletSchema', () => { currentContractClassId: expect.any(Fr), deployer: expect.any(AztecAddress), initializationHash: expect.any(Fr), + immutablesHash: expect.any(Fr), originalContractClassId: expect.any(Fr), publicKeys: expect.any(PublicKeys), salt: expect.any(Fr), - version: 1, + version: 2, }); }); @@ -335,12 +337,13 @@ describe('WalletSchema', () => { const mockInstance: ContractInstanceWithAddress = { address: address2, - version: 1, + version: 2, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: PublicKeys.default(), }; @@ -470,11 +473,12 @@ class MockWallet implements Wallet { async registerContract(_instanceData: any, _artifact?: any, _secretKey?: Fr): Promise { return { - version: 1, + version: 2, address: await AztecAddress.random(), currentContractClassId: Fr.random(), deployer: await AztecAddress.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), originalContractClassId: Fr.random(), publicKeys: await PublicKeys.random(), salt: Fr.random(), diff --git a/yarn-project/aztec/src/cli/aztec_start_action.ts b/yarn-project/aztec/src/cli/aztec_start_action.ts index 856ea28b4aaf..d41010e5f360 100644 --- a/yarn-project/aztec/src/cli/aztec_start_action.ts +++ b/yarn-project/aztec/src/cli/aztec_start_action.ts @@ -10,7 +10,7 @@ import type { ChainConfig } from '@aztec/stdlib/config'; import { AztecNodeAdminApiSchema, AztecNodeApiSchema, AztecNodeDebugApiSchema } from '@aztec/stdlib/interfaces/client'; import { getPackageVersion } from '@aztec/stdlib/update-checker'; import { getVersioningMiddleware } from '@aztec/stdlib/versioning'; -import { getOtelJsonRpcPropagationMiddleware } from '@aztec/telemetry-client'; +import { getOtelJsonRpcDiagnosticsMiddleware, getOtelJsonRpcPropagationMiddleware } from '@aztec/telemetry-client'; import { createLocalNetwork } from '../local-network/index.js'; import { github, splash } from '../splash.js'; @@ -95,6 +95,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg // Start the main JSON-RPC server if (Object.entries(services).length > 0) { const rpcServer = createNamespacedSafeJsonRpcServer(services, { + diagnostic: getOtelJsonRpcDiagnosticsMiddleware(), http200OnError: false, log: debugLogger, middlewares: [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions, versioningOpts)], @@ -126,6 +127,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg } const rpcServer = createNamespacedSafeJsonRpcServer(adminServices, { + diagnostic: getOtelJsonRpcDiagnosticsMiddleware(), http200OnError: false, log: debugLogger, middlewares: adminMiddlewares, diff --git a/yarn-project/aztec/src/cli/util.ts b/yarn-project/aztec/src/cli/util.ts index 06d91a711ae2..d0cff613a517 100644 --- a/yarn-project/aztec/src/cli/util.ts +++ b/yarn-project/aztec/src/cli/util.ts @@ -82,18 +82,12 @@ export async function createAccountLogs(accountManagers: AccountManager[], walle accountLogStrings.push(` Address: ${completeAddress.address.toString()}\n`); accountLogStrings.push(` Partial Address: ${completeAddress.partialAddress.toString()}\n`); accountLogStrings.push(` Secret Key: ${account.getSecretKey().toString()}\n`); + accountLogStrings.push(` Master nullifier public key hash: ${completeAddress.publicKeys.npkMHash.toString()}\n`); + accountLogStrings.push(` Master incoming viewing public key: ${completeAddress.publicKeys.ivpkM.toString()}\n\n`); accountLogStrings.push( - ` Master nullifier public key: ${completeAddress.publicKeys.masterNullifierPublicKey.toString()}\n`, - ); - accountLogStrings.push( - ` Master incoming viewing public key: ${completeAddress.publicKeys.masterIncomingViewingPublicKey.toString()}\n\n`, - ); - accountLogStrings.push( - ` Master outgoing viewing public key: ${completeAddress.publicKeys.masterOutgoingViewingPublicKey.toString()}\n\n`, - ); - accountLogStrings.push( - ` Master tagging public key: ${completeAddress.publicKeys.masterTaggingPublicKey.toString()}\n\n`, + ` Master outgoing viewing public key hash: ${completeAddress.publicKeys.ovpkMHash.toString()}\n\n`, ); + accountLogStrings.push(` Master tagging public key hash: ${completeAddress.publicKeys.tpkMHash.toString()}\n\n`); } } return accountLogStrings; diff --git a/yarn-project/aztec/src/local-network/local-network.ts b/yarn-project/aztec/src/local-network/local-network.ts index 6293df2653c5..a771e611b09c 100644 --- a/yarn-project/aztec/src/local-network/local-network.ts +++ b/yarn-project/aztec/src/local-network/local-network.ts @@ -206,6 +206,21 @@ export async function createLocalNetwork(config: Partial = { SequencerState.SYNCHRONIZING, ]); watcher?.setIsSequencerBuilding(() => !idleStates.has(sequencer.getState())); + // Under proposer pipelining the L1 publish for slot N happens during wall-clock slot N, + // but the proposer for slot N has already built the checkpoint during slot N-1 and is + // waiting for L1 to advance. We need to fast-forward L1 to wake that wait — and the wait + // we have to break first is `waitForValidParentCheckpointOnL1`, which blocks the + // checkpoint_proposal_job's background submission task until the archiver has synced past + // the build slot. That wait happens *before* `PUBLISHING_CHECKPOINT` is set, so a hook on + // that state transition would be circular (L1 has to advance before the state we'd use to + // advance L1 fires). The earliest pre-wait signal is `block-proposed`, which the sequencer + // emits once each block is built. In sandbox single-block-per-slot mode this is + // effectively "checkpoint built", and the watcher warp is harmless if a subsequent + // assembly/validation/parent-wait step aborts: L1 just sits one slot ahead, which the + // cascade absorbs. + if (watcher) { + sequencer.on('block-proposed', ({ slot }) => watcher!.setProposedTargetSlot(Number(slot))); + } } let epochTestSettler: EpochTestSettler | undefined; diff --git a/yarn-project/aztec/src/testing/anvil_test_watcher.ts b/yarn-project/aztec/src/testing/anvil_test_watcher.ts index e2f9c8ed2cbb..81505d5296fa 100644 --- a/yarn-project/aztec/src/testing/anvil_test_watcher.ts +++ b/yarn-project/aztec/src/testing/anvil_test_watcher.ts @@ -44,6 +44,12 @@ export class AnvilTestWatcher { // Tracks when we first observed the current unfilled slot with pending txs (real wall time). private unfilledSlotFirstSeen?: { slot: number; realTime: number }; + // Latest target slot for which the proposer has built a block destined for L1 but which has + // not yet been committed. Set by the proposer-pipelining hook from `block-proposed` events so + // the watcher can advance L1 (and the injected date provider) to the target slot ahead of the + // publisher's `sendRequestsAt` sleep, instead of waiting a full wall-clock slot. + private proposedTargetSlot?: number; + constructor( private cheatcodes: EthCheatCodes, rollupAddress: EthAddress, @@ -86,6 +92,18 @@ export class AnvilTestWatcher { this.isSequencerBuilding = fn; } + /** + * Records the target slot for which the proposer has built a block destined for L1. Used by + * the local-network watcher to fast-forward L1 (and the injected date provider) ahead of the + * pipelined publisher's `sendRequestsAt` sleep so it ends promptly instead of waiting a full + * wall-clock slot. Only ratchets up — late warps for stale slots are no-ops. + */ + setProposedTargetSlot(slot: number) { + if (this.proposedTargetSlot === undefined || slot > this.proposedTargetSlot) { + this.proposedTargetSlot = slot; + } + } + async start() { if (this.filledRunningPromise) { throw new Error('Watcher already watching for filled slot'); @@ -177,6 +195,20 @@ export class AnvilTestWatcher { return; } + // Pipelined-publish shortcut: if the proposer has built a block destined for a slot + // beyond the current L1 slot, fast-forward L1 to that slot's timestamp so the publisher's + // `sendRequestsAt(targetSlot)` sleep ends and the multicall mines inside the target slot. + // Without this, the publisher waits up to a full real-time slot for wall clock to catch up. + if (this.proposedTargetSlot !== undefined && this.proposedTargetSlot > currentSlot) { + const targetSlotTimestamp = Number( + await this.rollup.read.getTimestampForSlot([BigInt(this.proposedTargetSlot)]), + ); + if (await this.warpToTimestamp(targetSlotTimestamp)) { + this.logger.info(`Warped L1 to target slot ${this.proposedTargetSlot} for pipelined publish`); + } + return; + } + // If there are pending txs and the sequencer missed them, warp quickly (after a 2s real-time debounce) so the // sequencer can retry in the next slot. Without this, we'd have to wait a full real-time slot duration (~36s) for // the dateProvider to catch up to the next slot timestamp. We skip the warp if the sequencer is actively building diff --git a/yarn-project/aztec/src/testing/cheat_codes.ts b/yarn-project/aztec/src/testing/cheat_codes.ts index 7890b7f561f8..a78137eb3a1a 100644 --- a/yarn-project/aztec/src/testing/cheat_codes.ts +++ b/yarn-project/aztec/src/testing/cheat_codes.ts @@ -2,6 +2,7 @@ import { EthCheatCodes, RollupCheatCodes } from '@aztec/ethereum/test'; import { SlotNumber } from '@aztec/foundation/branded-types'; import { createLogger } from '@aztec/foundation/log'; import type { DateProvider } from '@aztec/foundation/timer'; +import type { AutomineSequencer } from '@aztec/sequencer-client'; import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; /** @@ -18,15 +19,22 @@ export class CheatCodes { public eth: EthCheatCodes, /** Cheat codes for the Aztec Rollup contract on L1. */ public rollup: RollupCheatCodes, + /** When wired, redirects time-warps through the AutomineSequencer queue (test-only). */ + private automine?: AutomineSequencer, ) {} - static async create(rpcUrls: string[], node: AztecNode, dateProvider: DateProvider): Promise { + static async create( + rpcUrls: string[], + node: AztecNode, + dateProvider: DateProvider, + automine?: AutomineSequencer, + ): Promise { const ethCheatCodes = new EthCheatCodes(rpcUrls, dateProvider); const rollupCheatCodes = new RollupCheatCodes( ethCheatCodes, await node.getNodeInfo().then(n => n.l1ContractAddresses), ); - return new CheatCodes(ethCheatCodes, rollupCheatCodes); + return new CheatCodes(ethCheatCodes, rollupCheatCodes, automine); } /** @@ -46,6 +54,15 @@ export class CheatCodes { ); } + // AutomineSequencer owns time control through its serial queue — delegate to keep warps atomic + // with respect to any in-flight build, and avoid the mineBlock-loop hack below. + // `warpTo` internally builds an empty L2 checkpoint, which auto-mines exactly one L1 block at + // the target slot boundary, so no separate `node.mineBlock()` is needed here. + if (this.automine) { + await this.automine.warpTo(Number(targetBigInt)); + return; + } + const currentSlot = await this.rollup.getSlot(); const targetSlot = await this.rollup.getSlotAt(targetBigInt); diff --git a/yarn-project/bootstrap.sh b/yarn-project/bootstrap.sh index 140dd2c6ca78..46c0c712bdac 100755 --- a/yarn-project/bootstrap.sh +++ b/yarn-project/bootstrap.sh @@ -203,9 +203,9 @@ function test_cmds { # Add debug logging for tests that require a bit more info if [[ "$test" == p2p/src/client/p2p_client.test.ts || "$test" == p2p/src/services/discv5/discv5_service.test.ts || "$test" == p2p/src/client/p2p_client.integration.test.ts ]]; then - cmd_env+=" LOG_LEVEL=debug" + cmd_env+=" LOG_LEVEL=\"debug; info: json-rpc, simulator\"" elif [[ "$test" =~ rollup_ivc_integration || "$test" =~ avm_integration ]]; then - cmd_env+=" LOG_LEVEL=debug BB_VERBOSE=1 " + cmd_env+=" LOG_LEVEL=\"debug; info: json-rpc, simulator\" BB_VERBOSE=1 " elif [[ "$test" =~ e2e_p2p ]]; then cmd_env+=" LOG_LEVEL='verbose; debug:p2p'" fi @@ -247,7 +247,7 @@ function bench_cmds { echo "$hash BENCH_OUTPUT=bench-out/kv_store.bench.json yarn-project/scripts/run_test.sh kv-store/src/bench/map_bench.test.ts" echo "$hash BENCH_OUTPUT=bench-out/tx_pool_v2.bench.json yarn-project/scripts/run_test.sh p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_bench.test.ts" echo "$hash BENCH_OUTPUT=bench-out/tx_validator.bench.json yarn-project/scripts/run_test.sh p2p/src/msg_validators/tx_validator/tx_validator_bench.test.ts" - echo "$hash:ISOLATE=1:CPUS=16:MEM=32g:TIMEOUT=1800 BENCH_OUTPUT=bench-out/p2p_client_proposal_tx_collector.bench.json yarn-project/scripts/run_test.sh p2p/src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts" + echo "$hash:ISOLATE=1:CPUS=16:MEM=32g:TIMEOUT=1800 BENCH_OUTPUT=bench-out/p2p_client_batch_tx_requester.bench.json yarn-project/scripts/run_test.sh p2p/src/client/test/p2p_client.batch_tx_requester.bench.test.ts" echo "$hash BENCH_OUTPUT=bench-out/tx.bench.json yarn-project/scripts/run_test.sh stdlib/src/tx/tx_bench.test.ts" echo "$hash:ISOLATE=1:CPUS=10:MEM=16g:LOG_LEVEL=silent BENCH_OUTPUT=bench-out/proving_broker.bench.json yarn-project/scripts/run_test.sh prover-client/src/test/proving_broker_testbench.test.ts" echo "$hash:ISOLATE=1:CPUS=16:MEM=16g BENCH_OUTPUT=bench-out/avm_bulk_test.bench.json yarn-project/scripts/run_test.sh bb-prover/src/avm_proving_tests/avm_bulk.test.ts" diff --git a/yarn-project/cli-wallet/package.json b/yarn-project/cli-wallet/package.json index f8046b3d1711..11f8ab5d5b45 100644 --- a/yarn-project/cli-wallet/package.json +++ b/yarn-project/cli-wallet/package.json @@ -19,7 +19,7 @@ "scripts": { "start": "node --no-warnings ./dest/bin", "start:debug": "node --inspect=0.0.0.0:9221 --no-warnings ./dest/bin", - "dev": "LOG_LEVEL=debug && node ./dest/bin", + "dev": "LOG_LEVEL=\"debug; info: json-rpc, simulator\" node ./dest/bin", "build": "yarn clean && ../scripts/tsc.sh", "build:dev": "../scripts/tsc.sh --watch", "clean": "rm -rf ./dest .tsbuildinfo", diff --git a/yarn-project/constants/src/constants.gen.ts b/yarn-project/constants/src/constants.gen.ts index 65028bb96a5e..ae24ee193e19 100644 --- a/yarn-project/constants/src/constants.gen.ts +++ b/yarn-project/constants/src/constants.gen.ts @@ -136,12 +136,15 @@ export const DEFAULT_OVPK_M_X = 122127877196173055705879288602884754543280089552 export const DEFAULT_OVPK_M_Y = 3646747884782549389807830220601404629716007431341772952958971658285958854707n; export const DEFAULT_TPK_M_X = 728059161893070741164607238299536939695876538801885465230641192969135857403n; export const DEFAULT_TPK_M_Y = 14575718736702206050102425029229426215631664471161015518982549597389390371695n; +export const DEFAULT_NPK_M_HASH = 9490941203163884203266873379528043162885952552009707050511473783876867365414n; +export const DEFAULT_OVPK_M_HASH = 6503635668323258394266152634006889881423098283582185344306514598322956522059n; +export const DEFAULT_TPK_M_HASH = 3696996950890211715833095099359687729113787313245035143274671977290400579312n; export const AZTEC_ADDRESS_LENGTH = 1; export const GAS_FEES_LENGTH = 2; export const GAS_LENGTH = 2; export const GAS_SETTINGS_LENGTH = 8; export const CALL_CONTEXT_LENGTH = 4; -export const CONTRACT_INSTANCE_LENGTH = 16; +export const CONTRACT_INSTANCE_LENGTH = 10; export const CONTRACT_STORAGE_READ_LENGTH = 3; export const CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH = 3; export const ETH_ADDRESS_LENGTH = 1; @@ -163,9 +166,9 @@ export const L2_TO_L1_MESSAGE_LENGTH = 2; export const COUNTED_L2_TO_L1_MESSAGE_LENGTH = 3; export const SCOPED_L2_TO_L1_MESSAGE_LENGTH = 3; export const SCOPED_COUNTED_L2_TO_L1_MESSAGE_LENGTH = 4; -export const KEY_VALIDATION_REQUEST_LENGTH = 4; -export const KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH = 5; -export const SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH = 6; +export const KEY_VALIDATION_REQUEST_LENGTH = 2; +export const KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH = 3; +export const SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH = 4; export const PARTIAL_STATE_REFERENCE_LENGTH = 6; export const TREE_LEAF_READ_REQUEST_LENGTH = 2; export const PRIVATE_LOG_SIZE_IN_FIELDS = 16; @@ -204,19 +207,19 @@ export const BLOCK_HEADER_LENGTH = 22; export const CHECKPOINT_HEADER_LENGTH = 12; export const CHECKPOINT_HEADER_SIZE_IN_BYTES = 316; export const SCOPED_READ_REQUEST_LEN = 3; -export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 870; +export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 838; export const PRIVATE_CONTEXT_INPUTS_LENGTH = 37; export const FEE_RECIPIENT_LENGTH = 2; export const HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE = 28; export const PAIRING_POINTS_SIZE = 8; export const IPA_CLAIM_SIZE = 6; export const PUBLIC_DATA_READ_LENGTH = 3; -export const PRIVATE_VALIDATION_REQUESTS_LENGTH = 771; +export const PRIVATE_VALIDATION_REQUESTS_LENGTH = 643; export const PRIVATE_TO_ROLLUP_ACCUMULATED_DATA_LENGTH = 1243; export const TX_CONSTANT_DATA_LENGTH = 34; export const COMBINED_CONSTANT_DATA_LENGTH = 43; export const PRIVATE_ACCUMULATED_DATA_LENGTH = 2059; -export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2873; +export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2745; export const PRIVATE_TO_PUBLIC_ACCUMULATED_DATA_LENGTH = 1371; export const PRIVATE_TO_AVM_ACCUMULATED_DATA_LENGTH = 152; export const NUM_PRIVATE_TO_AVM_ACCUMULATED_DATA_ARRAYS = 3; @@ -460,7 +463,7 @@ export const AVM_DEBUGLOG_BASE_L2_GAS = 9; export const AVM_POSEIDON2_BASE_L2_GAS = 360; export const AVM_SHA256COMPRESSION_BASE_L2_GAS = 12288; export const AVM_KECCAKF1600_BASE_L2_GAS = 58176; -export const AVM_ECADD_BASE_L2_GAS = 270; +export const AVM_ECADD_BASE_L2_GAS = 180; export const AVM_TORADIXBE_BASE_L2_GAS = 24; export const AVM_CALLDATACOPY_DYN_L2_GAS = 3; export const AVM_RETURNDATACOPY_DYN_L2_GAS = 3; @@ -536,8 +539,9 @@ export enum DomainSeparator { OVSK_M = 4272201051, TSK_M = 1546190975, PUBLIC_KEYS_HASH = 777457226, + SINGLE_PUBLIC_KEY_HASH = 3452068255, PARTIAL_ADDRESS = 2103633018, - CONTRACT_ADDRESS_V1 = 1788365517, + CONTRACT_ADDRESS_V2 = 4099338721, BLOCK_HEADER_HASH = 4195546849, TX_REQUEST = 3763737512, PUBLIC_TX_HASH = 1630108851, diff --git a/yarn-project/constants/src/scripts/constants.in.ts b/yarn-project/constants/src/scripts/constants.in.ts index 88d1c5fd6534..a864d6a2d2e3 100644 --- a/yarn-project/constants/src/scripts/constants.in.ts +++ b/yarn-project/constants/src/scripts/constants.in.ts @@ -122,9 +122,10 @@ const CPP_GENERATORS: string[] = [ 'BLOCK_HEADER_HASH', 'SALTED_INITIALIZATION_HASH', 'PARTIAL_ADDRESS', - 'CONTRACT_ADDRESS_V1', + 'CONTRACT_ADDRESS_V2', 'CONTRACT_CLASS_ID', 'PUBLIC_KEYS_HASH', + 'SINGLE_PUBLIC_KEY_HASH', 'NOTE_HASH_NONCE', 'UNIQUE_NOTE_HASH', 'SILOED_NOTE_HASH', @@ -316,9 +317,10 @@ const PIL_CONSTANTS = [ const PIL_GENERATORS: string[] = [ 'SALTED_INITIALIZATION_HASH', 'PARTIAL_ADDRESS', - 'CONTRACT_ADDRESS_V1', + 'CONTRACT_ADDRESS_V2', 'CONTRACT_CLASS_ID', 'PUBLIC_KEYS_HASH', + 'SINGLE_PUBLIC_KEY_HASH', 'NOTE_HASH_NONCE', 'UNIQUE_NOTE_HASH', 'SILOED_NOTE_HASH', diff --git a/yarn-project/end-to-end/bootstrap.sh b/yarn-project/end-to-end/bootstrap.sh index e0ec4356830e..a40cd127f22f 100755 --- a/yarn-project/end-to-end/bootstrap.sh +++ b/yarn-project/end-to-end/bootstrap.sh @@ -25,20 +25,23 @@ function set_dump_avm { function test_cmds { local run_test_script="yarn-project/end-to-end/scripts/run_test.sh" - local prefix="$hash:ISOLATE=1" + local prefix="$hash:ISOLATE=1:TIMEOUT=20m" if [ "$CI_FULL" -eq 1 ]; then echo "$prefix:TIMEOUT=20m:CPUS=16:MEM=96g:NAME=e2e_prover_full_real $run_test_script simple e2e_prover/full" else echo "$prefix:NAME=e2e_prover_full_fake FAKE_PROOFS=1 $run_test_script simple e2e_prover/full" fi - echo "$prefix:TIMEOUT=15m:NAME=e2e_block_building $(set_dump_avm e2e_block_building) $run_test_script simple e2e_block_building" + echo "$prefix:TIMEOUT=25m:NAME=e2e_block_building $(set_dump_avm e2e_block_building) $run_test_script simple e2e_block_building" + echo "$prefix:TIMEOUT=30m:NAME=e2e_avm_simulator $(set_dump_avm e2e_avm_simulator) $run_test_script simple src/e2e_avm_simulator.test.ts" + + local tests=( # List all standalone and nested tests, except for the ones listed above. src/e2e_!(prover)/*.test.ts src/e2e_p2p/reqresp/*.test.ts - src/e2e_!(block_building).test.ts + src/e2e_!(block_building|avm_simulator).test.ts ) for test in "${tests[@]}"; do local name=${test#*e2e_} @@ -50,6 +53,9 @@ function test_cmds { e2e_p2p/add_rollup) test_prefix="$prefix:TIMEOUT=20m" ;; + e2e_cross_chain_messaging/l1_to_l2) + test_prefix="$prefix:TIMEOUT=20m" + ;; esac # Check if this is a .parallel.test.ts file @@ -74,7 +80,7 @@ function test_cmds { ) for test in "${tests[@]}"; do # We must set ONLY_TERM_PARENT=1 to allow the script to fully control cleanup process. - echo "$hash:ONLY_TERM_PARENT=1 $run_test_script compose $test" + echo "$hash:ONLY_TERM_PARENT=1:TIMEOUT=20m $run_test_script compose $test" done tests=( @@ -82,7 +88,7 @@ function test_cmds { ) for test in "${tests[@]}"; do # We must set ONLY_TERM_PARENT=1 to allow the script to fully control cleanup process. - echo "$hash:ONLY_TERM_PARENT=1 $run_test_script web3signer $test" + echo "$hash:ONLY_TERM_PARENT=1:TIMEOUT=20m $run_test_script web3signer $test" done tests=( @@ -90,7 +96,7 @@ function test_cmds { ) for test in "${tests[@]}"; do # We must set ONLY_TERM_PARENT=1 to allow the script to fully control cleanup process. - echo "$hash:ONLY_TERM_PARENT=1 $run_test_script ha $test" + echo "$hash:ONLY_TERM_PARENT=1:TIMEOUT=30m $run_test_script ha $test" done #echo "$hash:ONLY_TERM_PARENT=1 $run_test_script simple src/e2e_multi_validator/e2e_multi_validator_node.test.ts" diff --git a/yarn-project/end-to-end/scripts/docker-compose.yml b/yarn-project/end-to-end/scripts/docker-compose.yml index 528efb33a286..e394e2610220 100644 --- a/yarn-project/end-to-end/scripts/docker-compose.yml +++ b/yarn-project/end-to-end/scripts/docker-compose.yml @@ -28,6 +28,7 @@ services: WS_BLOCK_CHECK_INTERVAL_MS: 500 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 P2P_MIN_TX_POOL_AGE_MS: 0 + SEQ_ENABLE_PROPOSER_PIPELINING: 'true' HARDWARE_CONCURRENCY: ${HARDWARE_CONCURRENCY:-} end-to-end: diff --git a/yarn-project/end-to-end/scripts/test_simple.sh b/yarn-project/end-to-end/scripts/test_simple.sh index ea2089cef1c6..4d878e805922 100755 --- a/yarn-project/end-to-end/scripts/test_simple.sh +++ b/yarn-project/end-to-end/scripts/test_simple.sh @@ -33,7 +33,7 @@ else [ -n "${test_name:-}" ] && test_name_arg=(--testNamePattern="$test_name") node --experimental-vm-modules ../node_modules/.bin/jest \ - --testTimeout=300000 \ + --testTimeout=600000 \ --no-cache \ "${cache_dir_arg[@]}" \ "${test_name_arg[@]}" \ diff --git a/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts b/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts index 56cdad9aba68..1d58f3a3e40e 100644 --- a/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts +++ b/yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts @@ -24,7 +24,7 @@ import type { TestWallet } from '../test-wallet/test_wallet.js'; import { proveInteraction } from '../test-wallet/utils.js'; // Set a 3 minute timeout. -const TIMEOUT = 180_000; +const TIMEOUT = 300_000; describe('transaction benchmarks', () => { const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS); diff --git a/yarn-project/end-to-end/src/composed/e2e_cheat_codes.test.ts b/yarn-project/end-to-end/src/composed/e2e_cheat_codes.test.ts index 956a5f8c9b81..6febfdf40ca8 100644 --- a/yarn-project/end-to-end/src/composed/e2e_cheat_codes.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_cheat_codes.test.ts @@ -71,14 +71,30 @@ describe('e2e_cheat_codes', () => { it('warpL2TimeAtLeastTo with target in current slot auto-adjusts to next slot', async () => { // Target is 1 second ahead of L1 time — still in the current slot, so auto-adjust should kick in. - const currentL1Timestamp = Number(await cheatCodes.eth.lastBlockTimestamp()); - const targetTimestamp = currentL1Timestamp + 1; - await cheatCodes.warpL2TimeAtLeastTo(nodeDebug, targetTimestamp); - - const blockNumber = await aztecNode.getBlockNumber(); - const block = await aztecNode.getBlock(blockNumber); - expect(block).toBeDefined(); - expect(Number(block!.header.globalVariables.timestamp)).toBeGreaterThanOrEqual(targetTimestamp); + // The sequencer running in this composed test advances L1 by a full slot when it proposes a block, + // and that warp can land between our `lastBlockTimestamp()` read and the cheat code's internal + // re-read, racing `currentL1 + 1` into the past. Retry on that specific race with a fresh target; + // a subsequent slot-jump within the retry window is improbable enough that a small cap suffices. + const maxAttempts = 5; + let lastError: unknown; + for (let attempt = 1; attempt <= maxAttempts; attempt++) { + const currentL1Timestamp = Number(await cheatCodes.eth.lastBlockTimestamp()); + const targetTimestamp = currentL1Timestamp + 1; + try { + await cheatCodes.warpL2TimeAtLeastTo(nodeDebug, targetTimestamp); + const blockNumber = await aztecNode.getBlockNumber(); + const block = await aztecNode.getBlock(blockNumber); + expect(block).toBeDefined(); + expect(Number(block!.header.globalVariables.timestamp)).toBeGreaterThanOrEqual(targetTimestamp); + return; + } catch (err) { + lastError = err; + if (!(err instanceof Error) || !err.message.includes('is not in the future')) { + throw err; + } + } + } + throw lastError; }); it('warpL2TimeAtLeastTo with past timestamp throws', async () => { diff --git a/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts b/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts index 2f01949e3c21..be5c43d80cb4 100644 --- a/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts @@ -114,7 +114,7 @@ describe('e2e_local_network_example', () => { expect(aliceBalance).toBe(initialSupply - transferQuantity); expect(bobBalance).toBe(transferQuantity + mintQuantity); - }); + }, 900_000); it('can create accounts on the local network', async () => { const logger = createLogger('e2e:token'); @@ -222,5 +222,5 @@ describe('e2e_local_network_example', () => { expect(bobNewBalance).toEqual(bobBalance - amountTransferToAlice); expect(await getFeeJuiceBalance(sponsoredFPC, node)).toEqual(initialFPCFeeJuice - receiptForBob.transactionFee!); - }); + }, 900_000); }); diff --git a/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts b/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts index 31b9667d0190..0853af29b175 100644 --- a/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_persistence.test.ts @@ -16,10 +16,11 @@ import { tmpdir } from 'os'; import { join } from 'path'; import { BlacklistTokenContractTest, Role } from '../e2e_blacklist_token_contract/blacklist_token_contract_test.js'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { type EndToEndContext, setup } from '../fixtures/utils.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; -jest.setTimeout(60_000); +jest.setTimeout(15 * 60 * 1000); describe('Aztec persistence', () => { /** @@ -60,7 +61,11 @@ describe('Aztec persistence', () => { beforeAll(async () => { dataDirectory = await mkdtemp(join(tmpdir(), 'aztec-node-')); - const initialContext = await setup(1, { dataDirectory, numberOfInitialFundedAccounts: 3 }, { dataDirectory }); + const initialContext = await setup( + 1, + { ...PIPELINING_SETUP_OPTS, dataDirectory, numberOfInitialFundedAccounts: 3 }, + { dataDirectory }, + ); aztecNode = initialContext.aztecNode; deployL1ContractsValues = initialContext.deployL1ContractsValues; initialFundedAccounts = initialContext.initialFundedAccounts; @@ -101,7 +106,7 @@ describe('Aztec persistence', () => { await progressBlocksPastDelay(contract); await initialContext.teardown(); - }, 180_000); + }, 600_000); const progressBlocksPastDelay = async (contract: TokenBlacklistContract) => { for (let i = 0; i < BlacklistTokenContractTest.CHANGE_ROLES_DELAY; ++i) { @@ -113,14 +118,19 @@ describe('Aztec persistence', () => { [ // ie we were shutdown and now starting back up. Initial sync should be ~instant 'when starting Node and PXE with existing databases', - () => setup(0, { dataDirectory, deployL1ContractsValues, initialFundedAccounts }, { dataDirectory }), - 1000, + () => + setup( + 0, + { ...PIPELINING_SETUP_OPTS, dataDirectory, deployL1ContractsValues, initialFundedAccounts }, + { dataDirectory }, + ), + 60_000, ], [ // ie our PXE was restarted, data kept intact and now connects to a "new" Node. Initial synch will synch from scratch 'when starting a PXE with an existing database, connected to a Node with database synched from scratch', - () => setup(0, { deployL1ContractsValues, initialFundedAccounts }, { dataDirectory }), - 10_000, + () => setup(0, { ...PIPELINING_SETUP_OPTS, deployL1ContractsValues, initialFundedAccounts }, { dataDirectory }), + 120_000, ], ])('%s', (_, contextSetup, timeout) => { let contract: TokenBlacklistContract; @@ -207,14 +217,14 @@ describe('Aztec persistence', () => { [ // ie. I'm setting up a new full node, sync from scratch and restore wallets/notes 'when starting the Node and PXE with empty databases', - () => setup(0, { deployL1ContractsValues, initialFundedAccounts }, {}), - 10_000, + () => setup(0, { ...PIPELINING_SETUP_OPTS, deployL1ContractsValues, initialFundedAccounts }, {}), + 120_000, ], [ // ie. I'm setting up a new PXE, restore wallets/notes from a Node 'when starting a PXE with an empty database connected to a Node with an existing database', - () => setup(0, { dataDirectory, deployL1ContractsValues, initialFundedAccounts }, {}), - 10_000, + () => setup(0, { ...PIPELINING_SETUP_OPTS, dataDirectory, deployL1ContractsValues, initialFundedAccounts }, {}), + 120_000, ], ])('%s', (_, contextSetup, timeout) => { beforeEach(async () => { @@ -285,7 +295,7 @@ describe('Aztec persistence', () => { // Then shutdown the temporary components and restart the original components // They should sync up from where they left off and be able to see the actions performed by the temporary node & PXE. beforeAll(async () => { - const temporaryContext = await setup(0, { deployL1ContractsValues }, {}); + const temporaryContext = await setup(0, { ...PIPELINING_SETUP_OPTS, deployL1ContractsValues }, {}); await temporaryContext.wallet.registerContract(contractInstance, TokenBlacklistContract.artifact); @@ -313,11 +323,11 @@ describe('Aztec persistence', () => { let contract: TokenBlacklistContract; beforeEach(async () => { - context = await setup(0, { dataDirectory, deployL1ContractsValues }, { dataDirectory }); + context = await setup(0, { ...PIPELINING_SETUP_OPTS, dataDirectory, deployL1ContractsValues }, { dataDirectory }); const account = initialFundedAccounts[0]; await context.wallet.createSchnorrAccount(account.secret, account.salt); contract = TokenBlacklistContract.at(contractAddress, context.wallet); - }); + }, 120_000); afterEach(async () => { await context.teardown(); diff --git a/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts b/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts index 532d25ee5832..b20a3d70274e 100644 --- a/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts @@ -211,5 +211,5 @@ describe('e2e_cross_chain_messaging token_bridge_tutorial_test', () => { const newL1Balance = await l1TokenManager.getL1TokenBalance(ownerEthAddress); logger.info(`New L1 balance of ${ownerEthAddress} is ${newL1Balance}`); expect(newL1Balance).toBe(withdrawAmount); - }, 300_000); + }, 900_000); }); diff --git a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts index 9a228508423b..443adbe3a2e0 100644 --- a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts +++ b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts @@ -27,6 +27,8 @@ import { GovernanceProposerAbi } from '@aztec/l1-artifacts/GovernanceProposerAbi import { StatefulTestContractArtifact } from '@aztec/noir-test-contracts.js/StatefulTest'; import { type AttestationInfo, getAttestationInfoFromPublishedCheckpoint } from '@aztec/stdlib/block'; import { Checkpoint } from '@aztec/stdlib/checkpoint'; +import { OffenseType } from '@aztec/stdlib/slashing'; +import { TxStatus } from '@aztec/stdlib/tx'; import type { GenesisData } from '@aztec/stdlib/world-state'; import type { ValidatorClient } from '@aztec/validator-client'; import { PostgresSlashingProtectionDatabase } from '@aztec/validator-ha-signer/db'; @@ -38,6 +40,7 @@ import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { Pool } from 'pg'; +import { PIPELINING_SETUP_OPTS } from '../../fixtures/fixtures.js'; import { type HADatabaseConfig, cleanupHADatabase, @@ -152,26 +155,30 @@ describe('HA Full Setup', () => { dateProvider, deployL1ContractsValues, genesis, - } = await setup(1, { - initialValidators, - sequencerPublisherPrivateKeys: [new SecretValue(publisherPrivateKeys[0])], - aztecTargetCommitteeSize: COMMITTEE_SIZE, - minTxsPerBlock: 1, - archiverPollingIntervalMS: 200, - sequencerPollingIntervalMS: 200, - worldStateBlockCheckIntervalMS: 200, - blockCheckIntervalMS: 200, - startProverNode: true, - // Disable validation on this node - disableValidator: true, - skipAccountDeployment: true, - // Enable P2P for transaction gossip - p2pEnabled: true, - // Enable slashing for testing governance + slashing vote coordination - slasherEnabled: true, - slashingRoundSizeInEpochs: 1, // 32 slots (1 epoch) - slashingQuorum: 17, // >50% of 32 slots for tally quorum, - })); + } = await setup( + 1, + { + ...PIPELINING_SETUP_OPTS, + initialValidators, + sequencerPublisherPrivateKeys: [new SecretValue(publisherPrivateKeys[0])], + aztecTargetCommitteeSize: COMMITTEE_SIZE, + archiverPollingIntervalMS: 200, + sequencerPollingIntervalMS: 200, + worldStateBlockCheckIntervalMS: 200, + blockCheckIntervalMS: 200, + startProverNode: true, + // Disable validation on this node + disableValidator: true, + skipAccountDeployment: true, + // Enable P2P for transaction gossip + p2pEnabled: true, + // Enable slashing for testing governance + slashing vote coordination + slasherEnabled: true, + slashingRoundSizeInEpochs: 1, // 32 slots (1 epoch) + slashingQuorum: 17, // >50% of 32 slots for tally quorum, + }, + { syncChainTip: 'proven' }, + )); if (!dateProvider) { throw new Error('dateProvider must be provided by setup for HA tests'); @@ -266,22 +273,30 @@ describe('HA Full Setup', () => { accountData.signingKey, ); const deployMethod = await accountManager.getDeployMethod(); - await deployMethod.send({ from: NO_FROM }); + await deployMethod.send({ from: NO_FROM, wait: { waitForStatus: TxStatus.CHECKPOINTED } }); ownerAddress = accountManager.address; logger.info(`Test account deployed at ${ownerAddress}`); }); afterAll(async () => { - // Cleanup all HA peer nodes + // Stop all HA peer nodes in parallel with a per-node deadline. A single stuck node can otherwise + // block the serial loop long enough to blow the jest hook timeout — e.g. a sequencer.stop() that + // awaits an L1 publish whose tx-timeout was computed on a test-warped clock and never fires. if (haNodeServices) { - for (let i = 0; i < haNodeServices.length; i++) { - try { + const STOP_DEADLINE_MS = 30_000; + await Promise.allSettled( + haNodeServices.map((service, i) => { logger.info(`Stopping HA peer node ${i}`); - await haNodeServices[i].stop(); - } catch (error) { - logger.error(`Failed to stop HA peer node ${i}: ${error}`); - } - } + return Promise.race([ + service.stop().catch(error => { + logger.error(`Failed to stop HA peer node ${i}: ${error}`); + }), + sleep(STOP_DEADLINE_MS).then(() => { + logger.error(`HA peer node ${i} stop did not return within ${STOP_DEADLINE_MS}ms; abandoning`); + }), + ]); + }), + ); } // Cleanup HA keystore temp directories @@ -333,6 +348,7 @@ describe('HA Full Setup', () => { logger.info(`Deploying contract from ${ownerAddress}`); const { receipt } = await deployer.deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }).send({ from: ownerAddress, + wait: { waitForStatus: TxStatus.CHECKPOINTED }, }); await waitForProven(aztecNode, receipt, { @@ -455,6 +471,7 @@ describe('HA Full Setup', () => { const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); const { receipt } = await deployer.deploy([ownerAddress, 42], { salt: Fr.random() }).send({ from: ownerAddress, + wait: { waitForStatus: TxStatus.CHECKPOINTED }, }); expect(receipt.blockNumber).toBeDefined(); logger.info(`Transaction mined in block ${receipt.blockNumber}`); @@ -476,15 +493,28 @@ describe('HA Full Setup', () => { const round = await governanceProposer.computeRound(blockSlot); logger.info(`Block slot ${blockSlot}, governance round ${round}`); - // Poll until L1 vote count converges with the DB duties. - // The DB records a duty as "signed" when the crypto signature is produced, but before the L1 tx mines. - // We need to wait for all in-flight L1 txs to land before comparing. - logger.info('Polling L1 for governance votes and waiting for DB convergence...'); + // Wait for at least one on-chain governance signal for our payload to land, then assert on + // the round *outcome* (payload-with-most-signals) rather than on a strict per-node duty + // count equality. + // + // Why not assert `l1VoteCount === uniqueSlots.size` like the previous version did? HA + // signing intentionally suppresses duplicate signatures across nodes for the same + // `(slot, validator)` duty: only one of the N HA peers actually emits the L1 tx for each + // scheduled slot. Under pipelining there is an additional build-slot-vs-target-slot offset + // where a vote signed in build slot N targets slot N+1, so at any measurement time the DB + // can have a duty row for slot S whose L1 tx hasn't mined yet. The old strict equality + // pinned the test to behavior that doesn't hold under either of those. + // + // What we actually care about: the HA cluster coordinated well enough that at least one + // successful governance signal landed for our payload, the round-winner converges on the + // payload we configured, no duty was double-signed for the same `(slot, validator)`, and + // every recorded duty ended in SIGNED state. + logger.info('Polling L1 for governance signals to confirm HA cluster coordination...'); const rollupAddr = deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString() as `0x${string}`; const govProposerAddr = deployL1ContractsValues.l1ContractAddresses.governanceProposerAddress.toString() as `0x${string}`; - const { l1VoteCount, governanceVoteDuties } = await retryUntil( + const { l1VoteCount, lastSignalSlot, payloadWithMostSignals } = await retryUntil( async () => { const snapshotBlock = await deployL1ContractsValues.l1Client.getBlockNumber(); const [roundData, l1VoteCountBig] = await Promise.all([ @@ -505,56 +535,68 @@ describe('HA Full Setup', () => { ]); const lastSignalSlot = Number(roundData.lastSignalSlot); const l1VoteCount = Number(l1VoteCountBig); - if (l1VoteCount === 0) { - return undefined; - } - - const dbResult = await mainPool.query( - `SELECT * FROM validator_duties WHERE slot::numeric <= $1 AND duty_type = 'GOVERNANCE_VOTE' ORDER BY slot, started_at`, - [lastSignalSlot.toString()], - ); - const governanceVoteDuties = dbResult.rows; - const uniqueSlots = new Set(governanceVoteDuties.map(row => row.slot)); - logger.info( `L1 round ${round}: lastSignalSlot=${lastSignalSlot}, l1VoteCount=${l1VoteCount}, ` + - `DB duties=${governanceVoteDuties.length}, uniqueSlots=${uniqueSlots.size} ` + + `payloadWithMostSignals=${roundData.payloadWithMostSignals} ` + `(snapshot at L1 block ${snapshotBlock})`, ); - - if (l1VoteCount < uniqueSlots.size) { + if (l1VoteCount === 0) { return undefined; } - return { l1VoteCount, governanceVoteDuties }; + return { + l1VoteCount, + lastSignalSlot, + payloadWithMostSignals: roundData.payloadWithMostSignals, + }; }, - 'L1 vote count to match DB duties', - 10, - 0.2, + `L1 governance round to land >= 1 signal`, + 120, + 0.5, ); + // Outcome 1: the round leader payload is the one we configured all HA nodes to vote for. + // This is the strongest "governance state advanced toward our payload" assertion the + // contract exposes per-round short of executing the proposal (which needs QUORUM_SIZE + // signals -- defaults to ~151 and takes many minutes to reach, way beyond a unit-test + // budget). expect(l1VoteCount).toBeGreaterThan(0); + expect(payloadWithMostSignals.toLowerCase()).toBe(mockGovernancePayload.toString().toLowerCase()); + logger.info( + `Governance round ${round} coordinated on payload ${payloadWithMostSignals}: ${l1VoteCount} signals on L1`, + ); - if (governanceVoteDuties.length > 0) { - const dutyKeys = governanceVoteDuties.map(row => `${row.slot}-${row.validator_address}`); - const uniqueDutyKeys = new Set(dutyKeys); - expect(uniqueDutyKeys.size).toBe(governanceVoteDuties.length); + // Outcome 2: every duty the HA cluster recorded for this round is in a healthy state, and + // no (slot, validator) pair was signed twice — i.e. HA dedup actually suppressed duplicates. + // We tolerate `uniqueDutySlots > l1VoteCount` (in-flight L1 txs that haven't mined yet) and + // `uniqueDutySlots < l1VoteCount` (duties that completed too recently to be visible at the + // snapshot read) — the only invariant we hold is "no two HA nodes both signed the same + // (slot, validator)". + const dbResult = await mainPool.query( + `SELECT * FROM validator_duties WHERE slot::numeric <= $1 AND duty_type = 'GOVERNANCE_VOTE' ORDER BY slot, started_at`, + [lastSignalSlot.toString()], + ); + const governanceVoteDuties = dbResult.rows; - for (const duty of governanceVoteDuties) { - logger.info( - ` Governance vote duty: slot ${duty.slot}, validator ${duty.validator_address}, node ${duty.node_id}, status ${duty.status}`, - ); - expect(duty.status).toBe(DutyStatus.SIGNED); - expect(duty.completed_at).toBeDefined(); - } + expect(governanceVoteDuties.length).toBeGreaterThan(0); + + const dutyKeys = governanceVoteDuties.map(row => `${row.slot}-${row.validator_address}`); + const uniqueDutyKeys = new Set(dutyKeys); + expect(uniqueDutyKeys.size).toBe(governanceVoteDuties.length); - const uniqueSlots = new Set(governanceVoteDuties.map(row => row.slot)); + for (const duty of governanceVoteDuties) { logger.info( - `L1 vote count: ${l1VoteCount}, unique slots in DB with governance votes: ${uniqueSlots.size} (slots: ${[...uniqueSlots].join(', ')})`, + ` Governance vote duty: slot ${duty.slot}, validator ${duty.validator_address}, node ${duty.node_id}, status ${duty.status}`, ); - expect(l1VoteCount).toBe(uniqueSlots.size); - logger.info(`Verified L1 votes (${l1VoteCount}) === unique slots with votes (${uniqueSlots.size})`); + expect(duty.status).toBe(DutyStatus.SIGNED); + expect(duty.completed_at).toBeDefined(); } + const uniqueSlots = new Set(governanceVoteDuties.map(row => row.slot)); + logger.info( + `L1 vote count: ${l1VoteCount}, governance vote duties: ${governanceVoteDuties.length}, ` + + `unique slots with votes: ${uniqueSlots.size} (slots: ${[...uniqueSlots].join(', ')})`, + ); + logger.info('Governance voting with HA coordination and L1 verification complete'); }); @@ -616,6 +658,7 @@ describe('HA Full Setup', () => { const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); const receipt = await deployer.deploy([ownerAddress, 201], { salt: new Fr(201) }).send({ from: ownerAddress, + wait: { waitForStatus: TxStatus.CHECKPOINTED }, }); expect(receipt.receipt.blockNumber).toBeDefined(); const [block] = await aztecNode.getBlocks(receipt.receipt.blockNumber!, 1, { @@ -662,6 +705,7 @@ describe('HA Full Setup', () => { const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); const { receipt } = await deployer.deploy([ownerAddress, i + 100], { salt: new Fr(BigInt(i + 100)) }).send({ from: ownerAddress, + wait: { waitForStatus: TxStatus.CHECKPOINTED }, }); expect(receipt.blockNumber).toBeDefined(); @@ -765,45 +809,6 @@ describe('HA Full Setup', () => { `Block ${receipt.blockNumber}: Database shows ${dutiesByValidator.size} unique validators attested (quorum: ${quorum}), no double-signing detected in DB`, ); - // P2P LAYER CHECK: Verify only one attestation per validator was sent over P2P - // Find first active node for P2P check - let p2pNodeIndex = 0; - for (let idx = 0; idx < haNodeServices.length; idx++) { - if (!killedNodes.includes(idx)) { - p2pNodeIndex = idx; - break; - } - } - - const p2pNode = haNodeServices[p2pNodeIndex]; - const p2p = p2pNode.getP2P(); - const slot = SlotNumber(Number(slotNumber)); - - // Get all attestations from P2P pool for this slot (before deduplication) - const p2pAttestations = await p2p.getCheckpointAttestationsForSlot(slot); - const p2pAttestationsWithSignatures = p2pAttestations.filter(a => !a.signature.isEmpty()); - expect(p2pAttestationsWithSignatures.length).toBeGreaterThan(0); - - // Extract validator addresses from P2P attestations using getSender() - const p2pValidatorAddresses = new Map(); - for (const attestation of p2pAttestationsWithSignatures) { - const sender = attestation.getSender(); - if (sender) { - const addr = sender.toString(); - p2pValidatorAddresses.set(addr, (p2pValidatorAddresses.get(addr) || 0) + 1); - } - } - - // Verify no validator sent multiple attestations over P2P - // Each validator should have sent exactly one attestation - for (const [_, count] of p2pValidatorAddresses.entries()) { - expect(count).toBe(1); - } - - logger.info( - `Block ${receipt.blockNumber}: P2P layer shows ${p2pValidatorAddresses.size} unique validators sent attestations, no duplicates detected`, - ); - // SECONDARY CHECK: Verify checkpoint attestations match database records const [publishedCheckpoint] = await aztecNode.getCheckpoints(block.checkpointNumber, 1, { includeAttestations: true, @@ -837,6 +842,19 @@ describe('HA Full Setup', () => { expect(dutiesByValidator.has(validatorAddress)).toBe(true); } } + + // GOSSIP-LAYER CHECK: each HA node's libp2p service detects when a signer attests to two + // distinct payloads at the same slot and fires `duplicateAttestationCallback` -> validator + // client emits WANT_TO_SLASH_EVENT -> SlashOffensesCollector persists a DUPLICATE_ATTESTATION + // offense. We assert no such offense (or DUPLICATE_PROPOSAL) was collected on any surviving + // HA node. Killed nodes are unreachable, but the surviving node — which has been alive the + // whole test — has observed all gossiped attestations and proposals across every slot. + const aliveNodes = haNodeServices.filter((_, idx) => !killedNodes.includes(idx)); + const allOffenses = (await Promise.all(aliveNodes.map(n => n.getSlashOffenses('all')))).flat(); + const equivocationOffenses = allOffenses.filter( + o => o.offenseType === OffenseType.DUPLICATE_ATTESTATION || o.offenseType === OffenseType.DUPLICATE_PROPOSAL, + ); + expect(equivocationOffenses).toEqual([]); }); describe('Clock Skew and Timezone Safety', () => { diff --git a/yarn-project/end-to-end/src/composed/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/end-to-end/src/composed/uniswap_trade_on_l1_from_l2.test.ts index a614516846dd..a85c1b4988b9 100644 --- a/yarn-project/end-to-end/src/composed/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/end-to-end/src/composed/uniswap_trade_on_l1_from_l2.test.ts @@ -1,3 +1,4 @@ +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { setup as e2eSetup } from '../fixtures/utils.js'; import { uniswapL1L2TestSuite } from '../shared/uniswap_l1_l2.js'; @@ -10,7 +11,7 @@ const EXPECTED_FORKED_BLOCK = 0; //17514288; let teardown: () => Promise; const testSetup = async () => { - const context = await e2eSetup(2, { stateLoad: dumpedState, startProverNode: true }); + const context = await e2eSetup(2, { ...PIPELINING_SETUP_OPTS, stateLoad: dumpedState, startProverNode: true }); teardown = context.teardown; diff --git a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts index 6d1f29501e2e..018c4a8e2f15 100644 --- a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts +++ b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts @@ -35,7 +35,7 @@ import { createKeyFile5, createKeyFile6, } from '../../e2e_multi_validator/utils.js'; -import { MNEMONIC } from '../../fixtures/fixtures.js'; +import { MNEMONIC, PIPELINING_SETUP_OPTS } from '../../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../../fixtures/utils.js'; import { createWeb3SignerKeystore, @@ -154,6 +154,8 @@ function verifyKeyStore(directory: string) { expect(validatorAdapter.getAttesterAddresses()).toHaveLength(VALIDATOR_COUNT); } +jest.setTimeout(10 * 60 * 1000); + describe('e2e_multi_validator_node', () => { let initialValidatorPrivateKeys: `0x${string}`[]; let validatorAddresses: `0x${string}`[]; @@ -283,6 +285,7 @@ describe('e2e_multi_validator_node', () => { aztecNode, sequencer: sequencerClient, } = await setup(1, { + ...PIPELINING_SETUP_OPTS, initialValidators, aztecTargetCommitteeSize: COMMITTEE_SIZE, keyStoreDirectory, @@ -293,6 +296,8 @@ describe('e2e_multi_validator_node', () => { worldStateBlockCheckIntervalMS: 200, blockCheckIntervalMS: 200, startProverNode: true, + aztecEpochDuration: 8, + aztecProofSubmissionEpochs: 4, })); sequencer = (sequencerClient! as TestSequencerClient).getSequencer(); diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index b9e15d0378cc..22274e82c59f 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -9,6 +9,7 @@ import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { expect, jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, expectTokenBalance, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup, setupPXEAndGetWallet } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; @@ -52,7 +53,7 @@ describe('e2e_2_pxes', () => { accounts: [accountAAddress], logger, teardown: teardownA, - } = await setup(1, { numberOfInitialFundedAccounts: 3 })); + } = await setup(1, { ...AUTOMINE_E2E_OPTS, numberOfInitialFundedAccounts: 3 })); ({ wallet: walletB, diff --git a/yarn-project/end-to-end/src/e2e_abi_types.test.ts b/yarn-project/end-to-end/src/e2e_abi_types.test.ts index 0244327b214a..81ca7f63667f 100644 --- a/yarn-project/end-to-end/src/e2e_abi_types.test.ts +++ b/yarn-project/end-to-end/src/e2e_abi_types.test.ts @@ -7,9 +7,10 @@ import { AbiTypesContract } from '@aztec/noir-test-contracts.js/AbiTypes'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; const U64_MAX = 2n ** 64n - 1n; const I64_MAX = 2n ** 63n - 1n; @@ -30,7 +31,7 @@ describe('AbiTypes', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: abiTypesContract } = await AbiTypesContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index d48af0ff7fe3..74a85e77875c 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -17,6 +17,7 @@ import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { createPXE, getPXEConfig } from '@aztec/pxe/server'; import { deriveSigningKey } from '@aztec/stdlib/keys'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; import { AztecNodeProxy } from './test-wallet/utils.js'; @@ -60,7 +61,10 @@ const itShouldBehaveLikeAnAccountContract = ( address, }; - ({ logger, teardown, aztecNode } = await setup(0, { initialFundedAccounts: [accountData] })); + ({ logger, teardown, aztecNode } = await setup(0, { + ...AUTOMINE_E2E_OPTS, + initialFundedAccounts: [accountData], + })); wallet = await TestWalletInternals.create(aztecNode); const accountManager = await wallet.createAccount({ secret, contract, salt }); diff --git a/yarn-project/end-to-end/src/e2e_amm.test.ts b/yarn-project/end-to-end/src/e2e_amm.test.ts index 1df2829bdc0a..2fb58fad62ae 100644 --- a/yarn-project/end-to-end/src/e2e_amm.test.ts +++ b/yarn-project/end-to-end/src/e2e_amm.test.ts @@ -6,11 +6,12 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 900_000; // TODO(F-560): Consider whether it makes sense to drop this // https://linear.app/aztec-labs/issue/F-560/add-more-tests-to-forward-compatibility-testing @@ -40,12 +41,17 @@ describe('AMM', () => { const INITIAL_TOKEN_BALANCE = 1_000_000_000n; beforeAll(async () => { + // Anchor the PXE to the checkpointed tip rather than the proposed tip. Under pipelining the + // proposed tip can be pruned when a slot ends without a checkpoint landing on L1 (e.g. when a + // time warp races `Sequencer.work`'s two epoch-cache reads and the wait-for-parent gate ends up + // pointing at the wrong slot). The checkpointed tip is L1-confirmed and cannot be pruned, so + // inflight setup txs survive the race. ({ teardown, wallet, accounts: [adminAddress, liquidityProviderAddress, otherLiquidityProviderAddress, swapperAddress], logger, - } = await setup(4)); + } = await setup(4, { ...AUTOMINE_E2E_OPTS }, { syncChainTip: 'checkpointed' })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_authwit.test.ts b/yarn-project/end-to-end/src/e2e_authwit.test.ts index a2e470e4d876..efe9c18b1408 100644 --- a/yarn-project/end-to-end/src/e2e_authwit.test.ts +++ b/yarn-project/end-to-end/src/e2e_authwit.test.ts @@ -9,11 +9,11 @@ import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { jest } from '@jest/globals'; import { sendThroughAuthwitProxy } from './fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from './fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from './fixtures/fixtures.js'; import { type EndToEndContext, ensureAccountContractsPublished, setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; -const TIMEOUT = 150_000; +const TIMEOUT = 300_000; describe('e2e_authwit_tests', () => { jest.setTimeout(TIMEOUT); @@ -31,7 +31,7 @@ describe('e2e_authwit_tests', () => { teardown, wallet, accounts: [account1Address, account2Address], - } = await setup(2)); + } = await setup(2, { ...AUTOMINE_E2E_OPTS })); await ensureAccountContractsPublished(wallet, [account1Address, account2Address]); ({ contract: auth } = await AuthWitTestContract.deploy(wallet).send({ from: account1Address })); diff --git a/yarn-project/end-to-end/src/e2e_automine_smoke.test.ts b/yarn-project/end-to-end/src/e2e_automine_smoke.test.ts new file mode 100644 index 000000000000..01c5eac6464b --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_automine_smoke.test.ts @@ -0,0 +1,137 @@ +import type { AztecNodeService } from '@aztec/aztec-node'; +import { AztecAddress } from '@aztec/aztec.js/addresses'; +import type { Wallet } from '@aztec/aztec.js/wallet'; +import type { CheatCodes } from '@aztec/aztec/testing'; +import { range } from '@aztec/foundation/array'; +import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; + +import { jest } from '@jest/globals'; +import 'jest-extended'; + +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; +import { setup } from './fixtures/utils.js'; + +describe('e2e_automine_smoke', () => { + jest.setTimeout(10 * 60 * 1000); + + let teardown: () => Promise; + let aztecNode: AztecNode & AztecNodeDebug; + let aztecNodeService: AztecNodeService; + let wallet: Wallet; + let owner: AztecAddress; + let cheatCodes: CheatCodes; + let contract: TestContract; + + beforeAll(async () => { + ({ + teardown, + aztecNode, + aztecNodeService, + wallet, + accounts: [owner], + cheatCodes, + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); + + ({ contract } = await TestContract.deploy(wallet).send({ from: owner })); + }); + + afterAll(() => teardown()); + + it('mines sequential dependent txs back-to-back', async () => { + const startBlock = await aztecNode.getBlockNumber(); + const blockNumbers: number[] = []; + for (let i = 0; i < 5; i++) { + const { receipt } = await contract.methods.emit_nullifier_public(BigInt(i + 1000)).send({ from: owner }); + blockNumbers.push(receipt.blockNumber!); + } + + // Each .send is sequential, so each tx lands in its own block. + expect(blockNumbers[0]).toBeGreaterThan(startBlock); + expect(blockNumbers).toEqual(range(5, startBlock + 1)); + }); + + it('parallel sends all land', async () => { + const startBlock = await aztecNode.getBlockNumber(); + + const results = await Promise.all( + [...Array(5).keys()].map(i => contract.methods.emit_nullifier_public(BigInt(i + 2000)).send({ from: owner })), + ); + + for (const r of results) { + expect(r.receipt.blockNumber).toBeGreaterThan(startBlock); + } + }); + + it('warp advances L1 timestamp and the next tx lands at a fresh slot', async () => { + const before = await cheatCodes.eth.lastBlockTimestamp(); + const warpBy = 24; + await cheatCodes.warpL2TimeAtLeastBy(aztecNode, warpBy); + const after = await cheatCodes.eth.lastBlockTimestamp(); + expect(after - before).toBeGreaterThanOrEqual(warpBy); + + const { receipt } = await contract.methods.emit_nullifier_public(BigInt(9999)).send({ from: owner }); + expect(receipt.blockNumber).toBeGreaterThan(0); + }); + + it('mineBlock produces an empty checkpoint', async () => { + const before = await aztecNode.getChainTips(); + await aztecNode.mineBlock(); + const after = await aztecNode.getChainTips(); + expect(after.checkpointed.checkpoint.number).toBeGreaterThan(before.checkpointed.checkpoint.number); + expect(after.checkpointed.block.number).toBeGreaterThan(before.checkpointed.block.number); + }); + + it('revertToCheckpoint rolls back L1+L2 state', async () => { + // Land a tx and record the checkpoint it landed at. + await contract.methods.emit_nullifier_public(BigInt(5000)).send({ from: owner }); + const checkpointBefore = (await aztecNode.getChainTips()).checkpointed.checkpoint.number; + + // Land another tx so we advance to a later checkpoint. + await contract.methods.emit_nullifier_public(BigInt(5001)).send({ from: owner }); + const checkpointAfter = (await aztecNode.getChainTips()).checkpointed.checkpoint.number; + expect(checkpointAfter).toBeGreaterThan(checkpointBefore); + + // Revert to the first checkpoint. + const automine = aztecNodeService.getAutomineSequencer()!; + await automine.revertToCheckpoint(checkpointBefore); + + // Archiver tip should be back at checkpointBefore. + const checkpointReverted = (await aztecNode.getChainTips()).checkpointed.checkpoint.number; + expect(checkpointReverted).toBe(checkpointBefore); + + // After reverting, a new tx should land cleanly. + const { receipt: r3 } = await contract.methods.emit_nullifier_public(BigInt(5002)).send({ from: owner }); + expect(r3.blockNumber).toBeGreaterThan(0); + }); + + it('interleaved txs and warps all land successfully', async () => { + const startBlock = await aztecNode.getBlockNumber(); + const startL1Ts = await cheatCodes.eth.lastBlockTimestamp(); + + // Fire off N sends without awaiting; intermix warps between them. + const pending: Array> = []; + const NUM_TXS = 6; + for (let i = 0; i < NUM_TXS; i++) { + pending.push(contract.methods.emit_nullifier_public(BigInt(i + 7000)).send({ from: owner })); + // Warp between every couple of sends without awaiting the sends. + if (i % 2 === 1) { + await cheatCodes.warpL2TimeAtLeastBy(aztecNode, 24); // 2 slots + } + } + + // All txs must eventually land. + const results = await Promise.all(pending); + for (const r of results) { + expect(r.receipt.blockNumber).toBeGreaterThan(startBlock); + } + + // L1 should have advanced by at least the warps we issued. + const endL1Ts = await cheatCodes.eth.lastBlockTimestamp(); + expect(endL1Ts - startL1Ts).toBeGreaterThanOrEqual(24 * Math.floor(NUM_TXS / 2)); + + // All NUM_TXS receipts must have valid block numbers above startBlock. + const blockNumbers = results.map(r => r.receipt.blockNumber!); + expect(blockNumbers.every(n => n > startBlock)).toBe(true); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts index 7e82f7eb9b68..9b344c1a424b 100644 --- a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts +++ b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts @@ -9,9 +9,10 @@ import { AvmTestContract } from '@aztec/noir-test-contracts.js/AvmTest'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; -const TIMEOUT = 100_000; +const TIMEOUT = 600_000; describe('e2e_avm_simulator', () => { jest.setTimeout(TIMEOUT); @@ -27,229 +28,252 @@ describe('e2e_avm_simulator', () => { wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); await ensureAccountContractsPublished(wallet, [defaultAccountAddress]); }); afterAll(() => teardown()); describe('AvmTestContract', () => { - let avmContract: AvmTestContract; - let avmContractInstance: ContractInstanceWithAddress; - let secondAvmContract: AvmTestContract; - - beforeEach(async () => { - ({ contract: avmContract, instance: avmContractInstance } = await AvmTestContract.deploy(wallet).send({ - from: defaultAccountAddress, - })); - ({ contract: secondAvmContract } = await AvmTestContract.deploy(wallet).send({ from: defaultAccountAddress })); - }); + // Read-only / non-mutating tests share a single deployment to keep slot-paced deploy txs + // out of the per-test critical path under proposer pipelining. + describe('with shared deployment', () => { + let avmContract: AvmTestContract; + let avmContractInstance: ContractInstanceWithAddress; + + beforeAll(async () => { + ({ contract: avmContract, instance: avmContractInstance } = await AvmTestContract.deploy(wallet).send({ + from: defaultAccountAddress, + })); + }); - describe('Assertions & error enriching', () => { - /** - * Expect an error like: - * Assertion failed: This assertion should fail! 'assert(not_true == true, "This assertion should fail!")' - * ... - * at assert(not_true == true, "This assertion should fail!") (../../../../../../../home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr:223:5) - * at inner_helper_with_failed_assertion() (../../../../../../../home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr:228:9) - * at quote { $self } (../std/meta/expr.nr:269:9) - * at function.name(); - * let call = quote { $name($args) (/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/macros/dispatch.nr:59:20) - * at AvmTest.0xc3515746 - */ - describe('Not nested', () => { - it('PXE processes user code assertions and recovers message (properly enriched)', async () => { - await expect( - avmContract.methods.assertion_failure().simulate({ from: defaultAccountAddress }), - ).rejects.toThrow( - expect.objectContaining({ - message: expect.stringMatching( - /Assertion failed: This assertion should fail! 'assert\(not_true == true, "This assertion should fail!"\)'/, - ), - stack: expect.stringMatching(/at inner_helper_with_failed_assertion[\s\S]*at AvmTest\..*/), - }), - ); - }); - it('PXE processes user code assertions and recovers message (complex)', async () => { - await expect( - avmContract.methods.assert_nullifier_exists(123).simulate({ from: defaultAccountAddress }), - ).rejects.toThrow("Assertion failed: Nullifier doesn't exist!"); + describe('Assertions & error enriching', () => { + /** + * Expect an error like: + * Assertion failed: This assertion should fail! 'assert(not_true == true, "This assertion should fail!")' + * ... + * at assert(not_true == true, "This assertion should fail!") (../../../../../../../home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr:223:5) + * at inner_helper_with_failed_assertion() (../../../../../../../home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr:228:9) + * at quote { $self } (../std/meta/expr.nr:269:9) + * at function.name(); + * let call = quote { $name($args) (/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/macros/dispatch.nr:59:20) + * at AvmTest.0xc3515746 + */ + describe('Not nested', () => { + it('PXE processes user code assertions and recovers message (properly enriched)', async () => { + await expect( + avmContract.methods.assertion_failure().simulate({ from: defaultAccountAddress }), + ).rejects.toThrow( + expect.objectContaining({ + message: expect.stringMatching( + /Assertion failed: This assertion should fail! 'assert\(not_true == true, "This assertion should fail!"\)'/, + ), + stack: expect.stringMatching(/at inner_helper_with_failed_assertion[\s\S]*at AvmTest\..*/), + }), + ); + }); + it('PXE processes user code assertions and recovers message (complex)', async () => { + await expect( + avmContract.methods.assert_nullifier_exists(123).simulate({ from: defaultAccountAddress }), + ).rejects.toThrow("Assertion failed: Nullifier doesn't exist!"); + }); + it('PXE processes intrinsic assertions and recovers message', async () => { + await expect( + avmContract.methods.divide_by_zero(0).simulate({ from: defaultAccountAddress }), + ).rejects.toThrow('Division by zero'); + }); }); - it('PXE processes intrinsic assertions and recovers message', async () => { - await expect(avmContract.methods.divide_by_zero(0).simulate({ from: defaultAccountAddress })).rejects.toThrow( - 'Division by zero', - ); + describe('Nested', () => { + it('PXE processes user code assertions and recovers message', async () => { + await expect( + avmContract.methods.external_call_to_assertion_failure().simulate({ from: defaultAccountAddress }), + ).rejects.toThrow('Assertion failed: This assertion should fail!'); + }); + it('PXE processes intrinsic assertions and recovers message', async () => { + await expect( + avmContract.methods.external_call_to_divide_by_zero().simulate({ from: defaultAccountAddress }), + ).rejects.toThrow('Division by zero'); + }); }); }); - describe('Nested', () => { - it('PXE processes user code assertions and recovers message', async () => { - await expect( - avmContract.methods.external_call_to_assertion_failure().simulate({ from: defaultAccountAddress }), - ).rejects.toThrow('Assertion failed: This assertion should fail!'); - }); - it('PXE processes intrinsic assertions and recovers message', async () => { - await expect( - avmContract.methods.external_call_to_divide_by_zero().simulate({ from: defaultAccountAddress }), - ).rejects.toThrow('Division by zero'); + + describe('From private', () => { + it('Should enqueue a public function correctly', async () => { + const request = await avmContract.methods.enqueue_public_from_private().request(); + const simulation = await wallet.simulateTx(request, { from: defaultAccountAddress }); + expect(simulation.publicOutput!.revertReason).toBeUndefined(); }); }); - }); - describe('From private', () => { - it('Should enqueue a public function correctly', async () => { - const request = await avmContract.methods.enqueue_public_from_private().request(); - const simulation = await wallet.simulateTx(request, { from: defaultAccountAddress }); - expect(simulation.publicOutput!.revertReason).toBeUndefined(); + describe('Gas metering', () => { + it('Tracks L2 gas usage on simulation', async () => { + const request = await avmContract.methods.add_args_return(20n, 30n).request(); + const simulation = await wallet.simulateTx(request, { from: defaultAccountAddress }); + // Subtract the teardown gas from the total gas to figure out the gas used by the contract logic. + const l2TeardownGas = simulation.publicOutput!.gasUsed.teardownGas.l2Gas; + const l2GasUsed = simulation.publicOutput!.gasUsed.totalGas.l2Gas - l2TeardownGas; + // L2 gas used will vary a lot depending on codegen and other factors, + // so we just set a wide range for it, and check it's not a suspiciously round number. + expect(l2GasUsed).toBeGreaterThan(150); + expect(l2GasUsed).toBeLessThan(1e6); + expect(l2GasUsed! % 1000).not.toEqual(0); + }); }); - }); - describe('Gas metering', () => { - it('Tracks L2 gas usage on simulation', async () => { - const request = await avmContract.methods.add_args_return(20n, 30n).request(); - const simulation = await wallet.simulateTx(request, { from: defaultAccountAddress }); - // Subtract the teardown gas from the total gas to figure out the gas used by the contract logic. - const l2TeardownGas = simulation.publicOutput!.gasUsed.teardownGas.l2Gas; - const l2GasUsed = simulation.publicOutput!.gasUsed.totalGas.l2Gas - l2TeardownGas; - // L2 gas used will vary a lot depending on codegen and other factors, - // so we just set a wide range for it, and check it's not a suspiciously round number. - expect(l2GasUsed).toBeGreaterThan(150); - expect(l2GasUsed).toBeLessThan(1e6); - expect(l2GasUsed! % 1000).not.toEqual(0); + describe('Contract instance', () => { + it('Works', async () => { + const { receipt: tx } = await avmContract.methods + .test_get_contract_instance_matches( + avmContract.address, + avmContractInstance.deployer, + avmContractInstance.currentContractClassId, + avmContractInstance.initializationHash, + avmContractInstance.immutablesHash, + ) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); }); - }); - describe('Storage', () => { - it('Modifies storage (Field)', async () => { - await avmContract.methods.set_storage_single(20n).send({ from: defaultAccountAddress }); - expect( - (await avmContract.methods.read_storage_single().simulate({ from: defaultAccountAddress })).result, - ).toEqual(20n); + describe('L2 to L1 messages', () => { + it('Should fail if emitting to an invalid ethereum address', async () => { + const recipient = Fr.MAX_FIELD_VALUE; + await expect( + avmContract.methods + .raw_l2_to_l1_msg({ address: recipient }, new Fr(1)) + .send({ from: defaultAccountAddress }), + ).rejects.toThrow(); + }); }); - it('Modifies storage (Map)', async () => { - const address = AztecAddress.fromBigInt(9090n); - await avmContract.methods.set_storage_map(address, 100).send({ from: defaultAccountAddress }); - await avmContract.methods.add_storage_map(address, 100).send({ from: defaultAccountAddress }); - expect( - (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, - ).toEqual(200n); - }); + describe('Nested calls', () => { + it('Nested call to non-existent contract reverts & rethrows by default', async () => { + // The nested call reverts and by default caller rethrows + await expect( + avmContract.methods.nested_call_to_nothing().simulate({ from: defaultAccountAddress }), + ).rejects.toThrow(/not deployed/); + }); - it('Preserves storage across enqueued public calls', async () => { - const address = AztecAddress.fromBigInt(9090n); - // This will create 1 tx with 2 public calls in it. - await new BatchCall(wallet, [ - avmContract.methods.set_storage_map(address, 100), - avmContract.methods.add_storage_map(address, 100), - ]).send({ from: defaultAccountAddress }); - // On a separate tx, we check the result. - expect( - (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, - ).toEqual(200n); + it('Nested CALL instruction to non-existent contract returns failure, but caller can recover', async () => { + // The nested call reverts (returns failure), but the caller doesn't HAVE to rethrow. + const { receipt: tx } = await avmContract.methods + .nested_call_to_nothing_recovers() + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); + it('Should NOT be able to emit the same unsiloed nullifier from the same contract', async () => { + const nullifier = new Fr(1); + await expect( + avmContract.methods + .create_same_nullifier_in_nested_call(avmContract.address, nullifier) + .send({ from: defaultAccountAddress }), + ).rejects.toThrow(); + }); }); }); - describe('Contract instance', () => { - it('Works', async () => { - const { receipt: tx } = await avmContract.methods - .test_get_contract_instance_matches( - avmContract.address, - avmContractInstance.deployer, - avmContractInstance.currentContractClassId, - avmContractInstance.initializationHash, - ) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + // State-mutating tests get a fresh deployment per test to avoid cross-test leakage of + // storage writes or persisted nullifiers. + describe('with fresh deployment per test', () => { + let avmContract: AvmTestContract; + let secondAvmContract: AvmTestContract; + + beforeEach(async () => { + ({ contract: avmContract } = await AvmTestContract.deploy(wallet).send({ + from: defaultAccountAddress, + })); + ({ contract: secondAvmContract } = await AvmTestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); - }); - describe('Nullifiers', () => { - // Nullifier will not yet be siloed by the kernel. - it('Emit and check in the same tx', async () => { - const { receipt: tx } = await avmContract.methods - .emit_nullifier_and_check(123456) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - }); + describe('Storage', () => { + it('Modifies storage (Field)', async () => { + await avmContract.methods.set_storage_single(20n).send({ from: defaultAccountAddress }); + expect( + (await avmContract.methods.read_storage_single().simulate({ from: defaultAccountAddress })).result, + ).toEqual(20n); + }); - // Nullifier will have been siloed by the kernel, but we check against the unsiloed one. - it('Emit and check in separate tx', async () => { - const nullifier = new Fr(123456); - let { receipt: tx } = await avmContract.methods.new_nullifier(nullifier).send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + it('Modifies storage (Map)', async () => { + const address = AztecAddress.fromBigInt(9090n); + await avmContract.methods.set_storage_map(address, 100).send({ from: defaultAccountAddress }); + await avmContract.methods.add_storage_map(address, 100).send({ from: defaultAccountAddress }); + expect( + (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, + ).toEqual(200n); + }); - ({ receipt: tx } = await avmContract.methods - .assert_nullifier_exists(nullifier) - .send({ from: defaultAccountAddress })); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + it('Preserves storage across enqueued public calls', async () => { + const address = AztecAddress.fromBigInt(9090n); + // This will create 1 tx with 2 public calls in it. + await new BatchCall(wallet, [ + avmContract.methods.set_storage_map(address, 100), + avmContract.methods.add_storage_map(address, 100), + ]).send({ from: defaultAccountAddress }); + // On a separate tx, we check the result. + expect( + (await avmContract.methods.read_storage_map(address).simulate({ from: defaultAccountAddress })).result, + ).toEqual(200n); + }); }); - it('Emit and check in separate enqueued calls but same tx', async () => { - const nullifier = new Fr(123456); - - // This will create 1 tx with 2 public calls in it. - await new BatchCall(wallet, [ - avmContract.methods.new_nullifier(nullifier), - avmContract.methods.assert_nullifier_exists(nullifier), - ]).send({ from: defaultAccountAddress }); - }); - }); + describe('Nullifiers', () => { + // Nullifier will not yet be siloed by the kernel. + it('Emit and check in the same tx', async () => { + const { receipt: tx } = await avmContract.methods + .emit_nullifier_and_check(123456) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); - describe('L2 to L1 messages', () => { - it('Should fail if emitting to an invalid ethereum address', async () => { - const recipient = Fr.MAX_FIELD_VALUE; - await expect( - avmContract.methods.raw_l2_to_l1_msg({ address: recipient }, new Fr(1)).send({ from: defaultAccountAddress }), - ).rejects.toThrow(); - }); - }); + // Nullifier will have been siloed by the kernel, but we check against the unsiloed one. + it('Emit and check in separate tx', async () => { + const nullifier = new Fr(123456); + let { receipt: tx } = await avmContract.methods + .new_nullifier(nullifier) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + + ({ receipt: tx } = await avmContract.methods + .assert_nullifier_exists(nullifier) + .send({ from: defaultAccountAddress })); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); - describe('Nested calls', () => { - it('Nested call to non-existent contract reverts & rethrows by default', async () => { - // The nested call reverts and by default caller rethrows - await expect( - avmContract.methods.nested_call_to_nothing().simulate({ from: defaultAccountAddress }), - ).rejects.toThrow(/not deployed/); - }); + it('Emit and check in separate enqueued calls but same tx', async () => { + const nullifier = new Fr(123456); - it('Nested CALL instruction to non-existent contract returns failure, but caller can recover', async () => { - // The nested call reverts (returns failure), but the caller doesn't HAVE to rethrow. - const { receipt: tx } = await avmContract.methods - .nested_call_to_nothing_recovers() - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - }); - it('Should NOT be able to emit the same unsiloed nullifier from the same contract', async () => { - const nullifier = new Fr(1); - await expect( - avmContract.methods - .create_same_nullifier_in_nested_call(avmContract.address, nullifier) - .send({ from: defaultAccountAddress }), - ).rejects.toThrow(); + // This will create 1 tx with 2 public calls in it. + await new BatchCall(wallet, [ + avmContract.methods.new_nullifier(nullifier), + avmContract.methods.assert_nullifier_exists(nullifier), + ]).send({ from: defaultAccountAddress }); + }); }); - it('Should be able to emit different unsiloed nullifiers from the same contract', async () => { - const nullifier = new Fr(1); - const { receipt: tx } = await avmContract.methods - .create_different_nullifier_in_nested_call(avmContract.address, nullifier) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - }); + describe('Nested calls', () => { + it('Should be able to emit different unsiloed nullifiers from the same contract', async () => { + const nullifier = new Fr(1); + const { receipt: tx } = await avmContract.methods + .create_different_nullifier_in_nested_call(avmContract.address, nullifier) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); - it('Should be able to emit the same unsiloed nullifier from two different contracts', async () => { - const nullifier = new Fr(1); - const { receipt: tx } = await avmContract.methods - .create_same_nullifier_in_nested_call(secondAvmContract.address, nullifier) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); - }); + it('Should be able to emit the same unsiloed nullifier from two different contracts', async () => { + const nullifier = new Fr(1); + const { receipt: tx } = await avmContract.methods + .create_same_nullifier_in_nested_call(secondAvmContract.address, nullifier) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); - it('Should be able to emit different unsiloed nullifiers from two different contracts', async () => { - const nullifier = new Fr(1); - const { receipt: tx } = await avmContract.methods - .create_different_nullifier_in_nested_call(secondAvmContract.address, nullifier) - .send({ from: defaultAccountAddress }); - expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + it('Should be able to emit different unsiloed nullifiers from two different contracts', async () => { + const nullifier = new Fr(1); + const { receipt: tx } = await avmContract.methods + .create_different_nullifier_in_nested_call(secondAvmContract.address, nullifier) + .send({ from: defaultAccountAddress }); + expect(tx.executionResult).toEqual(TxExecutionResult.SUCCESS); + }); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts index 76f015066d44..15c51b48c84f 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/access_control.test.ts @@ -1,12 +1,13 @@ import { AztecAddress } from '@aztec/aztec.js/addresses'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { BlacklistTokenContractTest, Role } from './blacklist_token_contract_test.js'; describe('e2e_blacklist_token_contract access control', () => { const t = new BlacklistTokenContractTest('access_control'); beforeAll(async () => { - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts index a8db3a6f3704..99b57844219f 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts @@ -14,7 +14,14 @@ import type { AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; -import { type EndToEndContext, deployAccounts, publicDeployAccounts, setup, teardown } from '../fixtures/setup.js'; +import { + type EndToEndContext, + type SetupOptions, + deployAccounts, + publicDeployAccounts, + setup, + teardown, +} from '../fixtures/setup.js'; import { TokenSimulator } from '../simulators/token_simulator.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; @@ -69,6 +76,12 @@ export class BlacklistTokenContractTest { } async crossTimestampOfChange() { + // Under AUTOMINE_E2E_OPTS, the 86400s warp crosses many epochs without any proofs being + // submitted. Mark current pending checkpoints as proven first so the rollup contract's + // pruning window doesn't reset the chain tip to genesis (which would make the warp's + // own empty-checkpoint propose fail with Rollup__InvalidArchive). See the AutomineSequencer + // README "Epoch proving caveat" and the equivalent pattern in lending_simulator.progressSlots. + await this.cheatCodes.rollup.markAsProven(); await this.cheatCodes.warpL2TimeAtLeastBy(this.aztecNode, BlacklistTokenContractTest.CHANGE_ROLES_DELAY); } @@ -78,8 +91,9 @@ export class BlacklistTokenContractTest { * 2. Publicly deploy accounts, deploy token contract and a "bad account". */ async applyBaseSetup() { - // Adding a timeout of 2 minutes in here such that it is propagated to the underlying tests - jest.setTimeout(120_000); + // Bumped from 2 min: pipelined cadence (~24s/dependent-tx) makes the 3-account deploy plus token/bad-account/ + // proxy deploys exceed the original window. + jest.setTimeout(600_000); this.logger.info('Deploying 3 accounts'); const { deployedAccounts } = await deployAccounts( @@ -139,9 +153,10 @@ export class BlacklistTokenContractTest { ).toEqual(new Role().withAdmin().toNoirStruct()); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up fresh context'); this.context = await setup(0, { + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, }); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts index 9b8b28204e15..f0d50c5eebcb 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/burn.test.ts @@ -2,6 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { DUPLICATE_NULLIFIER_ERROR, U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; @@ -10,7 +11,10 @@ describe('e2e_blacklist_token_contract burn', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the wallet as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts index 579a1cc42132..77666a652533 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts @@ -2,6 +2,7 @@ import { computeSecretHash } from '@aztec/aztec.js/crypto'; import { Fr } from '@aztec/aztec.js/fields'; import type { TxHash } from '@aztec/aztec.js/tx'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { U128_OVERFLOW_ERROR } from '../fixtures/index.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; @@ -10,7 +11,10 @@ describe('e2e_blacklist_token_contract mint', () => { let { asset, tokenSim, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the admin as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts index 7ac49c276345..55e22ac57043 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/shielding.test.ts @@ -1,6 +1,7 @@ import { computeSecretHash } from '@aztec/aztec.js/crypto'; import { Fr } from '@aztec/aztec.js/fields'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; @@ -9,7 +10,10 @@ describe('e2e_blacklist_token_contract shield + redeem_shield', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); await t.applyMint(); // Beware that we are adding the admin as minter here // Have to destructure again to ensure we have latest refs. ({ asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts index 88bbbf428fd5..1bc2e45f53e7 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_private.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; describe('e2e_blacklist_token_contract transfer private', () => { @@ -10,7 +10,10 @@ describe('e2e_blacklist_token_contract transfer private', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the admin as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts index 2862a3c735e7..2c5ff43cae93 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/transfer_public.test.ts @@ -1,5 +1,6 @@ import { Fr } from '@aztec/aztec.js/fields'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; @@ -8,7 +9,10 @@ describe('e2e_blacklist_token_contract transfer public', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the admin as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts index 9547b5b992dd..1f78751a2d7e 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/unshielding.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { BlacklistTokenContractTest } from './blacklist_token_contract_test.js'; describe('e2e_blacklist_token_contract unshielding', () => { @@ -10,7 +10,10 @@ describe('e2e_blacklist_token_contract unshielding', () => { let { asset, tokenSim, wallet, adminAddress, otherAddress, blacklistedAddress } = t; beforeAll(async () => { - await t.setup(); + // TODO(kill-non-pipelined): re-enable pipelining once B1 (world-state fork lifecycle) is + // fixed — BlacklistTokenContractTest.applyBaseSetup runs two 86400s warps which time out + // mineBlock under pipelining. See PIPELINING_GOTCHAS.md. + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Beware that we are adding the admin as minter here, which is very slow because it needs multiple blocks. await t.applyMint(); // Have to destructure again to ensure we have latest refs. diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index a89b49c30949..b5b2645777e0 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -27,7 +27,7 @@ import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; import { jest } from '@jest/globals'; import 'jest-extended'; -import { DUPLICATE_NULLIFIER_ERROR } from './fixtures/fixtures.js'; +import { DUPLICATE_NULLIFIER_ERROR, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -43,7 +43,7 @@ describe('e2e_block_building', () => { let aztecNode: AztecNode; let aztecNodeAdmin: AztecNodeAdmin; - let sequencer: TestSequencerClient; + let _sequencer: TestSequencerClient; let watcher: AnvilTestWatcher; let teardown: () => Promise; @@ -63,12 +63,13 @@ describe('e2e_block_building', () => { accounts: [ownerAddress, minterAddress], sequencer: sequencerClient, } = await setup(2, { + ...PIPELINING_SETUP_OPTS, archiverPollingIntervalMS: 200, sequencerPollingIntervalMS: 200, worldStateBlockCheckIntervalMS: 200, blockCheckIntervalMS: 200, })); - sequencer = sequencerClient! as TestSequencerClient; + _sequencer = sequencerClient! as TestSequencerClient; }); beforeEach(async () => { @@ -81,6 +82,7 @@ describe('e2e_block_building', () => { minTxsPerBlock: 1, maxTxsPerBlock: undefined, // reset to default enforceTimeTable: false, // reset to false (as it is in setup()) + blockDurationMs: undefined, // reset to single-block-per-slot mode }); // Clean up any mocks jest.restoreAllMocks(); @@ -88,44 +90,42 @@ describe('e2e_block_building', () => { afterAll(() => teardown()); + // Under pipelining, the proposer divides each slot into fixed sub-slots of length `blockDurationMs`. + // Each sub-slot owns the budget for exactly one L2 block; the block builder enforces the sub-slot + // deadline as a hard cap on tx execution. The invariant this test protects: if there are far more txs + // than fit in one sub-slot, the proposer must cut the block off at the deadline and roll the excess + // txs into the next sub-slot (and the next checkpoint when the slot ends). It must NOT pack everything + // into a single block and burn the whole slot on it. it('processes txs until hitting timetable', async () => { - const DEADLINE_S = 0.5; // half a second of building per block - const DEADLINE_MS = DEADLINE_S * 1000; - const MAX_TXS_FIT_IN_DEADLINE = 5; // via deadline and fake delay, we force this maximum to be true - const FAKE_DELAY_PER_TX_MS = DEADLINE_MS / MAX_TXS_FIT_IN_DEADLINE; // e.g. 100ms if 5 txs per 0.5s - - // the minimum number of blocks we want to see - const EXPECTED_BLOCKS = 3; - // choose a tx count should ensure that we use EXPECTED_BLOCKS or more - // Note that we don't need to ensure that last block is _full_ - const TX_COUNT = MAX_TXS_FIT_IN_DEADLINE * (EXPECTED_BLOCKS - 1) + 1; - - // print out the test parameters - logger.info(`multi-block timetable test parameters:`); - logger.info(` Deadline per block: ${DEADLINE_MS} ms`); - logger.info(` Fake delay per tx: ${FAKE_DELAY_PER_TX_MS} ms`); - logger.info(` Max txs that should fit in deadline: ${MAX_TXS_FIT_IN_DEADLINE}`); - logger.info(` Total txs to send: ${TX_COUNT}`); - logger.info(` Expected minimum blocks: ${EXPECTED_BLOCKS}`); + // Fixture defaults under pipelining: aztecSlotDuration=12s, ethereumSlotDuration=4s. With + // ethereumSlotDuration<8 the timing model uses checkpointInitializationTime=0.5s, + // checkpointAssembleTime=0.5s, p2pPropagationTime=0, minExecutionTime=1s. Picking a 2s sub-slot + // gives floor((12 - 0.5 - (0.5 + 2)) / 2) = 4 sub-slots per slot. + const BLOCK_DURATION_MS = 2000; + // Fake delay per tx, sized so ~3 txs fit in a 2s sub-slot before the builder cuts at the deadline. + const FAKE_DELAY_PER_TX_MS = 500; + // Send substantially more than fits in one sub-slot so the proposer must span multiple blocks. + const TX_COUNT = 10; + + logger.info(`multi-block timetable test parameters:`, { + blockDurationMs: BLOCK_DURATION_MS, + fakeDelayPerTxMs: FAKE_DELAY_PER_TX_MS, + txCount: TX_COUNT, + }); const { contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); logger.info(`Deployed stateful test contract at ${contract.address}`); - // Configure sequencer with a small delay per tx and enforce timetable + // Configure sequencer for multi-block-per-slot mode with a per-tx delay long enough that the + // builder must cut blocks off at each sub-slot deadline. await aztecNodeAdmin.setConfig({ - fakeProcessingDelayPerTxMs: FAKE_DELAY_PER_TX_MS, // ensure that each tx takes at least this long + fakeProcessingDelayPerTxMs: FAKE_DELAY_PER_TX_MS, minTxsPerBlock: 1, - maxTxsPerBlock: TX_COUNT, // intentionally large because we want to flex deadline, not this max + maxTxsPerBlock: TX_COUNT, // intentionally large; we want to flex the sub-slot deadline, not this cap enforceTimeTable: true, + blockDurationMs: BLOCK_DURATION_MS, }); - // Mock the timetable to limit time for block building. - jest.spyOn(sequencer.sequencer.timetable, 'canStartNextBlock').mockImplementation((secondsIntoSlot: number) => ({ - canStart: true, - deadline: secondsIntoSlot + DEADLINE_S, // limit block-building time - isLastBlock: true, - })); - // Flood the mempool with TX_COUNT simultaneous txs const methods = times(TX_COUNT, i => contract.methods.increment_public_value(ownerAddress, i)); const provenTxs = await asyncMap(methods, method => proveInteraction(wallet, method, { from: ownerAddress })); @@ -139,13 +139,23 @@ describe('e2e_block_building', () => { const receipts = await Promise.all(txHashes.map(txHash => waitForTx(aztecNode, txHash))); const blockNumbers = receipts.map(r => r.blockNumber!).sort((a, b) => a - b); logger.info(`Txs mined on blocks: ${unique(blockNumbers)}`); - expect(blockNumbers.at(-1)! - blockNumbers[0]).toBeGreaterThanOrEqual(EXPECTED_BLOCKS - 1); + // Spread must be at least 1 — i.e. txs are split across at least 2 distinct blocks. This fails + // (and the test catches a regression) if the proposer reverts to single-block-per-slot behavior + // or if sub-slot deadlines stop being enforced. + expect(blockNumbers.at(-1)! - blockNumbers[0]).toBeGreaterThanOrEqual(1); + expect(unique(blockNumbers).length).toBeGreaterThanOrEqual(2); }); it('assembles a block with multiple txs', async () => { // Assemble N contract deployment txs // We need to create them sequentially since we cannot have parallel calls to a circuit const TX_COUNT = 8; + + // Publish the contract class up front so that the N deploys below do not each include a + // ContractClassRegistry.publish call. Without this, every parallel deploy shares the same + // class-publication nullifier and only the first one is admitted to the mempool. + await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); + await aztecNodeAdmin.setConfig({ minTxsPerBlock: TX_COUNT }); // Need to have value > 0, so adding + 1 @@ -160,7 +170,7 @@ describe('e2e_block_building', () => { const provenTxs = []; const addresses = []; for (let i = 0; i < TX_COUNT; i++) { - const options: DeployOptions = { from: ownerAddress }; + const options: DeployOptions = { from: ownerAddress, skipClassPublication: true }; const instance = await methods[i].getInstance(); addresses.push(instance.address); provenTxs.push(await proveInteraction(wallet, methods[i], options)); @@ -297,7 +307,7 @@ describe('e2e_block_building', () => { logger, wallet, accounts: [ownerAddress], - } = await setup(1)); + } = await setup(1, { ...PIPELINING_SETUP_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: ownerAddress })); logger.info(`Test contract deployed at ${contract.address}`); }); @@ -423,11 +433,11 @@ describe('e2e_block_building', () => { logger, wallet, accounts: [ownerAddress], - } = await setup(1)); + } = await setup(1, { ...PIPELINING_SETUP_OPTS })); logger.info(`Deploying test contract`); ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: ownerAddress })); - }, 60_000); + }, 300_000); afterAll(() => teardown()); @@ -492,18 +502,19 @@ describe('e2e_block_building', () => { // Regression for https://github.com/AztecProtocol/aztec-packages/issues/7918 it('publishes two empty blocks', async () => { ({ teardown, wallet, logger, aztecNode } = await setup(0, { + ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 0, + buildCheckpointIfEmpty: true, })); - await retryUntil(async () => (await aztecNode.getBlockNumber()) >= 3, 'wait-block', 10, 1); + // Under pipelining, with `aztecSlotDuration=12s`, each empty checkpoint contains one empty + // block and lands roughly every 12s. Allow up to 60s for three empty blocks to appear. + await retryUntil(async () => (await aztecNode.getBlockNumber()) >= 3, 'wait-block', 60, 1); }); // Regression for https://github.com/AztecProtocol/aztec-packages/issues/7537 it('sends a tx on the first block', async () => { - const context = await setup(0, { - minTxsPerBlock: 0, - numberOfInitialFundedAccounts: 1, - }); + const context = await setup(0, { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 0, numberOfInitialFundedAccounts: 1 }); ({ teardown, logger, aztecNode, wallet } = context); await sleep(1000); @@ -524,9 +535,7 @@ describe('e2e_block_building', () => { wallet, aztecNodeAdmin, accounts: [ownerAddress], - } = await setup(1, { - minTxsPerBlock: 1, - })); + } = await setup(1, { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 1 })); logger.info('Deploying token contract'); const { contract: token } = await TokenContract.deploy(wallet, ownerAddress, 'TokenName', 'TokenSymbol', 18).send( @@ -554,10 +563,7 @@ describe('e2e_block_building', () => { // which translates in an incorrect end state for world state. We can easily detect this by checking whether the nullifier // tree next available leaf index is a multiple of 64. it('clears up all nullifiers if tx processing fails', async () => { - const context = await setup(1, { - minTxsPerBlock: 1, - numberOfInitialFundedAccounts: 1, - }); + const context = await setup(1, { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 1, numberOfInitialFundedAccounts: 1 }); ({ teardown, logger, @@ -588,14 +594,23 @@ describe('e2e_block_building', () => { const txHashResults = await Promise.all(batches.map(batch => batch.send({ from: ownerAddress, wait: NO_WAIT }))); const txHashes = txHashResults.map(({ txHash }) => txHash); logger.warn(`Sent two txs to test contract`, { txs: txHashes.map(hash => hash.toString()) }); - await Promise.race(txHashes.map(txHash => waitForTx(aztecNode, txHash, { timeout: 60 }))); + // Use Promise.any (not Promise.race): exactly one of the two txs will be dropped (the one that hits + // the fake AVM error in tx processing), so the dropped-tx rejection would settle Promise.race first. + // We want the first *successful* mine. + const minedTxHash = await Promise.any( + txHashes.map(async txHash => { + await waitForTx(aztecNode, txHash, { timeout: 60 }); + return txHash; + }), + ); - logger.warn(`At least one tx has been mined`); - const lastBlock = (await context.aztecNode.getBlockData('latest'))?.header; - expect(lastBlock).toBeDefined(); + logger.warn(`At least one tx has been mined`, { minedTxHash: minedTxHash.toString() }); + const minedReceipt = await aztecNode.getTxReceipt(minedTxHash); + const block = await context.aztecNode.getBlock(minedReceipt.blockNumber!); + expect(block).toBeDefined(); - logger.warn(`Latest block is ${lastBlock!.getBlockNumber()}`, { state: lastBlock?.state.partial }); - const nextNullifierIndex = lastBlock!.state.partial.nullifierTree.nextAvailableLeafIndex; + logger.warn(`Mined block is ${block!.header.getBlockNumber()}`, { state: block!.header.state.partial }); + const nextNullifierIndex = block!.header.state.partial.nullifierTree.nextAvailableLeafIndex; expect(nextNullifierIndex % 64).toEqual(0); }); }); @@ -616,7 +631,7 @@ describe('e2e_block_building', () => { cheatCodes, watcher, accounts: [ownerAddress], - } = await setup(1)); + } = await setup(1, { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 1 })); ({ contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress })); initialBlockNumber = await aztecNode.getBlockNumber(); @@ -624,10 +639,12 @@ describe('e2e_block_building', () => { await cheatCodes.rollup.advanceToNextEpoch(); + // Mark all blocks up to the current pending tip as proven so the contract-deployment block + // is anchored against a proven checkpoint. The e2e fixture's AnvilTestWatcher does NOT + // auto-prove under interval mining (only under automining), so we must drive proven manually. + await cheatCodes.rollup.markAsProven(); const bn = await aztecNode.getBlockNumber(); - while ((await aztecNode.getBlockNumber('proven')) < bn) { - await sleep(1000); - } + await retryUntil(async () => (await aztecNode.getBlockNumber('proven')) >= bn, 'wait-proven', 60, 1); watcher.setIsMarkingAsProven(false); }); diff --git a/yarn-project/end-to-end/src/e2e_bot.test.ts b/yarn-project/end-to-end/src/e2e_bot.test.ts index 381a22dfd889..6ff803dd388e 100644 --- a/yarn-project/end-to-end/src/e2e_bot.test.ts +++ b/yarn-project/end-to-end/src/e2e_bot.test.ts @@ -23,6 +23,7 @@ import { EmbeddedWallet } from '@aztec/wallets/embedded'; import { jest } from '@jest/globals'; +import { PIPELINED_FEE_PADDING, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from './fixtures/utils.js'; describe('e2e_bot', () => { @@ -36,7 +37,11 @@ describe('e2e_bot', () => { beforeAll(async () => { const [botAccount] = await getInitialTestAccountsData(); - const setupResult = await setup(0, { initialFundedAccounts: [botAccount] }); + const setupResult = await setup(0, { + ...PIPELINING_SETUP_OPTS, + aztecProofSubmissionEpochs: 640, + initialFundedAccounts: [botAccount], + }); ({ teardown, aztecNode, @@ -62,6 +67,7 @@ describe('e2e_bot', () => { ...getBotDefaultConfig(), followChain: 'CHECKPOINTED', botMode: 'transfer', + minFeePadding: PIPELINED_FEE_PADDING, }; bot = await Bot.create(config, wallet, aztecNode, undefined, new BotStore(await openTmpStore('bot'))); }); @@ -252,7 +258,7 @@ describe('e2e_bot', () => { // See 'can consume L1 to L2 message in %s after inbox drifts away from the rollup' // in end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts for context on this test. it('creates bot after inbox drift', async () => { - await cheatCodes.rollup.advanceInboxInProgress(10); + await cheatCodes.rollup.advanceInboxInProgress(4); await Bot.create(config, wallet, aztecNode, aztecNodeAdmin, new BotStore(await openTmpStore('bot'))); }, 300_000); }); @@ -292,13 +298,13 @@ describe('e2e_bot', () => { expect(block).toBeDefined(); const l2ToL1Msgs = block!.body.txEffects.flatMap(e => e.l2ToL1Msgs).filter(m => !m.isZero()); expect(l2ToL1Msgs.length).toBeGreaterThanOrEqual(1); - }, 120_000); + }, 300_000); it('replenishes the seeding pipeline across ticks', async () => { // Tick 2: the first tick consumed one message. This tick should seed a // replacement and still have a ready message to consume. const result = await bot.run(); expect(result).toBeDefined(); - }, 120_000); + }, 300_000); }); }); diff --git a/yarn-project/end-to-end/src/e2e_card_game.test.ts b/yarn-project/end-to-end/src/e2e_card_game.test.ts index 6f387d27e51c..5c6741a707b5 100644 --- a/yarn-project/end-to-end/src/e2e_card_game.test.ts +++ b/yarn-project/end-to-end/src/e2e_card_game.test.ts @@ -9,6 +9,7 @@ import { CardGameContract } from '@aztec/noir-contracts.js/CardGame'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; /* eslint-disable camelcase */ @@ -86,7 +87,7 @@ describe('e2e_card_game', () => { }; beforeAll(async () => { - const context = await setup(3); + const context = await setup(3, { ...AUTOMINE_E2E_OPTS }); ({ logger, teardown, wallet } = context); [firstPlayer, secondPlayer, thirdPlayer] = context.accounts; diff --git a/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts b/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts index 8b7a36f30576..e806f61dfe0c 100644 --- a/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts +++ b/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts @@ -3,6 +3,7 @@ import { MAX_APPS_PER_KERNEL } from '@aztec/constants'; import fs from 'fs/promises'; import path from 'path'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; /** @@ -16,7 +17,7 @@ describe('Circuit Recorder', () => { process.env.CIRCUIT_RECORD_DIR = RECORD_DIR; // Run setup which deploys an account contract and runs kernels - const { teardown } = await setup(1); + const { teardown } = await setup(1, { ...AUTOMINE_E2E_OPTS }); // Check recording directory exists const dirExists = await fs.stat(RECORD_DIR).then( @@ -81,5 +82,5 @@ describe('Circuit Recorder', () => { await fs.rm(RECORD_DIR, { recursive: true, force: true }); delete process.env.CIRCUIT_RECORD_DIR; await teardown(); - }, 60_000); + }, 120_000); }); diff --git a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts index 1e5bfd82bbf8..ab2aa16ac1ee 100644 --- a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts +++ b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts @@ -6,7 +6,6 @@ import type { AztecNode } from '@aztec/aztec.js/node'; import type { Wallet } from '@aztec/aztec.js/wallet'; import type { CheatCodes } from '@aztec/aztec/testing'; import { MINIMUM_UPDATE_DELAY, UPDATED_CLASS_IDS_SLOT } from '@aztec/constants'; -import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config'; import { UpdatableContract } from '@aztec/noir-test-contracts.js/Updatable'; import { UpdatedContract, UpdatedContractArtifact } from '@aztec/noir-test-contracts.js/Updated'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; @@ -22,11 +21,14 @@ import type { AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import { deriveSigningKey } from '@aztec/stdlib/keys'; import { PublicDataTreeLeaf } from '@aztec/stdlib/trees'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -// Set the update delay in genesis data so it's feasible to test in an e2e test -const { aztecSlotDuration } = getL1ContractsConfigEnvVars(); -const DEFAULT_TEST_UPDATE_DELAY = BigInt(aztecSlotDuration) * 10n; +// Set the update delay in genesis data so it's feasible to test in an e2e test. +// The protocol enforces `MINIMUM_UPDATE_DELAY` (600 seconds, see constants.gen.ts), so we use that +// as the test delay: it's the smallest the chain will accept, which keeps `warpL2TimeAtLeastBy` +// times reasonable while still exercising the same code path. +const DEFAULT_TEST_UPDATE_DELAY = BigInt(MINIMUM_UPDATE_DELAY); const INITIAL_UPDATABLE_CONTRACT_VALUE = 1n; // Constant copied over from Updated contract @@ -97,6 +99,7 @@ describe('e2e_contract_updates', () => { accounts: [defaultAccountAddress], cheatCodes, } = await setup(1, { + ...AUTOMINE_E2E_OPTS, genesisPublicData, initialFundedAccounts, })); @@ -122,7 +125,9 @@ describe('e2e_contract_updates', () => { INITIAL_UPDATABLE_CONTRACT_VALUE, ); await contract.methods.update_to(updatedContractClassId).send({ from: defaultAccountAddress }); - // Warp time to get past the timestamp of change where the update takes effect + // Warp time to get past the timestamp of change where the update takes effect so the latest + // header's timestamp (which the PXE uses to read the current class id) is past the update's + // timestampOfChange. await cheatCodes.warpL2TimeAtLeastBy(aztecNode, DEFAULT_TEST_UPDATE_DELAY); // Should be updated now await wallet.registerContract(instance, UpdatedContract.artifact); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts index 4f9fbc5ba363..7303a23f5fec 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts @@ -4,7 +4,7 @@ import { waitForProven } from '@aztec/aztec.js/contracts'; import { type Logger, createLogger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; import type { TxReceipt } from '@aztec/aztec.js/tx'; -import { CheatCodes } from '@aztec/aztec/testing'; +import { CheatCodes, EpochTestSettler } from '@aztec/aztec/testing'; import { createExtendedL1Client } from '@aztec/ethereum/client'; import { InboxContract, OutboxContract, RollupContract } from '@aztec/ethereum/contracts'; import type { @@ -19,6 +19,7 @@ import { sleep } from '@aztec/foundation/sleep'; import { TestERC20Abi, TestERC20Bytecode } from '@aztec/l1-artifacts'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge'; +import type { PXEConfig } from '@aztec/pxe/server'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { MNEMONIC } from '../fixtures/fixtures.js'; @@ -37,6 +38,7 @@ export class CrossChainMessagingTest { private requireEpochProven: boolean; private setupOptions: SetupOptions; private deployL1ContractsArgs: Partial; + private pxeOpts: Partial; logger: Logger; context!: EndToEndContext; aztecNode!: AztecNode; @@ -59,12 +61,23 @@ export class CrossChainMessagingTest { outbox!: OutboxContract; cheatCodes!: CheatCodes; + /** + * Background loop that marks each completed epoch as proven on L1. Started in `applyBaseSetup` + * when the test runs without a real prover node, because the e2e fixture uses L1 interval mining + * and the AnvilTestWatcher's auto-prove loop only runs under L1 automine. Without this, L1's + * `aztecProofSubmissionEpochs` window expires mid-test and triggers a chain prune that drops + * in-flight wallet txs. Tests that intentionally pause proving (e.g. inbox drift tests) can + * stop it via `await t.epochTestSettler?.stop()`. + */ + epochTestSettler?: EpochTestSettler; + deployL1ContractsValues!: DeployAztecL1ContractsReturnType; constructor( testName: string, opts: SetupOptions = {}, deployL1ContractsArgs: Partial = {}, + pxeOpts: Partial = {}, ) { this.logger = createLogger(`e2e:e2e_cross_chain_messaging:${testName}`); this.setupOptions = opts; @@ -72,17 +85,25 @@ export class CrossChainMessagingTest { initialValidators: [], ...deployL1ContractsArgs, }; + this.pxeOpts = pxeOpts; this.requireEpochProven = opts.startProverNode ?? false; } - async setup() { + async setup(opts: Partial = {}, pxeOpts: Partial = {}) { this.logger.info('Setting up cross chain messaging test'); - this.context = await setup(0, { - ...this.setupOptions, - fundSponsoredFPC: true, - skipAccountDeployment: true, - l1ContractsArgs: this.deployL1ContractsArgs, - }); + // Recompute requireEpochProven from the merged options so per-call startProverNode is honored. + this.requireEpochProven = opts.startProverNode ?? this.setupOptions.startProverNode ?? false; + this.context = await setup( + 0, + { + ...this.setupOptions, + ...opts, + fundSponsoredFPC: true, + skipAccountDeployment: true, + l1ContractsArgs: { ...this.deployL1ContractsArgs, ...opts.l1ContractsArgs }, + }, + { ...this.pxeOpts, ...pxeOpts }, + ); await this.applyBaseSetup(); } @@ -105,6 +126,7 @@ export class CrossChainMessagingTest { } async teardown() { + await this.epochTestSettler?.stop(); await teardown(this.context); } @@ -120,6 +142,19 @@ export class CrossChainMessagingTest { if (this.requireEpochProven) { // Turn off the watcher to prevent it from keep marking blocks as proven. this.context.watcher.setIsMarkingAsProven(false); + } else { + // When no real prover is running, the L1 proof window (aztecProofSubmissionEpochs) would + // otherwise expire mid-test and trigger a chain prune. The AnvilTestWatcher's auto-prove + // loop is dormant under L1 interval mining (it gates on `isAutoMining`), so start an + // EpochTestSettler to mark each completed epoch as proven on L1. + this.epochTestSettler = new EpochTestSettler( + this.context.ethCheatCodes, + this.context.deployL1ContractsValues.l1ContractAddresses.rollupAddress, + this.context.aztecNodeService.getBlockSource(), + this.logger.createChild('epoch-settler'), + { pollingIntervalMs: 500 }, + ); + await this.epochTestSettler.start(); } // Deploy 3 accounts diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.parallel.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.parallel.test.ts new file mode 100644 index 000000000000..7a182f2d4c6d --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.parallel.test.ts @@ -0,0 +1,324 @@ +import { AztecAddress } from '@aztec/aztec.js/addresses'; +import { generateClaimSecret } from '@aztec/aztec.js/ethereum'; +import { Fr } from '@aztec/aztec.js/fields'; +import type { Logger } from '@aztec/aztec.js/log'; +import { isL1ToL2MessageReady } from '@aztec/aztec.js/messaging'; +import type { AztecNode } from '@aztec/aztec.js/node'; +import { TxExecutionResult } from '@aztec/aztec.js/tx'; +import type { Wallet } from '@aztec/aztec.js/wallet'; +import { BlockNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; +import { timesAsync } from '@aztec/foundation/collection'; +import { retryUntil } from '@aztec/foundation/retry'; +import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { ExecutionPayload } from '@aztec/stdlib/tx'; + +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; +import { sendL1ToL2Message } from '../fixtures/l1_to_l2_messaging.js'; +import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; +import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; + +jest.setTimeout(300_000); + +describe('e2e_cross_chain_messaging l1_to_l2', () => { + let t: CrossChainMessagingTest; + let log: Logger; + let crossChainTestHarness: CrossChainTestHarness; + let aztecNode: AztecNode; + let wallet: Wallet; + let user1Address: AztecAddress; + let testContract: TestContract; + + beforeEach(async () => { + t = new CrossChainMessagingTest( + 'l1_to_l2', + // PIPELINING_SETUP_OPTS sets minTxsPerBlock=0; this test needs minTxsPerBlock=1 because it + // manually mines blocks one tx at a time via advanceBlock() and counts checkpoints, so empty + // pipelined checkpoints interleaving between txs would break the exact block-number assertions. + { ...PIPELINING_SETUP_OPTS, minTxsPerBlock: 1 }, + { aztecProofSubmissionEpochs: 2, aztecEpochDuration: 4 }, + // Anchor PXE to the checkpointed chain so that a proposed-chain invalidation cascade + // (e.g. a missed checkpoint publish that prunes the pipelined proposed chain) doesn't + // drop the wallet's in-flight tx via handlePrunedBlocks. + { syncChainTip: 'checkpointed' }, + ); + await t.setup(); + + ({ logger: log, crossChainTestHarness, wallet, user1Address, aztecNode } = t); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: user1Address })); + }, 300_000); + + afterEach(async () => { + await t.teardown(); + }); + + const getConsumeMethod = (scope: 'private' | 'public') => + scope === 'private' + ? testContract.methods.consume_message_from_arbitrary_sender_private + : testContract.methods.consume_message_from_arbitrary_sender_public; + + // Sends a tx to L2 to advance the block number by 1 + const advanceBlock = async () => { + const block = await aztecNode.getBlockNumber(); + log.warn(`Sending noop tx at block ${block}`); + await wallet.sendTx(ExecutionPayload.empty(), { from: user1Address }); + const newBlock = await aztecNode.getBlockNumber(); + log.warn(`Advanced to block ${newBlock}`); + if (newBlock === block) { + throw new Error(`Failed to advance block ${block}`); + } + // Under interval mining `AnvilTestWatcher.markAsProven` does not auto-fire; without an explicit + // prove call here, L1's `aztecProofSubmissionEpochs=2` window (96s with pipelined 12s slots) + // expires mid-test and triggers a chain prune that drops in-flight wallet txs. + await t.context.watcher.markAsProven(); + return newBlock; + }; + + const waitForBlockToCheckpoint = async (blockNumber: BlockNumber) => { + return await retryUntil( + async () => { + const checkpointedBlockNumber = await aztecNode.getBlockNumber('checkpointed'); + const isCheckpointed = checkpointedBlockNumber >= blockNumber; + if (!isCheckpointed) { + return undefined; + } + const [checkpointedBlock] = await aztecNode.getBlocks(blockNumber, 1, { + includeL1PublishInfo: true, + includeAttestations: true, + onlyCheckpointed: true, + }); + return checkpointedBlock.checkpointNumber; + }, + 'wait for block to checkpoint', + 60, + ); + }; + + const advanceCheckpoint = async () => { + let checkpoint = await aztecNode.getCheckpointNumber(); + const originalCheckpoint = checkpoint; + log.warn(`Original checkpoint ${originalCheckpoint}`); + do { + const newBlock = await advanceBlock(); + checkpoint = await waitForBlockToCheckpoint(newBlock); + } while (checkpoint <= originalCheckpoint); + log.warn(`At checkpoint ${checkpoint}`); + }; + + // Same as above but ignores errors. Useful if we expect a prune. + const tryAdvanceBlock = async () => { + try { + await advanceBlock(); + } catch (err) { + log.warn(`Failed to advance block: ${(err as Error).message}`); + } + }; + + // Waits until the message is fetched by the archiver of the node and returns the msg target checkpoint + const waitForMessageFetched = async (msgHash: Fr) => { + log.warn(`Waiting until the message is fetched by the node`); + return await retryUntil( + async () => { + const checkpoint = await aztecNode.getL1ToL2MessageCheckpoint(msgHash); + if (checkpoint !== undefined) { + return checkpoint; + } + await advanceBlock(); + return undefined; + }, + 'get msg checkpoint', + 60, + ); + }; + + // Waits until the message is ready to be consumed on L2 as it's been added to the world state + const waitForMessageReady = async ( + msgHash: Fr, + scope: 'private' | 'public', + onNotReady?: (blockNumber: BlockNumber) => Promise, + ) => { + const msgCheckpoint = await waitForMessageFetched(msgHash); + log.warn( + `Waiting until L2 reaches the first block of msg checkpoint ${msgCheckpoint} (current is ${await aztecNode.getCheckpointNumber()})`, + ); + await retryUntil( + async () => { + const [blockNumber, checkpointNumber] = await Promise.all([ + aztecNode.getBlockNumber(), + aztecNode.getCheckpointNumber(), + ]); + const witness = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash); + const isReady = await isL1ToL2MessageReady(aztecNode, msgHash); + log.info( + `Block is ${blockNumber}, checkpoint is ${checkpointNumber}. Message checkpoint is ${msgCheckpoint}. Witness ${!!witness}. Ready ${isReady}.`, + ); + if (!isReady) { + await (onNotReady ? onNotReady(blockNumber) : advanceBlock()); + } + return isReady; + }, + `wait for rollup to reach msg checkpoint ${msgCheckpoint}`, + 240, + ); + }; + + // We register one portal address when deploying contract but that address is no-longer the only address + // allowed to send messages to the given contract. In the following test we'll test that it's really the case. + // We'll also test that we can send the same message content across the bridge multiple times. + const canSendMessageFromNonRegisteredPortal = async (scope: 'private' | 'public') => { + // Generate and send the message to the L1 contract + const [secret, secretHash] = await generateClaimSecret(); + const message = { recipient: testContract.address, content: Fr.random(), secretHash }; + const { msgHash: message1Hash, globalLeafIndex: actualMessage1Index } = await sendL1ToL2Message( + message, + crossChainTestHarness, + ); + + await waitForMessageReady(message1Hash, scope); + + const [message1Index] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message1Hash))!; + expect(actualMessage1Index.toBigInt()).toBe(message1Index); + + const sendConsumeMsgTx = async (index: Fr) => { + const call = getConsumeMethod(scope)(message.content, secret, crossChainTestHarness.ethAccount, index); + if (scope === 'public') { + await call.simulate({ from: user1Address }); + } + await call.send({ from: user1Address }); + }; + + // We consume the L1 to L2 message using the test contract either from private or public + await sendConsumeMsgTx(actualMessage1Index); + + // We send and consume the exact same message the second time to test that oracles correctly return the new + // non-nullified message + const { msgHash: message2Hash, globalLeafIndex: actualMessage2Index } = await sendL1ToL2Message( + message, + crossChainTestHarness, + ); + + // We check that the duplicate message was correctly inserted by checking that its message index is defined + await waitForMessageReady(message2Hash, scope); + + const [message2Index] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message2Hash))!; + expect(message2Index).toBeDefined(); + expect(message2Index).toBeGreaterThan(actualMessage1Index.toBigInt()); + expect(actualMessage2Index.toBigInt()).toBe(message2Index); + + // Now we consume the message again. Everything should pass because oracle should return the duplicate message + // which is not nullified + await sendConsumeMsgTx(actualMessage2Index); + }; + + it('can send an L1 to L2 message from a non-registered portal address consumed from private repeatedly', async () => { + await canSendMessageFromNonRegisteredPortal('private'); + }); + + it('can send an L1 to L2 message from a non-registered portal address consumed from public repeatedly', async () => { + await canSendMessageFromNonRegisteredPortal('public'); + }); + + // Inbox checkpoint number can drift on two scenarios: if the rollup reorgs and rolls back its own + // checkpoint number, or if the inbox receives too many messages and they are inserted faster than + // they are consumed. In this test, we mine several checkpoints without marking them as proven until + // we can trigger a reorg, and then wait until the message can be processed to consume it. + const canConsumeMessageAfterInboxDrift = async (scope: 'private' | 'public') => { + // Stop the background epoch test settler so the drift scenario below can proceed without + // an auto-prover racing it. + await t.epochTestSettler?.stop(); + + // Reset the L1 proof window by marking the current pending tip as proven. The e2e fixture + // runs L1 on interval mining, so the watcher's auto-prove loop never starts (it gates on + // `isAutoMining`). That means L1's prune deadline has been anchored to chain genesis the + // whole setup, and would otherwise fire mid-test before we finish mining the 4 drift + // checkpoints below. + await t.context.watcher.markAsProven(); + + // Stop proving + const lastProven = await aztecNode.getBlockNumber(); + const [checkpointedProvenBlock] = await aztecNode.getBlocks(lastProven, 1, { + includeL1PublishInfo: true, + includeAttestations: true, + onlyCheckpointed: true, + }); + log.warn(`Stopping proof submission at checkpoint ${checkpointedProvenBlock.checkpointNumber} to allow drift`); + t.context.watcher.setIsMarkingAsProven(false); + + // Mine several checkpoints to ensure drift + log.warn(`Mining blocks to allow drift`); + await timesAsync(4, advanceCheckpoint); + + // Generate and send the message to the L1 contract + log.warn(`Sending L1 to L2 message`); + const [secret, secretHash] = await generateClaimSecret(); + const message = { recipient: testContract.address, content: Fr.random(), secretHash }; + const { msgHash, globalLeafIndex } = await sendL1ToL2Message(message, crossChainTestHarness); + + // Wait until the Aztec node has synced it + const msgCheckpointNumber = await waitForMessageFetched(msgHash); + log.warn(`Message synced for checkpoint ${msgCheckpointNumber}`); + expect(checkpointedProvenBlock.checkpointNumber + 4).toBeLessThan(msgCheckpointNumber); + + // And keep mining until we prune back to the original block number. Now the "waiting for two blocks" + // strategy for the message to be ready to use shouldn't work, since the lastProven block is more than + // two blocks behind the message block. This is the scenario we want to test. + log.warn(`Waiting until we prune back to ${lastProven}`); + await retryUntil( + async () => + (await aztecNode.getBlockNumber().then(b => b === lastProven || b === lastProven + 1)) || + (await tryAdvanceBlock()), + 'wait for prune', + 180, + ); + + // Check that there is no witness yet + expect(await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash)).toBeUndefined(); + + // Define L2 function to consume the message + const consume = () => + getConsumeMethod(scope)(message.content, secret, crossChainTestHarness.ethAccount, globalLeafIndex); + + // Wait until the message is ready to be consumed, checking that it cannot be consumed beforehand + await waitForMessageReady(msgHash, scope, async () => { + if (scope === 'private') { + // On private, we simulate the tx locally and check that we get a missing message error, then we advance to the next block + await expect(() => consume().simulate({ from: user1Address })).rejects.toThrow(/No L1 to L2 message found/); + await tryAdvanceBlock(); + } else { + // In public it is harder to determine when a message becomes consumable. + // We send a transaction, this advances the chain and the message MIGHT be consumed in the new block. + // If it does get consumed then we check that the block contains the message. + // If it fails we check that the block doesn't contain the message + const { receipt } = await consume().send({ from: user1Address, wait: { dontThrowOnRevert: true } }); + if (receipt.executionResult === TxExecutionResult.SUCCESS) { + // The block the transaction included should be for the message checkpoint number + // and be the first block in the checkpoint + const block = await aztecNode.getBlock(receipt.blockNumber!); + expect(block).toBeDefined(); + expect(block!.checkpointNumber).toEqual(msgCheckpointNumber); + expect(block!.indexWithinCheckpoint).toEqual(IndexWithinCheckpoint.ZERO); + } else { + expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); + } + } + await t.context.watcher.markAsProven(); + }); + + // Verify the membership witness is available for creating the tx (private-land only) + if (scope === 'private') { + const [messageIndex] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash))!; + expect(messageIndex).toEqual(globalLeafIndex.toBigInt()); + // And consume the message for private, public was already consumed. + await consume().send({ from: user1Address }); + } + }; + + it('can consume L1 to L2 message in private after inbox drifts away from the rollup', async () => { + await canConsumeMessageAfterInboxDrift('private'); + }); + + it('can consume L1 to L2 message in public after inbox drifts away from the rollup', async () => { + await canConsumeMessageAfterInboxDrift('public'); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts deleted file mode 100644 index 294069db6b86..000000000000 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts +++ /dev/null @@ -1,288 +0,0 @@ -import { AztecAddress } from '@aztec/aztec.js/addresses'; -import { generateClaimSecret } from '@aztec/aztec.js/ethereum'; -import { Fr } from '@aztec/aztec.js/fields'; -import type { Logger } from '@aztec/aztec.js/log'; -import { isL1ToL2MessageReady } from '@aztec/aztec.js/messaging'; -import type { AztecNode } from '@aztec/aztec.js/node'; -import { TxExecutionResult } from '@aztec/aztec.js/tx'; -import type { Wallet } from '@aztec/aztec.js/wallet'; -import { BlockNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; -import { timesAsync } from '@aztec/foundation/collection'; -import { retryUntil } from '@aztec/foundation/retry'; -import { TestContract } from '@aztec/noir-test-contracts.js/Test'; -import { ExecutionPayload } from '@aztec/stdlib/tx'; - -import { sendL1ToL2Message } from '../fixtures/l1_to_l2_messaging.js'; -import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; -import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; - -describe('e2e_cross_chain_messaging l1_to_l2', () => { - let t: CrossChainMessagingTest; - let log: Logger; - let crossChainTestHarness: CrossChainTestHarness; - let aztecNode: AztecNode; - let wallet: Wallet; - let user1Address: AztecAddress; - let testContract: TestContract; - - beforeEach(async () => { - t = new CrossChainMessagingTest( - 'l1_to_l2', - { minTxsPerBlock: 1 }, - { aztecProofSubmissionEpochs: 2, aztecEpochDuration: 4, inboxLag: 2 }, - ); - await t.setup(); - - ({ logger: log, crossChainTestHarness, wallet, user1Address, aztecNode } = t); - ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: user1Address })); - }, 300_000); - - afterEach(async () => { - await t.teardown(); - }); - - const getConsumeMethod = (scope: 'private' | 'public') => - scope === 'private' - ? testContract.methods.consume_message_from_arbitrary_sender_private - : testContract.methods.consume_message_from_arbitrary_sender_public; - - // Sends a tx to L2 to advance the block number by 1 - const advanceBlock = async () => { - const block = await aztecNode.getBlockNumber(); - log.warn(`Sending noop tx at block ${block}`); - await wallet.sendTx(ExecutionPayload.empty(), { from: user1Address }); - const newBlock = await aztecNode.getBlockNumber(); - log.warn(`Advanced to block ${newBlock}`); - if (newBlock === block) { - throw new Error(`Failed to advance block ${block}`); - } - return newBlock; - }; - - const waitForBlockToCheckpoint = async (blockNumber: BlockNumber) => { - return await retryUntil( - async () => { - const checkpointedBlockNumber = await aztecNode.getBlockNumber('checkpointed'); - const isCheckpointed = checkpointedBlockNumber >= blockNumber; - if (!isCheckpointed) { - return undefined; - } - const [checkpointedBlock] = await aztecNode.getBlocks(blockNumber, 1, { - includeL1PublishInfo: true, - includeAttestations: true, - onlyCheckpointed: true, - }); - return checkpointedBlock.checkpointNumber; - }, - 'wait for block to checkpoint', - 60, - ); - }; - - const advanceCheckpoint = async () => { - let checkpoint = await aztecNode.getCheckpointNumber(); - const originalCheckpoint = checkpoint; - log.warn(`Original checkpoint ${originalCheckpoint}`); - do { - const newBlock = await advanceBlock(); - checkpoint = await waitForBlockToCheckpoint(newBlock); - } while (checkpoint <= originalCheckpoint); - log.warn(`At checkpoint ${checkpoint}`); - }; - - // Same as above but ignores errors. Useful if we expect a prune. - const tryAdvanceBlock = async () => { - try { - await advanceBlock(); - } catch (err) { - log.warn(`Failed to advance block: ${(err as Error).message}`); - } - }; - - // Waits until the message is fetched by the archiver of the node and returns the msg target checkpoint - const waitForMessageFetched = async (msgHash: Fr) => { - log.warn(`Waiting until the message is fetched by the node`); - return await retryUntil( - async () => { - const checkpoint = await aztecNode.getL1ToL2MessageCheckpoint(msgHash); - if (checkpoint !== undefined) { - return checkpoint; - } - await advanceBlock(); - return undefined; - }, - 'get msg checkpoint', - 60, - ); - }; - - // Waits until the message is ready to be consumed on L2 as it's been added to the world state - const waitForMessageReady = async ( - msgHash: Fr, - scope: 'private' | 'public', - onNotReady?: (blockNumber: BlockNumber) => Promise, - ) => { - const msgCheckpoint = await waitForMessageFetched(msgHash); - log.warn( - `Waiting until L2 reaches the first block of msg checkpoint ${msgCheckpoint} (current is ${await aztecNode.getCheckpointNumber()})`, - ); - await retryUntil( - async () => { - const [blockNumber, checkpointNumber] = await Promise.all([ - aztecNode.getBlockNumber(), - aztecNode.getCheckpointNumber(), - ]); - const witness = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash); - const isReady = await isL1ToL2MessageReady(aztecNode, msgHash); - log.info( - `Block is ${blockNumber}, checkpoint is ${checkpointNumber}. Message checkpoint is ${msgCheckpoint}. Witness ${!!witness}. Ready ${isReady}.`, - ); - if (!isReady) { - await (onNotReady ? onNotReady(blockNumber) : advanceBlock()); - } - return isReady; - }, - `wait for rollup to reach msg checkpoint ${msgCheckpoint}`, - 120, - ); - }; - - // We register one portal address when deploying contract but that address is no-longer the only address - // allowed to send messages to the given contract. In the following test we'll test that it's really the case. - // We'll also test that we can send the same message content across the bridge multiple times. - it.each(['private', 'public'] as const)( - 'can send an L1 to L2 message from a non-registered portal address consumed from %s repeatedly', - async (scope: 'private' | 'public') => { - // Generate and send the message to the L1 contract - const [secret, secretHash] = await generateClaimSecret(); - const message = { recipient: testContract.address, content: Fr.random(), secretHash }; - const { msgHash: message1Hash, globalLeafIndex: actualMessage1Index } = await sendL1ToL2Message( - message, - crossChainTestHarness, - ); - - await waitForMessageReady(message1Hash, scope); - - const [message1Index] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message1Hash))!; - expect(actualMessage1Index.toBigInt()).toBe(message1Index); - - const sendConsumeMsgTx = async (index: Fr) => { - const call = getConsumeMethod(scope)(message.content, secret, crossChainTestHarness.ethAccount, index); - if (scope === 'public') { - await call.simulate({ from: user1Address }); - } - await call.send({ from: user1Address }); - }; - - // We consume the L1 to L2 message using the test contract either from private or public - await sendConsumeMsgTx(actualMessage1Index); - - // We send and consume the exact same message the second time to test that oracles correctly return the new - // non-nullified message - const { msgHash: message2Hash, globalLeafIndex: actualMessage2Index } = await sendL1ToL2Message( - message, - crossChainTestHarness, - ); - - // We check that the duplicate message was correctly inserted by checking that its message index is defined - await waitForMessageReady(message2Hash, scope); - - const [message2Index] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message2Hash))!; - expect(message2Index).toBeDefined(); - expect(message2Index).toBeGreaterThan(actualMessage1Index.toBigInt()); - expect(actualMessage2Index.toBigInt()).toBe(message2Index); - - // Now we consume the message again. Everything should pass because oracle should return the duplicate message - // which is not nullified - await sendConsumeMsgTx(actualMessage2Index); - }, - 120_000, - ); - - // Inbox checkpoint number can drift on two scenarios: if the rollup reorgs and rolls back its own - // checkpoint number, or if the inbox receives too many messages and they are inserted faster than - // they are consumed. In this test, we mine several checkpoints without marking them as proven until - // we can trigger a reorg, and then wait until the message can be processed to consume it. - it.each(['private', 'public'] as const)( - 'can consume L1 to L2 message in %s after inbox drifts away from the rollup', - async (scope: 'private' | 'public') => { - // Stop proving - const lastProven = await aztecNode.getBlockNumber(); - const [checkpointedProvenBlock] = await aztecNode.getBlocks(lastProven, 1, { - includeL1PublishInfo: true, - includeAttestations: true, - onlyCheckpointed: true, - }); - log.warn(`Stopping proof submission at checkpoint ${checkpointedProvenBlock.checkpointNumber} to allow drift`); - t.context.watcher.setIsMarkingAsProven(false); - - // Mine several checkpoints to ensure drift - log.warn(`Mining blocks to allow drift`); - await timesAsync(4, advanceCheckpoint); - - // Generate and send the message to the L1 contract - log.warn(`Sending L1 to L2 message`); - const [secret, secretHash] = await generateClaimSecret(); - const message = { recipient: testContract.address, content: Fr.random(), secretHash }; - const { msgHash, globalLeafIndex } = await sendL1ToL2Message(message, crossChainTestHarness); - - // Wait until the Aztec node has synced it - const msgCheckpointNumber = await waitForMessageFetched(msgHash); - log.warn(`Message synced for checkpoint ${msgCheckpointNumber}`); - expect(checkpointedProvenBlock.checkpointNumber + 4).toBeLessThan(msgCheckpointNumber); - - // And keep mining until we prune back to the original block number. Now the "waiting for two blocks" - // strategy for the message to be ready to use shouldn't work, since the lastProven block is more than - // two blocks behind the message block. This is the scenario we want to test. - log.warn(`Waiting until we prune back to ${lastProven}`); - await retryUntil( - async () => - (await aztecNode.getBlockNumber().then(b => b === lastProven || b === lastProven + 1)) || - (await tryAdvanceBlock()), - 'wait for prune', - 40, - ); - - // Check that there is no witness yet - expect(await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash)).toBeUndefined(); - - // Define L2 function to consume the message - const consume = () => - getConsumeMethod(scope)(message.content, secret, crossChainTestHarness.ethAccount, globalLeafIndex); - - // Wait until the message is ready to be consumed, checking that it cannot be consumed beforehand - await waitForMessageReady(msgHash, scope, async () => { - if (scope === 'private') { - // On private, we simulate the tx locally and check that we get a missing message error, then we advance to the next block - await expect(() => consume().simulate({ from: user1Address })).rejects.toThrow(/No L1 to L2 message found/); - await tryAdvanceBlock(); - } else { - // In public it is harder to determine when a message becomes consumable. - // We send a transaction, this advances the chain and the message MIGHT be consumed in the new block. - // If it does get consumed then we check that the block contains the message. - // If it fails we check that the block doesn't contain the message - const { receipt } = await consume().send({ from: user1Address, wait: { dontThrowOnRevert: true } }); - if (receipt.executionResult === TxExecutionResult.SUCCESS) { - // The block the transaction included should be for the message checkpoint number - // and be the first block in the checkpoint - const block = await aztecNode.getBlock(receipt.blockNumber!); - expect(block).toBeDefined(); - expect(block!.checkpointNumber).toEqual(msgCheckpointNumber); - expect(block!.indexWithinCheckpoint).toEqual(IndexWithinCheckpoint.ZERO); - } else { - expect(receipt.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); - } - } - await t.context.watcher.markAsProven(); - }); - - // Verify the membership witness is available for creating the tx (private-land only) - if (scope === 'private') { - const [messageIndex] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash))!; - expect(messageIndex).toEqual(globalLeafIndex.toBigInt()); - // And consume the message for private, public was already consumed. - await consume().send({ from: user1Address }); - } - }, - ); -}); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts index 6c123772337b..34b29d165450 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l2_to_l1.test.ts @@ -5,6 +5,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { OutboxContract, RollupContract, type ViemL2ToL1Msg } from '@aztec/ethereum/contracts'; import { OutboxAbi } from '@aztec/l1-artifacts'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { type Sequencer, type SequencerEvents, SequencerState } from '@aztec/sequencer-client'; import { computeL2ToL1MessageHash } from '@aztec/stdlib/hash'; import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { @@ -14,12 +15,43 @@ import { } from '@aztec/stdlib/messaging'; import type { TxHash } from '@aztec/stdlib/tx'; +import { jest } from '@jest/globals'; import { type Hex, decodeEventLog } from 'viem'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; +/** + * Waits for the sequencer to reach IDLE state so that subsequent setConfig() calls take effect on + * the next checkpoint job rather than racing with an in-flight one. Mirrors the helper in + * `e2e_fees/gas_estimation.test.ts`. + */ +function waitForSequencerIdle(sequencer: Sequencer, timeout = 30000): Promise { + if (sequencer.status().state === SequencerState.IDLE) { + return Promise.resolve(); + } + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + sequencer.off('state-changed', handler); + reject(new Error('Timeout waiting for sequencer IDLE state')); + }, timeout); + const handler = (args: Parameters[0]) => { + if (args.newState === SequencerState.IDLE) { + clearTimeout(timer); + sequencer.off('state-changed', handler); + resolve(); + } + }; + sequencer.on('state-changed', handler); + }); +} + describe('e2e_cross_chain_messaging l2_to_l1', () => { + // Pipelining slows wall-clock chain progress (12s slots); advanceToEpochProven plus the per-test + // multi-tx flows exceed the default 300s per-test budget. + jest.setTimeout(15 * 60 * 1000); + const t = new CrossChainMessagingTest('l2_to_l1', { startProverNode: true }); let crossChainTestHarness: CrossChainTestHarness; @@ -35,7 +67,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { let contract: TestContract; beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); ({ crossChainTestHarness, aztecNode, aztecNodeAdmin, wallet, user1Address, rollup, outbox } = t); @@ -59,6 +91,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { // Configure the node to be able to rollup only 1 tx. await aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); + await waitForSequencerIdle(t.context.sequencer!.getSequencer()); const { receipt: txReceipt } = await new BatchCall(wallet, [ contract.methods.create_l2_to_l1_message_arbitrary_recipient_private(contents[0], recipient), @@ -90,6 +123,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { // Configure the node to include the 2 txs in the same block. await aztecNodeAdmin.setConfig({ minTxsPerBlock: 2 }); + await waitForSequencerIdle(t.context.sequencer!.getSequencer()); // Send the 2 txs. const [{ receipt: noMessageReceipt }, { receipt: withMessageReceipt }] = await Promise.all([ @@ -112,6 +146,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { it('2 txs (balanced), one with 3 messages (unbalanced), one with 4 messages (balanced)', async () => { // Force txs to be in the same block. await aztecNodeAdmin!.setConfig({ minTxsPerBlock: 2 }); + await waitForSequencerIdle(t.context.sequencer!.getSequencer()); const tx0 = generateMessages(3); const tx1 = generateMessages(4); @@ -164,6 +199,7 @@ describe('e2e_cross_chain_messaging l2_to_l1', () => { it('3 txs (unbalanced), one with 3 messages (unbalanced), one with 1 message (the subtree root), one with 2 messages (balanced)', async () => { // Force txs to be in the same block. await aztecNodeAdmin!.setConfig({ minTxsPerBlock: 3 }); + await waitForSequencerIdle(t.context.sequencer!.getSequencer()); const tx0 = generateMessages(3); const tx1 = generateMessages(1); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_failure_cases.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_failure_cases.test.ts index d864b328ceef..13d7837d4133 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_failure_cases.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_failure_cases.test.ts @@ -5,7 +5,7 @@ import { sha256ToField } from '@aztec/foundation/crypto/sha256'; import { toFunctionSelector } from 'viem'; -import { NO_L1_TO_L2_MSG_ERROR } from '../fixtures/fixtures.js'; +import { NO_L1_TO_L2_MSG_ERROR, PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; describe('e2e_cross_chain_messaging token_bridge_failure_cases', () => { @@ -15,7 +15,7 @@ describe('e2e_cross_chain_messaging token_bridge_failure_cases', () => { let { crossChainTestHarness, ethAccount, l2Bridge, ownerAddress, user1Address, user2Address, rollup } = t; beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ crossChainTestHarness, user1Address, user2Address, ownerAddress, rollup } = t); ethAccount = crossChainTestHarness.ethAccount; @@ -40,7 +40,7 @@ describe('e2e_cross_chain_messaging token_bridge_failure_cases', () => { .exit_to_l1_public(ethAccount, withdrawAmount, EthAddress.ZERO, authwitNonce) .simulate({ from: user1Address }), ).rejects.toThrow(/unauthorized/); - }, 60_000); + }, 180_000); it("Can't claim funds privately which were intended for public deposit from the token portal", async () => { const bridgeAmount = 100n; @@ -72,7 +72,7 @@ describe('e2e_cross_chain_messaging token_bridge_failure_cases', () => { .claim_private(ownerAddress, wrongBridgeAmount, claim.claimSecret, claim.messageLeafIndex) .simulate({ from: user2Address }), ).rejects.toThrow(`No L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`); - }, 60_000); + }, 180_000); it("Can't claim funds publicly which were intended for private deposit from the token portal", async () => { // 1. Mint tokens on L1 diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts index 2060c5263a68..70cf8c1b53eb 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_private.test.ts @@ -6,11 +6,18 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import type { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge'; import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import type { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; describe('e2e_cross_chain_messaging token_bridge_private', () => { + // Pipelining slows wall-clock chain progress (12s slots); waitForProven via advanceToEpochProven + // needs more than the default 300s per-test budget. + jest.setTimeout(15 * 60 * 1000); + const t = new CrossChainMessagingTest('token_bridge_private', { startProverNode: true }); let crossChainTestHarness: CrossChainTestHarness; @@ -24,7 +31,7 @@ describe('e2e_cross_chain_messaging token_bridge_private', () => { let user2Address: AztecAddress; beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ crossChainTestHarness, ethAccount, aztecNode, logger, ownerAddress, l2Bridge, l2Token, wallet, user2Address } = t); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_public.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_public.test.ts index 4f4e4d34cc12..23894e168172 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/token_bridge_public.test.ts @@ -1,17 +1,23 @@ import { Fr } from '@aztec/aztec.js/fields'; import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; -import { NO_L1_TO_L2_MSG_ERROR } from '../fixtures/fixtures.js'; +import { jest } from '@jest/globals'; + +import { NO_L1_TO_L2_MSG_ERROR, PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; describe('e2e_cross_chain_messaging token_bridge_public', () => { + // Pipelining slows wall-clock chain progress (12s slots); waitForProven via advanceToEpochProven + // needs more than the default 300s per-test budget. + jest.setTimeout(15 * 60 * 1000); + const t = new CrossChainMessagingTest('token_bridge_public', { startProverNode: true }); let { crossChainTestHarness, ethAccount, aztecNode, logger, ownerAddress, l2Bridge, l2Token, wallet, user2Address } = t; beforeEach(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ crossChainTestHarness, wallet, user2Address } = t); @@ -93,7 +99,7 @@ describe('e2e_cross_chain_messaging token_bridge_public', () => { l2ToL1MessageResult.siblingPath, ); expect(await crossChainTestHarness.getL1BalanceOf(ethAccount)).toBe(l1TokenBalance - bridgeAmount + withdrawAmount); - }, 120_000); + }, 900_000); it('Someone else can mint funds to me on my behalf (publicly)', async () => { const l1TokenBalance = 1000000n; diff --git a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts index 1fd23d78063f..5c78970eae43 100644 --- a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts +++ b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts @@ -6,14 +6,16 @@ import { ClaimContract } from '@aztec/noir-contracts.js/Claim'; import { CrowdfundingContract } from '@aztec/noir-contracts.js/Crowdfunding'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; -jest.setTimeout(200_000); +jest.setTimeout(400_000); // Tests crowdfunding via the Crowdfunding contract and claiming the reward token via the Claim contract describe('e2e_crowdfunding_and_claim', () => { @@ -46,6 +48,7 @@ describe('e2e_crowdfunding_and_claim', () => { let crowdfundingSecretKey: Fr; let crowdfundingPublicKeys: PublicKeys; let cheatCodes: CheatCodes; + let _aztecNode: AztecNode & AztecNodeDebug; let deadline: number; // end of crowdfunding period let uintNote!: any; @@ -56,8 +59,9 @@ describe('e2e_crowdfunding_and_claim', () => { teardown, logger, wallet, + aztecNode: _aztecNode, accounts: [operatorAddress, donor1Address, donor2Address], - } = await setup(3)); + } = await setup(3, { ...AUTOMINE_E2E_OPTS })); // We set the deadline to a week from now deadline = (await cheatCodes.eth.lastBlockTimestamp()) + 7 * 24 * 60 * 60; @@ -309,8 +313,12 @@ describe('e2e_crowdfunding_and_claim', () => { ); const witness = await wallet.createAuthWit(donor2Address, { caller: crowdfundingContract.address, action }); - // 2) We set next block timestamp to be after the deadline - await cheatCodes.eth.warp(deadline + 1); + // 2) We warp L1 past the deadline. We don't mine an L2 block here: the deadline is set 7 + // days in the future during setup, and warping that far before mining would cause the + // archiver to predict-reorg every prior checkpoint (their L1 publish blocks fall in a stale + // anvil layout after the warp). The next donate tx is rejected by the contract because the + // next L2 block's timestamp is already past the deadline. + await cheatCodes.eth.warp(Number(deadline + 1), { resetBlockInterval: true }); // 3) We donate to the crowdfunding contract await expect( diff --git a/yarn-project/end-to-end/src/e2e_custom_message.test.ts b/yarn-project/end-to-end/src/e2e_custom_message.test.ts index 0ff387019d2e..34fa17f1c901 100644 --- a/yarn-project/end-to-end/src/e2e_custom_message.test.ts +++ b/yarn-project/end-to-end/src/e2e_custom_message.test.ts @@ -7,9 +7,10 @@ import { CustomMessageContract, type MultiLogEvent } from '@aztec/noir-test-cont import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('CustomMessage - Multi-Log Pattern', () => { let contract: CustomMessageContract; @@ -24,7 +25,7 @@ describe('CustomMessage - Multi-Log Pattern', () => { teardown, wallet, accounts: [account], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); await ensureAccountContractsPublished(wallet, [account]); ({ contract } = await CustomMessageContract.deploy(wallet).send({ from: account })); }); diff --git a/yarn-project/end-to-end/src/e2e_debug_trace.test.ts b/yarn-project/end-to-end/src/e2e_debug_trace.test.ts index 71f950086660..c79e42e6f1cd 100644 --- a/yarn-project/end-to-end/src/e2e_debug_trace.test.ts +++ b/yarn-project/end-to-end/src/e2e_debug_trace.test.ts @@ -52,6 +52,11 @@ describe('e2e_debug_trace_transaction', () => { maxSpeedUpAttempts: 0, // Disable speed ups, so that cancellation txs never make it through minTxsPerBlock: 0, coinbase: coinbase, + enableProposerPipelining: true, + aztecSlotDuration: 12, + ethereumSlotDuration: 4, + aztecProofSubmissionEpochs: 640, + inboxLag: 2, })); sequencer = sequencerClient! as TestSequencerClient; publisherManager = sequencer.publisherManager; @@ -122,7 +127,7 @@ describe('e2e_debug_trace_transaction', () => { // We now want to set the sequencer config to allow blocks with 0 transactions // Wait until we have successfully moved forward by a few blocks - const numBlocksToMine = 3; + const numBlocksToMine = 2; const startBlockNumber = await aztecNode.getBlockNumber(); await aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); const result = await retryUntil( @@ -131,7 +136,7 @@ describe('e2e_debug_trace_transaction', () => { return blockNumber >= startBlockNumber + numBlocksToMine; }, 'block number check', - 30, + 60, 1, ); expect(result).toBeTrue(); @@ -249,7 +254,7 @@ describe('e2e_debug_trace_transaction', () => { return blockNumber >= startBlockNumber + numBlocksToMine; }, 'block number check', - 30, + 60, 1, ); expect(result).toBeTrue(); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts index cb0a5b7cb54b..71344027a78d 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts @@ -12,16 +12,23 @@ import type { Logger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; import { TxExecutionResult, type TxReceipt } from '@aztec/aztec.js/tx'; import type { Wallet } from '@aztec/aztec.js/wallet'; +import type { BlockNumber } from '@aztec/foundation/branded-types'; import { writeTestData } from '@aztec/foundation/testing/files'; import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import type { ContractClassIdPreimage } from '@aztec/stdlib/contract'; import { PublicKeys } from '@aztec/stdlib/keys'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { jest } from '@jest/globals'; + +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { DeployTest, type StatefulContractCtorArgs } from './deploy_test.js'; describe('e2e_deploy_contract contract class registration', () => { + // Pipelined cadence (~24s/dependent-tx) inflates the chained deploy/publish setup beyond the default 5 min + // hook window. Many of the publishInstance helpers serially register multiple contracts/instances per case. + jest.setTimeout(900_000); + const t = new DeployTest('contract class'); let logger: Logger; @@ -34,7 +41,7 @@ describe('e2e_deploy_contract contract class registration', () => { let publicationTxReceipt: TxReceipt; beforeAll(async () => { - ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup()); + ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup({ ...AUTOMINE_E2E_OPTS })); artifact = StatefulTestContract.artifact; publicationTxReceipt = await publishContractClass(wallet, artifact).then(c => c.send({ from: defaultAccountAddress }).then(({ receipt }) => receipt), @@ -72,7 +79,10 @@ describe('e2e_deploy_contract contract class registration', () => { }); }); - const testDeployingAnInstance = (how: string, deployFn: (toDeploy: ContractInstanceWithAddress) => Promise) => + const testDeployingAnInstance = ( + how: string, + deployFn: (toDeploy: ContractInstanceWithAddress) => Promise, + ) => describe(`deploying a contract instance ${how}`, () => { let instance: ContractInstanceWithAddress; let initArgs: StatefulContractCtorArgs; @@ -91,7 +101,7 @@ describe('e2e_deploy_contract contract class registration', () => { }); const { address, currentContractClassId: contractClassId } = instance; logger.info(`Deploying contract instance at ${address.toString()} class id ${contractClassId.toString()}`); - await deployFn(instance); + const publishBlockNumber = await deployFn(instance); // TODO(@spalladino) We should **not** need the whole instance, including initArgs and salt, // in order to interact with a public function for the contract. We may even not need @@ -111,21 +121,25 @@ describe('e2e_deploy_contract contract class registration', () => { }); expect(registered.address).toEqual(instance.address); const contract = StatefulTestContract.at(instance.address, wallet); - return { contract, initArgs, instance, publicKeys }; + return { contract, initArgs, instance, publicKeys, publishBlockNumber }; }; describe('using a private constructor', () => { + let publishBlockNumber: BlockNumber; beforeAll(async () => { - ({ instance, initArgs, contract } = await publishInstance()); + const result = await publishInstance(); + ({ instance, initArgs, contract } = result); + publishBlockNumber = result.publishBlockNumber; }); it('stores contract instance in the aztec node', async () => { - // Contract instance deployed event is emitted via private logs. - const blockNumber = await aztecNode.getBlockNumber(); - - const logs = (await aztecNode.getBlock(blockNumber, { includeTransactions: true }))!.body.txEffects.flatMap( - t => t.privateLogs, - ); + // Contract instance deployed event is emitted via private logs. Read the block carrying + // the publish tx directly — under pipelining the "latest" block at this point may be an + // empty pipelined block, and the publish tx's receipt blockNumber is the authoritative + // anchor. + const logs = (await aztecNode.getBlock(publishBlockNumber, { + includeTransactions: true, + }))!.body.txEffects.flatMap(t => t.privateLogs); expect(logs.length).toBe(1); @@ -142,6 +156,7 @@ describe('e2e_deploy_contract contract class registration', () => { expect(deployed!.address).toEqual(instance.address); expect(deployed!.currentContractClassId).toEqual(contractClass.id); expect(deployed!.initializationHash).toEqual(instance.initializationHash); + expect(deployed!.immutablesHash).toEqual(instance.immutablesHash); expect(deployed!.publicKeys).toEqual(instance.publicKeys); expect(deployed!.salt).toEqual(instance.salt); expect(deployed!.deployer).toEqual(instance.deployer); @@ -161,7 +176,7 @@ describe('e2e_deploy_contract contract class registration', () => { const { receipt } = await contract.methods .increment_public_value(whom, 10) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); - expect(receipt.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); + expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); // Meanwhile we check we didn't increment the value expect( @@ -205,7 +220,7 @@ describe('e2e_deploy_contract contract class registration', () => { const { receipt } = await contract.methods .public_constructor(whom, 43) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); - expect(receipt.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); + expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); expect( (await contract.methods.get_public_value(whom).simulate({ from: defaultAccountAddress })).result, ).toEqual(0n); @@ -232,7 +247,8 @@ describe('e2e_deploy_contract contract class registration', () => { testDeployingAnInstance('from a wallet', async instance => { // Calls the deployer contract directly from a wallet const deployMethod = publishInstance(wallet, instance); - await deployMethod.send({ from: defaultAccountAddress }); + const { receipt } = await deployMethod.send({ from: defaultAccountAddress }); + return receipt.blockNumber!; }); testDeployingAnInstance('from a contract', async instance => { @@ -240,7 +256,10 @@ describe('e2e_deploy_contract contract class registration', () => { await wallet.registerContract(instance, artifact); // Set up the contract that calls the deployer (which happens to be the TestContract) and call it const { contract: deployer } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress }); - await deployer.methods.publish_contract_instance(instance.address).send({ from: defaultAccountAddress }); + const { receipt } = await deployer.methods + .publish_contract_instance(instance.address) + .send({ from: defaultAccountAddress }); + return receipt.blockNumber!; }); describe('error scenarios in deployment', () => { @@ -256,7 +275,7 @@ describe('e2e_deploy_contract contract class registration', () => { const { receipt: tx } = await instance.methods .increment_public_value_no_init_check(whom, 10) .send({ from: defaultAccountAddress, wait: { dontThrowOnRevert: true } }); - expect(tx.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); + expect(tx.executionResult).toEqual(TxExecutionResult.REVERTED); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts index 4bdf1e9fc248..e9799ed57b7d 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts @@ -11,6 +11,7 @@ import { NoConstructorContract } from '@aztec/noir-test-contracts.js/NoConstruct import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import { GasFees } from '@aztec/stdlib/gas'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { TestWallet } from '../test-wallet/test_wallet.js'; import { DeployTest } from './deploy_test.js'; @@ -23,7 +24,7 @@ describe('e2e_deploy_contract deploy method', () => { let defaultAccountAddress: AztecAddress; beforeAll(async () => { - ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup()); + ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup({ ...AUTOMINE_E2E_OPTS })); }); afterAll(() => t.teardown()); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts index 79c6ecce5c05..aeaf3da2d6fe 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts @@ -9,7 +9,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import type { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; -import { type EndToEndContext, deployAccounts, setup, teardown } from '../fixtures/setup.js'; +import { type EndToEndContext, type SetupOptions, deployAccounts, setup, teardown } from '../fixtures/setup.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; export class DeployTest { @@ -24,9 +24,10 @@ export class DeployTest { this.logger = createLogger(`e2e:e2e_deploy_contract:${testName}`); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up test environment'); this.context = await setup(0, { + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, }); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts index a4d1c1e0748d..17998c08d374 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts @@ -9,6 +9,7 @@ import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest import { TestContractArtifact } from '@aztec/noir-test-contracts.js/Test'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { DeployTest } from './deploy_test.js'; @@ -20,7 +21,7 @@ describe('e2e_deploy_contract legacy', () => { let defaultAccountAddress: AztecAddress; beforeAll(async () => { - ({ logger, wallet, defaultAccountAddress } = await t.setup()); + ({ logger, wallet, defaultAccountAddress } = await t.setup({ ...AUTOMINE_E2E_OPTS })); }); afterAll(() => t.teardown()); @@ -122,7 +123,7 @@ describe('e2e_deploy_contract legacy', () => { expect(goodTxReceipt!.blockNumber).toEqual(expect.any(Number)); expect(badTxReceipt!.blockNumber).toEqual(expect.any(Number)); - expect(badTxReceipt!.executionResult).toEqual(TxExecutionResult.APP_LOGIC_REVERTED); + expect(badTxReceipt!.executionResult).toEqual(TxExecutionResult.REVERTED); const badInstance = await badDeploy.getInstance(); // But the bad tx did not deploy the class diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts index 33d63164a9c1..9fbbbbd36598 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts @@ -11,6 +11,7 @@ import { PrivateInitTestContract } from '@aztec/noir-test-contracts.js/PrivateIn import { siloNullifier } from '@aztec/stdlib/hash'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { DeployTest } from './deploy_test.js'; @@ -25,7 +26,7 @@ describe('e2e_deploy_contract private initialization', () => { let aztecNode: AztecNode; beforeAll(async () => { - ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup()); + ({ logger, wallet, aztecNode, defaultAccountAddress } = await t.setup({ ...AUTOMINE_E2E_OPTS })); await publishContractClass(wallet, InitTestContract.artifact).then(c => c.send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_double_spend.test.ts b/yarn-project/end-to-end/src/e2e_double_spend.test.ts index 3cc69dec717d..94bb2ec72f7d 100644 --- a/yarn-project/end-to-end/src/e2e_double_spend.test.ts +++ b/yarn-project/end-to-end/src/e2e_double_spend.test.ts @@ -5,6 +5,7 @@ import { TxExecutionResult } from '@aztec/aztec.js/tx'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_double_spend', () => { @@ -23,7 +24,7 @@ describe('e2e_double_spend', () => { wallet, accounts: [defaultAccountAddress], logger, - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); @@ -46,7 +47,7 @@ describe('e2e_double_spend', () => { // tx will be included in a block but with app logic reverted await expect( contract.methods.emit_nullifier_public(nullifier).send({ from: defaultAccountAddress }), - ).rejects.toThrow(TxExecutionResult.APP_LOGIC_REVERTED); + ).rejects.toThrow(TxExecutionResult.REVERTED); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_equivocation.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_equivocation.test.ts index a72862c14d1d..080431c3549b 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_equivocation.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_equivocation.test.ts @@ -10,6 +10,7 @@ import { retryUntil } from '@aztec/foundation/retry'; import { bufferToHex } from '@aztec/foundation/string'; import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { tryStop } from '@aztec/stdlib/interfaces/server'; +import { OffenseType } from '@aztec/stdlib/slashing'; import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; @@ -58,6 +59,7 @@ describe('e2e_epochs/epochs_equivocation', () => { // - checkpointFinalization = 0.5s (assemble) + 0 (p2p in test) + 2s (L1 publish) = 2.5s // - finalBlockDuration = 8s (re-execution) // - Total: 0.5 + 24 + 8 + 2.5 = 35s => use 36s + const slashingUnit = BigInt(1e14); test = await EpochsTestContext.setup({ numberOfAccounts: 0, initialValidators: validators, @@ -76,6 +78,28 @@ describe('e2e_epochs/epochs_equivocation', () => { l1PublishingTime: 2, aztecTargetCommitteeSize: 4, skipInitialSequencer: true, + // Enable the slasher so we can assert the equivocating proposer is detected for slashing. + // Round size is aztecEpochDuration * slashingRoundSizeInEpochs = 4 slots; the L1 contract + // requires QUORUM > ROUND_SIZE / 2, so quorum must be at least 3. + slasherEnabled: true, + slashingQuorum: 3, + slashingRoundSizeInEpochs: 1, + slashingOffsetInRounds: 1, + slashAmountSmall: slashingUnit, + slashAmountMedium: slashingUnit * 2n, + slashAmountLarge: slashingUnit * 3n, + slashSelfAllowed: true, + slashDuplicateProposalPenalty: slashingUnit, + // Disable other offense penalties so we only see the equivocation offense. + slashInactivityPenalty: 0n, + slashDataWithholdingPenalty: 0n, + slashBroadcastedInvalidBlockPenalty: 0n, + slashBroadcastedInvalidCheckpointProposalPenalty: 0n, + slashDuplicateAttestationPenalty: 0n, + slashProposeInvalidAttestationsPenalty: 0n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 0n, + slashAttestInvalidCheckpointProposalPenalty: 0n, + slashUnknownPenalty: 0n, }); logger = test.logger; @@ -271,9 +295,26 @@ describe('e2e_epochs/epochs_equivocation', () => { ), ); - // TODO(A-980): assert the equivocating proposer of the first slot is eventually slashed - // for the DUPLICATE_PROPOSAL offense. Slasher is currently disabled in the harness - // (slasherEnabled: false) and enabling it requires plumbing offense submission and - // waiting for the slasher's offense window. + // Every observing validator should have recorded the equivocation offense. A has been stopped + // above and D is a non-validator (no slasher), so we poll only B and C. + logger.warn(`Waiting for DUPLICATE_PROPOSAL offense on every observing node`, { + proposerAttester, + submissionSlot, + }); + const matchesOffense = (o: { offenseType: OffenseType; validator: { toString(): string }; epochOrSlot: bigint }) => + o.offenseType === OffenseType.DUPLICATE_PROPOSAL && + o.validator.toString() === proposerAttester.toString() && + o.epochOrSlot === BigInt(submissionSlot); + await retryUntil( + async () => { + const found = await Promise.all( + [nodeB, nodeC].map(async n => (await n.getSlashOffenses('all')).some(matchesOffense)), + ); + return found.every(Boolean); + }, + `DUPLICATE_PROPOSAL offense on every observing node`, + test.L2_SLOT_DURATION_IN_S * 4, + 0.5, + ); }); }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts index 1f952fd76ef6..431632c757b2 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_invalidate_block.parallel.test.ts @@ -378,12 +378,19 @@ describe('e2e_epochs/epochs_invalidate_block', () => { // Wait for at least one checkpoint to be mined so that any in-progress slot has completed const initialCheckpointNumber = (await nodes[0].getChainTips()).checkpointed.checkpoint.number; await test.waitUntilCheckpointNumber(CheckpointNumber(initialCheckpointNumber + 1), test.L2_SLOT_DURATION_IN_S * 4); + + // Align to the start of an L2 slot before computing the bad slots, so we have a generous + // buffer to push the malicious config to badSlot1's proposer before it snapshots its config + // into a new CheckpointProposalJob. Under proposer pipelining, that job is built during the + // last L1 slot of the previous L2 slot (when getEpochAndSlotInNextL1Slot first returns the + // proposer's target slot), so the practical window is somewhat less than a full L2 slot. + await test.monitor.waitUntilNextL2Slot(); const { l2SlotNumber: currentSlot } = await test.monitor.run(); logger.warn(`First checkpoint mined, current slot is ${currentSlot}`); - // Pick the next two slots after the current one, with a 1-slot gap to account for pipelining - const badSlot1 = SlotNumber.add(currentSlot, 2); - const badSlot2 = SlotNumber.add(currentSlot, 3); + // Pick the next two slots with a 2-slot gap to account for pipelining plus a margin + const badSlot1 = SlotNumber.add(currentSlot, 3); + const badSlot2 = SlotNumber.add(currentSlot, 4); const badSlots = [badSlot1, badSlot2]; const badProposers = await Promise.all(badSlots.map(s => test.epochCache.getProposerAttesterAddressInSlot(s))); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts index a59b47b78071..18af37d8d167 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts @@ -314,7 +314,9 @@ describe('e2e_epochs/epochs_mbps', () => { 0.1, ); - const multiBlockCheckpoint = await assertMultipleBlocksPerSlot(EXPECTED_BLOCKS_PER_CHECKPOINT, logger); + // Mirror the sibling MBPS tests: we may lose one sub-slot to pipelined overhead, so accept >= 2 + // blocks per checkpoint rather than the legacy 3-block expectation. + const multiBlockCheckpoint = await assertMultipleBlocksPerSlot(2, logger); // Verify L2→L1 messages are in the blocks const checkpoints = await archiver.getCheckpoints({ from: CheckpointNumber(1), limit: 50 }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_missed_l1_slot.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_missed_l1_slot.test.ts index 0c32eaab5353..eda99eef06c3 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_missed_l1_slot.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_missed_l1_slot.test.ts @@ -234,9 +234,13 @@ describe('e2e_epochs/epochs_missed_l1_slot', () => { await eth.setIntervalMining(L1_BLOCK_TIME); // Step 5: Wait for the next checkpoint to confirm block production resumed cleanly. + // We allow up to 3 L2 slots because the slot-N+1 propose for this checkpoint is dropped + // pre-send by bundleSimulate (the resumed L1 block lands in slot N, not slot N+1, so + // propose's validateHeader would revert), and the publisher retries one or two slots + // later once L1 timing realigns. const finalCheckpoint = CheckpointNumber(checkpointEvent.checkpointNumber + 1); logger.info(`Waiting for checkpoint ${finalCheckpoint}...`); - await test.waitUntilCheckpointNumber(finalCheckpoint, 60); + await test.waitUntilCheckpointNumber(finalCheckpoint, L2_SLOT_DURATION * 3); await monitor.run(); logger.info(`Checkpoint ${finalCheckpoint} published in slot ${monitor.l2SlotNumber}`); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts index 9ae7af5040f8..eaf403de188c 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts @@ -172,7 +172,8 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { // Tighter happy-path bound: the proof must land BEFORE the boundary slot's pipelined build kicks // off. With pipelining, the boundary slot's build starts at the start of the previous L2 slot // (i.e. boundaryTs - L2_SLOT_DURATION_IN_S). If the proof's L1 block is strictly earlier than - // that, the build at the boundary observes `tips.proven` already advanced and skips the override. + // that, the build at the boundary observes `tips.proven` already advanced so the proven pin is + // defensive only (no prune is due) and the boundary checkpoint publishes on the happy path. const assertProofMinedBeforeBoundaryBuild = async (proofReceipt: { blockNumber: bigint }, boundaryTs: bigint) => { const proofBlock = await test.l1Client.getBlock({ blockNumber: proofReceipt.blockNumber }); expect(proofBlock.timestamp).toBeLessThan(boundaryTs - BigInt(test.L2_SLOT_DURATION_IN_S)); @@ -201,8 +202,8 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { it('proof lands during slot build and checkpoint succeeds at boundary', async () => { // The proof for the unproven epoch lands AFTER the boundary slot's pipelined build starts but - // BEFORE the publisher's preCheck. The proven-override lets the boundary checkpoint build - // before the proof has landed; the preCheck succeeds because the proof arrives in time. + // BEFORE the publisher's preCheck. The proven pin lets the boundary checkpoint build before + // the proof has landed; the preCheck succeeds because the proof arrives in time. await setupTest({ aztecProofSubmissionEpochs: 1 }); const sequencers = nodes.map(node => node.getSequencer()!); @@ -238,17 +239,16 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { expect(boundaryPublished).toBeDefined(); const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); - expect(boundaryPreparing.some(p => p.provenOverride !== undefined)).toBe(true); expect(boundaryPreparing.some(p => p.hadProposedParent)).toBe(true); expect(Number(test.monitor.checkpointNumber)).toBeGreaterThanOrEqual(Number(boundaryPublished!.checkpoint)); logger.warn(`Test passed. Final tip checkpoint=${test.monitor.checkpointNumber}`); }); - it('proof lands well before deadline and checkpoint succeeds without override', async () => { + it('proof lands well before deadline and checkpoint succeeds at boundary', async () => { // Sanity check: the prover runs on its natural schedule, so the proof lands well before the - // boundary epoch. By the time the boundary slot is built `tips.proven` is already advanced, - // `isPruneDueAtSlot` returns false, and the proven-override does not fire. + // boundary epoch. By the time the boundary slot is built `tips.proven` is already advanced + // and the proven pin is defensive only — but the boundary checkpoint must still publish. await setupTest({ aztecProofSubmissionEpochs: 1 }); const sequencers = nodes.map(node => node.getSequencer()!); @@ -272,15 +272,14 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); expect(boundaryPreparing.some(p => p.hadProposedParent)).toBe(true); - expect(boundaryPreparing.every(p => p.provenOverride === undefined)).toBe(true); expect(Number(test.monitor.checkpointNumber)).toBeGreaterThanOrEqual(Number(boundaryPublished!.checkpoint)); }); it('proof never lands so no checkpoint submission is attempted', async () => { - // The boundary slot's build applies the proven-override, but the publisher's preCheck rejects - // the propose tx because the proof never landed. After the prune fires on a later slot, a - // fresh propose advances the chain and a checkpoint is published in the new epoch. + // The boundary slot's build applies the proven pin, but the publisher's preCheck rejects the + // propose tx because the proof never landed. After the prune fires on a later slot, a fresh + // propose advances the chain and a checkpoint is published in the new epoch. await setupTest({ aztecProofSubmissionEpochs: 1 }); const sequencers = nodes.map(node => node.getSequencer()!); @@ -300,7 +299,6 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); expect(boundaryPreparing.some(p => p.hadProposedParent)).toBe(true); - expect(boundaryPreparing.some(p => p.provenOverride !== undefined)).toBe(true); // After the boundary fails, a subsequent slot's propose tx triggers the on-chain prune (since // the proof never landed and the deadline has expired) and resets `tips.pending`. The fresh @@ -314,7 +312,7 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { it('proof lands without a proposed parent and boundary checkpoint succeeds', async () => { // The slot before the boundary is paused so the boundary slot's build does not see a proposed - // parent. The proof still lands well before the deadline, so the proven-override never fires + // parent. The proof still lands well before the deadline, so the proven pin is defensive only // and the boundary checkpoint is published normally. await setupTest({ aztecProofSubmissionEpochs: 1 }); @@ -345,14 +343,13 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); expect(boundaryPreparing.length).toBeGreaterThan(0); expect(boundaryPreparing.every(p => !p.hadProposedParent)).toBe(true); - expect(boundaryPreparing.every(p => p.provenOverride === undefined)).toBe(true); expect(Number(test.monitor.checkpointNumber)).toBeGreaterThanOrEqual(Number(boundaryPublished!.checkpoint)); }); it('proof never lands without a proposed parent so no checkpoint submission is attempted', async () => { - // Same as the no-parent variant above but with the proof never landing. The proven-override - // fires (no parent + prune is due) but the publisher's preCheck rejects the propose, so no + // Same as the no-parent variant above but with the proof never landing. The proven pin fires + // (no parent + prune is due) but the publisher's preCheck rejects the propose, so no // checkpoint is published for the boundary slot. await setupTest({ aztecProofSubmissionEpochs: 1 }); @@ -378,7 +375,6 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => { const boundaryPreparing = events.preparing.filter(p => Number(p.targetSlot) === Number(boundarySlot)); expect(boundaryPreparing.length).toBeGreaterThan(0); expect(boundaryPreparing.every(p => !p.hadProposedParent)).toBe(true); - expect(boundaryPreparing.some(p => p.provenOverride !== undefined)).toBe(true); // See the parent test for the reasoning: a subsequent slot's propose triggers the on-chain // prune in-tx, so the first post-boundary checkpoint lands within a couple of slots. diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts index 0d9b27000373..33743e47394e 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_proof_public_cross_chain.test.ts @@ -98,7 +98,7 @@ describe('e2e_epochs/epochs_proof_public_cross_chain', () => { globalLeafIndex.toBigInt(), ) .send({ from: context.accounts[0], wait: { dontThrowOnRevert: true } }); - expect(failedReceipt.executionResult).toBe(TxExecutionResult.APP_LOGIC_REVERTED); + expect(failedReceipt.executionResult).toBe(TxExecutionResult.REVERTED); logger.info(`Test succeeded`); }); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts index d6d6905b6c61..1f2c8e1d4654 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts @@ -517,6 +517,7 @@ export class EpochsTestContext { 'proposer-rollup-check-failed', 'checkpoint-error', 'checkpoint-publish-failed', + 'header-validation-failed', 'pipelined-checkpoint-discarded', ...additionalFailEventKeys, ]; @@ -548,6 +549,13 @@ export class EpochsTestContext { }); failEventsKeys.forEach(eventName => { sequencer.getSequencer().on(eventName, (args: Parameters[0]) => { + // Skip benign block-build-failed events where the builder rejected the block because it + // could not collect enough valid txs. This is the same "not enough txs" case as + // block-tx-count-check-failed (which is already excluded above), just detected after we + // started processing txs rather than before. + if (eventName === 'block-build-failed' && (args as { reason?: string }).reason === 'Insufficient valid txs') { + return; + } const evt = makeEvent(i, eventName, args); failEvents.push(evt); this.logger.error(`Failed event ${eventName} from sequencer ${sequencerIndex}`, undefined, evt); diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index 4763abf825e0..6f6c33012a27 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -7,6 +7,7 @@ import { EscrowContract } from '@aztec/noir-contracts.js/Escrow'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import type { PublicKeys } from '@aztec/stdlib/keys'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { expectTokenBalance, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -32,7 +33,7 @@ describe('e2e_escrow_contract', () => { wallet, accounts: [owner, recipient], logger, - } = await setup(2)); + } = await setup(2, { ...AUTOMINE_E2E_OPTS })); // Generate private key for escrow contract, register key in PXE, and deploy // Note that we need to register it first if we want to emit an encrypted note for it in the constructor diff --git a/yarn-project/end-to-end/src/e2e_event_logs.test.ts b/yarn-project/end-to-end/src/e2e_event_logs.test.ts index 63f083e07d67..eada81d5429d 100644 --- a/yarn-project/end-to-end/src/e2e_event_logs.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_logs.test.ts @@ -17,9 +17,10 @@ import { import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('Logs', () => { let testLogContract: TestLogContract; @@ -41,7 +42,7 @@ describe('Logs', () => { accounts: [account1Address, account2Address], aztecNode, logger: log, - } = await setup(2)); + } = await setup(2, { ...AUTOMINE_E2E_OPTS })); log.warn(`Setup complete, checking account contracts published`); await ensureAccountContractsPublished(wallet, [account1Address, account2Address]); diff --git a/yarn-project/end-to-end/src/e2e_event_only.test.ts b/yarn-project/end-to-end/src/e2e_event_only.test.ts index d2b036f601a0..dda2710f7d06 100644 --- a/yarn-project/end-to-end/src/e2e_event_only.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_only.test.ts @@ -6,9 +6,10 @@ import { EventOnlyContract, type TestEvent } from '@aztec/noir-test-contracts.js import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; /// Tests that a private event can be obtained for a contract that does not work with notes. describe('EventOnly', () => { @@ -24,7 +25,7 @@ describe('EventOnly', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); await ensureAccountContractsPublished(wallet, [defaultAccountAddress]); ({ contract: eventOnlyContract } = await EventOnlyContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts b/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts index 7f8700cd7d5a..69ca90026ab2 100644 --- a/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts +++ b/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts @@ -1,9 +1,11 @@ import { AztecAddress } from '@aztec/aztec.js/addresses'; -import type { AztecNode } from '@aztec/aztec.js/node'; +import type { CheatCodes } from '@aztec/aztec/testing'; import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import { TX_ERROR_INVALID_EXPIRATION_TIMESTAMP } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -11,7 +13,8 @@ import { proveInteraction } from './test-wallet/utils.js'; describe('e2e_expiration_timestamp', () => { let wallet: TestWallet; let defaultAccountAddress: AztecAddress; - let aztecNode: AztecNode; + let aztecNode: AztecNode & AztecNodeDebug; + let cheatCodes: CheatCodes; let teardown: () => Promise; let contract: TestContract; @@ -23,8 +26,9 @@ describe('e2e_expiration_timestamp', () => { teardown, wallet, aztecNode, + cheatCodes, accounts: [defaultAccountAddress], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); @@ -38,8 +42,10 @@ describe('e2e_expiration_timestamp', () => { if (!header) { throw new Error('Block header not found in the setup of e2e_expiration_timestamp.test.ts'); } - // The timestamp of the next slot. - expirationTimestamp = header.globalVariables.timestamp + aztecSlotDuration; + // Two slots ahead of the latest mined block — gives enough headroom that the expiration + // is safely above the next block's timestamp even if there's a brief delay between + // fetching the header and proving the tx. + expirationTimestamp = header.globalVariables.timestamp + aztecSlotDuration * 2n; }); describe('with no enqueued public calls', () => { @@ -91,7 +97,10 @@ describe('e2e_expiration_timestamp', () => { if (!header) { throw new Error('Block header not found in the setup of e2e_expiration_timestamp.test.ts'); } - // 1n lower than the next slot. + // 1n below the start of the next slot (header.timestamp + slotDuration). Under + // AutomineSequencer the next block is always one slot ahead, so an expiration just + // before that boundary is provable (expiration > anchor block timestamp) but rejected + // at submission because nextSlotTimestamp >= expiration. expirationTimestamp = header.globalVariables.timestamp + aztecSlotDuration - 1n; }); @@ -108,11 +117,7 @@ describe('e2e_expiration_timestamp', () => { }); it('invalidates the transaction', async () => { - await expect( - contract.methods - .set_expiration_timestamp(expirationTimestamp, enqueuePublicCall) - .send({ from: defaultAccountAddress }), - ).rejects.toThrow(TX_ERROR_INVALID_EXPIRATION_TIMESTAMP); + await runInvalidatesTest(enqueuePublicCall); }); }); @@ -129,13 +134,46 @@ describe('e2e_expiration_timestamp', () => { }); it('invalidates the transaction', async () => { - await expect( - contract.methods - .set_expiration_timestamp(expirationTimestamp, enqueuePublicCall) - .send({ from: defaultAccountAddress }), - ).rejects.toThrow(TX_ERROR_INVALID_EXPIRATION_TIMESTAMP); + await runInvalidatesTest(enqueuePublicCall); }); }); + + // Prove a tx with an expiration a few slots above the latest mined block's timestamp (so it passes + // the PXE's prove-time check that requires `expirationTimestamp > anchor block timestamp`), then + // warp L1 time past the expiration. Submitting the proven tx must then be rejected by the node + // because the next slot's timestamp (derived from L1 time) is greater than the tx expiration. + async function runInvalidatesTest(enqueuePublicCall: boolean) { + const header = (await aztecNode.getBlockData('latest'))?.header; + if (!header) { + throw new Error('Block header not found in invalidates-the-transaction setup'); + } + const requestedExpiration = header.globalVariables.timestamp + aztecSlotDuration * 5n; + + const provenTx = await proveInteraction( + wallet, + contract.methods.set_expiration_timestamp(requestedExpiration, enqueuePublicCall), + { from: defaultAccountAddress }, + ); + const provedExpiration = provenTx.data.expirationTimestamp; + expect(provedExpiration).toBeGreaterThan(0n); + + // Warp L1 time past the tx expiration. The node's `isValidTx` uses the next L1 slot timestamp + // (via `epochCache.getEpochAndSlotInNextL1Slot()`), so warping L1 alone is enough — we don't + // mine an L2 block here. Warping multiple slots forward and then mining would cause the + // archiver to predict-reorg prior checkpoints (their L1 publish blocks fall in a stale + // anvil layout after the warp). We use the lower-level `cheatCodes.eth.warp` rather than + // the queue-aware `warpL2TimeAtLeastTo` helper, since the latter also forces an L2 block. + // No mempool poller race here — no txs are pending until `provenTx.send()` below. + // If L1 time has already advanced past the expiration (e.g. due to a prior test's warp), skip + // the warp — the tx is already invalid against the current L1 slot. + const currentL1Timestamp = BigInt(await cheatCodes.eth.lastBlockTimestamp()); + const targetTimestamp = provedExpiration + aztecSlotDuration; + if (targetTimestamp > currentL1Timestamp) { + await cheatCodes.eth.warp(Number(targetTimestamp), { resetBlockInterval: true }); + } + + await expect(provenTx.send()).rejects.toThrow(TX_ERROR_INVALID_EXPIRATION_TIMESTAMP); + } }); describe('when requesting expiration timestamp lower than the one of a mined block', () => { diff --git a/yarn-project/end-to-end/src/e2e_fee_asset_price_oracle.test.ts b/yarn-project/end-to-end/src/e2e_fee_asset_price_oracle.test.ts index b898b1f3c5f0..a59840840152 100644 --- a/yarn-project/end-to-end/src/e2e_fee_asset_price_oracle.test.ts +++ b/yarn-project/end-to-end/src/e2e_fee_asset_price_oracle.test.ts @@ -10,12 +10,12 @@ import { jest } from '@jest/globals'; import { mnemonicToAccount } from 'viem/accounts'; import { foundry } from 'viem/chains'; -import { MNEMONIC } from './fixtures/fixtures.js'; +import { MNEMONIC, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { getLogger, setup, startAnvil } from './fixtures/utils.js'; import { MockStateView, diffInBps } from './shared/mock_state_view.js'; describe('FeeAssetPriceOracle E2E', () => { - jest.setTimeout(300_000); + jest.setTimeout(15 * 60 * 1000); let logger: Logger; let teardown: () => Promise; @@ -54,7 +54,7 @@ describe('FeeAssetPriceOracle E2E', () => { await ethCheatCodes.mine(10); await ethCheatCodes.mineEmptyBlock(); - const context = await setup(0, { l1ChainId: chain.id, minTxsPerBlock: 0 }, {}, chain); + const context = await setup(0, { ...PIPELINING_SETUP_OPTS, l1ChainId: chain.id }, {}, chain); teardown = context.teardown; const l1Client = context.deployL1ContractsValues.l1Client; diff --git a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts index 29fc20ddd03a..b05bf4ce0edf 100644 --- a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts @@ -17,17 +17,19 @@ import { GasSettings } from '@aztec/stdlib/gas'; import { jest } from '@jest/globals'; -import { getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; +import { PIPELINING_SETUP_OPTS, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { FeesTest } from './fees_test.js'; -jest.setTimeout(300_000); +// FeesTest.setup + applyFundAliceWithBananas + applyFPCSetup chains many dependent txs which run at the +// ~24s/tx pipelined cadence, exceeding the default 5 min hook window. +jest.setTimeout(15 * 60 * 1000); describe('e2e_fees account_init', () => { const t = new FeesTest('account_init', 1); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applyFundAliceWithBananas(); await t.applyFPCSetup(); ({ aliceAddress, wallet, bananaCoin, bananaFPC, logger, aztecNode } = t); diff --git a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts index 554bb03f16ea..13ddaadf0980 100644 --- a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts @@ -14,11 +14,17 @@ import { FunctionCall, FunctionType } from '@aztec/stdlib/abi'; import { Gas, GasSettings } from '@aztec/stdlib/gas'; import { ExecutionPayload } from '@aztec/stdlib/tx'; -import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { expectMapping } from '../fixtures/utils.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees failures', () => { + // FeesTest.setup + applyFPCSetup chains many dependent txs which run at the + // ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(900_000); + let wallet: Wallet; let aliceAddress: AztecAddress; let sequencerAddress: AztecAddress; @@ -31,7 +37,10 @@ describe('e2e_fees failures', () => { const t = new FeesTest('failures', 3, { coinbase }); beforeAll(async () => { - await t.setup(); + // Shorter epochs (default 32 → 4) speed the per-test `advanceToNextEpoch + waitForProven` + // cycle: the prover-node submits a proof as soon as the epoch is complete, so ~8x shorter + // epochs ≈ ~8x faster proof cadence per cycle. Setup itself stays slot-bound. + await t.setup({ ...PIPELINING_SETUP_OPTS, aztecProofSubmissionEpochs: 640, aztecEpochDuration: 4 }); await t.applyFPCSetup(); ({ wallet, aliceAddress, sequencerAddress, bananaCoin, bananaFPC, gasSettings } = t); aztecNode = t.aztecNode; @@ -87,6 +96,7 @@ describe('e2e_fees failures', () => { await t.catchUpProvenChain(); const currentSequencerRewards = await t.getCoinbaseSequencerRewards(); + const provenCheckpointBefore = await t.rollupContract.getProvenCheckpointNumber(); const { receipt: txReceipt } = await bananaCoin.methods .transfer_in_public(aliceAddress, sequencerAddress, outrageousPublicAmountAliceDoesNotHave, 0) @@ -98,7 +108,7 @@ describe('e2e_fees failures', () => { wait: { dontThrowOnRevert: true }, }); - expect(txReceipt.executionResult).toBe(TxExecutionResult.APP_LOGIC_REVERTED); + expect(txReceipt.executionResult).toBe(TxExecutionResult.REVERTED); const { sequencerBlockRewards } = await t.getBlockRewards(); @@ -106,13 +116,27 @@ describe('e2e_fees failures', () => { // epoch and thereby pays out fees at the same time (when proven). await t.context.watcher.trigger(); await t.cheatCodes.rollup.advanceToNextEpoch(); - await t.catchUpProvenChain(); + const provenTimeout = + (t.context.config.aztecProofSubmissionEpochs + 1) * + t.context.config.aztecEpochDuration * + t.context.config.aztecSlotDuration; + await waitForProven(aztecNode, txReceipt, { provenTimeout }); + + // Under pipelining, multiple empty checkpoints can land and prove between the snapshot and waitForProven; + // each one contributes a block reward to the coinbase, so multiply by the actual proven-checkpoint delta. + const provenCheckpointAfter = await t.rollupContract.getProvenCheckpointNumber(); + const newlyProvenCheckpoints = BigInt(provenCheckpointAfter - provenCheckpointBefore); const feeAmount = txReceipt.transactionFee!; - const expectedProverFee = await t.getProverFee(txReceipt.blockNumber!); + const expectedProverFee = await t.getCommittedProverFee(txReceipt.blockNumber!); + const expectedBurn = await t.getCommittedBurn(txReceipt.blockNumber!); const newSequencerRewards = await t.getCoinbaseSequencerRewards(); expect(newSequencerRewards).toEqual( - currentSequencerRewards + sequencerBlockRewards + feeAmount - expectedProverFee, + currentSequencerRewards + + newlyProvenCheckpoints * sequencerBlockRewards + + feeAmount - + expectedBurn - + expectedProverFee, ); // and thus we paid the fee @@ -201,7 +225,7 @@ describe('e2e_fees failures', () => { wait: { dontThrowOnRevert: true }, }); - expect(txReceipt.executionResult).toBe(TxExecutionResult.APP_LOGIC_REVERTED); + expect(txReceipt.executionResult).toBe(TxExecutionResult.REVERTED); const feeAmount = txReceipt.transactionFee!; // and thus we paid the fee @@ -298,7 +322,7 @@ describe('e2e_fees failures', () => { }, wait: { dontThrowOnRevert: true }, }); - expect(receipt.executionResult).toEqual(TxExecutionResult.TEARDOWN_REVERTED); + expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); expect(receipt.transactionFee).toBeGreaterThan(0n); await expectMapping( @@ -346,7 +370,7 @@ describe('e2e_fees failures', () => { wait: { dontThrowOnRevert: true }, }); - expect(receipt.executionResult).toBe(TxExecutionResult.BOTH_REVERTED); + expect(receipt.executionResult).toBe(TxExecutionResult.REVERTED); expect(receipt.transactionFee).toBeGreaterThan(0n); await t.context.watcher.trigger(); diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts index c8ba437bcdcf..df16714a7ce1 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts @@ -6,10 +6,17 @@ import type { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice'; import type { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token'; import type { GasSettings } from '@aztec/stdlib/gas'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees Fee Juice payments', () => { + // FeesTest.setup + applyFundAliceWithBananas chains many dependent txs which run at the + // ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(15 * 60 * 1000); + let aliceAddress: AztecAddress; let wallet: TestWallet; let bobAddress: AztecAddress; @@ -20,7 +27,7 @@ describe('e2e_fees Fee Juice payments', () => { const t = new FeesTest('fee_juice', 1); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applyFundAliceWithBananas(); ({ feeJuiceContract, aliceAddress, wallet, bananaCoin, gasSettings } = t); diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts index 2c025c2cb526..1ec24f5563dc 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_settings.test.ts @@ -1,7 +1,7 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import type { AztecNode } from '@aztec/aztec.js/node'; import { CheatCodes } from '@aztec/aztec/testing'; -import type { BlockNumber } from '@aztec/foundation/branded-types'; +import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; import { retryUntil } from '@aztec/foundation/retry'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; @@ -24,7 +24,27 @@ describe('e2e_fees fee settings', () => { let gasSettings: Partial; let testContract: TestContract; let testContractDeployBlock: BlockNumber; - const t = new FeesTest('fee_juice', 1); + + // Run under proposer pipelining. `manaTarget` is set just above the largest setup tx + // (account deploy ~6.5M mana, so manaLimit = 2 * manaTarget = 8M covers it). `walletMinFeePadding: 30` + // matches PR #23150's pipelining-aware default — under pipelining the proposer's fee evolves up to ~20x + // between PXE snapshot and inclusion for setup txs, so the 5x default is no longer sufficient. + // (Test-body txs explicitly call `wallet.setMinFeePadding(...)` so they don't use the wallet default.) + const AZTEC_SLOT_DURATION = 12; + const t = new FeesTest('fee_juice', 1, { + enableProposerPipelining: true, + inboxLag: 2, + minTxsPerBlock: 0, + aztecSlotDuration: AZTEC_SLOT_DURATION, + ethereumSlotDuration: 4, + aztecProofSubmissionEpochs: 640, + walletMinFeePadding: 30, + manaTarget: 4_000_000n, + }); + + // FeesTest.setup chains many dependent txs which run at the pipelined cadence (one per L2 slot); + // the default 300s jest hook timeout is not enough. + jest.setTimeout(600_000); beforeAll(async () => { await t.setup(); @@ -43,21 +63,77 @@ describe('e2e_fees fee settings', () => { }); describe('setting max fee per gas', () => { - const bumpL2Fees = async () => { - const before = await aztecNode.getCurrentMinFees(); - t.logger.info(`Initial L2 min fees are ${inspect(before)}`, { minFees: before.toInspect() }); - await cheatCodes.rollup.bumpProvingCostPerMana(current => (current * 120n) / 100n); + // Drive an organic L2 fee bump via an L1 base-fee spike. On mainnet, L1 base fees fluctuate + // organically with L1 demand and dominate `feePerL2Gas` (the rollup's L1 gas oracle samples + // L1 base fee into `post` at every successful rotation and the L2 manaMinFee is derived from + // it). We simulate that by setting the next L1 block's base fee to a multiple of the current + // one and forcing an oracle rotation via the cheatcode-callable `Rollup.updateL1GasFeeOracle`. + // Unlike `bumpProvingCostPerMana` (the only-owner governance write previously used here), this + // does NOT mutate `FeeStore.config`, so it does not trigger the `Rollup__InvalidManaMinFee` + // recovery race that pipelined proposers hit when governance config mutates between header + // build and L1 submission. + // + // Congestion via heavy L2 txs was considered: each `emit_nullifier_public` is only ~570k mana, + // and at `manaTarget=4M` the sequencer takes ~3 of those per checkpoint (~1.88M mana — well + // below target), so excessMana stays at zero and the congestion-multiplier channel never + // engages. The L1 base-fee channel is both more reliable here and a closer analogue to + // mainnet behaviour (L1 base fee swings happen routinely; sustained L2 congestion is rarer). + // + // `reference` is the snapshot the caller intends to compare against. The retry waits until the + // post-rotation L2 fee is at least 1.3x of `reference` — an earlier version compared `after` + // against an internal `before` captured at function entry and exited as soon as `after > before`, + // but the natural L2 fee fluctuates between L1 blocks (EIP-1559 decay swings the sample), so a + // 1-wei drift above `before` satisfied that condition without the oracle ever rotating. The + // retry returned ~15s in — well before the LIFETIME-LAG=3 slot (36s) oracle deadband opened — + // and the caller's `> reference * 1.1` assertion failed because the returned value was just + // natural noise. Requiring `after >= reference * 13/10` distinguishes a real rotation (≥1.5x + // rise) from ambient noise (≤±10%). + const inflateL2FeesViaL1BaseFee = async (reference: GasFees) => { + const beforeAtCall = await aztecNode.getCurrentMinFees(); + t.logger.info(`Initial L2 min fees are ${inspect(beforeAtCall)} (reference=${inspect(reference)})`, { + minFees: beforeAtCall.toInspect(), + reference: reference.toInspect(), + }); + + const minRiseTarget = (reference.feePerL2Gas * 13n) / 10n; + + // Bump next L1 block base fee above both the current L1 fee and the L1 fee implied by + // the requested L2 fee rise, with a 0.1 gwei absolute floor. The absolute floor + // matters when anvil's natural EIP-1559 decay has driven `currentL1BaseFee` close to zero — + // multiplying tiny numbers stays tiny, so a target below the previous oracle snapshot can + // *decrease* L2 fees. The reference-derived floor matters after an earlier spike has + // already raised the L2 fee baseline: repeating the same absolute L1 base fee can leave + // the derived L2 fee below the required 1.3x rise. The oracle rotation deadband + // (`LIFETIME - LAG = 3` L2 slots between successful rotations, see FeeLib.sol:170) + // silently no-ops `updateL1GasFeeOracle` until the window opens; we retry every second so + // the *first* call after the deadband opens captures our bumped block. + const latestL1Block = await cheatCodes.eth.publicClient.getBlock(); + const currentL1BaseFee = latestL1Block.baseFeePerGas ?? 1_000_000_000n; + const referenceDerivedL1BaseFee = minRiseTarget / 8_000n; + const targetL1BaseFee = [currentL1BaseFee * 2n, 100_000_000n, referenceDerivedL1BaseFee].reduce((a, b) => + a > b ? a : b, + ); + t.logger.info(`Targeting L1 base fee ${targetL1BaseFee} (current ${currentL1BaseFee})`); + return await retryUntil( async () => { + await cheatCodes.eth.setNextBlockBaseFeePerGas(targetL1BaseFee); + await cheatCodes.eth.mine(); + try { + await cheatCodes.rollup.updateL1GasFeeOracle(); + } catch { + // Rotation deadband closed — try again on the next iteration. + } const after = await aztecNode.getCurrentMinFees(); t.logger.info(`L2 min fees are now ${inspect(after)}`, { - minFeesBefore: before.toInspect(), + minFeesBefore: beforeAtCall.toInspect(), minFeesAfter: after.toInspect(), + minRiseTarget: minRiseTarget.toString(), }); - return after.feePerL2Gas > before.feePerL2Gas ? after : undefined; + return after.feePerL2Gas >= minRiseTarget ? after : undefined; }, - 'L2 min fee increase', - 5, + 'L2 min fee organic increase (L1 base fee bump) above reference', + 90, 1, ); }; @@ -93,7 +169,8 @@ describe('e2e_fees fee settings', () => { }; const prepareTxsWithMockedMinFees = async (noPaddingMinFees: GasFees, defaultPaddingMinFees: GasFees) => { - // Mock getPredictedMinFees (used by the wallet) and getCurrentMinFees (used by bumpL2Fees and other callers). + // Mock getPredictedMinFees (used by the wallet) and getCurrentMinFees (used by inflateL2FeesViaCongestion + // and other callers). const getPredictedMinFeesSpy = jest .spyOn(aztecNode, 'getPredictedMinFees') .mockResolvedValueOnce([noPaddingMinFees]) @@ -124,9 +201,14 @@ describe('e2e_fees fee settings', () => { ), ).toBe(true); - // Now bump the L2 fees before we actually send them - const bumpedMinFees = await bumpL2Fees(); + // Now bump the L2 fees organically (L1 base fee spike) before we actually send them. + // Require the bump to be at least 10% — a "any-positive-rise" check is satisfied by 1 wei + // and doesn't prove a meaningful fee shift was handled. `inflateL2FeesViaL1BaseFee` takes + // `stableMinFees` as the reference so its retry waits until the oracle has actually rotated + // to our bumped L1 fee, rather than returning on the first sub-percent natural fluctuation. + const bumpedMinFees = await inflateL2FeesViaL1BaseFee(stableMinFees); expect(stableMinFees.feePerL2Gas).toBeLessThan(bumpedMinFees.feePerL2Gas); + expect(bumpedMinFees.feePerL2Gas).toBeGreaterThan((stableMinFees.feePerL2Gas * 11n) / 10n); expect(stableMinFees.mul(1 + DEFAULT_MIN_FEE_PADDING).feePerL2Gas).toBeGreaterThan(bumpedMinFees.feePerL2Gas); // And check that the no-padding does not get mined, but the default padding is good enough @@ -137,7 +219,11 @@ describe('e2e_fees fee settings', () => { it('reproduces the stale fee snapshot race deterministically', async () => { const lowerMinFees = await getCurrentMinFeesAfterCheckpoint(testContractDeployBlock); - const higherMinFees = lowerMinFees.mul(2); + // `higherMinFees` is the synthetic "stale" snapshot the wallet supposedly took before the + // real L2 fee bumped — it only needs to stay above the realized `bumpedMinFees` so that + // `txWithNoPadding` is still mineable after the bump. Use `4x` for unambiguous headroom + // while keeping the snapshot below the 6x default-padding cap. + const higherMinFees = lowerMinFees.mul(4); const { txWithNoPadding, txWithDefaultPadding } = await prepareTxsWithMockedMinFees(higherMinFees, lowerMinFees); @@ -148,8 +234,9 @@ describe('e2e_fees fee settings', () => { ), ).toBe(true); - const bumpedMinFees = await bumpL2Fees(); + const bumpedMinFees = await inflateL2FeesViaL1BaseFee(lowerMinFees); expect(lowerMinFees.feePerL2Gas).toBeLessThan(bumpedMinFees.feePerL2Gas); + expect(bumpedMinFees.feePerL2Gas).toBeGreaterThan((lowerMinFees.feePerL2Gas * 11n) / 10n); expect(higherMinFees.feePerL2Gas).toBeGreaterThan(bumpedMinFees.feePerL2Gas); expect(lowerMinFees.mul(1 + DEFAULT_MIN_FEE_PADDING).feePerL2Gas).toBeGreaterThan(bumpedMinFees.feePerL2Gas); @@ -158,5 +245,58 @@ describe('e2e_fees fee settings', () => { await expect(txWithNoPadding.send()).resolves.toBeDefined(); await expect(txWithDefaultPadding.send()).resolves.toBeDefined(); }); + + // Regression test for A-1057. Under pipelining, the proposer for slot N starts building the + // checkpoint header (and bakes `manaMinFee` into `gasFees.feePerL2Gas`) during slot N-1. If + // governance executes `setProvingCostPerMana` or `updateManaTarget` between that build and the + // L1 submission, L1 recomputes `manaMinFee` from the post-mutation `FeeStore.config` and the + // submitted header reverts with `Rollup__InvalidManaMinFee`. The chain should eat the + // in-flight checkpoint and the next pipelined proposer should produce a header that validates, + // resuming normal block production. This test exercises that path end-to-end: bump once, then + // verify the chain advances and a fresh tx still mines. + it('recovers after a governance fee-config bump invalidates a pipelined checkpoint', async () => { + // Take a fresh checkpoint baseline so we measure progress strictly post-bump, and capture + // the slot of `checkpointBefore` so we can assert below that at least one L2 slot was + // skipped between the bump and recovery — that's the positive signal that a pipelined + // header was actually dropped, distinguishing the A-1057 recovery path from a chain that + // silently absorbed the governance write without exercising the failure case. + const checkpointBefore = await aztecNode.getCheckpointNumber('checkpointed'); + const slotBefore = (await aztecNode.getCheckpoint(checkpointBefore))!.header.slotNumber; + + t.logger.info(`Bumping provingCostPerMana at checkpointed=${checkpointBefore} (slot ${slotBefore})`); + await cheatCodes.rollup.bumpProvingCostPerMana(current => (current * 120n) / 100n); + + // At most a couple of pipelined headers were built against the pre-bump config; allow up to + // 6 slot windows before insisting the chain has made forward progress past the bump. With + // pipelining + minTxsPerBlock=0 an idle chain still emits empty checkpoints, so the + // `checkpointed` tip must strictly advance. + const RECOVERY_TARGET = CheckpointNumber.add(checkpointBefore, 3); + const RECOVERY_BUDGET_SECONDS = AZTEC_SLOT_DURATION * 6; + await retryUntil( + async () => (await aztecNode.getCheckpointNumber('checkpointed')) >= RECOVERY_TARGET, + `chain advances at least ${RECOVERY_TARGET - checkpointBefore} checkpoints past governance bump`, + RECOVERY_BUDGET_SECONDS, + 1, + ); + + // Healthy pipelining produces one checkpoint per L2 slot, so an advance of 3 checkpoints + // covers exactly 3 slots. If a pipelined header was invalidated and dropped (the A-1057 + // path), the recovery span will cover at least one extra slot. A passing assertion here + // proves the test exercised the invalidation+recovery flow rather than landing the bump + // outside the vulnerable window. + const slotAfter = (await aztecNode.getCheckpoint(RECOVERY_TARGET))!.header.slotNumber; + const slotSpan = slotAfter - slotBefore; + t.logger.info(`Recovery spanned ${slotSpan} slots for ${RECOVERY_TARGET - checkpointBefore} checkpoints`, { + slotBefore, + slotAfter, + checkpointBefore, + recoveryTarget: RECOVERY_TARGET, + }); + expect(slotSpan).toBeGreaterThan(RECOVERY_TARGET - checkpointBefore); + + // Fresh tx prepared against the post-bump fee snapshot still mines under default padding. + const tx = await proveTx(undefined); + await expect(tx.send()).resolves.toBeDefined(); + }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts index 478687371913..7cdd897b450e 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts @@ -84,6 +84,8 @@ export class FeesTest { public getBananaPublicBalanceFn!: BalancesFn; public getBananaPrivateBalanceFn!: BalancesFn; public getProverFee!: (blockNumber: BlockNumber) => Promise; + public getCommittedProverFee!: (blockNumber: BlockNumber) => Promise; + public getCommittedBurn!: (blockNumber: BlockNumber) => Promise; public readonly ALICE_INITIAL_BANANAS = BigInt(1e22); public readonly SUBSCRIPTION_AMOUNT = BigInt(1e19); @@ -102,13 +104,14 @@ export class FeesTest { this.logger = createLogger(`e2e:e2e_fees:${testName}`); } - async setup() { + async setup(opts: Partial = {}) { this.logger.verbose('Setting up fresh context...'); // Token allowlist entries are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha. const tokenAllowList = await getTokenAllowedSetupFunctions(); this.context = await setup(0, { startProverNode: true, ...this.setupOptions, + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, l1ContractsArgs: { ...this.setupOptions }, @@ -302,6 +305,27 @@ export class FeesTest { const mana = block!.header.totalManaUsed.toBigInt(); return mulDiv(mana * proverCost, 10n ** 12n, price); }; + + /** + * Reads the prover fee that the rollup actually committed for the block's checkpoint, which is what + * RewardLib uses to pay prover rewards. Unlike `getProverFee`, this does not re-derive the value + * from current L1 fees or current eth-per-fee-asset price, so it is robust to pipelined fee-asset-price + * drift between propose-time and reward-payout-time. + */ + this.getCommittedProverFee = async (blockNumber: BlockNumber) => { + const block = await this.aztecNode.getBlock(blockNumber); + const feeHeader = await this.rollupContract.getFeeHeader(BigInt(block!.checkpointNumber)); + return feeHeader.manaUsed * feeHeader.proverCost; + }; + + // RewardLib computes sequencerFee = checkpointFee - burn - proverFee where burn = manaUsed * congestionCost. + // The fixture's typical case keeps congestionCost at zero, but reading it explicitly avoids latent bugs + // when test load changes excess mana. + this.getCommittedBurn = async (blockNumber: BlockNumber) => { + const block = await this.aztecNode.getBlock(blockNumber); + const feeHeader = await this.rollupContract.getFeeHeader(BigInt(block!.checkpointNumber)); + return feeHeader.manaUsed * feeHeader.congestionCost; + }; } public async applySponsoredFPCSetup() { diff --git a/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts b/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts index 53fb5bd0498e..5a629951347b 100644 --- a/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts @@ -16,8 +16,10 @@ import { GasSettings, } from '@aztec/stdlib/gas'; +import { jest } from '@jest/globals'; import { inspect } from 'util'; +import { PIPELINING_SETUP_OPTS, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; import { FeesTest } from './fees_test.js'; /** @@ -49,6 +51,10 @@ function waitForSequencerIdle(sequencer: Sequencer, timeout = 30000): Promise { + // FeesTest.setup + applyFPCSetup + applyFundAliceWithBananas chains many dependent txs which run + // at the pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(900_000); + let wallet: Wallet; let aliceAddress: AztecAddress; let bobAddress: AztecAddress; @@ -61,18 +67,21 @@ describe('e2e_fees gas_estimation', () => { const t = new FeesTest('gas_estimation'); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applyFPCSetup(); await t.applyFundAliceWithBananas(); ({ wallet, aliceAddress, bobAddress, bananaCoin, bananaFPC, gasSettings, logger, aztecNode } = t); }); beforeEach(async () => { - // Load the gas fees at the start of each test, use those exactly as the max fees per gas - const gasFees = await aztecNode.getCurrentMinFees(); + // Pad max fees per gas to absorb pipelined fee-asset price evolution between snapshot and + // submission. The assertions below compare `transactionFee` (manaUsed * block.gasFees) against + // `estimatedGas.gasLimits.computeFee(block.gasFees)`, so they only require `gasLimits == manaUsed` + // (guaranteed by `estimatedGasPadding: 0`); they do not require `maxFeesPerGas == block.gasFees`. + const paddedMaxFees = await getPaddedMaxFeesPerGas(aztecNode); gasSettings = GasSettings.from({ ...gasSettings, - maxFeesPerGas: gasFees, + maxFeesPerGas: paddedMaxFees, maxPriorityFeesPerGas: new GasFees(0, 0), }); }, 10000); diff --git a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts index 9563d02815da..15b37f516b5d 100644 --- a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts @@ -7,12 +7,19 @@ import type { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token import { GasSettings } from '@aztec/stdlib/gas'; import { TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE } from '@aztec/stdlib/tx'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { expectMapping } from '../fixtures/utils.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; import { proveInteraction } from '../test-wallet/utils.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees private_payment', () => { + // FeesTest.setup + applyFPCSetup + applyFundAliceWithBananas chains many dependent txs which run at the + // ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(900_000); + let wallet: TestWallet; let aliceAddress: AztecAddress; let bobAddress: AztecAddress; @@ -25,7 +32,10 @@ describe('e2e_fees private_payment', () => { const t = new FeesTest('private_payment'); beforeAll(async () => { - await t.setup(); + // Shorter epochs (default 32 → 4) speed the per-test `advanceToNextEpoch + waitForProven` + // cycle: the prover-node submits a proof as soon as the epoch is complete, so ~8x shorter + // epochs ≈ ~8x faster proof cadence per cycle. Setup itself stays slot-bound. + await t.setup({ ...PIPELINING_SETUP_OPTS, aztecProofSubmissionEpochs: 640, aztecEpochDuration: 4 }); await t.applyFPCSetup(); await t.applyFundAliceWithBananas(); ({ wallet, aliceAddress, bobAddress, sequencerAddress, bananaCoin, bananaFPC, gasSettings, aztecNode } = t); @@ -106,17 +116,28 @@ describe('e2e_fees private_payment', () => { const sequencerRewardsBefore = await t.getCoinbaseSequencerRewards(); const { sequencerBlockRewards } = await t.getBlockRewards(); + const provenCheckpointBefore = await t.rollupContract.getProvenCheckpointNumber(); const receipt = await localTx.send({ timeout: 300, interval: 10 }); await t.cheatCodes.rollup.advanceToNextEpoch(); await waitForProven(aztecNode, receipt, { provenTimeout: 300 }); + // Under pipelining, multiple empty checkpoints can land and prove between the snapshot and waitForProven; + // each one contributes a block reward to the coinbase, so multiply by the actual proven-checkpoint delta. + const provenCheckpointAfter = await t.rollupContract.getProvenCheckpointNumber(); + const newlyProvenCheckpoints = BigInt(provenCheckpointAfter - provenCheckpointBefore); + // @note There is a potential race condition here if other tests send transactions that get into the same // epoch and thereby pays out fees at the same time (when proven). - const expectedProverFee = await t.getProverFee(receipt.blockNumber!); + const expectedProverFee = await t.getCommittedProverFee(receipt.blockNumber!); + const expectedBurn = await t.getCommittedBurn(receipt.blockNumber!); await expect(t.getCoinbaseSequencerRewards()).resolves.toEqual( - sequencerRewardsBefore + sequencerBlockRewards + receipt.transactionFee! - expectedProverFee, + sequencerRewardsBefore + + newlyProvenCheckpoints * sequencerBlockRewards + + receipt.transactionFee! - + expectedBurn - + expectedProverFee, ); const feeAmount = receipt.transactionFee!; diff --git a/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts index b059938777db..df4cc32f479a 100644 --- a/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts @@ -6,10 +6,17 @@ import type { FPCContract } from '@aztec/noir-contracts.js/FPC'; import type { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token'; import { GasSettings } from '@aztec/stdlib/gas'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; import { expectMapping } from '../fixtures/utils.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees public_payment', () => { + // FeesTest.setup + applyFPCSetup + applyFundAliceWithBananas chains many dependent txs which run + // at the ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(15 * 60 * 1000); + let aztecNode: AztecNode; let wallet: Wallet; let aliceAddress: AztecAddress; @@ -22,7 +29,7 @@ describe('e2e_fees public_payment', () => { const t = new FeesTest('public_payment'); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applyFPCSetup(); await t.applyFundAliceWithBananas(); ({ wallet, aliceAddress, bobAddress, sequencerAddress, bananaCoin, bananaFPC, gasSettings, aztecNode } = t); @@ -45,7 +52,7 @@ describe('e2e_fees public_payment', () => { beforeEach(async () => { gasSettings = GasSettings.from({ ...gasSettings, - maxFeesPerGas: await aztecNode.getCurrentMinFees(), + maxFeesPerGas: await getPaddedMaxFeesPerGas(aztecNode), }); [ diff --git a/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts index ec9726d9d129..6e1f89dbff21 100644 --- a/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/sponsored_payments.test.ts @@ -5,10 +5,17 @@ import type { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { GasSettings } from '@aztec/stdlib/gas'; +import { jest } from '@jest/globals'; + +import { PIPELINING_SETUP_OPTS, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js'; import { expectMapping } from '../fixtures/utils.js'; import { FeesTest } from './fees_test.js'; describe('e2e_fees sponsored_public_payment', () => { + // FeesTest.setup + applySponsoredFPCSetup + applyFundAliceWithBananas chains many dependent txs which run + // at the ~24s/tx pipelined cadence, exceeding the default 5 min hook window. + jest.setTimeout(15 * 60 * 1000); + let aztecNode: AztecNode; let aliceAddress: AztecAddress; let bobAddress: AztecAddress; @@ -20,7 +27,7 @@ describe('e2e_fees sponsored_public_payment', () => { const t = new FeesTest('sponsored_payment'); beforeAll(async () => { - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); await t.applySponsoredFPCSetup(); await t.applyFundAliceWithBananas(); ({ aztecNode, aliceAddress, bobAddress, sequencerAddress, sponsoredFPC, bananaCoin, gasSettings } = t); @@ -43,7 +50,7 @@ describe('e2e_fees sponsored_public_payment', () => { beforeEach(async () => { gasSettings = GasSettings.from({ ...gasSettings, - maxFeesPerGas: await aztecNode.getCurrentMinFees(), + maxFeesPerGas: await getPaddedMaxFeesPerGas(aztecNode), }); [[initialAlicePublicBananas, initialBobPublicBananas], [initialAliceGas, initialFPCGas, initialSequencerGas]] = diff --git a/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts b/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts index 06b9e8729eb1..1543890e7c59 100644 --- a/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts +++ b/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts @@ -2,6 +2,7 @@ import { NO_FROM } from '@aztec/aztec.js/account'; import { createLogger } from '@aztec/aztec.js/log'; import { retryUntil } from '@aztec/foundation/retry'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { type EndToEndContext, setup } from './fixtures/utils.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -11,21 +12,11 @@ describe('e2e_genesis_timestamp', () => { const logger = createLogger('e2e:genesis_timestamp'); beforeEach(async () => { - // Skip account deployment and prevent the sequencer from mining empty blocks. - // Configure PXE to sync anchor only to proven blocks so its anchor lags behind proposed blocks - // (tests do not spin up a prover, so nothing will ever be proven and the anchor stays at genesis). - context = await setup( - 0, - { - skipAccountDeployment: true, - minTxsPerBlock: 1, - startProverNode: false, - anvilTestWatcherOpts: { isMarkingAsProven: false }, - }, - { syncChainTip: 'proven' }, - ); - - context.watcher.setIsMarkingAsProven(false); + // Skip account deployment and configure PXE to sync its anchor only to proven blocks so its + // anchor lags behind proposed blocks. Under AUTOMINE_E2E_OPTS the AnvilTestWatcher is disabled + // and the AutomineSequencer never marks blocks as proven on its own, so without a prover node + // the proven tip stays at genesis for the duration of the test. + context = await setup(0, { ...AUTOMINE_E2E_OPTS, skipAccountDeployment: true }, { syncChainTip: 'proven' }); }); afterEach(() => context.teardown()); @@ -56,7 +47,7 @@ describe('e2e_genesis_timestamp', () => { }; it('can include genesis-anchored tx in a block after block 1', async () => { - const { aztecNode, aztecNodeAdmin } = context; + const { aztecNode } = context; // We're at block 0 -- no blocks have been mined yet. expect(await aztecNode.getBlockNumber()).toBe(0); @@ -64,21 +55,19 @@ describe('e2e_genesis_timestamp', () => { // Step 1: Prove the account deploy tx while PXE is still anchored to genesis (block 0). const provenTx = await proveTxAnchoredToGenesis(); - // Step 2: Mine an empty block to advance past genesis. - await aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); + // Step 2: Mine an empty block to advance past genesis. Under AUTOMINE_E2E_OPTS the sequencer + // only mines on tx submission or explicit `mineBlock()`, so we drive it directly here. + await aztecNode.mineBlock(); await awaitBlockCheckpointed(); - // Step 3: Prevent further empty blocks so the next block only mines when our tx arrives. - await aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); - - // Step 4: Send the genesis-anchored proven tx. It should land in a block after block 1. + // Step 3: Send the genesis-anchored proven tx. It should land in a block after block 1. const receipt = await provenTx.send(); logger.info(`Tx mined in block ${receipt.blockNumber}`); // The tx landed after block 1, proving that genesis-anchored transactions // are valid beyond the first block when the genesis has a non-zero timestamp. expect(receipt.blockNumber).toBeGreaterThan(1); - }, 120_000); + }, 300_000); // Regression for an issue where PXE failed to prove txs while anchored to block zero // if there were new blocks mined that modified the public data tree. @@ -113,5 +102,5 @@ describe('e2e_genesis_timestamp', () => { logger.info(`Second genesis-anchored deploy mined in block ${secondReceipt.blockNumber}`); expect(secondReceipt.blockNumber).toBeDefined(); expect(secondReceipt.blockNumber!).toBeGreaterThan(firstReceipt.blockNumber!); - }, 180_000); + }, 400_000); }); diff --git a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts index bc3567df0c7b..e89ac4a3c436 100644 --- a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts +++ b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts @@ -20,6 +20,7 @@ import { MerkleTreeId } from '@aztec/stdlib/trees'; import { jest } from '@jest/globals'; import { simulateThroughAuthwitProxy } from './fixtures/authwit_proxy.js'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -56,7 +57,7 @@ describe('Kernelless simulation', () => { wallet, accounts: [adminAddress, liquidityProviderAddress, swapperAddress], logger, - } = await setup(3)); + } = await setup(3, { ...AUTOMINE_E2E_OPTS })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_keys.test.ts b/yarn-project/end-to-end/src/e2e_keys.test.ts index c566e6ef525f..0890b1c721ed 100644 --- a/yarn-project/end-to-end/src/e2e_keys.test.ts +++ b/yarn-project/end-to-end/src/e2e_keys.test.ts @@ -14,13 +14,15 @@ import { deriveMasterNullifierHidingKey, deriveMasterOutgoingViewingSecretKey, derivePublicKeyFromSecretKey, + hashPublicKey, } from '@aztec/stdlib/keys'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('Keys', () => { jest.setTimeout(TIMEOUT); @@ -42,7 +44,7 @@ describe('Keys', () => { wallet, accounts: [defaultAccountAddress], initialFundedAccounts, - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); @@ -114,9 +116,13 @@ describe('Keys', () => { describe('ovsk_app', () => { it('gets ovsk_app', async () => { - // Derive the ovpk_m_hash from the account secret + // Derive the ovpk_m_hash from the account secret. Use `hashPublicKey` (the + // domain-separated hash over `[x, y]`) rather than `Point.hash()` (which hashes + // `[x, y, is_infinite]` with no separator) -- the PXE's `KeyStore.addAccount` stores + // master-key hashes computed via `hashPublicKey`, so this is what the + // `aztec_utl_getKeyValidationRequest` lookup compares against. const ovskM = deriveMasterOutgoingViewingSecretKey(secret); - const ovpkMHash = await (await derivePublicKeyFromSecretKey(ovskM)).hash(); + const ovpkMHash = await hashPublicKey(await derivePublicKeyFromSecretKey(ovskM)); // Compute the expected ovsk_app const expectedOvskApp = await computeAppSecretKey(ovskM, testContract.address, 'ov'); diff --git a/yarn-project/end-to-end/src/e2e_l1_publisher/e2e_l1_publisher.test.ts b/yarn-project/end-to-end/src/e2e_l1_publisher/e2e_l1_publisher.test.ts index 70503811095d..d9e62b7a5deb 100644 --- a/yarn-project/end-to-end/src/e2e_l1_publisher/e2e_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/e2e_l1_publisher/e2e_l1_publisher.test.ts @@ -175,6 +175,23 @@ describe('L1Publisher integration', () => { } }; + // Warp the chain forward so that the current L2 slot matches `targetSlot`, and resync the + // dateProvider so `epochCache.getSlotNow()` (used by the bundle-level eth_simulateV1 and the + // L1 tx mine timestamp) also lands on `targetSlot`. The rollup contract rejects header slots + // that don't match block.timestamp, so the test must align both the chain and the date + // provider to the header's slot before calling sendRequests. + const progressToSlot = async (targetSlot: bigint) => { + const currentSlot = await rollup.getSlotNumber(); + if (BigInt(targetSlot) > BigInt(currentSlot)) { + await progressTimeBySlot(Number(BigInt(targetSlot) - BigInt(currentSlot))); + } + // Always resync the dateProvider so `epochCache.getSlotNow()` matches L1's block.timestamp. + // `sendRequests` derives its bundle-simulate timestamp from `getCurrentL2Slot()`, so if the + // dateProvider lags the chain the simulate runs at a stale slot and the rollup rejects the + // header with `HeaderLib__InvalidSlotNumber`. + await ethCheatCodes.syncDateProvider(); + }; + let port = 8545; // We increase the port for each test to avoid anvil conflicts const setup = async (deployL1ContractsArgs: Partial = {}) => { ({ rpcUrl, anvil } = await startAnvil({ port: port++ })); @@ -532,6 +549,8 @@ describe('L1Publisher integration', () => { CommitteeAttestationsAndSigners.empty(getSignatureContext()), Signature.empty(), ); + // Align chain time so the bundle simulate and the L1 send both run at the header's slot. + await progressToSlot(BigInt(checkpoint.header.slotNumber)); await publisher.sendRequests(); const logs = await l1Client.getLogs({ @@ -643,6 +662,8 @@ describe('L1Publisher integration', () => { new CommitteeAttestationsAndSigners(attestations, getSignatureContext()), signature, ); + // Align chain time so the bundle simulate and the L1 send both run at the header's slot. + await progressToSlot(BigInt(checkpoint.header.slotNumber)); const result = await publisher.sendRequests(); expect(result!.successfulActions).toEqual(['propose']); expect(result!.failedActions).toEqual([]); @@ -680,9 +701,23 @@ describe('L1Publisher integration', () => { expect(canPropose?.slot).toEqual(block.header.getSlot()); await publisher.validateBlockHeader(checkpoint.header); - await expect( - publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, Signature.empty()), - ).rejects.toThrow(/ValidatorSelection__InvalidCommitteeCommitment/); + // Enqueue no longer simulates — the bundle simulate at send time drops the failing propose + // and sendRequests returns undefined (no surviving actions). The drop is reported via a + // warn log carrying the on-chain revert reason (raw hex selector since the propose request + // has no ABI attached). + const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, Signature.empty()); + await progressToSlot(BigInt(checkpoint.header.slotNumber)); + const result = await publisher.sendRequests(); + expect(result).toBeUndefined(); + // 0xca8d5954 == ValidatorSelection__InvalidCommitteeCommitment selector + expect(loggerWarnSpy).toHaveBeenCalledWith( + 'Bundle entry dropped: action reverted in sim', + expect.objectContaining({ + action: 'propose', + returnData: expect.stringMatching(/^0xca8d5954/), + }), + ); }); it('rejects flipped proposer signature', async () => { @@ -701,13 +736,25 @@ describe('L1Publisher integration', () => { validators.find(v => v.address.equals(proposer!))!, ); - await expect( - publisher.enqueueProposeCheckpoint( - checkpoint, - attestationsAndSigners, - flipSignature(attestationsAndSignersSignature), - ), - ).rejects.toThrow(/ECDSAInvalidSignatureS/); + // Enqueue no longer simulates — the bundle simulate at send time drops the failing propose + // and sendRequests returns undefined. + const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); + await publisher.enqueueProposeCheckpoint( + checkpoint, + attestationsAndSigners, + flipSignature(attestationsAndSignersSignature), + ); + await progressToSlot(BigInt(checkpoint.header.slotNumber)); + const result = await publisher.sendRequests(); + expect(result).toBeUndefined(); + // 0xd78bce0c == ECDSAInvalidSignatureS selector + expect(loggerWarnSpy).toHaveBeenCalledWith( + 'Bundle entry dropped: action reverted in sim', + expect.objectContaining({ + action: 'propose', + returnData: expect.stringMatching(/^0xd78bce0c/), + }), + ); }); it('rejects signature with invalid recovery value', async () => { @@ -732,8 +779,20 @@ describe('L1Publisher integration', () => { const wrongV = attestationsAndSignersSignature.v - 27; const wrongSig = new Signature(attestationsAndSignersSignature.r, attestationsAndSignersSignature.s, wrongV); - await expect(publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, wrongSig)).rejects.toThrow( - /ECDSAInvalidSignature/, + // Enqueue no longer simulates — the bundle simulate at send time drops the failing propose + // and sendRequests returns undefined. + const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, wrongSig); + await progressToSlot(BigInt(checkpoint.header.slotNumber)); + const result = await publisher.sendRequests(); + expect(result).toBeUndefined(); + // 0xf645eedf == ECDSAInvalidSignature selector + expect(loggerWarnSpy).toHaveBeenCalledWith( + 'Bundle entry dropped: action reverted in sim', + expect.objectContaining({ + action: 'propose', + returnData: expect.stringMatching(/^0xf645eedf/), + }), ); }); @@ -810,9 +869,7 @@ describe('L1Publisher integration', () => { // Invalidate and propose logger.warn('Enqueuing requests to invalidate and propose the checkpoint'); publisher.enqueueInvalidateCheckpoint(invalidateRequest); - await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, { - simulationOverridesPlan: invalidationSimulationOverridesPlan, - }); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, attestationsAndSignersSignature); const result = await publisher.sendRequests(); expect(result!.successfulActions).toEqual(['invalidate-by-insufficient-attestations', 'propose']); expect(result!.failedActions).toEqual([]); @@ -853,20 +910,24 @@ describe('L1Publisher integration', () => { const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(1n)); const { checkpoint } = await buildSingleCheckpoint({ l1ToL2Messages }); - // Expect the simulation to fail - const loggerErrorSpy = jest.spyOn((publisher as any).log, 'error'); - await expect( - publisher.enqueueProposeCheckpoint( - checkpoint, - CommitteeAttestationsAndSigners.empty(getSignatureContext()), - Signature.empty(), - ), - ).rejects.toThrow(/Rollup__InvalidInHash/); - expect(loggerErrorSpy).toHaveBeenNthCalledWith( - 2, - expect.stringMatching('Rollup__InvalidInHash'), - expect.anything(), - expect.objectContaining({ checkpointNumber: 1 }), + // Enqueue no longer simulates per action — the bundle simulate at send time drops the + // failing propose and reports the on-chain revert reason via a warn log. + const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); + await publisher.enqueueProposeCheckpoint( + checkpoint, + CommitteeAttestationsAndSigners.empty(getSignatureContext()), + Signature.empty(), + ); + await progressToSlot(BigInt(checkpoint.header.slotNumber)); + const result = await publisher.sendRequests(); + expect(result).toBeUndefined(); + // 0xcd6f4233 == Rollup__InvalidInHash selector + expect(loggerWarnSpy).toHaveBeenCalledWith( + 'Bundle entry dropped: action reverted in sim', + expect.objectContaining({ + action: 'propose', + returnData: expect.stringMatching(/^0xcd6f4233/), + }), ); }); }); @@ -1022,10 +1083,21 @@ describe('L1Publisher integration', () => { expect(BigInt(block2.slot)).toEqual(initialL2Slot + 1n); sendRequestsResult = undefined; await enqueueProposeL2Checkpoint(checkpoint2); + // Align chain time so the bundle simulate at send time runs at slot N+1 (matches the + // checkpoint2 header). Without this the bundle simulate (which uses getSlotNow()) sees + // the wrong slot and drops the propose entry. + await progressToSlot(BigInt(checkpoint2.header.slotNumber)); await sendRequests(); - // Wait for the new proposal to be sent to the pool - await retryUntil(() => ethCheatCodes.getTxPoolStatus().then(s => s.queued + s.pending > 1), 'tx queued', 20, 0.1); + // Wait for the new proposal to be sent to the pool. The progressToSlot warp above may have + // already mined the cancellation from the first proposal, so the pool may hold either the + // cancel-and-new-propose (two entries) or just the new propose (one entry). + await retryUntil( + () => ethCheatCodes.getTxPoolStatus().then(s => s.queued + s.pending >= 1), + 'tx queued', + 20, + 0.1, + ); // Mine a block await ethCheatCodes.mine(); diff --git a/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts b/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts index 7d955369ffdb..57c1ab475d64 100644 --- a/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts +++ b/yarn-project/end-to-end/src/e2e_l1_with_wall_time.test.ts @@ -2,12 +2,12 @@ import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses'; import { Fr } from '@aztec/aztec.js/fields'; import type { Logger } from '@aztec/aztec.js/log'; import { type AztecNode, waitForTx } from '@aztec/aztec.js/node'; -import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config'; import { SecretValue } from '@aztec/foundation/config'; import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from './fixtures/utils.js'; import { submitTxsTo } from './shared/submit-transactions.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -35,21 +35,21 @@ describe('e2e_l1_with_wall_time', () => { bn254SecretKey: new SecretValue(Fr.random().toBigInt()), }, ]; - const { ethereumSlotDuration } = getL1ContractsConfigEnvVars(); + // Don't pass ethereumSlotDuration explicitly — the env default is 12s, which would clash with + // the fixture's pipelining override (aztecSlotDuration=12, ethereumSlotDuration=4). With both at + // 12s the pipelined timing model can't fit propose+attest+publish in one Aztec slot and txs + // get dropped from the mempool. Let the fixture pick its pipelining-aware defaults. ({ teardown, logger, wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup(1, { - initialValidators, - ethereumSlotDuration, - })); + } = await setup(1, { ...PIPELINING_SETUP_OPTS, initialValidators })); }); - afterEach(() => teardown()); + afterEach(() => teardown?.()); it('should produce blocks with a bunch of transactions', async () => { for (let i = 0; i < numberOfBlocks; i++) { diff --git a/yarn-project/end-to-end/src/e2e_large_public_event.test.ts b/yarn-project/end-to-end/src/e2e_large_public_event.test.ts index 81997ac4cf6b..34db71a443f1 100644 --- a/yarn-project/end-to-end/src/e2e_large_public_event.test.ts +++ b/yarn-project/end-to-end/src/e2e_large_public_event.test.ts @@ -8,9 +8,10 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; /// Tests that events exceeding MAX_EVENT_SERIALIZED_LEN can be emitted publicly. describe('LargePublicEvent', () => { @@ -28,7 +29,7 @@ describe('LargePublicEvent', () => { wallet, aztecNode, accounts: [accountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await LargePublicEventContract.deploy(wallet).send({ from: accountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 22c1964fe1f8..5756862b31e3 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -4,6 +4,7 @@ import type { Logger } from '@aztec/aztec.js/log'; import { CheatCodes } from '@aztec/aztec/testing'; import { RollupContract } from '@aztec/ethereum/contracts'; import type { DeployAztecL1ContractsReturnType } from '@aztec/ethereum/deploy-aztec-l1-contracts'; +import { BlockNumber } from '@aztec/foundation/branded-types'; import type { TestDateProvider } from '@aztec/foundation/timer'; import { LendingContract } from '@aztec/noir-contracts.js/Lending'; import { PriceFeedContract } from '@aztec/noir-contracts.js/PriceFeed'; @@ -11,6 +12,8 @@ import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { afterAll, jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; +import type { EndToEndContext } from './fixtures/setup.js'; import { mintTokensToPrivate } from './fixtures/token_utils.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; import { LendingAccount, LendingSimulator, TokenSimulator } from './simulators/index.js'; @@ -21,6 +24,7 @@ describe('e2e_lending_contract', () => { let wallet: TestWallet; let defaultAccountAddress: AztecAddress; let deployL1ContractsValues: DeployAztecL1ContractsReturnType; + let aztecNode: EndToEndContext['aztecNode']; let logger: Logger; let teardown: () => Promise; @@ -77,7 +81,7 @@ describe('e2e_lending_contract', () => { }; beforeAll(async () => { - const ctx = await setup(1); + const ctx = await setup(1, { ...AUTOMINE_E2E_OPTS }); ({ teardown, logger, @@ -85,6 +89,7 @@ describe('e2e_lending_contract', () => { wallet, deployL1ContractsValues, dateProvider, + aztecNode, accounts: [defaultAccountAddress], } = ctx); ({ lendingContract, priceFeedContract, collateralAsset, stableCoin } = await deployContracts()); @@ -123,6 +128,11 @@ describe('e2e_lending_contract', () => { await lendingSim.check(); }); + const observeBlock = async (blockNumber: number | undefined) => { + const block = await aztecNode.getBlock(BlockNumber(blockNumber!)); + lendingSim.observeBlockTimestamp(Number(block!.header.globalVariables.timestamp)); + }; + it('Mint assets for later usage', async () => { await priceFeedContract.methods.set_price(0n, 2n * 10n ** 9n).send({ from: defaultAccountAddress }); @@ -145,11 +155,15 @@ describe('e2e_lending_contract', () => { }); it('Initialize the contract', async () => { - await lendingSim.prepare(); logger.info('Initializing contract'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .init(priceFeedContract.address, 8000, collateralAsset.address, stableCoin.address) .send({ from: defaultAccountAddress }); + // init writes accumulator = BASE and last_updated_ts = block.timestamp. + // Match that exactly without advancing the accumulator from the previous (zero) time. + const block = await aztecNode.getBlock(BlockNumber(receipt.blockNumber!)); + lendingSim.prepare(); + lendingSim.time = Number(block!.header.globalVariables.timestamp); }); describe('Deposits', () => { @@ -165,8 +179,7 @@ describe('e2e_lending_contract', () => { authwitNonce, ), }); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.depositPrivate(lendingAccount.address, await lendingAccount.key(), activationThreshold); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private deposit of funds into own account. // This should: @@ -174,7 +187,7 @@ describe('e2e_lending_contract', () => { // - increase last updated timestamp. // - increase the private collateral. logger.info('Depositing 🥸 : 💰 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .deposit_private( lendingAccount.address, activationThreshold, @@ -184,6 +197,8 @@ describe('e2e_lending_contract', () => { collateralAsset.address, ) .send({ from: defaultAccountAddress, authWitnesses: [transferToPublicAuthwit] }); + await observeBlock(receipt.blockNumber); + lendingSim.depositPrivate(lendingAccount.address, await lendingAccount.key(), activationThreshold); }); it('Depositing 🥸 on behalf of recipient: 💰 -> 🏦', async () => { @@ -199,15 +214,14 @@ describe('e2e_lending_contract', () => { ), }); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.depositPrivate(lendingAccount.address, lendingAccount.address.toField(), activationThreshold); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private deposit of funds into another account, in this case, a public account. // This should: // - increase the interest accumulator // - increase last updated timestamp. // - increase the public collateral. logger.info('Depositing 🥸 on behalf of recipient: 💰 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .deposit_private( lendingAccount.address, activationThreshold, @@ -217,6 +231,8 @@ describe('e2e_lending_contract', () => { collateralAsset.address, ) .send({ from: defaultAccountAddress, authWitnesses: [transferToPublicAuthwit] }); + await observeBlock(receipt.blockNumber); + lendingSim.depositPrivate(lendingAccount.address, lendingAccount.address.toField(), activationThreshold); }); it('Depositing: 💰 -> 🏦', async () => { @@ -240,8 +256,7 @@ describe('e2e_lending_contract', () => { ); await validateAction.send(); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.depositPublic(lendingAccount.address, lendingAccount.address.toField(), activationThreshold); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a public deposit of funds into self. // This should: @@ -250,17 +265,18 @@ describe('e2e_lending_contract', () => { // - increase the public collateral. logger.info('Depositing: 💰 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .deposit_public(activationThreshold, authwitNonce, lendingAccount.address, collateralAsset.address) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.depositPublic(lendingAccount.address, lendingAccount.address.toField(), activationThreshold); }); }); describe('Borrow', () => { it('Borrow 🥸 : 🏦 -> 🍌', async () => { const borrowAmount = 69n; - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.borrow(await lendingAccount.key(), lendingAccount.address, borrowAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private borrow using the private account // This should: @@ -269,15 +285,16 @@ describe('e2e_lending_contract', () => { // - increase the private debt. logger.info('Borrow 🥸 : 🏦 -> 🍌'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .borrow_private(lendingAccount.secret, lendingAccount.address, borrowAmount) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.borrow(await lendingAccount.key(), lendingAccount.address, borrowAmount); }); it('Borrow: 🏦 -> 🍌', async () => { const borrowAmount = 69n; - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.borrow(lendingAccount.address.toField(), lendingAccount.address, borrowAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a public borrow using the private account // This should: @@ -286,9 +303,11 @@ describe('e2e_lending_contract', () => { // - increase the public debt. logger.info('Borrow: 🏦 -> 🍌'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .borrow_public(lendingAccount.address, borrowAmount) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.borrow(lendingAccount.address.toField(), lendingAccount.address, borrowAmount); }); }); @@ -301,8 +320,7 @@ describe('e2e_lending_contract', () => { action: stableCoin.methods.burn_private(lendingAccount.address, repayAmount, authwitNonce), }); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.repayPrivate(lendingAccount.address, await lendingAccount.key(), repayAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private repay of the debt in the private account // This should: @@ -311,9 +329,11 @@ describe('e2e_lending_contract', () => { // - decrease the private debt. logger.info('Repay 🥸 : 🍌 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .repay_private(lendingAccount.address, repayAmount, authwitNonce, lendingAccount.secret, 0n, stableCoin.address) .send({ from: defaultAccountAddress, authWitnesses: [burnPrivateAuthwit] }); + await observeBlock(receipt.blockNumber); + lendingSim.repayPrivate(lendingAccount.address, await lendingAccount.key(), repayAmount); }); it('Repay 🥸 on behalf of public: 🍌 -> 🏦', async () => { @@ -324,8 +344,7 @@ describe('e2e_lending_contract', () => { action: stableCoin.methods.burn_private(lendingAccount.address, repayAmount, authwitNonce), }); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.repayPrivate(lendingAccount.address, lendingAccount.address.toField(), repayAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a private repay of the debt in the public account // This should: @@ -334,7 +353,7 @@ describe('e2e_lending_contract', () => { // - decrease the public debt. logger.info('Repay 🥸 on behalf of public: 🍌 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .repay_private( lendingAccount.address, repayAmount, @@ -344,6 +363,8 @@ describe('e2e_lending_contract', () => { stableCoin.address, ) .send({ from: defaultAccountAddress, authWitnesses: [burnPrivateAuthwit] }); + await observeBlock(receipt.blockNumber); + lendingSim.repayPrivate(lendingAccount.address, lendingAccount.address.toField(), repayAmount); }); it('Repay: 🍌 -> 🏦', async () => { @@ -361,8 +382,7 @@ describe('e2e_lending_contract', () => { ); await validateAction.send(); - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.repayPublic(lendingAccount.address, lendingAccount.address.toField(), repayAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Make a public repay of the debt in the public account // This should: @@ -371,17 +391,18 @@ describe('e2e_lending_contract', () => { // - decrease the public debt. logger.info('Repay: 🍌 -> 🏦'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .repay_public(repayAmount, authwitNonce, lendingAccount.address, stableCoin.address) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.repayPublic(lendingAccount.address, lendingAccount.address.toField(), repayAmount); }); }); describe('Withdraw', () => { it('Withdraw: 🏦 -> 💰', async () => { const withdrawAmount = 42n; - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.withdraw(lendingAccount.address.toField(), lendingAccount.address, withdrawAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Withdraw funds from the public account // This should: @@ -390,15 +411,16 @@ describe('e2e_lending_contract', () => { // - decrease the public collateral. logger.info('Withdraw: 🏦 -> 💰'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .withdraw_public(lendingAccount.address, withdrawAmount) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.withdraw(lendingAccount.address.toField(), lendingAccount.address, withdrawAmount); }); it('Withdraw 🥸 : 🏦 -> 💰', async () => { const withdrawAmount = 42n; - await lendingSim.progressSlots(SLOT_JUMP, dateProvider); - lendingSim.withdraw(await lendingAccount.key(), lendingAccount.address, withdrawAmount); + await lendingSim.progressSlots(SLOT_JUMP, dateProvider, aztecNode); // Withdraw funds from the private account // This should: @@ -407,9 +429,11 @@ describe('e2e_lending_contract', () => { // - decrease the private collateral. logger.info('Withdraw 🥸 : 🏦 -> 💰'); - await lendingContract.methods + const { receipt } = await lendingContract.methods .withdraw_private(lendingAccount.secret, lendingAccount.address, withdrawAmount) .send({ from: defaultAccountAddress }); + await observeBlock(receipt.blockNumber); + lendingSim.withdraw(await lendingAccount.key(), lendingAccount.address, withdrawAmount); }); describe('failure cases', () => { diff --git a/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts b/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts index f46ff8a3a165..5e39ebd6949f 100644 --- a/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts +++ b/yarn-project/end-to-end/src/e2e_mempool_limit.test.ts @@ -4,6 +4,7 @@ import { TxStatus } from '@aztec/aztec.js/tx'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { type EndToEndContext, setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -24,6 +25,7 @@ describe('e2e_mempool_limit', () => { wallet, accounts: [defaultAccountAddress], } = await setup(1, { + ...AUTOMINE_E2E_OPTS, proverTestVerificationDelayMs: undefined, })); @@ -46,8 +48,9 @@ describe('e2e_mempool_limit', () => { { from: defaultAccountAddress }, ); - // set a min tx greater than the mempool so that the sequencer doesn't all of a sudden build a block - await aztecNodeAdmin!.setConfig({ maxPendingTxCount: 2, minTxsPerBlock: 4 }); + // Cap the mempool, then pause the sequencer so pending txs accumulate without being mined. + await aztecNodeAdmin!.setConfig({ maxPendingTxCount: 2 }); + await aztecNodeAdmin!.pauseSequencer(); const tx2 = await proveInteraction( wallet, diff --git a/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts b/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts index beb0ae32e5b2..727bd706883a 100644 --- a/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts +++ b/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts @@ -20,7 +20,7 @@ import 'jest-extended'; import { type Hex, type TransactionSerialized, recoverTransactionAddress } from 'viem'; import { mnemonicToAccount } from 'viem/accounts'; -import { MNEMONIC } from './fixtures/fixtures.js'; +import { MNEMONIC, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -75,15 +75,23 @@ describe('e2e_multi_eoa', () => { accounts: [defaultAccountAddress], sequencer: sequencerClient, ethCheatCodes, - } = await setup(2, { - archiverPollingIntervalMS: 200, - sequencerPollingIntervalMS: 200, - worldStateBlockCheckIntervalMS: 200, - blockCheckIntervalMS: 200, - sequencerPublisherPrivateKeys: sequencerKeysAndAddresses.map(k => k.key), - l1PublisherKey: allKeysAndAddresses[0].key, - maxSpeedUpAttempts: 0, // Disable speed ups, so that cancellation txs never make it through - })); + } = await setup( + 2, + { + ...PIPELINING_SETUP_OPTS, + archiverPollingIntervalMS: 200, + sequencerPollingIntervalMS: 200, + worldStateBlockCheckIntervalMS: 200, + blockCheckIntervalMS: 200, + sequencerPublisherPrivateKeys: sequencerKeysAndAddresses.map(k => k.key), + l1PublisherKey: allKeysAndAddresses[0].key, + maxSpeedUpAttempts: 0, // Disable speed ups, so that cancellation txs never make it through + }, + // Anchor PXE to the checkpointed chain so that a missed-publish from publisher #1 in slot N + // (which invalidates the pipelined proposed chain) doesn't drop the wallet's in-flight tx + // when slot N+1's job rotates to publisher #2. + { syncChainTip: 'checkpointed' }, + )); sequencer = sequencerClient! as TestSequencerClient; publisherManager = sequencer.publisherManager; aztecNodeAdmin = maybeAztecNodeAdmin!; @@ -204,9 +212,10 @@ describe('e2e_multi_eoa', () => { return sequencerKeysAndAddresses.findIndex(ka => ka.address === address); }; - // We should be at L2 block 2 + // We should be at L2 block 2 or later (empty pipelined checkpoints can land between setup + // and the first assertion, so accept >=2 rather than pinning to exactly 2). const blockNumber = await aztecNode.getBlockNumber(); - expect(blockNumber).toBe(2); + expect(blockNumber).toBeGreaterThanOrEqual(2); // This means that 2 of our accounts have been used to send blocks to L1. // We want to figure out which ones these are, they will be in the 'MINED' state within the sequencer diff --git a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts index e41b54eba63f..5b662846434c 100644 --- a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts +++ b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts @@ -1,12 +1,12 @@ +import type { InitialAccountData } from '@aztec/accounts/testing'; import type { Archiver } from '@aztec/archiver'; import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; +import { NO_FROM } from '@aztec/aztec.js/account'; import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses'; -import { waitForProven } from '@aztec/aztec.js/contracts'; import { ContractDeployer } from '@aztec/aztec.js/deployment'; import { Fr } from '@aztec/aztec.js/fields'; import type { Logger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; -import type { Wallet } from '@aztec/aztec.js/wallet'; import type { CheatCodes } from '@aztec/aztec/testing'; import { createExtendedL1Client } from '@aztec/ethereum/client'; import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config'; @@ -19,22 +19,30 @@ import { retryUntil } from '@aztec/foundation/retry'; import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi'; import { StatefulTestContractArtifact } from '@aztec/noir-test-contracts.js/StatefulTest'; import { CheckpointAttestation, ConsensusPayload } from '@aztec/stdlib/p2p'; +import { TxStatus } from '@aztec/stdlib/tx'; +import { jest } from '@jest/globals'; import { getContract } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../fixtures/utils.js'; +import type { TestWallet } from '../test-wallet/test_wallet.js'; const VALIDATOR_COUNT = 5; const COMMITTEE_SIZE = VALIDATOR_COUNT - 2; const PUBLISHER_COUNT = 2; describe('e2e_multi_validator_node', () => { + // Each test starts its own multi-validator network and waits for checkpointed L2 transactions. + jest.setTimeout(15 * 60 * 1000); + let initialValidatorPrivateKeys: `0x${string}`[]; let validatorAddresses: `0x${string}`[]; let teardown: () => Promise; - let wallet: Wallet; + let wallet: TestWallet; let ownerAddress: AztecAddress; + let initialFundedAccounts: InitialAccountData[]; let aztecNode: AztecNode; let config: AztecNodeConfig; let logger: Logger; @@ -67,26 +75,22 @@ describe('e2e_multi_validator_node', () => { }); const { aztecSlotDuration: _aztecSlotDuration } = getL1ContractsConfigEnvVars(); - ({ - teardown, - logger, - wallet, - accounts: [ownerAddress], - aztecNode, - config, - deployL1ContractsValues, - cheatCodes, - } = await setup(1, { - initialValidators, - aztecTargetCommitteeSize: COMMITTEE_SIZE, - sequencerPublisherPrivateKeys: publisherPrivateKeys.map(k => new SecretValue(k)), - minTxsPerBlock: 1, - archiverPollingIntervalMS: 200, - sequencerPollingIntervalMS: 200, - worldStateBlockCheckIntervalMS: 200, - blockCheckIntervalMS: 200, - startProverNode: true, - })); + ({ teardown, logger, wallet, initialFundedAccounts, aztecNode, config, deployL1ContractsValues, cheatCodes } = + await setup( + 1, + { + ...PIPELINING_SETUP_OPTS, + initialValidators, + aztecTargetCommitteeSize: COMMITTEE_SIZE, + sequencerPublisherPrivateKeys: publisherPrivateKeys.map(k => new SecretValue(k)), + archiverPollingIntervalMS: 200, + sequencerPollingIntervalMS: 200, + worldStateBlockCheckIntervalMS: 200, + blockCheckIntervalMS: 200, + skipAccountDeployment: true, + }, + { syncChainTip: 'checkpointed' }, + )); rollup = new RollupContract( deployL1ContractsValues.l1Client, @@ -109,16 +113,34 @@ describe('e2e_multi_validator_node', () => { await teardown(); }); + const deployOwnerAccount = async () => { + const accountData = initialFundedAccounts[0]; + const accountManager = await wallet.createSchnorrAccount( + accountData.secret, + accountData.salt, + accountData.signingKey, + ); + const deployMethod = await accountManager.getDeployMethod(); + await deployMethod.send({ + from: NO_FROM, + wait: { + waitForStatus: TxStatus.CHECKPOINTED, + timeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, + }, + }); + await wallet.sync(); + ownerAddress = accountManager.address; + }; + it('should build blocks & attest with multiple validator keys', async () => { + await deployOwnerAccount(); + const deployer = new ContractDeployer(artifact, wallet); logger.info(`Deploying contract from ${ownerAddress}`); const { receipt: tx } = await deployer .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) .send({ from: ownerAddress }); - await waitForProven(aztecNode, tx, { - provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, - }); expect(tx.blockNumber).toBeDefined(); const dataStore = (aztecNode as AztecNodeService).getBlockSource() as Archiver; @@ -166,6 +188,7 @@ describe('e2e_multi_validator_node', () => { BigInt(await cheatCodes.rollup.getEpoch()) + BigInt(config.lagInEpochsForValidatorSet + 1), ), ); + await deployOwnerAccount(); // check that the committee is undefined const committee = await rollup.getCurrentEpochCommittee(); @@ -177,9 +200,6 @@ describe('e2e_multi_validator_node', () => { const { receipt: tx } = await deployer .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) .send({ from: ownerAddress }); - await waitForProven(aztecNode, tx, { - provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, - }); expect(tx.blockNumber).toBeDefined(); const dataStore = (aztecNode as AztecNodeService).getBlockSource() as Archiver; @@ -196,8 +216,13 @@ describe('e2e_multi_validator_node', () => { expect(attestations.length).toBeGreaterThanOrEqual((COMMITTEE_SIZE * 2) / 3 + 1); - const signers = attestations.map(att => att.getSender()!.toString()); + const signers = attestations.map(att => att.getSender()!.toString().toLowerCase()); + const validatorAddressesLower = validatorAddresses.map(a => a.toLowerCase()); + expect(signers.every(s => validatorAddressesLower.includes(s))).toBe(true); - expect(signers).toEqual(expect.arrayContaining(validatorAddresses.slice(0, COMMITTEE_SIZE))); + const committeeAtCheckpoint = await rollup.getCommitteeAt(publishedCheckpoint.checkpoint.header.timestamp); + expect(committeeAtCheckpoint?.length).toBe(COMMITTEE_SIZE); + const committeeAtCheckpointLower = committeeAtCheckpoint!.map(a => a.toString().toLowerCase()); + expect(signers.every(s => committeeAtCheckpointLower.includes(s))).toBe(true); }); }); diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index dd61f6328e4f..b8948b1c5f46 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -5,6 +5,7 @@ import type { Logger } from '@aztec/aztec.js/log'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, expectTokenBalance } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; @@ -38,7 +39,10 @@ describe('e2e_multiple_accounts_1_enc_key', () => { }), ); - ({ teardown, logger, wallet, accounts } = await setup(numAccounts, { initialFundedAccounts })); + ({ teardown, logger, wallet, accounts } = await setup(numAccounts, { + ...AUTOMINE_E2E_OPTS, + initialFundedAccounts, + })); logger.info('Account contracts deployed'); ({ contract: token } = await deployToken(wallet, accounts[0], initialBalance, logger)); @@ -96,5 +100,5 @@ describe('e2e_multiple_accounts_1_enc_key', () => { expectedBalancesAfterTransfer2[2] + transferAmount3, ]; await transfer(1, 2, transferAmount3, expectedBalancesAfterTransfer3); - }, 120_000); + }, 300_000); }); diff --git a/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts b/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts index 316fd63a5bba..f14dacab2420 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_blobs.test.ts @@ -13,6 +13,7 @@ import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import { L2Block } from '@aztec/stdlib/block'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_multiple_blobs', () => { @@ -34,7 +35,7 @@ describe('e2e_multiple_blobs', () => { aztecNodeAdmin: maybeAztecNodeAdmin, wallet, teardown, - } = await setup(1)); + } = await setup(1, { ...PIPELINING_SETUP_OPTS })); aztecNodeAdmin = maybeAztecNodeAdmin!; ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts index aab6d6fb59c4..abee1fff29d8 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts @@ -1,6 +1,7 @@ import { ImportTestContract } from '@aztec/noir-test-contracts.js/ImportTest'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -10,7 +11,7 @@ describe('e2e_nested_contract manual', () => { let { wallet, logger, defaultAccountAddress } = t; beforeAll(async () => { - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ wallet, logger, defaultAccountAddress } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts index d702434c7f10..46ce281b4387 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts @@ -1,3 +1,4 @@ +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -5,7 +6,7 @@ describe('e2e_nested_contract manual', () => { let { parentContract, childContract, defaultAccountAddress } = t; beforeAll(async () => { - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); await t.applyManual(); ({ parentContract, childContract, defaultAccountAddress } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts index 0e19664a5662..3996780c3895 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts @@ -3,6 +3,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { ParentContract } from '@aztec/noir-test-contracts.js/Parent'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual_enqueue', () => { @@ -14,7 +15,7 @@ describe('e2e_nested_contract manual_enqueue', () => { beforeAll(async () => { // We don't deploy contracts in beforeAll because every test requires a fresh setup - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ wallet, defaultAccountAddress, aztecNode } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts index a699ea8f1764..53ddaa2c06f6 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts @@ -4,6 +4,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; import { serializeToBuffer } from '@aztec/foundation/serialize'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -14,7 +15,7 @@ describe('e2e_nested_contract manual', () => { aztecNode.getPublicStorageAt('latest', child.address, new Fr(1)); beforeAll(async () => { - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); await t.applyManual(); ({ wallet, parentContract, childContract, defaultAccountAddress, aztecNode } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts index 769db81c1ba0..d68dcc808b16 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts @@ -7,6 +7,7 @@ import { ParentContract } from '@aztec/noir-test-contracts.js/Parent'; import { type EndToEndContext, + type SetupOptions, deployAccounts, publicDeployAccounts, setup, @@ -50,9 +51,10 @@ export class NestedContractTest { await publicDeployAccounts(this.wallet, [this.defaultAccountAddress]); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up fresh subsystems'); this.context = await setup(0, { + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, }); diff --git a/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts b/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts index 1d7ba02c11c8..d06520a1ae6b 100644 --- a/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts @@ -5,9 +5,10 @@ import type { UtilityCallAuthorizationRequest } from '@aztec/pxe/server'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; // Verifies nested utility calls via pow_utility(x, n) = x^n (recursive utility→utility), // calling it from a private function via pow_private, and the default hook behavior. @@ -25,7 +26,7 @@ describe('Nested utility calls', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: contractA } = await NestedUtilityContract.deploy(wallet).send({ from: defaultAccountAddress })); ({ contract: contractB } = await NestedUtilityContract.deploy(wallet).send({ from: defaultAccountAddress })); }); @@ -77,6 +78,7 @@ describe('authorizeUtilityCall hook', () => { wallet, accounts: [defaultAccountAddress], } = await setup(1, { + ...AUTOMINE_E2E_OPTS, pxeCreationOptions: { hooks: { authorizeUtilityCall: (req: UtilityCallAuthorizationRequest) => { diff --git a/yarn-project/end-to-end/src/e2e_nft.test.ts b/yarn-project/end-to-end/src/e2e_nft.test.ts index 7e7f8da1079a..61ed76a31318 100644 --- a/yarn-project/end-to-end/src/e2e_nft.test.ts +++ b/yarn-project/end-to-end/src/e2e_nft.test.ts @@ -5,9 +5,10 @@ import { NFTContract } from '@aztec/noir-contracts.js/NFT'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; // This is a very simple test checking only the happy path. More complete tests of the NFT are implemented with TXE. // This test is only kept around to check that public data writes are squashed as expected. @@ -30,7 +31,7 @@ describe('NFT', () => { beforeAll(async () => { let accounts: AztecAddress[]; - ({ teardown, wallet, accounts } = await setup(4)); + ({ teardown, wallet, accounts } = await setup(4, { ...AUTOMINE_E2E_OPTS })); [adminAddress, minterAddress, user1Address, user2Address] = accounts; ({ contract: nftContract } = await NFTContract.deploy(wallet, adminAddress, 'FROG', 'FRG').send({ diff --git a/yarn-project/end-to-end/src/e2e_note_getter.test.ts b/yarn-project/end-to-end/src/e2e_note_getter.test.ts index a72a1fc61393..db658379f610 100644 --- a/yarn-project/end-to-end/src/e2e_note_getter.test.ts +++ b/yarn-project/end-to-end/src/e2e_note_getter.test.ts @@ -4,6 +4,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { NoteGetterContract } from '@aztec/noir-test-contracts.js/NoteGetter'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; interface NoirBoundedVec { @@ -25,7 +26,7 @@ describe('e2e_note_getter', () => { teardown, wallet, accounts: [defaultAddress], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); }); afterAll(() => teardown()); diff --git a/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts b/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts index fe8db573792b..a44255b1e78e 100644 --- a/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts +++ b/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts @@ -5,11 +5,12 @@ import { OffchainEffectContract, type TestEvent } from '@aztec/noir-test-contrac import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('e2e_offchain_effect', () => { let contract1: OffchainEffectContract; @@ -25,7 +26,7 @@ describe('e2e_offchain_effect', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: contract1 } = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress })); ({ contract: contract2 } = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts b/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts index 52087116c316..c1158d3a998a 100644 --- a/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts +++ b/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts @@ -1,26 +1,24 @@ /* eslint-disable camelcase */ +import type { AztecNodeService } from '@aztec/aztec-node'; import { AztecAddress } from '@aztec/aztec.js/addresses'; import { extractOffchainOutput } from '@aztec/aztec.js/contracts'; import type { AztecNode } from '@aztec/aztec.js/node'; -import type { CheatCodes } from '@aztec/aztec/testing'; -import type { BlockNumber } from '@aztec/foundation/branded-types'; import { retryUntil } from '@aztec/foundation/retry'; import { OffchainPaymentContract } from '@aztec/noir-test-contracts.js/OffchainPayment'; -import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { getLogger, setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('e2e_offchain_payment', () => { let contract: OffchainPaymentContract; let aztecNode: AztecNode; - let aztecNodeAdmin: AztecNodeAdmin; - let cheatCodes: CheatCodes; + let aztecNodeService: AztecNodeService; let wallet: TestWallet; let accounts: AztecAddress[]; let teardown: () => Promise; @@ -29,7 +27,8 @@ describe('e2e_offchain_payment', () => { jest.setTimeout(TIMEOUT); beforeAll(async () => { - ({ teardown, wallet, accounts, aztecNode, aztecNodeAdmin, cheatCodes } = await setup(2, { + ({ teardown, wallet, accounts, aztecNode, aztecNodeService } = await setup(2, { + ...AUTOMINE_E2E_OPTS, anvilSlotsInAnEpoch: 32, })); }); @@ -43,43 +42,14 @@ describe('e2e_offchain_payment', () => { async function forceEmptyBlock() { const blockBefore = await aztecNode.getBlockNumber(); logger.info(`Forcing empty block. Current L2 block: ${blockBefore}`); - await aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); - await retryUntil( - async () => { - const current = await aztecNode.getBlockNumber(); - logger.info(`Waiting for new L2 block. Current: ${current}`); - return current > blockBefore; - }, - 'new L2 block', - 30, - 1, - ); - await aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); + await aztecNodeService.mineBlock(); + logger.info(`Empty block mined. New L2 block: ${await aztecNode.getBlockNumber()}`); } - async function forceReorg(block: BlockNumber) { - // Pause sync as soon as the block is checkpointed so finalization doesn't race ahead - // of the rollback target. Without this, the archiver can finalize past the target block - // between the retryUntil returning and pauseSync executing. - await retryUntil( - async () => { - const tips = await aztecNode.getChainTips(); - if (tips.checkpointed.block.number >= block) { - await aztecNodeAdmin.pauseSync(); - return true; - } - return false; - }, - 'checkpointed block', - 30, - 1, - ); - - await cheatCodes.eth.reorg(1); - // Pass resumeSync=false so the archiver doesn't immediately re-download the same checkpoint - // (which would re-sync the PXE before callers can inspect the rolled-back state). - await aztecNodeAdmin.rollbackTo(Number(block) - 1, /* force */ false, /* resumeSync */ false); - expect(await aztecNode.getBlockNumber()).toBe(Number(block) - 1); + async function forceReorg(checkpointBeforeTx: number) { + const automine = aztecNodeService.getAutomineSequencer()!; + await automine.revertToCheckpoint(checkpointBeforeTx); + logger.info(`Reverted to checkpoint ${checkpointBeforeTx}`); } it('processes an offchain-delivered private payment via QR-style handoff', async () => { @@ -142,6 +112,9 @@ describe('e2e_offchain_payment', () => { await contract.methods.mint(mintAmount, alice).send({ from: alice }); + // Capture the checkpoint tip before the transfer tx so we know where to revert to. + const checkpointBeforeTx = (await aztecNode.getChainTips()).checkpointed.checkpoint.number; + const provenTx = await proveInteraction(wallet, contract.methods.transfer_offchain(paymentAmount, bob), { from: alice, }); @@ -149,7 +122,6 @@ describe('e2e_offchain_payment', () => { const receipt = await provenTx.send(); expect(receipt.blockNumber).toBeDefined(); - const txBlockNumber = receipt.blockNumber!; const txHash = provenTx.getTxHash(); const txEffectBeforeReorg = await aztecNode.getTxEffect(txHash); @@ -196,7 +168,7 @@ describe('e2e_offchain_payment', () => { const { result: aliceBalance } = await contract.methods.get_balance(alice).simulate({ from: alice }); expect(aliceBalance).toBe(mintAmount - paymentAmount); - await forceReorg(txBlockNumber); + await forceReorg(checkpointBeforeTx); // Verify that the payment TX is no longer present after the reorg const txEffectAfterRollback = await aztecNode.getTxEffect(txHash); @@ -210,13 +182,23 @@ describe('e2e_offchain_payment', () => { const { result: aliceAfterRollback } = await contract.methods.get_balance(alice).simulate({ from: alice }); expect(aliceAfterRollback).toBe(mintAmount); - // Resume sync so the archiver can re-download the checkpoints and the sequencer can produce blocks. - await aztecNodeAdmin.resumeSync(); - - // The archiver re-syncs the same checkpoints from L1 after the reorg, so the tx gets re-mined automatically. - // Force an empty block so the PXE re-syncs and reprocesses the offchain-delivered notes. + // The p2p tx pool marks rolled-back txs as pending again, so the AutomineSequencer + // re-mines the transfer tx automatically. Force a block build so the PXE re-syncs + // and reprocesses the offchain-delivered notes. await forceEmptyBlock(); + // Wait for the PXE to process the re-mined block and update its note view. + // The PXE syncs asynchronously from the archiver, so the balance may lag briefly. + await retryUntil( + async () => { + const { result } = await contract.methods.get_balance(bob).simulate({ from: bob }); + return result === paymentAmount; + }, + 'Bob balance restored after re-mine', + 30, + 0.1, + ); + // Check that the message was reprocessed and Bob has his payment again. // Notice what we want to test here is that the offchain effects don't need to be re-enqueued // for the system to re-process it. diff --git a/yarn-project/end-to-end/src/e2e_option_params.test.ts b/yarn-project/end-to-end/src/e2e_option_params.test.ts index 99c373092636..1ece966388d9 100644 --- a/yarn-project/end-to-end/src/e2e_option_params.test.ts +++ b/yarn-project/end-to-end/src/e2e_option_params.test.ts @@ -5,9 +5,10 @@ import { OptionParamContract } from '@aztec/noir-test-contracts.js/OptionParam'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; const U64_MAX = 2n ** 64n - 1n; const I64_MIN = -(2n ** 63n); @@ -32,7 +33,7 @@ describe('Option params', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); contract = (await OptionParamContract.deploy(wallet).send({ from: defaultAccountAddress })).contract; }); diff --git a/yarn-project/end-to-end/src/e2e_orderbook.test.ts b/yarn-project/end-to-end/src/e2e_orderbook.test.ts index 4f566ca466c8..6a959b27de86 100644 --- a/yarn-project/end-to-end/src/e2e_orderbook.test.ts +++ b/yarn-project/end-to-end/src/e2e_orderbook.test.ts @@ -9,11 +9,12 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; // Unhappy path tests are written only in Noir. // @@ -47,7 +48,7 @@ describe('Orderbook', () => { accounts: [adminAddress, makerAddress, takerAddress], aztecNode, logger, - } = await setup(3)); + } = await setup(3, { ...AUTOMINE_E2E_OPTS })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_ordering.test.ts b/yarn-project/end-to-end/src/e2e_ordering.test.ts index 56f8df05058a..c7f15e8cc36b 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -11,6 +11,7 @@ import { computeCalldataHash } from '@aztec/stdlib/hash'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -26,8 +27,7 @@ describe('e2e_ordering', () => { let defaultAccountAddress: AztecAddress; let teardown: () => Promise; - const expectLogsFromLastBlockToBe = async (logMessages: bigint[]) => { - const fromBlock = await aztecNode.getBlockNumber(); + const expectLogsFromBlockToBe = async (logMessages: bigint[], fromBlock: number) => { const logFilter = { fromBlock, toBlock: fromBlock + 1, @@ -45,7 +45,7 @@ describe('e2e_ordering', () => { wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); }, TIMEOUT); afterEach(() => teardown()); @@ -77,7 +77,7 @@ describe('e2e_ordering', () => { const action = parent.methods[method](child.address, pubSetValueSelector); const tx = await proveInteraction(wallet, action, { from: defaultAccountAddress }); - await tx.send(); + const receipt = await tx.send(); // There are two enqueued calls const enqueuedPublicCalls = tx.getPublicCallRequestsWithCalldata(); @@ -94,7 +94,7 @@ describe('e2e_ordering', () => { expect(enqueuedPublicCalls.map(c => c.args[0].toBigInt())).toEqual(expectedOrder); // Logs are emitted in the expected order - await expectLogsFromLastBlockToBe(expectedOrder); + await expectLogsFromBlockToBe(expectedOrder, receipt.blockNumber!); // The final value of the child is the last one set const value = await aztecNode.getPublicStorageAt('latest', child.address, new Fr(1)); @@ -133,10 +133,10 @@ describe('e2e_ordering', () => { ] as const)('orders public logs in %s', async method => { const expectedOrder = expectedOrders[method]; - await child.methods[method]().send({ from: defaultAccountAddress }); + const { receipt } = await child.methods[method]().send({ from: defaultAccountAddress }); // Logs are emitted in the expected order - await expectLogsFromLastBlockToBe(expectedOrder); + await expectLogsFromBlockToBe(expectedOrder, receipt.blockNumber!); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts index e386f7ae17c3..5c4c468fbcdf 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts @@ -10,7 +10,7 @@ import { RollupCheatCodes } from '@aztec/aztec/testing'; import { FeeAssetHandlerContract, RegistryContract, RollupContract } from '@aztec/ethereum/contracts'; import { deployRollupForUpgrade } from '@aztec/ethereum/deploy-aztec-l1-contracts'; import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract'; -import { type L1ContractAddresses, pickL1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses'; +import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses'; import { L1TxUtils, createL1TxUtils } from '@aztec/ethereum/l1-tx-utils'; import type { ExtendedViemWalletClient } from '@aztec/ethereum/types'; import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; @@ -555,8 +555,7 @@ describe('e2e_p2p_add_rollup', () => { dataDirectory: DATA_DIR_NEW, rollupVersion: Number(newVersion), governanceProposerPayload: EthAddress.ZERO, - ...t.ctx.deployL1ContractsValues.l1ContractAddresses, - ...addresses, + l1Contracts: { ...t.ctx.deployL1ContractsValues.l1ContractAddresses, ...addresses }, }; await setupSharedBlobStorage(newConfig); @@ -611,7 +610,7 @@ describe('e2e_p2p_add_rollup', () => { nodes[0], initialTestAccounts[0], t.ctx.deployL1ContractsValues.l1Client, - pickL1ContractAddresses(newConfig), + newConfig.l1Contracts, BigInt(newConfig.rollupVersion), newConfig.l1RpcUrls, ); diff --git a/yarn-project/end-to-end/src/e2e_p2p/broadcasted_invalid_block_proposal_slash.test.ts b/yarn-project/end-to-end/src/e2e_p2p/broadcasted_invalid_block_proposal_slash.test.ts index 02dd223b3b86..2915bca2ce86 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/broadcasted_invalid_block_proposal_slash.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/broadcasted_invalid_block_proposal_slash.test.ts @@ -1,4 +1,5 @@ import type { AztecNodeService } from '@aztec/aztec-node'; +import type { TestAztecNodeService } from '@aztec/aztec-node/test'; import { EthAddress } from '@aztec/aztec.js/addresses'; import { EpochNumber } from '@aztec/foundation/branded-types'; import { promiseWithResolvers } from '@aztec/foundation/promise'; @@ -13,7 +14,7 @@ import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; import { createNodes } from '../fixtures/setup_p2p_test.js'; import { P2PNetworkTest } from './p2p_network.js'; -import { awaitCommitteeExists, awaitOffenseDetected } from './shared.js'; +import { advanceToEpochBeforeProposer, awaitCommitteeExists, awaitOffenseDetected } from './shared.js'; const TEST_TIMEOUT = 1_000_000; @@ -114,10 +115,14 @@ describe('e2e_p2p_broadcasted_invalid_block_proposal_slash', () => { t.logger.warn('Creating nodes'); - // Create first node that broadcasts invalid proposals + // Create first node that broadcasts invalid proposals. Keep its sequencer stopped until + // every node has joined the P2P mesh; otherwise (under proposer pipelining) the invalid + // proposer can publish its sole bad block to slot N before the honest nodes are connected, + // and they will reject the proposal as "invalid slot number" instead of slashing it. const invalidProposerConfig = { ...t.ctx.aztecNodeConfig, broadcastInvalidBlockProposal: true, + dontStartSequencer: true, }; const invalidProposerNodes = await createNodes( invalidProposerConfig, @@ -134,9 +139,9 @@ describe('e2e_p2p_broadcasted_invalid_block_proposal_slash', () => { const invalidProposerAddress = invalidProposerNodes[0].getSequencer()!.validatorAddresses![0]; t.logger.warn(`Invalid proposer address: ${invalidProposerAddress.toString()}`); - // Create remaining honest nodes + // Create remaining honest nodes, also with sequencers stopped, for the same reason. const honestNodes = await createNodes( - t.ctx.aztecNodeConfig, + { ...t.ctx.aztecNodeConfig, dontStartSequencer: true }, t.ctx.dateProvider, t.bootstrapNodeEnr, NUM_VALIDATORS - 1, @@ -149,42 +154,39 @@ describe('e2e_p2p_broadcasted_invalid_block_proposal_slash', () => { nodes = [...invalidProposerNodes, ...honestNodes]; - // Wait for P2P mesh to be fully formed before proceeding + // Wait for P2P mesh to be fully formed before starting sequencers await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); await awaitCommitteeExists({ rollup, logger: t.logger }); - const startSlot = await rollup.getSlotNumber(); - const proposerEarliestSlot = startSlot + 1; - - // Wait until the bad proposer has had a slot - await retryUntil( - async () => { - const currentSlot = await rollup.getSlotNumber(); - return currentSlot >= proposerEarliestSlot; - }, - 'Wait for next slot...', - TEST_TIMEOUT / 1000, - ETHEREUM_SLOT_DURATION, - ); - - await retryUntil( - async () => { - const currentProposer = await rollup.getCurrentProposer(); - if (!currentProposer.equals(invalidProposerAddress)) { - t.logger.info( - `Current proposer: ${currentProposer}, waiting for malicious proposer ${invalidProposerAddress} to get a slot...`, - ); - return false; - } - return true; - }, - 'Wait for malicious proposer slot...', - TEST_TIMEOUT / 1000, - ETHEREUM_SLOT_DURATION, - ); + // Find an epoch where the invalid proposer is selected, stopping one epoch before so + // we have time to start sequencers before the target epoch arrives. + const epochCache = (honestNodes[0] as TestAztecNodeService).epochCache; + const { targetEpoch } = await advanceToEpochBeforeProposer({ + epochCache, + cheatCodes: t.ctx.cheatCodes.rollup, + targetProposer: invalidProposerAddress, + logger: t.logger, + }); - const offenses = await awaitOffenseDetected({ + // Start all sequencers while still one epoch before the target + t.logger.warn('Starting all sequencers'); + await Promise.all(nodes.map(n => n.getSequencer()!.start())); + + // Now warp to one slot before the target epoch — sequencers are already running. + // Under proposer pipelining, the invalid proposer begins building for the first slot + // of the target epoch one slot earlier; warping to the start of the epoch would force + // the bad proposal to serialize past the slot boundary, after which honest receivers + // reject it as late. + t.logger.warn(`Advancing to one slot before target epoch ${targetEpoch}`); + await t.ctx.cheatCodes.rollup.advanceToEpoch(targetEpoch, { offset: -AZTEC_SLOT_DURATION }); + + // Wait for offense to be detected. Under proposer pipelining, the invalid block proposal is + // broadcast at the slot boundary while a receiver's wall clock may have already advanced + // past the build slot — when that happens, the honest node rejects the gossip with "invalid + // slot number" before slashing logic runs. Collect offenses from every node so we catch + // whichever node managed to process the proposal while still in the build slot. + await awaitOffenseDetected({ epochDuration: t.ctx.aztecNodeConfig.aztecEpochDuration, logger: t.logger, nodeAdmin: nodes[1], // Use honest node to check for offenses @@ -193,10 +195,23 @@ describe('e2e_p2p_broadcasted_invalid_block_proposal_slash', () => { timeoutSeconds: AZTEC_SLOT_DURATION * 16, }); - // Check offense is correct - expect(offenses).toHaveLength(1); - expect(offenses[0].offenseType).toEqual(OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL); - expect(offenses[0].validator.toString()).toEqual(t.validators[0].attester.toString()); + const invalidBlockOffenses = await retryUntil( + async () => { + const allOffenses = (await Promise.all(nodes.map(n => n.getSlashOffenses('all')))).flat(); + const filtered = allOffenses.filter(o => o.offenseType === OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL); + if (filtered.length > 0) { + return filtered; + } + }, + 'broadcasted invalid block proposal offense', + AZTEC_SLOT_DURATION * 4, + ); + + t.logger.warn(`Collected broadcasted invalid block proposal offenses`, { invalidBlockOffenses }); + expect(invalidBlockOffenses.length).toBeGreaterThan(0); + for (const offense of invalidBlockOffenses) { + expect(offense.validator.toString()).toEqual(invalidProposerAddress.toString()); + } // Check slash is recorded on chain const slashPromise = promiseWithResolvers<{ amount: bigint; attester: EthAddress }>(); diff --git a/yarn-project/end-to-end/src/e2e_p2p/data_withholding_slash.test.ts b/yarn-project/end-to-end/src/e2e_p2p/data_withholding_slash.test.ts index 808b7222a1d0..bf3bb2aac524 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/data_withholding_slash.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/data_withholding_slash.test.ts @@ -1,8 +1,9 @@ import type { AztecNodeService } from '@aztec/aztec-node'; import { waitForTx } from '@aztec/aztec.js/node'; -import { EpochNumber } from '@aztec/foundation/branded-types'; -import { times } from '@aztec/foundation/collection'; +import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types'; +import { retryUntil } from '@aztec/foundation/retry'; import { OffenseType } from '@aztec/slasher'; +import { Tx, TxHash } from '@aztec/stdlib/tx'; import { jest } from '@jest/globals'; import fs from 'fs'; @@ -11,43 +12,56 @@ import path from 'path'; import { shouldCollectMetrics } from '../fixtures/fixtures.js'; import { createNodes } from '../fixtures/setup_p2p_test.js'; -import { P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js'; -import { awaitCommitteeExists, awaitCommitteeKicked, awaitOffenseDetected, submitTransactions } from './shared.js'; +import { P2PNetworkTest } from './p2p_network.js'; +import { awaitCommitteeExists, awaitOffenseDetected, submitTransactions } from './shared.js'; -jest.setTimeout(1000000); +const TEST_TIMEOUT = 1_000_000; +jest.setTimeout(TEST_TIMEOUT); -// Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds +// Don't set this above 9 — each node uses a distinct anvil seed for its publisher account. const NUM_VALIDATORS = 4; const BOOT_NODE_UDP_PORT = 4500; const COMMITTEE_SIZE = NUM_VALIDATORS; - -// This test needs longer slot window to ensure that the client has enough time to submit their txs, -// and have the nodes get recreated, prior to the reorg. -const AZTEC_SLOT_DURATION = process.env.AZTEC_SLOT_DURATION ? parseInt(process.env.AZTEC_SLOT_DURATION) : 32; +const ETHEREUM_SLOT_DURATION = 4; +const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 3; +const TOLERANCE_SLOTS = 3; const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'data-withholding-slash-')); /** - * Demonstrate that slashing occurs when the chain is pruned, and we are unable to collect the transactions data post-hoc. - * - * The setup of the test is as follows: - * 1. Create the "initial" node, and 4 other nodes - * 2. Await the 4 other nodes to form the committee - * 3. Send a tx to the initial node - * 4. Stop all the nodes and wipe their data directories - * 5. Re-create the nodes - * 6. Expect that a slash payload is deployed with the data withholding offense + * Verifies the per-slot data-withholding slash path (A-523). * - * The reason is that with the data directories wiped, they have no way to get the original transaction data - * when the chain is pruned. So they slash themselves. + * Scenario — a realistic data-withholding attack: * + * 1. 4 validators, all in the committee. slashSelfAllowed, quorum 3. + * 2. Pick one validator to be the malicious proposer (A). Its outbound tx gossip is + * stubbed so the tx never leaves A's mempool. The tx is sent directly to A. + * 3. Two other committee members (B, C) are configured to "attest blindly" — their + * block- and checkpoint-proposal handlers are stubbed to return isValid:true without + * re-executing. They sign whatever A broadcasts. + * 4. The fourth committee member (D) is honest: it tries to fetch the missing tx, can't, + * and refuses to attest. + * 5. Tx-collection is also stubbed on every node so no path can pull the tx from A — + * not at proposal time, not via post-mining backfill. This simulates the data being + * genuinely unavailable to anyone except A. + * 6. A self-attests + collects B's and C's attestations → quorum 3 → publishes. + * 7. After `slashDataWithholdingToleranceSlots` full slots, the watchers on B, C, and D + * probe `getAvailableTxs` against their own mempools, find the tx missing, and emit + * a slot-keyed DATA_WITHHOLDING for the three attesters (A, B, C). + * 8. With slashSelfAllowed the offense reaches quorum; A, B, C are slashed on L1. D is + * not slashed because it never attested. */ describe('e2e_p2p_data_withholding_slash', () => { let t: P2PNetworkTest; - let nodes: AztecNodeService[]; + let nodes: AztecNodeService[] = []; const slashingUnit = BigInt(1e18); const slashingQuorum = 3; + // L1 enforces `QUORUM > ROUND_SIZE / 2`, so with quorum=3 we cap round size at 5. + // With committee 4 and only B/C/D voting (A has the tx and never detects the offense), + // a single 4-slot round only meets quorum when all three of B/C/D happen to propose + // (~23% probability). Extending slashOffenseExpirationRounds gives us several rounds to + // hit quorum before the offense expires. const slashingRoundSize = 4; const aztecEpochDuration = 2; @@ -62,17 +76,20 @@ describe('e2e_p2p_data_withholding_slash', () => { anvilSlotsInAnEpoch: 4, listenAddress: '127.0.0.1', aztecEpochDuration, - ethereumSlotDuration: 4, + ethereumSlotDuration: ETHEREUM_SLOT_DURATION, aztecSlotDuration: AZTEC_SLOT_DURATION, - aztecProofSubmissionEpochs: 0, // effectively forces instant reorgs aztecTargetCommitteeSize: COMMITTEE_SIZE, + // Long proof submission window so the legacy L1-prune path is irrelevant. + aztecProofSubmissionEpochs: 1024, + slashInactivityConsecutiveEpochThreshold: 32, slashingQuorum, slashingRoundSizeInEpochs: slashingRoundSize / aztecEpochDuration, slashAmountSmall: slashingUnit, slashAmountMedium: slashingUnit * 2n, slashAmountLarge: slashingUnit * 3n, slashSelfAllowed: true, - minTxsPerBlock: 0, + slashDataWithholdingToleranceSlots: TOLERANCE_SLOTS, + minTxsPerBlock: 1, enableProposerPipelining: true, inboxLag: 2, }, @@ -83,41 +100,53 @@ describe('e2e_p2p_data_withholding_slash', () => { }); afterEach(async () => { - await t.stopNodes(nodes); + if (nodes.length > 0) { + await t.stopNodes(nodes); + } await t.teardown(); for (let i = 0; i < NUM_VALIDATORS; i++) { fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); } }); - const debugRollup = async () => { - await t.ctx.cheatCodes.rollup.debugRollup(); - }; - - it('slashes the committee when data is unavailable for the pruned epoch', async () => { + it('slashes attesters that attest to proposals containing withheld transactions', async () => { if (!t.bootstrapNodeEnr) { throw new Error('Bootstrap node ENR is not available'); } - const { rollup, slashingProposer } = await t.getContracts(); - - // Jump forward to an epoch in the future such that the validator set is not empty - await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); - await debugRollup(); + const { rollup } = await t.getContracts(); + + // Jump to an epoch where the validator set is non-empty. The validator set rotates per + // epoch and sometimes lands empty for early epochs, so advance epoch-by-epoch until we + // find one with a full committee. + let epoch = EpochNumber(4); + await retryUntil( + async () => { + await t.ctx.cheatCodes.rollup.advanceToEpoch(epoch); + const committee = await rollup.getCurrentEpochCommittee(); + if (committee?.length === NUM_VALIDATORS) { + t.logger.warn(`Found valid committee of ${committee.length} at epoch ${epoch}`); + return true; + } + t.logger.warn(`Epoch ${epoch} has ${committee?.length ?? 0} committee members, advancing`); + epoch = EpochNumber(epoch + 1); + return false; + }, + 'epoch with full committee', + 120, + 0, + ); const [activationThreshold, ejectionThreshold, localEjectionThreshold] = await Promise.all([ rollup.getActivationThreshold(), rollup.getEjectionThreshold(), rollup.getLocalEjectionThreshold(), ]); - - // Slashing amount should be enough to kick validators out const slashingAmount = slashingUnit * 3n; const biggestEjection = ejectionThreshold > localEjectionThreshold ? ejectionThreshold : localEjectionThreshold; expect(activationThreshold - slashingAmount).toBeLessThan(biggestEjection); t.ctx.aztecNodeConfig.slashDataWithholdingPenalty = slashingAmount; - t.ctx.aztecNodeConfig.slashPrunePenalty = slashingAmount; t.ctx.aztecNodeConfig.minTxsPerBlock = 1; t.logger.warn('Creating nodes'); @@ -129,124 +158,106 @@ describe('e2e_p2p_data_withholding_slash', () => { BOOT_NODE_UDP_PORT, t.genesis, DATA_DIR, - // To collect metrics - run in aztec-packages `docker compose --profile metrics up` and set COLLECT_METRICS=true shouldCollectMetrics(), ); - // Wait for P2P mesh to be fully formed before proceeding await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); - await debugRollup(); - const committee = await awaitCommitteeExists({ rollup, logger: t.logger }); - await debugRollup(); + await awaitCommitteeExists({ rollup, logger: t.logger }); - // Jump forward more time to ensure we're at the beginning of an epoch. - // This should reduce flake, since we need to have the transaction included - // and the nodes recreated, prior to the reorg. - // Considering the slot duration is 32 seconds, - // Considering the epoch duration is 2 slots, - // we have ~64 seconds to do this. + // The validator watchers floor processing at their boot slot. Advance past it so the tx + // checkpoint lands in a slot the watcher will actually process. await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(8)); - await t.sendDummyTx(); - await debugRollup(); - - // Send L2 txs through a validator node to ensure blocks are built (needed for pruning to trigger). - t.logger.warn('Sending L2 txs through a validator node'); - const txHashes = await submitTransactions(t.logger, nodes[0], 1, t.fundedAccount); - await Promise.all(txHashes.map(txHash => waitForTx(nodes[0], txHash, { timeout: WAIT_FOR_TX_TIMEOUT }))); - t.logger.warn('L2 txs mined'); - - t.logger.warn('Stopping nodes'); - // removeInitialNode sends a dummy L1 tx and awaits its receipt to sync the - // dateProvider, so it must run while L1 mining is still active. - await t.removeInitialNode(); - - // Pause L1 block production while we tear down and recreate validators. With - // `aztecProofSubmissionEpochs=0`, epoch 8 becomes prunable as soon as epoch 9 begins - // (~32s after slot 17). The stop/wipe/recreate cycle takes longer than that, so L1 - // would otherwise race past the prune deadline before the recreated nodes come up. - // When that happens, the recreated archivers detect the prune during their initial - // sync (`handleEpochPrune` emits `L2PruneUnproven`), but the `EpochPruneWatcher` - // listener is only attached after `archiver.waitForInitialSync()` resolves - // (see `aztec-node/server.ts`), so the event is dropped and `DATA_WITHHOLDING` is - // never emitted. By freezing L1 here, the recreated archivers ingest checkpoint 1 - // cleanly during initial sync, the watcher starts and attaches its listener, and - // then we resume L1 below so the prune fires while the listener is live. - const ethCheatCodes = t.ctx.cheatCodes.eth; - await ethCheatCodes.setAutomine(false); - await ethCheatCodes.setIntervalMining(0); - - // Fail fast if we paused too late — i.e. if L1 already crossed into epoch 9 before - // we got here. In that case the recreated nodes would still see the prune during - // initial sync and the test would flake exactly the same way. - const epochAtPause = await rollup.getCurrentEpoch(); - expect(Number(epochAtPause)).toBeLessThan(9); - - // Now stop the validator nodes. With L1 paused, any in-flight L1 submissions from - // the validator sequencers would hang `sequencer.stop()` (it awaits pending L1 - // submissions). Since `minTxsPerBlock=1` and no txs are queued for slot 18+, the - // sequencers don't submit further L1 transactions after the slot-17 checkpoint - // (already published before `waitForTx` returned), so this is safe. - await t.stopNodes(nodes); - // And remove the data directories (which forms the crux of the "attack") - for (let i = 0; i < NUM_VALIDATORS; i++) { - fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); - } - // Re-create the nodes. - // ASSUMING they sync in the middle of the epoch, they will "see" the reorg, and try to slash. - // Reset minTxsPerBlock to 0 so re-created validators build empty checkpoints. Under proposer - // pipelining, the vote-offenses signature is bound to the target slot and the multicall is only - // delayed to the target slot start when a checkpoint is being proposed; without a proposal, - // votes would mine in the current wall-clock slot, causing the EIP-712 signature verification to fail. - t.ctx.aztecNodeConfig.minTxsPerBlock = 0; - t.logger.warn('Re-creating nodes'); - nodes = await createNodes( - t.ctx.aztecNodeConfig, - t.ctx.dateProvider, - t.bootstrapNodeEnr, - NUM_VALIDATORS, - BOOT_NODE_UDP_PORT, - t.genesis, - DATA_DIR, + // Assign roles. With minTxsPerBlock=1 and tx gossip suppressed on the proposer, only the + // proposer can ever build a block, so we just wait for it to be designated proposer. + const [proposerNode, blindAttester1, blindAttester2, honestNode] = nodes; + const proposerAddress = proposerNode.getSequencer()!.validatorAddresses![0]; + const blindAttester1Address = blindAttester1.getSequencer()!.validatorAddresses![0]; + const blindAttester2Address = blindAttester2.getSequencer()!.validatorAddresses![0]; + const honestAddress = honestNode.getSequencer()!.validatorAddresses![0]; + t.logger.warn( + `Proposer ${proposerAddress}, blind attesters ${blindAttester1Address}/${blindAttester2Address}, honest ${honestAddress}`, ); - // Wait for P2P mesh to be fully formed before proceeding - await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); + // 1. Stub outbound tx gossip on the proposer. Tx messages going out are dropped silently; + // other gossip topics (proposals, attestations) pass through. + const proposerP2pService: any = (proposerNode as any).p2pClient.p2pService; + const originalPropagate = proposerP2pService.propagate.bind(proposerP2pService); + jest.spyOn(proposerP2pService, 'propagate').mockImplementation(((msg: any) => { + if (msg instanceof Tx) { + t.logger.info(`Suppressing outbound tx gossip from proposer ${proposerAddress}`); + return Promise.resolve(); + } + return originalPropagate(msg); + }) as any); + + // 2. Stub tx-collection on EVERY node so nothing can pull the tx back from the proposer + // over reqresp (neither at proposal time nor via post-mining backfill). + for (const node of nodes) { + const txCollection: any = (node as any).p2pClient.txCollection; + jest.spyOn(txCollection, 'collectFastFor').mockResolvedValue([]); + jest.spyOn(txCollection, 'collectFastForBlock').mockResolvedValue(undefined); + } + + // 3. Stub block- and checkpoint-proposal handling on the blind attesters so they attest + // without re-executing or fetching txs. + for (const node of [blindAttester1, blindAttester2]) { + const proposalHandler: any = (node as any).validatorClient.getProposalHandler(); + jest.spyOn(proposalHandler, 'handleBlockProposal').mockImplementation((async () => { + const blockNumber = await node.getBlockNumber(); + return { isValid: true, blockNumber: BlockNumber(blockNumber + 1) }; + }) as any); + jest.spyOn(proposalHandler, 'handleCheckpointProposal').mockResolvedValue({ + isValid: true, + checkpointNumber: CheckpointNumber(1), + } as any); + } - // Resume L1 block production. Warp L1 forward to current wall-clock time so the - // epoch-8 deadline is crossed immediately on the next L1 block, then re-enable - // interval mining. By now each recreated archiver has block 1 stored locally and - // its `EpochPruneWatcher` listener is attached, so the next sync iteration emits - // `L2PruneUnproven` for epoch 8 to a live listener → `DATA_WITHHOLDING`. - const resumeTimestamp = Math.floor(t.ctx.dateProvider.now() / 1000); - await ethCheatCodes.setNextBlockTimestamp(resumeTimestamp); - await ethCheatCodes.mine(); - await ethCheatCodes.setIntervalMining(t.ctx.aztecNodeConfig.ethereumSlotDuration); + // 4. Send the tx directly to the proposer; it propagates into the local mempool and stays + // there (gossip suppressed). Combined with `minTxsPerBlock: 1`, only the proposer can + // build a block, so the tx sits in the mempool until the proposer is next selected. + t.logger.warn(`Submitting tx through proposer ${proposerAddress}`); + const [txHash] = await submitTransactions(t.logger, proposerNode, 1, t.fundedAccount); + await waitForTx(proposerNode, txHash, { timeout: AZTEC_SLOT_DURATION * 6 * 1000 }); + const checkpointSlot = await getMinedSlot(proposerNode, txHash); + t.logger.warn(`Tx ${txHash} mined at checkpoint slot ${checkpointSlot}`); + + // 5. After the tolerance window, every non-proposer's watcher should fire for the 3 + // attesters (proposer A self-signs, plus blind attesters B and C). + const expectedOffendedAddresses = [proposerAddress, blindAttester1Address, blindAttester2Address] + .map(a => a.toString()) + .sort(); const offenses = await awaitOffenseDetected({ epochDuration: t.ctx.aztecNodeConfig.aztecEpochDuration, logger: t.logger, - nodeAdmin: nodes[0], + nodeAdmin: honestNode, slashingRoundSize, - waitUntilOffenseCount: COMMITTEE_SIZE, + waitUntilOffenseCount: 3, + timeoutSeconds: AZTEC_SLOT_DURATION * (TOLERANCE_SLOTS + 8), }); - // Check offenses are correct - expect(offenses.map(o => o.validator.toString()).sort()).toEqual(committee.map(a => a.toString()).sort()); - expect(offenses.map(o => o.offenseType)).toEqual(times(COMMITTEE_SIZE, () => OffenseType.DATA_WITHHOLDING)); - const offenseEpoch = Number(offenses[0].epochOrSlot); - - await awaitCommitteeKicked({ - rollup, - cheatCodes: t.ctx.cheatCodes.rollup, - committee, - slashingProposer, - slashingRoundSize, - aztecSlotDuration: AZTEC_SLOT_DURATION, - logger: t.logger, - offenseEpoch, - aztecEpochDuration, - }); + expect(offenses).toHaveLength(3); + expect(offenses.map(o => o.offenseType)).toEqual(offenses.map(() => OffenseType.DATA_WITHHOLDING)); + for (const offense of offenses) { + expect(offense.epochOrSlot).toEqual(BigInt(checkpointSlot)); + } + expect(offenses.map(o => o.validator.toString()).sort()).toEqual(expectedOffendedAddresses); + // The honest non-attester must NOT be slashed. + expect(offenses.map(o => o.validator.toString())).not.toContain(honestAddress.toString()); }); }); + +/** Returns the slot at which a tx was included, by querying the node's tx receipt. */ +async function getMinedSlot(node: AztecNodeService, txHash: TxHash): Promise { + const receipt = await node.getTxReceipt(txHash); + if (!receipt.blockNumber) { + throw new Error(`Tx ${txHash} has no block number on receipt`); + } + const block = await node.getBlock(receipt.blockNumber); + if (!block) { + throw new Error(`Block ${receipt.blockNumber} not found`); + } + return Number(block.header.getSlot()); +} diff --git a/yarn-project/end-to-end/src/e2e_p2p/duplicate_attestation_slash.test.ts b/yarn-project/end-to-end/src/e2e_p2p/duplicate_attestation_slash.test.ts index ce4a8f706999..9c27e88a5f4f 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/duplicate_attestation_slash.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/duplicate_attestation_slash.test.ts @@ -213,6 +213,18 @@ describe('e2e_p2p_duplicate_attestation_slash', () => { nodes = [maliciousNode1, maliciousNode2, honestNode1, honestNode2]; + // Stub the proposer's own-checkpoint-proposal loopback on the malicious nodes. The default + // path awaits a local handleCheckpointProposal → validateCheckpointProposal that retries + // until the proposed block lands in the archiver — but skipPushProposedBlocksToArchiver + // means it never does, so the await hangs until the retry deadline (~one slot). By the + // time the proposer returns from broadcast, the wallclock is in the target slot and the + // staleness gate refuses the self-attestation, so no duplicate attestations are ever + // broadcast. + for (const node of [maliciousNode1, maliciousNode2]) { + const p2pService: any = (node as any).p2pClient.p2pService; + jest.spyOn(p2pService, 'notifyOwnCheckpointProposal').mockResolvedValue(undefined); + } + // Wait for P2P mesh on all needed topics before starting sequencers await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS, 30, 0.1, [ TopicType.tx, diff --git a/yarn-project/end-to-end/src/e2e_p2p/fee_asset_price_oracle_gossip.test.ts b/yarn-project/end-to-end/src/e2e_p2p/fee_asset_price_oracle_gossip.test.ts index c384797a938c..06fc7ac0d486 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/fee_asset_price_oracle_gossip.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/fee_asset_price_oracle_gossip.test.ts @@ -63,6 +63,8 @@ describe('e2e_p2p_network', () => { slashingRoundSizeInEpochs: 2, slashingQuorum: 5, listenAddress: '127.0.0.1', + // Pipelining: target-slot is one ahead of build-slot; inboxLag sources L1->L2 + // messages from the previous checkpoint to avoid L1ToL2MessagesNotReadyError. enableProposerPipelining: true, inboxLag: 2, }, diff --git a/yarn-project/end-to-end/src/e2e_p2p/multiple_validators_sentinel.parallel.test.ts b/yarn-project/end-to-end/src/e2e_p2p/multiple_validators_sentinel.parallel.test.ts index b270212db706..eb907ce5571e 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/multiple_validators_sentinel.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/multiple_validators_sentinel.parallel.test.ts @@ -1,6 +1,6 @@ import type { AztecNodeService } from '@aztec/aztec-node'; import { RollupContract } from '@aztec/ethereum/contracts'; -import type { SlotNumber } from '@aztec/foundation/branded-types'; +import { SlotNumber } from '@aztec/foundation/branded-types'; import { retryUntil } from '@aztec/foundation/retry'; import { tryStop } from '@aztec/stdlib/interfaces/server'; @@ -216,7 +216,7 @@ describe('e2e_p2p_multiple_validators_sentinel', () => { const firstNodeBlockProposedHistory = firstNodeValidators .flatMap(v => stats.stats[v.toString().toLowerCase()].history) .filter(h => h.slot > initialSlot && h.slot <= slotForSentinel) - .filter(h => h.status === 'checkpoint-proposed'); + .filter(h => h.status === 'checkpoint-valid' || h.status === 'checkpoint-mined'); expect(firstNodeBlockProposedHistory).not.toBeEmpty(); // And all of the proposers for the offline node must be seen as missed attestation or proposal diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp.test.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp.test.ts index bb6fdba84001..18b9e94818b5 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp.test.ts @@ -1,10 +1,16 @@ import type { AztecNodeService } from '@aztec/aztec-node'; +import { jest } from '@jest/globals'; + import type { P2PNetworkTest } from '../p2p_network.js'; import { cleanupReqrespTest, createReqrespDataDir, createReqrespTest, runReqrespTxTest } from './utils.js'; const DATA_DIR = createReqrespDataDir(); +// Under pipelining a 36s aztec slot plus build-slot/target-slot round trip + L1 +// publish exceeds the default 5 min jest test timeout. Allow 15 min. +jest.setTimeout(15 * 60 * 1000); + describe('e2e_p2p_reqresp_tx', () => { let t: P2PNetworkTest; let nodes: AztecNodeService[]; diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp_no_handshake.test.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp_no_handshake.test.ts index 9816c47621e8..48d503d127d7 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp_no_handshake.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp/reqresp_no_handshake.test.ts @@ -1,5 +1,7 @@ import type { AztecNodeService } from '@aztec/aztec-node'; +import { jest } from '@jest/globals'; + import type { P2PNetworkTest } from '../p2p_network.js'; import { cleanupReqrespTest, createReqrespDataDir, createReqrespTest, runReqrespTxTest } from './utils.js'; @@ -9,6 +11,10 @@ import { cleanupReqrespTest, createReqrespDataDir, createReqrespTest, runReqresp const DATA_DIR = createReqrespDataDir(); +// Under pipelining a 36s aztec slot plus build-slot/target-slot round trip + L1 +// publish exceeds the default 5 min jest test timeout. Allow 15 min. +jest.setTimeout(15 * 60 * 1000); + describe('e2e_p2p_reqresp_tx_no_handshake', () => { let t: P2PNetworkTest; let nodes: AztecNodeService[]; diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts index 71f440695add..84ed608550ca 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts @@ -14,7 +14,7 @@ import path from 'path'; import { getBootNodeUdpPort, shouldCollectMetrics } from '../../fixtures/fixtures.js'; import { createNodes } from '../../fixtures/setup_p2p_test.js'; -import { P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from '../p2p_network.js'; +import { P2PNetworkTest } from '../p2p_network.js'; import { prepareTransactions } from '../shared.js'; // Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds @@ -49,6 +49,10 @@ export async function createReqrespTest(options: ReqrespOptions = {}): Promise

L2 + // messages from the previous checkpoint to avoid L1ToL2MessagesNotReadyError. + enableProposerPipelining: true, + inboxLag: 2, }, }); await t.setup(); @@ -125,7 +129,15 @@ export async function runReqrespTxTest(params: { t.ctx.dateProvider.setTime(Number(timestamp) * 1000); const startSlotTimestamp = BigInt(timestamp); - const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes(t, startSlotTimestamp); + // Under pipelining the active builder during wallclock slot S targets slot S+1, so + // we must address the proposer of S+1 (not S) for batch 0. Shift the proposer lookup + // window by the pipelining offset so we always send to the currently-building proposer. + const proposerSlotOffset = t.ctx.aztecNodeConfig.enableProposerPipelining ? 1 : 0; + const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes( + t, + startSlotTimestamp, + proposerSlotOffset, + ); t.logger.info(`Turning off tx gossip for nodes: ${nodesToTurnOffTxGossip.map(getNodePort)}`); t.logger.info(`Sending txs to proposer nodes: ${proposerIndexes.map(getNodePort)}`); @@ -176,12 +188,17 @@ export async function runReqrespTxTest(params: { t.logger.info(`Node ${getNodePort(i)} pool has ${count} pending txs`); } + // Use the test's own aztecSlotDuration (not the env default that p2p_network's + // WAIT_FOR_TX_TIMEOUT is derived from) so the timeout scales with this test's 36s slot. + // Under pipelining the round-trip is roughly build-slot + target-slot + L1 publish, so + // budget for >= 3 slots. + const waitForTxTimeout = t.ctx.aztecNodeConfig.aztecSlotDuration * 4.5; t.logger.info('Waiting for all transactions to be mined'); await Promise.all( submittedTxs.flatMap((batch, batchIndex) => batch.map(async (submittedTx, txIndex) => { t.logger.info(`Waiting for tx ${batchIndex}-${txIndex} ${submittedTx.txHash.toString()} to be mined`); - await waitForTx(submittedTx.node, submittedTx.txHash, { timeout: WAIT_FOR_TX_TIMEOUT * 1.5 }); + await waitForTx(submittedTx.node, submittedTx.txHash, { timeout: waitForTxTimeout }); t.logger.info(`Tx ${batchIndex}-${txIndex} ${submittedTx.txHash.toString()} has been mined`); }), ), @@ -223,7 +240,7 @@ export async function runReqrespTxTest(params: { return nodes; } -async function getProposerIndexes(t: P2PNetworkTest, startSlotTimestamp: bigint) { +async function getProposerIndexes(t: P2PNetworkTest, startSlotTimestamp: bigint, slotOffset = 0) { // Get the nodes for the next set of slots const rollupContract = new RollupContract( t.ctx.deployL1ContractsValues.l1Client, @@ -235,7 +252,7 @@ async function getProposerIndexes(t: P2PNetworkTest, startSlotTimestamp: bigint) const proposers = await Promise.all( Array.from({ length: 3 }, async (_, i) => { - const slot = SlotNumber(startSlot + i); + const slot = SlotNumber(startSlot + slotOffset + i); const slotTimestamp = await rollupContract.getTimestampForSlot(slot); return await rollupContract.getProposerAt(slotTimestamp); }), diff --git a/yarn-project/end-to-end/src/e2e_p2p/sentinel_status_slash.parallel.test.ts b/yarn-project/end-to-end/src/e2e_p2p/sentinel_status_slash.parallel.test.ts new file mode 100644 index 000000000000..bf315256df17 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_p2p/sentinel_status_slash.parallel.test.ts @@ -0,0 +1,414 @@ +import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; +import type { TestAztecNodeService } from '@aztec/aztec-node/test'; +import type { EthAddress } from '@aztec/aztec.js/addresses'; +import { RollupContract } from '@aztec/ethereum/contracts'; +import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { unique } from '@aztec/foundation/collection'; +import { retryUntil } from '@aztec/foundation/retry'; +import { OffenseType } from '@aztec/slasher'; +import { tryStop } from '@aztec/stdlib/interfaces/server'; +import type { ValidatorStatusInSlot } from '@aztec/stdlib/validators'; + +import { jest } from '@jest/globals'; +import fs from 'fs'; +import 'jest-extended'; +import os from 'os'; +import path from 'path'; + +import { shouldCollectMetrics } from '../fixtures/fixtures.js'; +import { createNodes } from '../fixtures/setup_p2p_test.js'; +import { P2PNetworkTest } from './p2p_network.js'; +import { awaitCommitteeExists } from './shared.js'; + +/** + * Exercises the sentinel's six-case proposer-status taxonomy end-to-end by driving each of the + * status variants via in-tree validator-config flags (no jest stubbing of internals): + * + * 1. `checkpoint-unvalidated` (case 3) — one validator runs with `broadcastInvalidBlockProposal`, + * so honest observers reject its block proposals (state_mismatch) and never push them to + * their archivers. When the checkpoint proposal arrives, observers fail to load the last + * block → record `unvalidated`; the sentinel slashes the proposer for inactivity. + * + * 2. `checkpoint-invalid` (case 4) — one validator runs with + * `broadcastInvalidCheckpointProposalOnly`, so its block proposals stay valid (pushed to + * observers' archivers) but its checkpoint proposal carries a random archive. Observers + * load the last block, find an archive mismatch, and record `invalid`; the sentinel + * slashes the proposer for inactivity. + * + * 3. Successful re-execution + missing attestor (case 5) — all six validators start + * honest, then one is stopped mid-test. The stopped node misses its own proposer slots + * and stops attesting to others; the sentinel slashes it for inactivity. + */ + +const TEST_TIMEOUT = 1_000_000; +jest.setTimeout(TEST_TIMEOUT); + +const NUM_VALIDATORS = 6; +const COMMITTEE_SIZE = NUM_VALIDATORS; +const BOOT_NODE_UDP_PORT = 4700; +const ETHEREUM_SLOT_DURATION = process.env.CI ? 8 : 4; +const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 2; +const AZTEC_EPOCH_DURATION = 2; +const SLASHING_UNIT = BigInt(1e18); +const SLASHING_AMOUNT = SLASHING_UNIT * 3n; +const SLASHING_QUORUM = 3; +const SLASHING_ROUND_SIZE_IN_EPOCHS = 2; + +const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'sentinel-status-slash-')); + +describe('e2e_p2p_sentinel_status_slash', () => { + let t: P2PNetworkTest; + let nodes: AztecNodeService[] = []; + let rollup: RollupContract; + + beforeEach(async () => { + t = await P2PNetworkTest.create({ + testName: 'e2e_p2p_sentinel_status_slash', + numberOfNodes: 0, + numberOfValidators: NUM_VALIDATORS, + basePort: BOOT_NODE_UDP_PORT, + metricsPort: shouldCollectMetrics(), + startProverNode: true, + initialConfig: { + anvilSlotsInAnEpoch: 4, + listenAddress: '127.0.0.1', + aztecTargetCommitteeSize: COMMITTEE_SIZE, + aztecSlotDuration: AZTEC_SLOT_DURATION, + ethereumSlotDuration: ETHEREUM_SLOT_DURATION, + aztecEpochDuration: AZTEC_EPOCH_DURATION, + aztecProofSubmissionEpochs: 1024, + minTxsPerBlock: 0, + enableProposerPipelining: true, + inboxLag: 2, + mockGossipSubNetwork: true, + sentinelEnabled: true, + // A single proposer-fault slot in an epoch gives missed/total = 1/6 ≈ 0.167; threshold + // 0.1 lets that single fault trip inactivity. + slashInactivityTargetPercentage: 0.1, + slashInactivityConsecutiveEpochThreshold: 1, + slashingQuorum: SLASHING_QUORUM, + slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE_IN_EPOCHS, + slashAmountSmall: SLASHING_UNIT, + slashAmountMedium: SLASHING_UNIT * 2n, + slashAmountLarge: SLASHING_AMOUNT, + slashInactivityPenalty: SLASHING_AMOUNT, + slashSelfAllowed: true, + // Sentinel evaluates an epoch's performance once this buffer has elapsed past its last slot. + sentinelEpochEndBufferSlots: 2, + // Suppress the BROADCASTED_INVALID_BLOCK_PROPOSAL slash so the only slashing signal in + // tests 1 and 2 is the INACTIVITY offense from the sentinel. + slashBroadcastedInvalidBlockPenalty: 0n, + }, + }); + + await t.setup(); + await t.applyBaseSetup(); + + ({ rollup } = await t.getContracts()); + + // Advance until the committee is populated. + let epoch = EpochNumber(4); + await retryUntil( + async () => { + await t.ctx.cheatCodes.rollup.advanceToEpoch(epoch); + const committee = await rollup.getCurrentEpochCommittee(); + if (committee?.length === NUM_VALIDATORS) { + return true; + } + epoch = EpochNumber(epoch + 1); + return false; + }, + 'epoch with full committee', + 120, + 0, + ); + }); + + afterEach(async () => { + if (nodes.length > 0) { + await t.stopNodes(nodes); + nodes = []; + } + await t.teardown(); + for (let i = 0; i < NUM_VALIDATORS; i++) { + fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); + } + }); + + it('slashes the proposer with INACTIVITY when checkpoint validation records unvalidated', async () => { + // One malicious node broadcasts invalid block proposals; honest observers reject them via + // re-execution state_mismatch and therefore never push to their archivers, so the malicious + // node's checkpoint proposals can't find their last block and observers record `unvalidated`. + const targetAddress = await spawnMaliciousAndHonestNodes({ broadcastInvalidBlockProposal: true }); + // Warp near the malicious node's proposer slot to keep wall-clock down. We discover the slot at + // which the fault is actually recorded rather than assuming it is the warped block-proposer + // slot: the re-execution outcome is keyed by the checkpoint proposal's slot, and a proposer + // only emits a checkpoint proposal when its slot closes a checkpoint, which does not always + // coincide with the block-proposer slot we warp to. + await warpToSlotBeforeTargetProposer(targetAddress); + // nodes[0] is the malicious node; honest observers are nodes[1..]. + const honestObservers = nodes.slice(1); + const faultSlot = await findObservedStatusSlot(honestObservers, targetAddress, 'checkpoint-unvalidated'); + await assertAllObserversSentinelStatus(honestObservers, targetAddress, faultSlot, 'checkpoint-unvalidated'); + // The malicious node self-records `checkpoint-valid` for that slot using the locally computed + // archive (broadcastInvalidBlockProposal only corrupts the broadcast archive, not the + // proposer's local state). + await assertAllObserversSentinelStatus([nodes[0]], targetAddress, faultSlot, 'checkpoint-valid'); + await assertInactivityOffenseFor(targetAddress, nodes[1]); + }); + + it('slashes the proposer with INACTIVITY when checkpoint validation records invalid', async () => { + // One malicious node broadcasts invalid CHECKPOINT proposals while keeping the underlying + // block proposals valid; observers accept the blocks (so they land in the archiver) but + // reject the checkpoint via header_mismatch, recording `invalid`. + const targetAddress = await spawnMaliciousAndHonestNodes({ broadcastInvalidCheckpointProposalOnly: true }); + await warpToSlotBeforeTargetProposer(targetAddress); + const honestObservers = nodes.slice(1); + const faultSlot = await findObservedStatusSlot(honestObservers, targetAddress, 'checkpoint-invalid'); + await assertAllObserversSentinelStatus(honestObservers, targetAddress, faultSlot, 'checkpoint-invalid'); + // Malicious self-records `checkpoint-valid` for that slot — proposers always consider their + // own freshly-built proposal valid from their local-state perspective. + await assertAllObserversSentinelStatus([nodes[0]], targetAddress, faultSlot, 'checkpoint-valid'); + await assertInactivityOffenseFor(targetAddress, nodes[1]); + }); + + it('slashes an attestor that gets stopped after the network is running', async () => { + nodes = await createNodes( + t.ctx.aztecNodeConfig, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + NUM_VALIDATORS, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + ); + + await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); + await awaitCommitteeExists({ rollup, logger: t.logger }); + + // Pick the last node as the one to stop so that target proposer rotation is unaffected. + const targetIdx = NUM_VALIDATORS - 1; + const targetAddress = (nodes[targetIdx] as any).getSequencer()!.validatorAddresses![0] as EthAddress; + t.logger.warn(`Stopping node ${targetIdx} (validator ${targetAddress})`); + await tryStop(nodes[targetIdx]); + // Remove from the array we will tear down in afterEach to avoid double-stop. + nodes = nodes.filter((_, i) => i !== targetIdx); + + // All remaining nodes are honest observers. + await assertAllObserversObservedAttestationMissed(nodes, targetAddress); + await assertInactivityOffenseFor(targetAddress, nodes[0]); + }); + + // -- helpers ------------------------------------------------------------------------------ + + /** + * Spawns 1 malicious node at index 0 with the given config override, then `NUM_VALIDATORS - 1` + * honest nodes at indices 1..N-1. Returns the malicious node's validator address. + */ + async function spawnMaliciousAndHonestNodes(maliciousOverride: Partial): Promise { + const maliciousNodes = await createNodes( + { ...t.ctx.aztecNodeConfig, ...maliciousOverride }, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + 1, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + 0, + ); + const targetAddress = (maliciousNodes[0] as any).getSequencer()!.validatorAddresses![0] as EthAddress; + t.logger.warn(`Malicious node validator address: ${targetAddress}`, { maliciousOverride }); + + const honestNodes = await createNodes( + t.ctx.aztecNodeConfig, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + NUM_VALIDATORS - 1, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + 1, + ); + + nodes = [...maliciousNodes, ...honestNodes]; + + await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); + await awaitCommitteeExists({ rollup, logger: t.logger }); + await t.monitor.waitUntilCheckpoint(CheckpointNumber(1)); + + return targetAddress; + } + + /** + * Finds the next slot at which `targetAddress` is the proposer and warps L1 time to the slot + * just before it (so the proposer-pipelining build phase for the target's slot lands on the + * malicious node immediately, with no need to poll for the slot to come around naturally). + * + * Probes the NEXT epoch's slots only (further epochs revert with `EpochNotStable`). If the + * target isn't selected next epoch, advances one epoch and tries again. + */ + async function warpToSlotBeforeTargetProposer(targetAddress: EthAddress): Promise { + const epochCache = (nodes[0] as TestAztecNodeService).epochCache; + const cheatCodes = t.ctx.cheatCodes.rollup; + const maxEpochAttempts = 20; + // Minimum slots between the warp landing (`targetSlot - 1`) and where we currently are. + // Without this, the malicious's bad broadcast lands while observers are still transitioning + // across the epoch boundary and gossipsub may drop the proposal. Two slots of real-time + // is enough for everyone to stabilise. + const minBufferSlots = 2; + + for (let attempt = 0; attempt < maxEpochAttempts; attempt++) { + const currentSlot = Number(await cheatCodes.getSlot()); + const currentEpoch = Math.floor(currentSlot / AZTEC_EPOCH_DURATION); + // Search the remainder of the current epoch and all of the next epoch (the second-next + // epoch's committee may revert with EpochNotStable). Skip slots within `minBufferSlots` + // of the current slot — too close to warp into safely. + const searchStart = currentSlot + minBufferSlots; + const searchEnd = (currentEpoch + 2) * AZTEC_EPOCH_DURATION - 1; + + let targetSlot: number | undefined; + for (let s = searchStart; s <= searchEnd; s++) { + const proposer = await epochCache.getProposerAttesterAddressInSlot(SlotNumber(s)); + if (proposer && targetAddress.equals(proposer)) { + targetSlot = s; + break; + } + } + + if (targetSlot === undefined) { + t.logger.info(`Target not selected as proposer in slots ${searchStart}..${searchEnd}; advancing one epoch`); + await cheatCodes.advanceToNextEpoch(); + continue; + } + + // Land 2 slots before the target. The malicious's sequencer pipelines for slot N during + // slot N-1, so landing at N-2 gives the network one full slot (N-1) of real-time to + // settle after the warp before the malicious starts building. Use the absolute-slot + // helper rather than `advanceSlots(N)` so any real-time elapsed between the slot search + // above and this call doesn't push us past the intended landing slot. + const landingSlot = SlotNumber(targetSlot - 2); + t.logger.warn( + `Target proposes at slot ${targetSlot}; warping to slot ${landingSlot} (target is 2 slots ahead to let gossipsub stabilise before the malicious broadcasts)`, + ); + if (landingSlot > currentSlot) { + await cheatCodes.advanceToSlot(landingSlot); + } + return SlotNumber(targetSlot); + } + + throw new Error( + `Target proposer ${targetAddress} not found with sufficient buffer within ${maxEpochAttempts} epochs`, + ); + } + + /** + * Finds the earliest slot at which EVERY honest observer has recorded `expectedStatus` for + * `targetAddress`. The slot at which the malicious node closes its checkpoint (and so the fault + * is recorded) is not necessarily the block-proposer slot we warp to, so we discover it rather + * than assuming it. Requiring cross-observer agreement avoids picking a slot that only one + * observer saw (e.g. one peer happened to be synced to the malicious proposer's gossip earlier + * than the others), which would then time out the downstream per-observer assertion. Times out + * — and therefore fails the test — if no common fault slot is ever recorded, so a genuine + * failure to detect the malicious proposal is still caught. + */ + async function findObservedStatusSlot( + observerNodes: AztecNodeService[], + targetAddress: EthAddress, + expectedStatus: ValidatorStatusInSlot, + ): Promise { + const slot = await retryUntil( + async () => { + const slotSets = await Promise.all( + observerNodes.map(async observerNode => { + const stats = await observerNode.getValidatorsStats(); + const history = stats.stats[targetAddress.toString()]?.history ?? []; + return new Set(history.filter(h => h.status === expectedStatus).map(h => Number(h.slot))); + }), + ); + if (slotSets.some(s => s.size === 0)) { + return undefined; + } + const [first, ...rest] = slotSets; + const common = [...first].filter(s => rest.every(other => other.has(s))).sort((a, b) => a - b); + return common.length > 0 ? SlotNumber(common[0]) : undefined; + }, + `cross-observer ${expectedStatus} for ${targetAddress}`, + AZTEC_SLOT_DURATION * 15, + ); + return slot; + } + + /** + * Polls every honest observer node until each has its sentinel record `expectedStatus` for the + * target at the given slot. Asserts the recorded status matches exactly on every observer. + */ + async function assertAllObserversSentinelStatus( + observerNodes: AztecNodeService[], + targetAddress: EthAddress, + slot: SlotNumber, + expectedStatus: ValidatorStatusInSlot, + ): Promise { + for (const observerNode of observerNodes) { + const status = await retryUntil( + async () => { + const stats = await observerNode.getValidatorsStats(); + const validator = stats.stats[targetAddress.toString()]; + const entry = validator?.history.find(h => Number(h.slot) === Number(slot)); + return entry?.status; + }, + `sentinel status for ${targetAddress} at slot ${slot}`, + AZTEC_SLOT_DURATION * 10, + ); + expect(status).toEqual(expectedStatus); + } + t.logger.warn( + `All ${observerNodes.length} observers recorded ${expectedStatus} for ${targetAddress} at slot ${slot}`, + ); + } + + /** + * Polls every honest observer node until each one has at least one `attestation-missed` entry + * for the target. Used by the stopped-attestor test where the slot of the miss is + * non-deterministic. + */ + async function assertAllObserversObservedAttestationMissed( + observerNodes: AztecNodeService[], + targetAddress: EthAddress, + ): Promise { + for (const observerNode of observerNodes) { + const slot = await retryUntil( + async () => { + const stats = await observerNode.getValidatorsStats(); + const validator = stats.stats[targetAddress.toString()]; + const miss = validator?.history.find(h => h.status === 'attestation-missed'); + return miss?.slot; + }, + `attestation-missed entry for ${targetAddress}`, + AZTEC_SLOT_DURATION * 20, + ); + expect(slot).toBeDefined(); + } + t.logger.warn(`All ${observerNodes.length} observers recorded attestation-missed for ${targetAddress}`); + } + + /** Polls the given honest observer node until an INACTIVITY offense for the target appears. */ + async function assertInactivityOffenseFor(targetAddress: EthAddress, observerNode: AztecNodeService): Promise { + const offenses = await retryUntil( + async () => { + const collected = await observerNode.getSlashOffenses('all'); + const inactivityForTarget = collected.filter( + o => o.offenseType === OffenseType.INACTIVITY && targetAddress.equals(o.validator), + ); + return inactivityForTarget.length > 0 ? inactivityForTarget : undefined; + }, + 'inactivity offense for target', + AZTEC_SLOT_DURATION * 40, + ); + t.logger.warn(`Detected ${offenses.length} INACTIVITY offense(s) for ${targetAddress}`, { offenses }); + expect(unique(offenses.map(o => o.validator.toString()))).toEqual([targetAddress.toString()]); + expect(unique(offenses.map(o => o.offenseType))).toEqual([OffenseType.INACTIVITY]); + } +}); diff --git a/yarn-project/end-to-end/src/e2e_p2p/valid_epoch_pruned_slash.test.ts b/yarn-project/end-to-end/src/e2e_p2p/valid_epoch_pruned_slash.test.ts deleted file mode 100644 index c9129bf2f3d6..000000000000 --- a/yarn-project/end-to-end/src/e2e_p2p/valid_epoch_pruned_slash.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -import type { AztecNodeService } from '@aztec/aztec-node'; -import { EpochNumber } from '@aztec/foundation/branded-types'; -import { times } from '@aztec/foundation/collection'; -import { sleep } from '@aztec/foundation/sleep'; -import { SpamContract } from '@aztec/noir-test-contracts.js/Spam'; -import { OffenseType } from '@aztec/slasher'; - -import { jest } from '@jest/globals'; -import fs from 'fs'; -import os from 'os'; -import path from 'path'; - -import { shouldCollectMetrics } from '../fixtures/fixtures.js'; -import { createNodes } from '../fixtures/setup_p2p_test.js'; -import { P2PNetworkTest } from './p2p_network.js'; -import { awaitCommitteeExists, awaitCommitteeKicked, awaitOffenseDetected } from './shared.js'; - -jest.setTimeout(10 * 60_000); // 10 minutes - -// Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds -const NUM_VALIDATORS = 4; -const COMMITTEE_SIZE = NUM_VALIDATORS; -const BOOT_NODE_UDP_PORT = 4500; - -const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'valid-epoch-pruned-slash-')); - -/** - * Test that we slash the committee when the pruned epoch could have been proven. - * We don't need to do anything special for this test other than to run it without a prover node - * (which is the default), and this will produce pruned epochs that could have been proven. But we do - * need to send a tx to make sure that the slash is due to valid epoch prune and not data withholding. - * - * TODO(palla/mbps): Add tests for 1) out messages and 2) partial epoch prunes - */ -describe('e2e_p2p_valid_epoch_pruned_slash', () => { - let t: P2PNetworkTest; - let nodes: AztecNodeService[]; - - const slashingQuorum = 3; - const slashingRoundSize = 4; - const ethereumSlotDuration = 8; - const aztecSlotDuration = 24; - const aztecEpochDuration = 2; - const initialEpoch = 8; - const slashingUnit = BigInt(1e18); - - beforeEach(async () => { - t = await P2PNetworkTest.create({ - testName: 'e2e_p2p_valid_epoch_pruned', - numberOfNodes: 0, - numberOfValidators: NUM_VALIDATORS, - basePort: BOOT_NODE_UDP_PORT, - metricsPort: shouldCollectMetrics(), - initialConfig: { - anvilSlotsInAnEpoch: 4, - enforceTimeTable: true, - cancelTxOnTimeout: false, - sequencerPublisherAllowInvalidStates: true, - listenAddress: '127.0.0.1', - aztecEpochDuration, - ethereumSlotDuration, - aztecSlotDuration, - aztecProofSubmissionEpochs: 1, - slashingQuorum, - slashingRoundSizeInEpochs: slashingRoundSize / aztecEpochDuration, - slashSelfAllowed: true, - slashGracePeriodL2Slots: initialEpoch * aztecEpochDuration, - slashAmountSmall: slashingUnit, - slashAmountMedium: slashingUnit * 2n, - slashAmountLarge: slashingUnit * 3n, - aztecTargetCommitteeSize: COMMITTEE_SIZE, - enableProposerPipelining: true, - inboxLag: 2, - }, - }); - - await t.setup(); - await t.applyBaseSetup(); - }); - - afterEach(async () => { - await t.stopNodes(nodes); - await t.teardown(); - for (let i = 0; i < NUM_VALIDATORS; i++) { - fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); - } - }); - - const debugRollup = async () => { - await t.ctx.cheatCodes.rollup.debugRollup(); - }; - - it('slashes the committee when the pruned epoch could have been proven', async () => { - // create the bootstrap node for the network - if (!t.bootstrapNodeEnr) { - throw new Error('Bootstrap node ENR is not available'); - } - - const { rollup, slashingProposer } = await t.getContracts(); - const [activationThreshold, ejectionThreshold, localEjectionThreshold] = await Promise.all([ - rollup.getActivationThreshold(), - rollup.getEjectionThreshold(), - rollup.getLocalEjectionThreshold(), - ]); - - // Slashing amount should be enough to kick validators out - const slashingAmount = slashingUnit * 3n; - const biggestEjection = ejectionThreshold > localEjectionThreshold ? ejectionThreshold : localEjectionThreshold; - expect(activationThreshold - slashingAmount).toBeLessThan(biggestEjection); - - t.ctx.aztecNodeConfig.slashPrunePenalty = slashingAmount; - t.ctx.aztecNodeConfig.minTxsPerBlock = 1; - t.ctx.aztecNodeConfig.txPoolDeleteTxsAfterReorg = true; - - t.logger.warn(`Creating ${NUM_VALIDATORS} new nodes`); - nodes = await createNodes( - t.ctx.aztecNodeConfig, - t.ctx.dateProvider, - t.bootstrapNodeEnr, - NUM_VALIDATORS, - BOOT_NODE_UDP_PORT, - t.genesis, - DATA_DIR, - // To collect metrics - run in aztec-packages `docker compose --profile metrics up` and set COLLECT_METRICS=true - shouldCollectMetrics(), - ); - - // Wait a bit for peers to discover each other - await sleep(4000); - await debugRollup(); - - // Wait for the committee to exist - await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(2)); - await t.ctx.cheatCodes.rollup.markAsProven(); - const committee = await awaitCommitteeExists({ rollup, logger: t.logger }); - await debugRollup(); - - // Set up a wallet and keep it out of reorgs - await t.ctx.cheatCodes.rollup.markAsProven(); - t.setupWalletOnNode(nodes[0]); - await t.setupAccount(); - await t.ctx.cheatCodes.rollup.markAsProven(); - - // Warp forward to after the initial grace period - expect(await rollup.getCurrentEpoch()).toBeLessThan(initialEpoch); - await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(initialEpoch), { offset: -ethereumSlotDuration }); - await t.ctx.cheatCodes.rollup.markAsProven(); - - // Send a tx to deploy a contract so that we have a tx with public function execution in the pruned epoch - // This allows us to test that the slashed offense is valid epoch prune and not data withholding - t.logger.warn(`Submitting deployment tx to the network`); - const _spamContract = await SpamContract.deploy(t.wallet!).send({ from: t.defaultAccountAddress! }); - - // And send a tx that depends on a tx with public function execution on a contract class that will be reorged out - // This allows us to test that we handle pruned contract classes correctly - // TODO(palla/A-51): For this check to actually check what we need, we need to ensure the deployment and the - // this tx are in different blocks but within the same epoch, so it gets reexecuted by the prune-watcher. - // This does not always happen in the current test setup. - // t.logger.warn(`Submitting tx with public function execution to the network`); - // await spamContract.methods.spam(1, 1, true).send({ from: t.defaultAccountAddress! }); - - // Remove initial node (it's a lightweight archiver with no P2P/validator/sequencer, but clean up anyway) - t.logger.warn(`Removing initial node`); - await t.removeInitialNode(); - - // Wait for epoch to be pruned and the offense to be detected - const offenses = await awaitOffenseDetected({ - logger: t.logger, - nodeAdmin: nodes[0], - slashingRoundSize, - epochDuration: t.ctx.aztecNodeConfig.aztecEpochDuration, - waitUntilOffenseCount: COMMITTEE_SIZE, - }); - - // Check offenses are correct - expect(offenses.map(o => o.validator.toString()).sort()).toEqual(committee.map(a => a.toString()).sort()); - expect(offenses.map(o => o.offenseType)).toEqual(times(COMMITTEE_SIZE, () => OffenseType.VALID_EPOCH_PRUNED)); - const offenseEpoch = Number(offenses[0].epochOrSlot); - - // And then wait for them to be kicked out - await awaitCommitteeKicked({ - rollup, - cheatCodes: t.ctx.cheatCodes.rollup, - committee, - slashingProposer, - slashingRoundSize, - aztecSlotDuration, - logger: t.logger, - offenseEpoch, - aztecEpochDuration, - }); - }); -}); diff --git a/yarn-project/end-to-end/src/e2e_partial_notes.test.ts b/yarn-project/end-to-end/src/e2e_partial_notes.test.ts index 8742a20129a0..ec1e4be32ac2 100644 --- a/yarn-project/end-to-end/src/e2e_partial_notes.test.ts +++ b/yarn-project/end-to-end/src/e2e_partial_notes.test.ts @@ -5,10 +5,11 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; -const TIMEOUT = 120_000; +const TIMEOUT = 300_000; describe('partial notes', () => { jest.setTimeout(TIMEOUT); @@ -32,7 +33,7 @@ describe('partial notes', () => { wallet, accounts: [adminAddress, liquidityProviderAddress], logger, - } = await setup(2)); + } = await setup(2, { ...AUTOMINE_E2E_OPTS })); const { contract } = await deployToken(wallet, adminAddress, 0n, logger); token0 = contract; diff --git a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts index 05e3086eccda..7eebbe478baf 100644 --- a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts @@ -10,6 +10,7 @@ import { } from '@aztec/constants'; import { PendingNoteHashesContract } from '@aztec/noir-test-contracts.js/PendingNoteHashes'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -28,14 +29,25 @@ describe('e2e_pending_note_hashes_contract', () => { wallet, logger, accounts: [owner], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); }); afterAll(() => teardown()); + // Find the most recent block containing tx effects; pipelining may produce empty blocks after a tx lands. + const getLatestNonEmptyBlock = async () => { + const latest = await aztecNode.getBlockNumber(); + for (let n = latest; n > 0; n--) { + const block = (await aztecNode.getBlocks(n, 1, { includeTransactions: true }))[0]; + if (block.body.txEffects.length > 0) { + return block; + } + } + throw new Error('No non-empty block found'); + }; + const expectNoteHashesSquashedExcept = async (exceptFirstFew: number) => { - const blockNum = await aztecNode.getBlockNumber(); - const block = (await aztecNode.getBlocks(blockNum, 1, { includeTransactions: true }))[0]; + const block = await getLatestNonEmptyBlock(); const noteHashes = block.body.txEffects.flatMap(txEffect => txEffect.noteHashes); @@ -50,8 +62,7 @@ describe('e2e_pending_note_hashes_contract', () => { }; const expectNullifiersSquashedExcept = async (exceptFirstFew: number) => { - const blockNum = await aztecNode.getBlockNumber(); - const block = (await aztecNode.getBlocks(blockNum, 1, { includeTransactions: true }))[0]; + const block = await getLatestNonEmptyBlock(); const nullifierArray = block.body.txEffects.flatMap(txEffect => txEffect.nullifiers); @@ -66,8 +77,7 @@ describe('e2e_pending_note_hashes_contract', () => { }; const expectNoteLogsSquashedExcept = async (exceptFirstFew: number) => { - const blockNum = await aztecNode.getBlockNumber(); - const block = (await aztecNode.getBlocks(blockNum, 1, { includeTransactions: true }))[0]; + const block = await getLatestNonEmptyBlock(); const privateLogs = block.body.txEffects.flatMap(txEffect => txEffect.privateLogs); expect(privateLogs.length).toBe(exceptFirstFew); diff --git a/yarn-project/end-to-end/src/e2e_phase_check.test.ts b/yarn-project/end-to-end/src/e2e_phase_check.test.ts index 793368f9c582..bf72a88f06d3 100644 --- a/yarn-project/end-to-end/src/e2e_phase_check.test.ts +++ b/yarn-project/end-to-end/src/e2e_phase_check.test.ts @@ -9,6 +9,7 @@ import { getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contra import { PublicDataTreeLeaf } from '@aztec/stdlib/trees'; import { defaultInitialAccountFeeJuice } from '@aztec/world-state/testing'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -33,7 +34,7 @@ describe('Phase check', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { genesisPublicData: [genesisBalanceEntry] })); + } = await setup(1, { ...AUTOMINE_E2E_OPTS, genesisPublicData: [genesisBalanceEntry] })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); sponsoredFPC = await SponsoredFPCNoEndSetupContract.deploy(wallet, { diff --git a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts index 6a60739c2d36..98065f606d98 100644 --- a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts @@ -5,6 +5,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { PrivateVotingContract } from '@aztec/noir-contracts.js/PrivateVoting'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_voting_contract', () => { @@ -23,7 +24,7 @@ describe('e2e_voting_contract', () => { wallet, logger, accounts: [owner], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract: votingContract } = await PrivateVotingContract.deploy(wallet, owner).send({ from: owner })); diff --git a/yarn-project/end-to-end/src/e2e_prover/client.test.ts b/yarn-project/end-to-end/src/e2e_prover/client.test.ts index aef6fcd86af6..f7821478e99a 100644 --- a/yarn-project/end-to-end/src/e2e_prover/client.test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/client.test.ts @@ -4,15 +4,20 @@ import type { ExtendedViemWalletClient } from '@aztec/ethereum/types'; import { parseBooleanEnv } from '@aztec/foundation/config'; import { FeeJuicePortalAbi, TestERC20Abi } from '@aztec/l1-artifacts'; -import '@jest/globals'; +import { jest } from '@jest/globals'; import { type GetContractReturnType, getContract } from 'viem'; import { FullProverTest } from '../fixtures/e2e_prover_test.js'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { proveInteraction } from '../test-wallet/utils.js'; // Set a very long 20 minute timeout. const TIMEOUT = 1_200_000; +// Pipelined 12s-slot setup chain (account deploys + token deploy + mint + epoch advance + +// prover-node startup) exceeds the default 5min jest per-test budget. +jest.setTimeout(15 * 60 * 1000); + describe('client_prover', () => { const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS); const COINBASE_ADDRESS = EthAddress.random(); @@ -25,26 +30,29 @@ describe('client_prover', () => { let feeJuiceToken: GetContractReturnType; let feeJuicePortal: GetContractReturnType; - beforeAll(async () => { - t.logger.warn(`Running suite with ${REAL_PROOFS ? 'real' : 'fake'} proofs`); + beforeAll( + async () => { + t.logger.warn(`Running suite with ${REAL_PROOFS ? 'real' : 'fake'} proofs`); - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); - ({ provenAsset, accounts, logger, wallet } = t); - [sender, recipient] = accounts; + ({ provenAsset, accounts, logger, wallet } = t); + [sender, recipient] = accounts; - feeJuicePortal = getContract({ - abi: FeeJuicePortalAbi, - address: t.l1Contracts.l1ContractAddresses.feeJuicePortalAddress.toString(), - client: t.l1Contracts.l1Client, - }); + feeJuicePortal = getContract({ + abi: FeeJuicePortalAbi, + address: t.l1Contracts.l1ContractAddresses.feeJuicePortalAddress.toString(), + client: t.l1Contracts.l1Client, + }); - feeJuiceToken = getContract({ - abi: TestERC20Abi, - address: t.l1Contracts.l1ContractAddresses.feeJuiceAddress.toString(), - client: t.l1Contracts.l1Client, - }); - }, 120_000); + feeJuiceToken = getContract({ + abi: TestERC20Abi, + address: t.l1Contracts.l1ContractAddresses.feeJuiceAddress.toString(), + client: t.l1Contracts.l1Client, + }); + }, + 15 * 60 * 1000, + ); afterAll(async () => { await t.teardown(); diff --git a/yarn-project/end-to-end/src/e2e_prover/full.test.ts b/yarn-project/end-to-end/src/e2e_prover/full.test.ts index 0afaf59aac08..615a54b23725 100644 --- a/yarn-project/end-to-end/src/e2e_prover/full.test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/full.test.ts @@ -1,6 +1,6 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import { EthAddress } from '@aztec/aztec.js/addresses'; -import { NO_WAIT, waitForProven } from '@aztec/aztec.js/contracts'; +import { BatchCall, NO_WAIT, waitForProven } from '@aztec/aztec.js/contracts'; import { waitForTx } from '@aztec/aztec.js/node'; import { Tx, TxExecutionResult } from '@aztec/aztec.js/tx'; import { RollupContract } from '@aztec/ethereum/contracts'; @@ -10,6 +10,8 @@ import { parseBooleanEnv } from '@aztec/foundation/config'; import { getTestData, isGenerateTestDataEnabled } from '@aztec/foundation/testing'; import { updateProtocolCircuitSampleInputs } from '@aztec/foundation/testing/files'; import { FeeJuicePortalAbi, TestERC20Abi } from '@aztec/l1-artifacts'; +import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; +import { ParentContract } from '@aztec/noir-test-contracts.js/Parent'; import { Gas } from '@aztec/stdlib/gas'; import { PrivateKernelTailCircuitPublicInputs } from '@aztec/stdlib/kernel'; import { ChonkProof } from '@aztec/stdlib/proofs'; @@ -17,17 +19,25 @@ import type { CircuitName } from '@aztec/stdlib/stats'; import { TX_ERROR_INVALID_PROOF } from '@aztec/stdlib/tx'; import TOML from '@iarna/toml'; -import '@jest/globals'; +import { jest } from '@jest/globals'; import { type GetContractReturnType, getContract } from 'viem'; import { FullProverTest } from '../fixtures/e2e_prover_test.js'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { ProvenTx, proveInteraction } from '../test-wallet/utils.js'; -// Set a very long 15 minute timeout. -const TIMEOUT = 900_000; +const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS); + +// Real proving can take 10+ min per epoch; under pipelined 12s slots a multi-epoch test +// can exceed 30 min. Keep 15 min for fake proofs, 45 min for real. +const TIMEOUT = REAL_PROOFS ? 45 * 60 * 1000 : 15 * 60 * 1000; + +// Apply the same budget to module-level hooks (beforeAll/afterAll/afterEach) so the +// pipelined setup chain (account deploys + token deploy + mint + epoch advance + +// prover-node startup) doesn't time out. +jest.setTimeout(TIMEOUT); describe('full_prover', () => { - const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS); const COINBASE_ADDRESS = EthAddress.random(); const t = new FullProverTest('full_prover', 1, COINBASE_ADDRESS, REAL_PROOFS); @@ -42,7 +52,7 @@ describe('full_prover', () => { beforeAll(async () => { t.logger.warn(`Running suite with ${REAL_PROOFS ? 'real' : 'fake'} proofs`); - await t.setup(); + await t.setup({ ...PIPELINING_SETUP_OPTS }); ({ provenAsset, accounts, tokenSim, logger, cheatCodes, provenWallet, aztecNode } = t); [sender, recipient] = accounts; @@ -60,7 +70,7 @@ describe('full_prover', () => { address: t.l1Contracts.l1ContractAddresses.feeJuiceAddress.toString(), client: t.l1Contracts.l1Client, }); - }, 120_000); + }, TIMEOUT); afterAll(async () => { await t.teardown(); @@ -182,6 +192,34 @@ describe('full_prover', () => { if (!isGenerateTestDataEnabled() || REAL_PROOFS) { return; } + // Deploy Parent + Child and prove three private chains to regenerate + // `private-kernel-inner{,-2,-3}/Prover.toml`. The Token transfers below pack into init_2 / + // init_3 and never invoke plain `inner` / `inner_2` / `inner_3`. The planner is N=3 greedy, + // so we exercise it with three transactions: + // - 4 apps (entrypoint → parent.private_nested_static_call → parent.private_call → + // child.private_get_value) → init_3 + inner + // - 5 apps (BatchCall: nested chain + one extra leaf call) → init_3 + inner_2 + // - 6 apps (BatchCall: nested chain + two extra leaf calls) → init_3 + inner_3 + // `proveInteraction` alone is enough to capture `pushTestData('private-kernel-inner{,-2,-3}', + // ...)`; no need to land the txs. + logger.info(`Deploying Parent + Child contracts to exercise inner kernels`); + const { contract: childContract } = await ChildContract.deploy(provenWallet).send({ from: sender }); + const { contract: parentContract } = await ParentContract.deploy(provenWallet).send({ from: sender }); + // Seed a note in child so the static private_get_value reads below have something to return. + await childContract.methods.private_set_value(42n, sender).send({ from: sender }); + const getValueSelector = await childContract.methods.private_get_value.selector(); + const nestedChain = () => + parentContract.methods.private_nested_static_call(childContract.address, getValueSelector, [42n, sender]); + const extraLeaf = () => childContract.methods.private_get_value(42n, sender); + logger.info(`Proving 4-app nested-call tx to populate private-kernel-inner test data`); + await proveInteraction(provenWallet, nestedChain(), { from: sender }); + logger.info(`Proving 5-app batched tx to populate private-kernel-inner-2 test data`); + await proveInteraction(provenWallet, new BatchCall(provenWallet, [nestedChain(), extraLeaf()]), { from: sender }); + logger.info(`Proving 6-app batched tx to populate private-kernel-inner-3 test data`); + await proveInteraction(provenWallet, new BatchCall(provenWallet, [nestedChain(), extraLeaf(), extraLeaf()]), { + from: sender, + }); + // Create the two transactions const { result: privateBalance } = await provenAsset.methods.balance_of_private(sender).simulate({ from: sender }); const privateSendAmount = privateBalance / 20n; @@ -250,7 +288,11 @@ describe('full_prover', () => { ( [ 'private-kernel-init', + 'private-kernel-init-2', + 'private-kernel-init-3', 'private-kernel-inner', + 'private-kernel-inner-2', + 'private-kernel-inner-3', 'private-kernel-tail', 'private-kernel-tail-to-public', 'private-kernel-reset', diff --git a/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts b/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts index e83ca1782c54..460ddd1b4a26 100644 --- a/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts +++ b/yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts @@ -1,22 +1,27 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import type { Logger } from '@aztec/aztec.js/log'; -import type { AztecNode } from '@aztec/aztec.js/node'; import { MerkleTreeId } from '@aztec/aztec.js/trees'; import type { Wallet } from '@aztec/aztec.js/wallet'; +import { CheatCodes } from '@aztec/aztec/testing'; import { retryUntil } from '@aztec/foundation/retry'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; +import { jest } from '@jest/globals'; + +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; // Tests PXE interacting with a node that has pruned relevant blocks, preventing usage of the archive API (which PXE // should not rely on). describe('e2e_pruned_blocks', () => { + jest.setTimeout(5 * 60 * 1000); + let logger: Logger; let teardown: () => Promise; - let aztecNode: AztecNode; - let aztecNodeAdmin: AztecNodeAdmin | undefined; + let aztecNode: AztecNode & AztecNodeDebug; + let cheatCodes: CheatCodes; let wallet: Wallet; @@ -36,12 +41,13 @@ describe('e2e_pruned_blocks', () => { beforeAll(async () => { ({ aztecNode, - aztecNodeAdmin, + cheatCodes, logger, teardown, wallet, accounts: [admin, sender, recipient], } = await setup(3, { + ...AUTOMINE_E2E_OPTS, worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY, worldStateBlockCheckIntervalMS: WORLD_STATE_CHECK_INTERVAL_MS, archiverPollingIntervalMS: ARCHIVER_POLLING_INTERVAL_MS, @@ -54,10 +60,10 @@ describe('e2e_pruned_blocks', () => { afterAll(() => teardown()); - async function waitBlocks(blocks: number): Promise { - logger.warn(`Awaiting ${blocks} blocks to be mined`); + async function mineEmptyBlocks(blocks: number): Promise { + logger.warn(`Mining ${blocks} empty blocks`); for (let i = 0; i < blocks; i++) { - await token.methods.private_get_name().send({ from: admin }); + await aztecNode.mineBlock(); logger.warn(`Mined ${i + 1}/${blocks} blocks`); } } @@ -87,13 +93,15 @@ describe('e2e_pruned_blocks', () => { .data, ).toBeGreaterThan(0); - // Mine enough blocks so the first mint block gets pruned. The test infrastructure auto-proves every - // checkpoint as it lands, and with slotsInAnEpoch=1 Anvil reports finalized = latest - 2, so - // finalization lags proving by just 2 L1 blocks. We mine WORLD_STATE_CHECKPOINT_HISTORY + 3 blocks: - // WORLD_STATE_CHECKPOINT_HISTORY to push the first mint block far enough back in history, and 3 to - // account for the 2-block finality lag plus one buffer. - await aztecNodeAdmin!.setConfig({ minTxsPerBlock: 0 }); - await waitBlocks(WORLD_STATE_CHECKPOINT_HISTORY + 3); + // Mine enough empty blocks past the first mint block so it becomes eligible for pruning, then + // mark the chain as proven. AUTOMINE_E2E_OPTS disables AnvilTestWatcher (no auto-markAsProven + // loop) and no EpochTestSettler is wired in the e2e fixture, so we mark explicitly here. + // World-state prunes on the chain-finalized event; with Anvil's `finalized = latest - 2` + // heuristic, we need a couple of additional L1 blocks after markAsProven so the archiver's + // `getFinalizedL1Block` query resolves to a block that already sees the new proven tip. + await mineEmptyBlocks(WORLD_STATE_CHECKPOINT_HISTORY + 1); + await cheatCodes.rollup.markAsProven(); + await cheatCodes.eth.mineEmptyBlock(3); // The same historical query we performed before should now fail since this block is not available anymore. We poll // the node for a bit until it processes the blocks we marked as proven, causing the historical query to fail. @@ -108,8 +116,8 @@ describe('e2e_pruned_blocks', () => { } }, 'waiting for pruning', - (WORLD_STATE_CHECK_INTERVAL_MS + ARCHIVER_POLLING_INTERVAL_MS) * 5, - 0.2, + 60, + 0.5, ); // We've completed the setup we were interested in, and can now simply mint the second half of the amount, transfer diff --git a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts index bf507e00cbe2..a8eb16753b3f 100644 --- a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts @@ -7,6 +7,7 @@ import { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken'; import { foundry, sepolia } from 'viem/chains'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { setup } from '../fixtures/utils.js'; // process.env.SEQ_PUBLISHER_PRIVATE_KEY = ''; @@ -30,6 +31,7 @@ describe(`deploys and transfers a private only token`, () => { ({ logger, teardown, wallet, accounts } = await setup( 2, // Deploy 2 accounts. { + ...PIPELINING_SETUP_OPTS, numberOfInitialFundedAccounts: 2, // Fund 2 accounts. stateLoad: undefined, }, diff --git a/yarn-project/end-to-end/src/e2e_publisher_funding_multi.test.ts b/yarn-project/end-to-end/src/e2e_publisher_funding_multi.test.ts index e48477c8fefa..940174e33e24 100644 --- a/yarn-project/end-to-end/src/e2e_publisher_funding_multi.test.ts +++ b/yarn-project/end-to-end/src/e2e_publisher_funding_multi.test.ts @@ -17,6 +17,7 @@ import { join } from 'path'; import { type Hex, parseEther } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from './fixtures/utils.js'; // Key indices from the test MNEMONIC (all pre-funded by Anvil): @@ -89,6 +90,7 @@ describe('e2e_publisher_funding_multi', () => { sequencer: sequencerClient, ethCheatCodes, } = await setup(0, { + ...PIPELINING_SETUP_OPTS, initialValidators, keyStoreDirectory, publisherFundingThreshold: FUNDING_THRESHOLD, @@ -156,9 +158,11 @@ describe('e2e_publisher_funding_multi', () => { // Funder should have sent 2 * FUNDING_AMOUNT plus gas costs (single multicall) expect(funderSpent).toBeGreaterThanOrEqual(2n * FUNDING_AMOUNT); - // Second round: after funding, publishers are above threshold. The active publisher will - // spend gas publishing blocks and eventually drop below threshold again, triggering re-funding - // for that one publisher. + // Second round: deterministically drop one publisher below threshold after the first refill. + // Waiting for organic gas depletion is brittle under pipelined publisher rotation: the exact + // publisher cadence and L1 gas burn vary enough that the balance may not cross the threshold + // before the test timeout, even though the periodic funding loop is healthy. + await ethCheatCodes.setBalance(publisher1Address, LOW_BALANCE); const funderBalanceBefore2 = await ethCheatCodes.getBalance(funderAddress); logger.info(`Waiting for second funding round`); diff --git a/yarn-project/end-to-end/src/e2e_pxe.test.ts b/yarn-project/end-to-end/src/e2e_pxe.test.ts index efeb60c27cbe..8b34d702cac0 100644 --- a/yarn-project/end-to-end/src/e2e_pxe.test.ts +++ b/yarn-project/end-to-end/src/e2e_pxe.test.ts @@ -3,6 +3,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -20,7 +21,7 @@ describe('e2e_pxe', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts b/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts index 5c8e4e2fdfc2..d12c4fe0d80f 100644 --- a/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts +++ b/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts @@ -2,6 +2,7 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { ScopeTestContract } from '@aztec/noir-test-contracts.js/ScopeTest'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e scope isolation', () => { @@ -18,7 +19,7 @@ describe('e2e scope isolation', () => { const BOB_NOTE_VALUE = 100n; beforeAll(async () => { - ({ teardown, wallet, accounts } = await setup(3)); + ({ teardown, wallet, accounts } = await setup(3, { ...AUTOMINE_E2E_OPTS })); [alice, bob, charlie] = accounts; ({ contract } = await ScopeTestContract.deploy(wallet).send({ from: alice })); diff --git a/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts index a333e9129db4..216b0abef73e 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts @@ -20,6 +20,7 @@ import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../fixtures/utils.js'; const OPEN_THE_HATCH = true; @@ -61,20 +62,25 @@ describe('e2e_escape_hatch_vote_only', () => { }); const context = await setup(1, { + ...PIPELINING_SETUP_OPTS, anvilAccounts: 10, aztecTargetCommitteeSize: COMMITTEE_SIZE, initialValidators: validators.map(v => ({ ...v, bn254SecretKey: new SecretValue(Fr.random().toBigInt()) })), validatorPrivateKeys: new SecretValue(validators.map(v => v.privateKey)), governanceProposerRoundSize: ROUND_SIZE, governanceProposerQuorum: QUORUM_SIZE, + // Override PIPELINING_SETUP_OPTS slot durations for the longer cadence this test needs. ethereumSlotDuration: ETHEREUM_SLOT_DURATION, aztecSlotDuration: AZTEC_SLOT_DURATION, aztecEpochDuration: AZTEC_EPOCH_DURATION, // Keep pruning far away for this test. aztecProofSubmissionEpochs: 15, // needed so ACTIVE_DURATION=2 is a valid EscapeHatch config - minTxsPerBlock: 0, enforceTimeTable: true, automineL1Setup: true, + // Pipelining opts — exercise the §6 B5 fix (tryVoteWhenEscapeHatchOpen signing/submitting for targetSlot). + // inboxLag: 2 so the sequencer sources L1->L2 messages from a sealed checkpoint when building for slot+1. + enableProposerPipelining: true, + inboxLag: 2, }); ({ @@ -142,25 +148,45 @@ describe('e2e_escape_hatch_vote_only', () => { afterEach(() => teardown()); it('casts governance signals and advances checkpoints while escape hatch is closed', async () => { + const sequencer = sequencerClient!.getSequencer(); + // Enable voting from the sequencer. await aztecNodeAdmin!.setConfig({ governanceProposerPayload: newGovernanceProposerPayloadAddress, minTxsPerBlock: 0, }); - // Set up event listeners to track sequencer behavior + // We need to set it for hatch 1, and then make a time jump. We do this such that we don't pollute the epoch cache. + // The warp must happen before we attach failure-event listeners, because any checkpoint proposal in flight at warp + // time will fail (its propose tx becomes invalid after the L1 timestamp jump) — that is a test-setup artifact, not + // a behavior we are asserting on. + if (OPEN_THE_HATCH) { + await ethCheatCodes.store( + await rollup.getEscapeHatchAddress(), + ethCheatCodes.keccak256(BigInt(EscapeHatchStorage.find(s => s.label === '$designatedProposer')!.slot), 1n), + escapeHatchProposerAddress.toField().toBigInt(), + ); + expect(await rollup.isEscapeHatchOpen(EpochNumber(Number(ESCAPE_HATCH_FREQUENCY)))).toBeTruthy(); + + logger.info(`Advancing to epoch ${ESCAPE_HATCH_FREQUENCY}`); + + await cheatCodes.rollup.advanceToEpoch(EpochNumber(Number(ESCAPE_HATCH_FREQUENCY)), { + offset: -ETHEREUM_SLOT_DURATION, + }); + } + + // Set up event listeners to track sequencer behavior during the vote-only window const failEvents: Array<{ type: keyof SequencerEvents; args: any }> = []; const blockProposedEvents: Array<{ blockNumber: any; slot: any }> = []; const checkpointPublishedEvents: Array<{ checkpoint: any; slot: any }> = []; - const sequencer = sequencerClient!.getSequencer(); - // Track failure events that indicate problems const failEventTypes: (keyof SequencerEvents)[] = [ 'block-build-failed', 'checkpoint-publish-failed', 'proposer-rollup-check-failed', 'checkpoint-error', + 'header-validation-failed', ]; failEventTypes.forEach(eventType => { @@ -191,22 +217,6 @@ describe('e2e_escape_hatch_vote_only', () => { logger.warn(`Sequencer published checkpoint when escape hatch should be open`, args); }); - // We need to set it for hatch 1, and then make a time jump. We do this such that we don't pollute the epoch cache - if (OPEN_THE_HATCH) { - await ethCheatCodes.store( - await rollup.getEscapeHatchAddress(), - ethCheatCodes.keccak256(BigInt(EscapeHatchStorage.find(s => s.label === '$designatedProposer')!.slot), 1n), - escapeHatchProposerAddress.toField().toBigInt(), - ); - expect(await rollup.isEscapeHatchOpen(EpochNumber(Number(ESCAPE_HATCH_FREQUENCY)))).toBeTruthy(); - - logger.info(`Advancing to epoch ${ESCAPE_HATCH_FREQUENCY}`); - - await cheatCodes.rollup.advanceToEpoch(EpochNumber(Number(ESCAPE_HATCH_FREQUENCY)), { - offset: -ETHEREUM_SLOT_DURATION, - }); - } - const getStats = async () => ({ slot: await rollup.getSlotNumber(), epoch: await rollup.getEpochNumberForSlotNumber(await rollup.getSlotNumber()), @@ -228,20 +238,37 @@ describe('e2e_escape_hatch_vote_only', () => { 1, ); - const finalStats = await getStats(); - - // Due to the the stats not being pulled at the same time, a vote could land after the slot is fetched, but before the votes are. - // Therefore, we use the slots passed as the lower bound. - const slotsPassed = finalStats.slot - initialStats.slot; + // Snapshot the slot we will assert against now; under proposer pipelining the sequencer signs a vote in build + // slot N for target slot N+1 and submits it at the start of N+1, so the votes corresponding to slots up through + // `slotAtMeasurement` lag the current slot by one. Wait for the L1 slot to advance one more so the last + // in-flight vote (signed for `slotAtMeasurement`) has time to mine before we count votes. + const slotAtMeasurement = await rollup.getSlotNumber(); + const slotsPassed = slotAtMeasurement - initialStats.slot; expect(slotsPassed).toBeGreaterThan(0); + const drainTarget = slotAtMeasurement + 2; + await retryUntil( + () => rollup.getSlotNumber().then(s => s >= drainTarget), + 'pipelined vote drain', + AZTEC_SLOT_DURATION * 4, + 1, + ); + + const finalStats = await getStats(); expect(finalStats.votes - initialStats.votes).toBeGreaterThanOrEqual(slotsPassed); if (OPEN_THE_HATCH) { expect(finalStats.pending - initialStats.pending).toBe(0); // When escape hatch is open, sequencer should only vote, not build blocks nor checkpoints, but there should also be no failures. - expect(blockProposedEvents).toEqual([]); - expect(failEvents).toEqual([]); - expect(checkpointPublishedEvents).toEqual([]); + // Filter out events corresponding to pre-warp slots — they are checkpoint proposals that were in flight when + // the test warped past their target slot and whose L1 propose tx then fails. That's a setup artifact of the + // warp, not behavior we are asserting on in the vote-only window. + const inVoteOnlyWindow = (e: T) => { + const slotValue = (e as any).slot ?? (e as any).args?.slot; + return slotValue === undefined || Number(slotValue) >= Number(initialStats.slot); + }; + expect(blockProposedEvents.filter(inVoteOnlyWindow)).toEqual([]); + expect(failEvents.filter(inVoteOnlyWindow)).toEqual([]); + expect(checkpointPublishedEvents.filter(inVoteOnlyWindow)).toEqual([]); } else { expect(finalStats.pending - initialStats.pending).toBeGreaterThanOrEqual(slotsPassed); } diff --git a/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts index 8795dc257a6f..ec03b1615960 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts @@ -28,6 +28,7 @@ import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client' import { jest } from '@jest/globals'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../fixtures/utils.js'; const ETHEREUM_SLOT_DURATION = 8; @@ -66,6 +67,7 @@ describe('e2e_gov_proposal', () => { let accounts: AztecAddress[] = []; const context = await setup(1, { + ...PIPELINING_SETUP_OPTS, anvilAccounts: 100, aztecTargetCommitteeSize: COMMITTEE_SIZE, initialValidators: validators.map(v => ({ ...v, bn254SecretKey: new SecretValue(Fr.random().toBigInt()) })), @@ -78,6 +80,15 @@ describe('e2e_gov_proposal', () => { minTxsPerBlock: TXS_PER_BLOCK, enforceTimeTable: true, automineL1Setup: true, // speed up setup + // Force the L1 sync to fetch blobs rather than promote the locally-proposed checkpoint. + // The "should vote even when unable to build blocks" test relies on the blob client being the + // only source of truth for block sync: disabling the blob client should make the tx un-syncable. + // Under pipelining the proposer also enters its proposed checkpoint into the local store + // (proposal_handler.ts § setProposedCheckpointFromBlocks), and the L1 synchronizer would then + // promote that proposed checkpoint into a published one without going through the blob client + // (l1_synchronizer.ts § tryBuildPublishedCheckpointFromProposed). Forcing the blob path here + // restores the legacy assumption for both tests in this describe block. + skipPromoteProposedCheckpointDuringL1Sync: true, }); ({ @@ -138,8 +149,12 @@ describe('e2e_gov_proposal', () => { round, }); - // We warp to one L1 slot before the start of the slot, since that's when we start building the L2 block - await cheatCodes.eth.warp(Number(nextRoundBeginsAtTimestamp) - ETHEREUM_SLOT_DURATION, { + // Under proposer pipelining the sequencer for slot N builds during slot N-1 and the L1 propose mines in slot N. + // So to land a vote in the very first slot of the round we need to be in the build slot for it, which is one + // L2 slot (not one L1 slot) earlier. Warping just one L1 slot before the round start puts the sequencer in the + // build slot for round_start+1, costing us the first vote of the round. Warp one full L2 slot earlier instead + // so the build slot for round_start fires while we are inside the round. + await cheatCodes.eth.warp(Number(nextRoundBeginsAtTimestamp) - AZTEC_SLOT_DURATION - ETHEREUM_SLOT_DURATION, { resetBlockInterval: true, }); @@ -168,6 +183,12 @@ describe('e2e_gov_proposal', () => { // We know that this will last at least as long as the round duration, // since we wait for the txs to be mined, and do so `roundDuration` times. // Simultaneously, we should be voting for the proposal in every slot. + // + // Under proposer pipelining, the proposer for slot N builds in slot N-1 and the L1 propose tx mines during + // slot N. After the L1-time warp in setupVotingRound, the first post-warp checkpoint takes at least two slots + // to land (one to detect the new wall-clock slot and start a pipelined build, one for the propose to mine). + // Allow up to 3 slots per tx to absorb that warp catch-up and pipelining lag. + const waitForTxTimeout = AZTEC_SLOT_DURATION * 3 + 10; for (let i = 0; i < roundDuration; i++) { const txHashes = await timesAsync(TXS_PER_BLOCK, async () => { const { txHash } = await testContract.methods @@ -178,7 +199,7 @@ describe('e2e_gov_proposal', () => { await Promise.all( txHashes.map((hash, j) => { logger.info(`Waiting for tx ${i}-${j}: ${hash} to be mined`); - return waitForTx(aztecNode!, hash, { timeout: AZTEC_SLOT_DURATION + 10 }); + return waitForTx(aztecNode!, hash, { timeout: waitForTxTimeout }); }), ); } @@ -190,21 +211,39 @@ describe('e2e_gov_proposal', () => { it('should vote even when unable to build blocks', async () => { const monitor = new ChainMonitor(rollup, dateProvider).start(); - // Break the blob client so no new blocks are synced + // Disable the in-process proposer→archiver block shortcut (validator-client and + // checkpoint_proposal_job both push the just-built block into the local archiver) and then + // disable the blob client. The archiver-side `skipPromoteProposedCheckpointDuringL1Sync` + // shortcut is disabled at setup() — without it the L1 synchronizer would promote the locally + // proposed checkpoint into a published one without going through the blob client, and the + // tx would still be observed as `checkpointed` regardless of the disabled blob client. With + // all three shortcuts off the node has no choice but to rely on the blob client for sync. + await aztecNodeAdmin!.setConfig({ skipPushProposedBlocksToArchiver: true }); ((aztecNodeAdmin as AztecNodeService).getBlobClient() as HttpBlobClient).setDisabled(true); await sleep(1000); const lastBlockSynced = await aztecNode!.getBlockNumber(); logger.warn(`blob client is disabled (last block synced is ${lastBlockSynced})`); - // And send a tx which shouldnt be syncable but does move the block forward + // And send a tx which shouldnt be syncable but does move the block forward. + // Under proposer pipelining the proposer builds in slot N-1 and the L1 propose mines in slot N, so a single + // slot is not enough to observe the L1 checkpoint advance. Wait at least two slots before declaring the tx + // un-syncable and before checking that L1 has progressed. await expect(() => testContract.methods .create_l2_to_l1_message_arbitrary_recipient_private(Fr.random(), EthAddress.random()) - .send({ from: defaultAccountAddress, wait: { timeout: AZTEC_SLOT_DURATION + 2 } }), + .send({ from: defaultAccountAddress, wait: { timeout: AZTEC_SLOT_DURATION * 2 + 2 } }), ).rejects.toThrow(TimeoutError); logger.warn(`Test tx timed out as expected`); - // Check that the block number has indeed increased on L1 so sequencers cant pass the sync check + // Check that the block number has indeed increased on L1 so sequencers cant pass the sync check. + // Allow another slot for any in-flight L1 propose to mine, since the work loop above hits its wait timeout the + // moment the tx misses L2 sync, not the moment the L1 tx lands. + await retryUntil( + async () => (await monitor.run().then(b => b.checkpointNumber)) > lastBlockSynced, + 'L1 checkpoint to advance after disabling blob client', + AZTEC_SLOT_DURATION + 5, + 1, + ); expect(await monitor.run().then(b => b.checkpointNumber)).toBeGreaterThan(lastBlockSynced); logger.warn(`L2 block number has increased on L1`); @@ -212,9 +251,11 @@ describe('e2e_gov_proposal', () => { await aztecNodeAdmin!.setConfig({ governanceProposerPayload: newGovernanceProposerAddress }); const { round, roundDuration, nextRoundBeginsAtSlot } = await setupVotingRound(); - // And wait until the round is over + // And wait until the round is over. Add one extra slot to absorb pipelining catch-up after the L1 warp in + // setupVotingRound — the proposer for round_start builds during the slot before it, so the L1 chain takes + // an extra slot to advance past nextRoundEndsAtSlot. const nextRoundEndsAtSlot = SlotNumber(nextRoundBeginsAtSlot + Number(roundDuration)); - const timeout = AZTEC_SLOT_DURATION * Number(roundDuration + 1n) + 20; + const timeout = AZTEC_SLOT_DURATION * Number(roundDuration + 2n) + 20; logger.warn(`Waiting until slot ${nextRoundEndsAtSlot} for round to end (timeout ${timeout}s)`); await retryUntil(() => rollup.getSlotNumber().then(s => s > nextRoundEndsAtSlot), 'round end', timeout, 1); diff --git a/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts index 30e71f924153..89c975f297b6 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts @@ -19,6 +19,7 @@ import { tmpdir } from 'os'; import { join } from 'path'; import { privateKeyToAccount } from 'viem/accounts'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../fixtures/utils.js'; const VALIDATOR_KEY_INDICES = [0, 2, 4, 5]; @@ -92,6 +93,7 @@ describe('e2e_reload_keystore', () => { accounts: [ownerAddress], sequencer: sequencerClient, } = await setup(1, { + ...PIPELINING_SETUP_OPTS, initialValidators, aztecTargetCommitteeSize: COMMITTEE_SIZE, keyStoreDirectory, diff --git a/yarn-project/end-to-end/src/e2e_sequencer/slasher_config.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/slasher_config.test.ts index bbd0e37baf45..da24120ff255 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/slasher_config.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/slasher_config.test.ts @@ -2,6 +2,7 @@ import type { TestAztecNodeService } from '@aztec/aztec-node/test'; import type { SlasherClientInterface } from '@aztec/slasher'; import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; +import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js'; import { type EndToEndContext, setup } from '../fixtures/utils.js'; describe('e2e_slasher_config', () => { @@ -11,6 +12,7 @@ describe('e2e_slasher_config', () => { beforeAll(async () => { ({ aztecNodeAdmin, aztecNode, teardown } = await setup(0, { + ...PIPELINING_SETUP_OPTS, anvilSlotsInAnEpoch: 4, slashInactivityTargetPercentage: 1, slashInactivityPenalty: 42n, diff --git a/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts b/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts index 40316c6152ea..91c964ed1e07 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts @@ -12,6 +12,7 @@ import { EmbeddedWallet } from '@aztec/wallets/embedded'; import { jest } from '@jest/globals'; import 'jest-extended'; +import { PIPELINED_FEE_PADDING, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_sequencer_config', () => { @@ -35,6 +36,7 @@ describe('e2e_sequencer_config', () => { beforeAll(async () => { const [botAccount] = await getInitialTestAccountsData(); ({ teardown, sequencer, aztecNode, logger } = await setup(0, { + ...PIPELINING_SETUP_OPTS, maxL2BlockGas: manaTarget * 2, manaTarget: BigInt(manaTarget), initialFundedAccounts: [botAccount], @@ -43,7 +45,10 @@ describe('e2e_sequencer_config', () => { ...getBotDefaultConfig(), followChain: 'CHECKPOINTED', botMode: 'transfer', - txMinedWaitSeconds: 12, + txMinedWaitSeconds: 60, + // Match pipelining fee padding so the bot's maxFeesPerGas keeps up with + // fee-asset price evolution between PXE snapshot and inclusion. + minFeePadding: PIPELINED_FEE_PADDING, }; wallet = await EmbeddedWallet.create(aztecNode, { ephemeral: true }); const accountManager = await wallet.createSchnorrAccount( diff --git a/yarn-project/end-to-end/src/e2e_simple.test.ts b/yarn-project/end-to-end/src/e2e_simple.test.ts index 0732b761fb88..c58e75d68ef9 100644 --- a/yarn-project/end-to-end/src/e2e_simple.test.ts +++ b/yarn-project/end-to-end/src/e2e_simple.test.ts @@ -11,6 +11,7 @@ import { StatefulTestContractArtifact } from '@aztec/noir-test-contracts.js/Stat import { jest } from '@jest/globals'; import 'jest-extended'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_simple', () => { @@ -37,14 +38,13 @@ describe('e2e_simple', () => { config, aztecNode, } = await setup(1, { + ...PIPELINING_SETUP_OPTS, archiverPollingIntervalMS: 200, sequencerPollingIntervalMS: 200, worldStateBlockCheckIntervalMS: 200, blockCheckIntervalMS: 200, minTxsPerBlock: 1, aztecEpochDuration: 4, - aztecSlotDuration: 12, - ethereumSlotDuration: 4, aztecTargetCommitteeSize: 0, startProverNode: true, })); diff --git a/yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts b/yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts new file mode 100644 index 000000000000..3dc0f67ad3e5 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts @@ -0,0 +1,574 @@ +import type { AztecNodeService } from '@aztec/aztec-node'; +import type { TestAztecNodeService } from '@aztec/aztec-node/test'; +import { EthAddress } from '@aztec/aztec.js/addresses'; +import { NO_WAIT } from '@aztec/aztec.js/contracts'; +import { Fr, GrumpkinScalar } from '@aztec/aztec.js/fields'; +import type { RollupCheatCodes } from '@aztec/aztec/testing'; +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { BlockNumber, EpochNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; +import { Buffer32 } from '@aztec/foundation/buffer'; +import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; +import { retryUntil } from '@aztec/foundation/retry'; +import { getPXEConfig } from '@aztec/pxe/server'; +import type { SequencerEvents } from '@aztec/sequencer-client'; +import { OffenseType } from '@aztec/slasher'; +import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { makeBlockHeader, makeBlockProposal } from '@aztec/stdlib/testing'; +import { TxHash } from '@aztec/stdlib/tx'; + +import { jest } from '@jest/globals'; +import fs from 'fs'; +import os from 'os'; +import path from 'path'; + +import { P2PNetworkTest } from '../e2e_p2p/p2p_network.js'; +import { awaitCommitteeExists } from '../e2e_p2p/shared.js'; +import { shouldCollectMetrics } from '../fixtures/fixtures.js'; +import { SchnorrHardcodedKeyAccountContract } from '../fixtures/schnorr_hardcoded_account_contract.js'; +import { ATTESTER_PRIVATE_KEYS_START_INDEX, createNode } from '../fixtures/setup_p2p_test.js'; +import { getPrivateKeyFromIndex } from '../fixtures/utils.js'; +import { TestWallet } from '../test-wallet/test_wallet.js'; + +const TEST_TIMEOUT = 1_000_000; + +jest.setTimeout(TEST_TIMEOUT); + +const NUM_VALIDATORS = 3; +const BOOT_NODE_UDP_PORT = 4700; +const COMMITTEE_SIZE = NUM_VALIDATORS; +const ETHEREUM_SLOT_DURATION = 4; +const AZTEC_SLOT_DURATION = 36; +const BLOCK_DURATION_MS = 8_000; +const BLOCKS_PER_CHECKPOINT = 3; +const BAD_BLOCK_INDEX_WITHIN_CHECKPOINT = 1; +const BAD_SLOT_COMPLETION_TIMEOUT = AZTEC_SLOT_DURATION * 3; +const LAZY_ATTESTATION_TIMEOUT = AZTEC_SLOT_DURATION * 3; +const OFFENSE_DETECTION_TIMEOUT = AZTEC_SLOT_DURATION * 3; +const INVALID_BLOCK_REMOVAL_TIMEOUT = AZTEC_SLOT_DURATION * 3; + +const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'attested-invalid-proposal-')); + +type BlockProposedEvent = Parameters[0]; +type SlashOffense = Awaited>[number]; + +function findSlashOffense(offenses: SlashOffense[], validator: EthAddress, offenseType: OffenseType, slot: SlotNumber) { + return offenses.find( + offense => + offense.validator.equals(validator) && + offense.offenseType === offenseType && + offense.epochOrSlot === BigInt(slot), + ); +} + +function getAttesterSigner(validatorIndex: number) { + const privateKey = getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + validatorIndex)!; + return new Secp256k1Signer(Buffer32.fromBuffer(privateKey)); +} + +async function makeEquivocatedBlockProposal({ + blockNumber, + targetSlot, + signer, + signatureContext, +}: { + blockNumber: number; + targetSlot: SlotNumber; + signer: Secp256k1Signer; + signatureContext: CoordinationSignatureContext; +}) { + return await makeBlockProposal({ + blockHeader: makeBlockHeader(0xa521, { + blockNumber: BlockNumber(blockNumber), + slotNumber: targetSlot, + }), + indexWithinCheckpoint: IndexWithinCheckpoint(BAD_BLOCK_INDEX_WITHIN_CHECKPOINT), + txHashes: [TxHash.random()], + archiveRoot: Fr.random(), + signer, + signatureContext, + }); +} + +async function submitDeploymentTxsWithoutWaiting(node: AztecNodeService, t: P2PNetworkTest, numTxs: number) { + const wallet = await TestWallet.create( + node, + { ...getPXEConfig(), proverEnabled: false, syncChainTip: 'checkpointed' }, + { loggerActorLabel: 'pxe-tx' }, + ); + const fundedAccountManager = await wallet.createAccount({ + secret: t.fundedAccount.secret, + salt: t.fundedAccount.salt, + contract: new SchnorrHardcodedKeyAccountContract(), + }); + + const txHashes = []; + for (let i = 0; i < numTxs; i++) { + const accountManager = await wallet.createSchnorrAccount(Fr.random(), Fr.random(), GrumpkinScalar.random()); + const deployMethod = await accountManager.getDeployMethod(); + const { txHash } = await deployMethod.send({ from: fundedAccountManager.address, wait: NO_WAIT }); + txHashes.push(txHash); + } + return txHashes; +} + +async function getBlockHash(node: AztecNodeService, blockNumber: number) { + const block = await node.getBlockData(BlockNumber(blockNumber)); + return block ? (await block.header.hash()).toString() : undefined; +} + +async function advanceToEpochBeforePipelinedTargetSlot({ + epochCache, + cheatCodes, + targetProposer, + logger, + maxAttempts = 30, +}: { + epochCache: EpochCacheInterface; + cheatCodes: RollupCheatCodes; + targetProposer: EthAddress; + logger: P2PNetworkTest['logger']; + maxAttempts?: number; +}): Promise<{ targetEpoch: EpochNumber; targetSlot: SlotNumber }> { + const { epochDuration } = await cheatCodes.getConfig(); + + for (let attempt = 0; attempt < maxAttempts; attempt++) { + const currentEpoch = await cheatCodes.getEpoch(); + const nextEpoch = Number(currentEpoch) + 1; + const firstSlotOfNextEpoch = nextEpoch * Number(epochDuration); + const pipelinedTargetSlot = SlotNumber(firstSlotOfNextEpoch + 1); + const proposer = await epochCache.getProposerAttesterAddressInSlot(pipelinedTargetSlot); + + logger.info( + `Checking pipelined target slot ${pipelinedTargetSlot} in epoch ${nextEpoch} for proposer ${targetProposer}`, + { proposer: proposer?.toString() }, + ); + + if (proposer?.equals(targetProposer)) { + return { targetEpoch: EpochNumber(nextEpoch), targetSlot: pipelinedTargetSlot }; + } + + await cheatCodes.advanceToNextEpoch(); + } + + throw new Error(`Target proposer ${targetProposer.toString()} not found after ${maxAttempts} epoch attempts`); +} + +describe('e2e_slashing_attested_invalid_proposal', () => { + let t: P2PNetworkTest; + let nodes: AztecNodeService[] = []; + + beforeEach(async () => { + t = await P2PNetworkTest.create({ + testName: 'e2e_slashing_attested_invalid_proposal', + numberOfNodes: 0, + numberOfValidators: NUM_VALIDATORS, + basePort: BOOT_NODE_UDP_PORT, + metricsPort: shouldCollectMetrics(), + initialConfig: { + anvilSlotsInAnEpoch: 4, + listenAddress: '127.0.0.1', + aztecEpochDuration: 2, + ethereumSlotDuration: ETHEREUM_SLOT_DURATION, + aztecSlotDuration: AZTEC_SLOT_DURATION, + aztecTargetCommitteeSize: COMMITTEE_SIZE, + aztecProofSubmissionEpochs: 1024, + slashInactivityConsecutiveEpochThreshold: 32, + mockGossipSubNetwork: true, + minTxsPerBlock: 1, + maxTxsPerBlock: 1, + minBlocksForCheckpoint: BLOCKS_PER_CHECKPOINT, + maxBlocksPerCheckpoint: BLOCKS_PER_CHECKPOINT, + publishTxsWithProposals: true, + enforceTimeTable: true, + blockDurationMs: BLOCK_DURATION_MS, + l1PublishingTime: 2, + attestationPropagationTime: 0.5, + enableProposerPipelining: true, + slashDuplicateProposalPenalty: 1n, + }, + }); + + await t.setup(); + await t.applyBaseSetup(); + }); + + afterEach(async () => { + await t.stopNodes(nodes); + await t.teardown(); + for (let i = 0; i < NUM_VALIDATORS; i++) { + fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); + } + }); + + async function createInvalidProposalSlashingScenario({ + badProposerConfig = {}, + }: { badProposerConfig?: Partial[0]> } = {}) { + const { rollup } = await t.getContracts(); + + await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); + await t.ctx.cheatCodes.rollup.debugRollup(); + + const badProposerNode = await createNode( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + invalidBlockProposalIndexWithinCheckpoint: BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + ...badProposerConfig, + }, + t.ctx.dateProvider!, + BOOT_NODE_UDP_PORT + 1, + t.bootstrapNodeEnr, + 0, + t.genesis, + `${DATA_DIR}-0`, + shouldCollectMetrics(), + ); + + const lazyValidatorNode = await createNode( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + skipProposalSlotValidation: true, + skipCheckpointProposalValidation: true, + }, + t.ctx.dateProvider!, + BOOT_NODE_UDP_PORT + 2, + t.bootstrapNodeEnr, + 1, + t.genesis, + `${DATA_DIR}-1`, + shouldCollectMetrics(), + ); + + const honestValidatorNode = await createNode( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + skipProposalSlotValidation: true, + }, + t.ctx.dateProvider!, + BOOT_NODE_UDP_PORT + 3, + t.bootstrapNodeEnr, + 2, + t.genesis, + `${DATA_DIR}-2`, + shouldCollectMetrics(), + ); + + nodes = [badProposerNode, lazyValidatorNode, honestValidatorNode]; + + const badProposer = t.validators[0].attester; + const lazyValidator = t.validators[1].attester; + const honestValidator = t.validators[2].attester; + t.logger.warn('Created invalid proposal slashing scenario actors', { + badProposer: badProposer.toString(), + lazyValidator: lazyValidator.toString(), + honestValidator: honestValidator.toString(), + }); + + await awaitCommitteeExists({ rollup, logger: t.logger }); + + const epochCache = (honestValidatorNode as TestAztecNodeService).epochCache; + const { targetEpoch, targetSlot } = await advanceToEpochBeforePipelinedTargetSlot({ + epochCache, + cheatCodes: t.ctx.cheatCodes.rollup, + targetProposer: badProposer, + logger: t.logger, + }); + + const txHashes = await submitDeploymentTxsWithoutWaiting(badProposerNode, t, BLOCKS_PER_CHECKPOINT); + t.logger.warn(`Submitted ${txHashes.length} transactions for the checkpoint`, { + txHashes: txHashes.map(txHash => txHash.toString()), + targetEpoch, + targetSlot, + }); + + await retryUntil( + async () => { + const pendingTxCount = await badProposerNode.getPendingTxCount(); + t.logger.info(`Bad proposer pending tx count is ${pendingTxCount}`); + return pendingTxCount >= 3; + }, + 'bad proposer pending txs', + AZTEC_SLOT_DURATION, + 0.5, + ); + + const badProposerBlockProposedEvents: BlockProposedEvent[] = []; + badProposerNode + .getSequencer()! + .getSequencer() + .on('block-proposed', (args: BlockProposedEvent) => { + if (Number(args.slot) !== Number(targetSlot)) { + return; + } + + badProposerBlockProposedEvents.push(args); + t.logger.warn('Captured bad proposer block-proposed event', { + ...args, + blockHash: args.blockHash.toString(), + }); + }); + + await Promise.all(nodes.map(node => node.getSequencer()!.start())); + + t.logger.warn(`Advancing to epoch ${targetEpoch}; bad proposer should build for slot ${targetSlot}`); + await t.ctx.cheatCodes.rollup.advanceToEpoch(targetEpoch); + + const badCheckpointBlockHashes = await retryUntil( + () => { + const blocksByNumber = new Map( + badProposerBlockProposedEvents.map(event => [ + event.blockNumber.toString(), + { + number: Number(event.blockNumber), + checkpointNumber: Number(event.checkpointNumber), + indexWithinCheckpoint: Number(event.indexWithinCheckpoint), + hash: event.blockHash.toString(), + }, + ]), + ); + const proposedBlocks = [...blocksByNumber.values()].sort( + (a, b) => a.indexWithinCheckpoint - b.indexWithinCheckpoint, + ); + const badBlock = proposedBlocks.find( + block => block.indexWithinCheckpoint === BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + ); + + t.logger.warn('Waiting for bad proposer block-proposed events for invalid checkpoint', { + targetSlot, + badBlockIndexWithinCheckpoint: BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + proposedBlocks, + badBlock, + }); + + return proposedBlocks.length >= BLOCKS_PER_CHECKPOINT && badBlock ? proposedBlocks : undefined; + }, + 'bad proposer invalid checkpoint block-proposed events', + AZTEC_SLOT_DURATION, + 1, + ); + const badBlock = badCheckpointBlockHashes.find( + block => block.indexWithinCheckpoint === BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + ); + t.logger.warn('Captured invalid checkpoint blocks from bad proposer block-proposed events', { + targetSlot, + badBlockIndexWithinCheckpoint: BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + badBlock, + badCheckpointBlockHashes, + }); + + const lazyAttestations = await retryUntil( + async () => { + const attestations = await lazyValidatorNode.getP2P().getCheckpointAttestationsForSlot(targetSlot); + const lazyValidatorAttestations = attestations.filter(attestation => + attestation.getSender()?.equals(lazyValidator), + ); + t.logger.warn('Waiting for lazy validator attestation before checking assertions', { + targetSlot, + attestationCount: attestations.length, + lazyValidatorAttestationCount: lazyValidatorAttestations.length, + attesters: attestations.map(attestation => attestation.getSender()?.toString()), + }); + return lazyValidatorAttestations.length > 0 ? attestations : undefined; + }, + 'lazy validator checkpoint attestation', + LAZY_ATTESTATION_TIMEOUT, + 1, + ); + const honestAttestations = await honestValidatorNode.getP2P().getCheckpointAttestationsForSlot(targetSlot); + const initialOffenses = await honestValidatorNode.getSlashOffenses('all'); + t.logger.warn('Observed state after invalid checkpoint proposal scenario', { + targetSlot, + invalidBlockIndexWithinCheckpoint: BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + lazyNodeAttestationCount: lazyAttestations.length, + lazyNodeAttesters: lazyAttestations.map(attestation => attestation.getSender()?.toString()), + honestNodeAttestationCount: honestAttestations.length, + honestNodeAttesters: honestAttestations.map(attestation => attestation.getSender()?.toString()), + offenses: initialOffenses, + }); + + const expectedSlashOffenses = [ + { + description: 'bad proposer broadcasted invalid block proposal', + validator: badProposer, + offenseType: OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL, + }, + { + description: 'lazy validator attested to invalid checkpoint proposal', + validator: lazyValidator, + offenseType: OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, + }, + ]; + + const offensesWithExpectedSlashes = await retryUntil( + async () => { + const currentOffenses = await honestValidatorNode.getSlashOffenses('all'); + t.logger.warn('Waiting for expected slash offenses on honest validator', { + targetSlot, + offenses: currentOffenses, + }); + return expectedSlashOffenses.every( + ({ validator, offenseType }) => + findSlashOffense(currentOffenses, validator, offenseType, targetSlot) !== undefined, + ) + ? currentOffenses + : undefined; + }, + 'honest validator slash offenses for invalid proposal attestation', + OFFENSE_DETECTION_TIMEOUT, + 1, + ); + + for (const { description, validator, offenseType } of expectedSlashOffenses) { + const offense = findSlashOffense(offensesWithExpectedSlashes, validator, offenseType, targetSlot)!; + expect(offense.amount).toBeGreaterThan(0n); + t.logger.warn(`Observed expected slash offense: ${description}`, { offense }); + } + + return { + rollup, + badProposerNode, + lazyValidatorNode, + honestValidatorNode, + badProposer, + lazyValidator, + honestValidator, + targetSlot, + badCheckpointBlockHashes, + }; + } + + it('slashes a lazy attester for an invalid checkpoint and clears it on delayed equivocation', async () => { + const { + rollup, + badProposerNode, + honestValidatorNode, + badProposer, + lazyValidator, + targetSlot, + badCheckpointBlockHashes, + } = await createInvalidProposalSlashingScenario({ + badProposerConfig: { + broadcastEquivocatedProposals: true, + }, + }); + + await retryUntil( + async () => { + const currentSlot = await rollup.getSlotNumber(); + t.logger.warn('Waiting for invalid checkpoint proposal slot to complete', { + targetSlot, + currentSlot, + }); + return currentSlot >= targetSlot + 1 ? currentSlot : undefined; + }, + 'wait for invalid checkpoint proposal slot to complete', + BAD_SLOT_COMPLETION_TIMEOUT, + 1, + ); + + const getNodeBadCheckpointHashes = () => + Promise.all( + nodes.map(async (node, nodeIndex) => ({ + nodeIndex, + blocks: await Promise.all( + badCheckpointBlockHashes.map(async block => ({ + ...block, + nodeBlockHash: await getBlockHash(node, block.number), + })), + ), + })), + ); + + const nodeBlockHashes = await retryUntil( + async () => { + const currentNodeBlockHashes = await getNodeBadCheckpointHashes(); + t.logger.warn('Waiting for invalid checkpoint blocks to be absent from node block data', { + targetSlot, + nodeBlockHashes: currentNodeBlockHashes, + }); + return currentNodeBlockHashes.every(nodeState => + nodeState.blocks.every(block => block.nodeBlockHash !== block.hash), + ) + ? currentNodeBlockHashes + : undefined; + }, + 'invalid checkpoint blocks absent from node block data', + INVALID_BLOCK_REMOVAL_TIMEOUT, + 1, + ); + + for (const nodeState of nodeBlockHashes) { + for (const block of nodeState.blocks) { + expect(block.nodeBlockHash).not.toEqual(block.hash); + } + } + + const badBlock = badCheckpointBlockHashes.find( + block => block.indexWithinCheckpoint === BAD_BLOCK_INDEX_WITHIN_CHECKPOINT, + ); + expect(badBlock).toBeDefined(); + + const equivocatedProposal = await makeEquivocatedBlockProposal({ + blockNumber: badBlock!.number, + targetSlot, + signer: getAttesterSigner(0), + signatureContext: { + chainId: t.ctx.aztecNodeConfig.l1ChainId, + rollupAddress: t.ctx.deployL1ContractsValues.l1ContractAddresses.rollupAddress, + }, + }); + + t.logger.warn('Broadcasting delayed equivocated block proposal for already-slashed slot', { + targetSlot, + indexWithinCheckpoint: equivocatedProposal.indexWithinCheckpoint, + payloadHash: equivocatedProposal.getPayloadHash().toString(), + proposer: equivocatedProposal.getSender()?.toString(), + }); + await badProposerNode.getP2P().broadcastProposal(equivocatedProposal); + + const offensesAfterClear = await retryUntil( + async () => { + const currentOffenses = await honestValidatorNode.getSlashOffenses('all'); + const badAttestationOffense = findSlashOffense( + currentOffenses, + lazyValidator, + OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, + targetSlot, + ); + const duplicateProposalOffense = findSlashOffense( + currentOffenses, + badProposer, + OffenseType.DUPLICATE_PROPOSAL, + targetSlot, + ); + + t.logger.warn('Waiting for delayed equivocation to clear bad attestation slash', { + targetSlot, + badAttestationOffense, + duplicateProposalOffense, + currentOffenses, + }); + + return !badAttestationOffense && duplicateProposalOffense ? currentOffenses : undefined; + }, + 'bad attestation slash cleared after delayed block proposal equivocation', + OFFENSE_DETECTION_TIMEOUT, + 1, + ); + + expect( + findSlashOffense( + offensesAfterClear, + lazyValidator, + OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, + targetSlot, + ), + ).toBeUndefined(); + expect( + findSlashOffense(offensesAfterClear, badProposer, OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL, targetSlot), + ).toBeDefined(); + expect(findSlashOffense(offensesAfterClear, badProposer, OffenseType.DUPLICATE_PROPOSAL, targetSlot)).toBeDefined(); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts b/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts new file mode 100644 index 000000000000..c6244020b214 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts @@ -0,0 +1,489 @@ +import type { AztecNodeService } from '@aztec/aztec-node'; +import type { TestAztecNodeService } from '@aztec/aztec-node/test'; +import { Fr } from '@aztec/aztec.js/fields'; +import { BlockNumber, EpochNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; +import { Buffer32 } from '@aztec/foundation/buffer'; +import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; +import { retryUntil } from '@aztec/foundation/retry'; +import { sleep } from '@aztec/foundation/sleep'; +import { OffenseType } from '@aztec/slasher'; +import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { + makeBlockHeader, + makeBlockProposal, + makeCheckpointHeader, + makeCheckpointProposal, +} from '@aztec/stdlib/testing'; +import { TxHash } from '@aztec/stdlib/tx'; + +import { jest } from '@jest/globals'; +import fs from 'fs'; +import os from 'os'; +import path from 'path'; + +import { P2PNetworkTest } from '../e2e_p2p/p2p_network.js'; +import { advanceToEpochBeforeProposer, awaitCommitteeExists } from '../e2e_p2p/shared.js'; +import { shouldCollectMetrics } from '../fixtures/fixtures.js'; +import { ATTESTER_PRIVATE_KEYS_START_INDEX, createNode, createNodes } from '../fixtures/setup_p2p_test.js'; +import { getPrivateKeyFromIndex } from '../fixtures/utils.js'; + +const TEST_TIMEOUT = 1_000_000; + +jest.setTimeout(TEST_TIMEOUT); + +const NUM_VALIDATORS = 2; +const BOOT_NODE_UDP_PORT = 4900; +const COMMITTEE_SIZE = NUM_VALIDATORS; +const ETHEREUM_SLOT_DURATION = 4; +const AZTEC_EPOCH_DURATION = 2; +const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * AZTEC_EPOCH_DURATION; +const SLASHING_QUORUM = 5; +const SLASHING_ROUND_SIZE = 8; +const TERMINAL_BLOCK_INDEX = IndexWithinCheckpoint(1); +const HIGHER_BLOCK_INDEX = IndexWithinCheckpoint(2); + +const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'broadcasted-invalid-checkpoint-proposal-slash-')); + +type SlashOffense = Awaited>[number]; + +function getAttesterSigner(validatorIndex: number) { + const privateKey = getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + validatorIndex)!; + return new Secp256k1Signer(Buffer32.fromBuffer(privateKey)); +} + +function findBroadcastedInvalidCheckpointOffense( + offenses: SlashOffense[], + validator: string, + slot: SlotNumber, +): SlashOffense | undefined { + return offenses.find( + offense => + offense.validator.toString() === validator && + offense.offenseType === OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL && + offense.epochOrSlot === BigInt(slot), + ); +} + +async function awaitBroadcastedInvalidCheckpointOffense({ + node, + validator, + slot, +}: { + node: AztecNodeService; + validator: string; + slot: SlotNumber; +}) { + return await retryUntil( + async () => { + const offenses = await node.getSlashOffenses('all'); + return findBroadcastedInvalidCheckpointOffense(offenses, validator, slot); + }, + `A-520 offense for slot ${slot}`, + AZTEC_SLOT_DURATION * 3, + 1, + ); +} + +async function awaitAnyBroadcastedInvalidCheckpointOffense({ + nodes, + validator, +}: { + nodes: AztecNodeService[]; + validator: string; +}) { + return await retryUntil( + async () => { + const offenses = (await Promise.all(nodes.map(node => node.getSlashOffenses('all')))).flat(); + const matchingOffenses = offenses.filter( + offense => + offense.validator.toString() === validator && + offense.offenseType === OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + ); + return matchingOffenses.length > 0 ? matchingOffenses : undefined; + }, + `broadcasted invalid checkpoint proposal offense for ${validator}`, + AZTEC_SLOT_DURATION * 12, + 1, + ); +} + +async function expectNoBroadcastedInvalidCheckpointOffense({ + node, + validator, + slot, +}: { + node: AztecNodeService; + validator: string; + slot: SlotNumber; +}) { + // The watcher polls every second with this test's slot timing; wait long enough + // for the closed slot to be scanned before asserting no offense was recorded. + await sleep(2_000); + const offenses = await node.getSlashOffenses('all'); + expect(findBroadcastedInvalidCheckpointOffense(offenses, validator, slot)).toBeUndefined(); +} + +async function awaitRetainedProposalsForSlot({ + node, + slot, + blockCount, + checkpointCount, +}: { + node: AztecNodeService; + slot: SlotNumber; + blockCount: number; + checkpointCount: number; +}) { + return await retryUntil( + async () => { + const proposals = await node.getP2P().getProposalsForSlot(slot); + return proposals.blockProposals.length === blockCount && proposals.checkpointProposals.length === checkpointCount + ? proposals + : undefined; + }, + `retained proposals for slot ${slot}`, + 5, + 0.2, + ); +} + +async function makeBlock({ + signer, + signatureContext, + targetSlot, + indexWithinCheckpoint, + seed, +}: { + signer: Secp256k1Signer; + signatureContext: CoordinationSignatureContext; + targetSlot: SlotNumber; + indexWithinCheckpoint: IndexWithinCheckpoint; + seed: number; +}) { + return await makeBlockProposal({ + blockHeader: makeBlockHeader(seed, { + blockNumber: BlockNumber(seed), + slotNumber: targetSlot, + }), + indexWithinCheckpoint, + txHashes: [TxHash.random()], + archiveRoot: Fr.random(), + signer, + signatureContext, + }); +} + +async function makeInvalidCheckpointProposals({ + signer, + signatureContext, + targetSlot, + seed, + includeTerminalBlockAsLastBlock = false, +}: { + signer: Secp256k1Signer; + signatureContext: CoordinationSignatureContext; + targetSlot: SlotNumber; + seed: number; + includeTerminalBlockAsLastBlock?: boolean; +}) { + const earlierBlock = await makeBlock({ + signer, + signatureContext, + targetSlot, + indexWithinCheckpoint: IndexWithinCheckpoint(0), + seed, + }); + const terminalBlock = await makeBlock({ + signer, + signatureContext, + targetSlot, + indexWithinCheckpoint: TERMINAL_BLOCK_INDEX, + seed: seed + 1, + }); + const higherBlock = await makeBlock({ + signer, + signatureContext, + targetSlot, + indexWithinCheckpoint: HIGHER_BLOCK_INDEX, + seed: seed + 2, + }); + const checkpoint = await makeCheckpointProposal({ + signer, + checkpointHeader: makeCheckpointHeader(seed, { slotNumber: targetSlot }), + archiveRoot: terminalBlock.archive, + lastBlock: includeTerminalBlockAsLastBlock + ? { + blockHeader: terminalBlock.blockHeader, + indexWithinCheckpoint: terminalBlock.indexWithinCheckpoint, + txHashes: terminalBlock.txHashes, + } + : undefined, + signatureContext, + }); + + return { earlierBlock, terminalBlock, higherBlock, checkpoint }; +} + +describe('e2e_slashing_broadcasted_invalid_checkpoint_proposal_slash', () => { + let t: P2PNetworkTest; + let nodes: AztecNodeService[] = []; + + const slashingUnit = BigInt(1e14); + + beforeEach(async () => { + t = await P2PNetworkTest.create({ + testName: 'e2e_slashing_broadcasted_invalid_checkpoint_proposal_slash', + numberOfNodes: 0, + numberOfValidators: NUM_VALIDATORS, + basePort: BOOT_NODE_UDP_PORT, + metricsPort: shouldCollectMetrics(), + initialConfig: { + anvilSlotsInAnEpoch: 4, + listenAddress: '127.0.0.1', + aztecEpochDuration: AZTEC_EPOCH_DURATION, + ethereumSlotDuration: ETHEREUM_SLOT_DURATION, + aztecSlotDuration: AZTEC_SLOT_DURATION, + aztecTargetCommitteeSize: COMMITTEE_SIZE, + aztecProofSubmissionEpochs: 1024, + minTxsPerBlock: 0, + enableProposerPipelining: true, + inboxLag: 2, + mockGossipSubNetwork: true, + slashingQuorum: SLASHING_QUORUM, + slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE / AZTEC_EPOCH_DURATION, + slashAmountSmall: slashingUnit, + slashAmountMedium: slashingUnit * 2n, + slashAmountLarge: slashingUnit * 3n, + slashDataWithholdingPenalty: 0n, + slashInactivityPenalty: 0n, + slashBroadcastedInvalidBlockPenalty: 0n, + slashBroadcastedInvalidCheckpointProposalPenalty: slashingUnit, + slashDuplicateProposalPenalty: 0n, + slashDuplicateAttestationPenalty: 0n, + slashProposeInvalidAttestationsPenalty: 0n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 0n, + slashAttestInvalidCheckpointProposalPenalty: 0n, + slashUnknownPenalty: 0n, + slashSelfAllowed: true, + }, + }); + + await t.setup(); + await t.applyBaseSetup(); + }); + + afterEach(async () => { + await t.stopNodes(nodes); + if (t.monitor) { + await t.teardown(); + } + for (let i = 0; i < NUM_VALIDATORS; i++) { + fs.rmSync(`${DATA_DIR}-${i}`, { recursive: true, force: true, maxRetries: 3 }); + } + }); + + const setupNodeAndValidator = async () => { + const { rollup } = await t.getContracts(); + + await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); + await t.ctx.cheatCodes.rollup.debugRollup(); + + const node = await createNode( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + minTxsPerBlock: 0, + enableProposerPipelining: true, + slashBroadcastedInvalidCheckpointProposalPenalty: slashingUnit, + slashSelfAllowed: true, + }, + t.ctx.dateProvider, + BOOT_NODE_UDP_PORT + 1, + t.bootstrapNodeEnr, + 0, + t.genesis, + `${DATA_DIR}-0`, + shouldCollectMetrics(), + ); + nodes = [node]; + + await retryUntil(() => node.isReady(), 'node ready', 30, 0.5); + await awaitCommitteeExists({ rollup, logger: t.logger }); + + const currentSlot = await rollup.getSlotNumber(); + expect(currentSlot).toBeGreaterThan(2); + + const signer = getAttesterSigner(0); + const validator = t.validators[0].attester.toString(); + const signatureContext: CoordinationSignatureContext = { + chainId: t.ctx.aztecNodeConfig.l1ChainId, + rollupAddress: t.ctx.deployL1ContractsValues.l1ContractAddresses.rollupAddress, + }; + + return { node, currentSlot, signer, validator, signatureContext }; + }; + + it('slashes a validator that broadcasts a checkpoint truncated below its own retained block proposal', async () => { + const { node, currentSlot, signer, validator, signatureContext } = await setupNodeAndValidator(); + const targetSlot = SlotNumber(Number(currentSlot) - 2); + + const alreadyRetainedProposals = await makeInvalidCheckpointProposals({ + signer, + signatureContext, + targetSlot, + seed: 0xa520, + }); + + await node.getP2P().broadcastProposal(alreadyRetainedProposals.earlierBlock); + await node.getP2P().broadcastProposal(alreadyRetainedProposals.terminalBlock); + await node.getP2P().broadcastProposal(alreadyRetainedProposals.higherBlock); + await node.getP2P().broadcastCheckpointProposal(alreadyRetainedProposals.checkpoint); + + const firstProposals = await awaitRetainedProposalsForSlot({ + node, + slot: targetSlot, + blockCount: 3, + checkpointCount: 1, + }); + expect(firstProposals.blockProposals.map(proposal => proposal.getSender()?.toString())).toEqual([ + validator, + validator, + validator, + ]); + expect(firstProposals.checkpointProposals[0].getSender()?.toString()).toEqual(validator); + + const firstOffense = await awaitBroadcastedInvalidCheckpointOffense({ + node, + validator, + slot: targetSlot, + }); + expect(firstOffense.amount).toEqual(slashingUnit); + }); + + it('slashes a validator that broadcasts a checkpoint with a mismatched header', async () => { + const { rollup } = await t.getContracts(); + + await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(4)); + await t.ctx.cheatCodes.rollup.debugRollup(); + + const invalidProposerNodes = await createNodes( + { + ...t.ctx.aztecNodeConfig, + broadcastInvalidCheckpointProposalOnly: true, + dontStartSequencer: true, + minTxsPerBlock: 0, + slashBroadcastedInvalidCheckpointProposalPenalty: slashingUnit, + slashSelfAllowed: true, + }, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + 1, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + 0, + ); + const honestNodes = await createNodes( + { + ...t.ctx.aztecNodeConfig, + dontStartSequencer: true, + minTxsPerBlock: 0, + slashBroadcastedInvalidCheckpointProposalPenalty: slashingUnit, + slashSelfAllowed: true, + }, + t.ctx.dateProvider, + t.bootstrapNodeEnr, + NUM_VALIDATORS - 1, + BOOT_NODE_UDP_PORT, + t.genesis, + DATA_DIR, + shouldCollectMetrics(), + 1, + ); + nodes = [...invalidProposerNodes, ...honestNodes]; + + await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS); + await awaitCommitteeExists({ rollup, logger: t.logger }); + + const invalidProposer = invalidProposerNodes[0].getSequencer()!.validatorAddresses![0]; + const epochCache = (honestNodes[0] as TestAztecNodeService).epochCache; + const { targetEpoch } = await advanceToEpochBeforeProposer({ + epochCache, + cheatCodes: t.ctx.cheatCodes.rollup, + targetProposer: invalidProposer, + logger: t.logger, + }); + + await Promise.all(nodes.map(node => node.getSequencer()!.start())); + await t.ctx.cheatCodes.rollup.advanceToEpoch(targetEpoch, { offset: -AZTEC_SLOT_DURATION }); + + const offenses = await awaitAnyBroadcastedInvalidCheckpointOffense({ + nodes: honestNodes, + validator: invalidProposer.toString(), + }); + + t.logger.warn(`Collected broadcasted invalid checkpoint proposal offenses`, { offenses }); + expect(offenses.length).toBeGreaterThan(0); + for (const offense of offenses) { + expect(offense.validator.toString()).toEqual(invalidProposer.toString()); + expect(offense.offenseType).toEqual(OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL); + expect(offense.amount).toEqual(slashingUnit); + expect(offense.epochOrSlot > 0n).toBe(true); + } + }); + + it('does not slash a valid checkpoint whose lastBlock supplies the terminal proposal until a delayed higher-index block is retained', async () => { + const { node, currentSlot, signer, validator, signatureContext } = await setupNodeAndValidator(); + const targetSlot = SlotNumber(Number(currentSlot) - 2); + const lateHigherBlockProposals = await makeInvalidCheckpointProposals({ + signer, + signatureContext, + targetSlot, + seed: 0xa530, + includeTerminalBlockAsLastBlock: true, + }); + + await node.getP2P().broadcastProposal(lateHigherBlockProposals.earlierBlock); + await node.getP2P().broadcastCheckpointProposal(lateHigherBlockProposals.checkpoint); + + const validProposals = await awaitRetainedProposalsForSlot({ + node, + slot: targetSlot, + blockCount: 2, + checkpointCount: 1, + }); + expect(validProposals.blockProposals.map(proposal => proposal.getSender()?.toString())).toEqual([ + validator, + validator, + ]); + const terminalProposal = validProposals.blockProposals.find( + proposal => proposal.indexWithinCheckpoint === TERMINAL_BLOCK_INDEX, + ); + expect(terminalProposal?.archive.toString()).toEqual(lateHigherBlockProposals.terminalBlock.archive.toString()); + expect(terminalProposal?.getSender()?.toString()).toEqual(validator); + expect(validProposals.checkpointProposals[0].getSender()?.toString()).toEqual(validator); + await expectNoBroadcastedInvalidCheckpointOffense({ node, validator, slot: targetSlot }); + + await node.getP2P().broadcastProposal(lateHigherBlockProposals.higherBlock); + + const invalidProposals = await awaitRetainedProposalsForSlot({ + node, + slot: targetSlot, + blockCount: 3, + checkpointCount: 1, + }); + expect(invalidProposals.blockProposals.map(proposal => proposal.getSender()?.toString())).toEqual([ + validator, + validator, + validator, + ]); + + const offense = await awaitBroadcastedInvalidCheckpointOffense({ + node, + validator, + slot: targetSlot, + }); + expect(offense.amount).toEqual(slashingUnit); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_snapshot_sync.test.ts b/yarn-project/end-to-end/src/e2e_snapshot_sync.test.ts index 965a158c367f..0ae9e0969f96 100644 --- a/yarn-project/end-to-end/src/e2e_snapshot_sync.test.ts +++ b/yarn-project/end-to-end/src/e2e_snapshot_sync.test.ts @@ -15,6 +15,7 @@ import { cp, mkdtemp, readFile, readdir, rm, writeFile } from 'fs/promises'; import { tmpdir } from 'os'; import { join } from 'path'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { type EndToEndContext, setup } from './fixtures/utils.js'; const L1_BLOCK_TIME_IN_S = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : 8; @@ -32,7 +33,7 @@ describe('e2e_snapshot_sync', () => { beforeAll(async () => { context = await setup(0, { - minTxsPerBlock: 0, + ...PIPELINING_SETUP_OPTS, ethereumSlotDuration: L1_BLOCK_TIME_IN_S, aztecSlotDuration: L1_BLOCK_TIME_IN_S * 2, aztecEpochDuration: 64, diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index d1f1c32d0644..b94cfa307c13 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -7,11 +7,12 @@ import { StateVarsContract } from '@aztec/noir-test-contracts.js/StateVars'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; -const TIMEOUT = 180_000; +const TIMEOUT = 300_000; describe('e2e_state_vars', () => { jest.setTimeout(TIMEOUT); @@ -32,7 +33,7 @@ describe('e2e_state_vars', () => { aztecNode, wallet, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); ({ contract } = await StateVarsContract.deploy(wallet).send({ from: defaultAccountAddress })); }); @@ -352,12 +353,6 @@ describe('e2e_state_vars', () => { const aztecSlotDuration = DefaultL1ContractsConfig.aztecSlotDuration; - const delay = async (blocks: number) => { - for (let i = 0; i < blocks; i++) { - await authContract.methods.get_authorized().send({ from: defaultAccountAddress }); - } - }; - beforeAll(async () => { // We use the auth contract here because has a nice, clear, simple implementation of Delayed Public Mutable ({ contract: authContract } = await AuthContract.deploy(wallet, defaultAccountAddress).send({ @@ -372,29 +367,46 @@ describe('e2e_state_vars', () => { }); it('sets the expiration timestamp property', async () => { + // Mirrors CHANGE_AUTHORIZED_DELAY in noir-contracts/contracts/app/auth_contract/src/main.nr. + const oldDelay = 360n; const newDelay = BigInt(aztecSlotDuration * 2); // We change the DelayedPublicMutable authorized delay here to 2 slots, this means that a change to the "authorized" // value can only be applied 2 slots after it is initiated, and thus read requests on a historical state without // an initiated change is valid for at least 2 slots. - await authContract.methods.set_authorized_delay(newDelay).send({ from: defaultAccountAddress }); - - // Note: Because we are decreasing the delay, we must first wait for the (full previous delay - 1 slot). - // Since the CHANGE_AUTHORIZED_DELAY in the Auth contract is equal to 5 slots we just wait for 4 blocks. - await delay(4); - - // The validity of our DelayedPublicMutable read request should be limited to the new delay - // Note: We subtract 1 because blocks within the same checkpoint can share timestamps so the earliest scheduling - // can happen at the anchor timestamp itself. For this reason, the latest timestamp at which a change is - // guaranteed to not have happened is the anchor timestamp + the new delay - 1. - const expectedModifiedExpirationTimestamp = - (await aztecNode.getBlockData('latest'))!.header.globalVariables.timestamp + newDelay - 1n; + const setDelayResult = await authContract.methods + .set_authorized_delay(newDelay) + .send({ from: defaultAccountAddress }); + const setDelayBlockNumber = setDelayResult.receipt.blockNumber; + if (setDelayBlockNumber === undefined) { + throw new Error('set_authorized_delay tx did not return a block number'); + } + const setDelayBlock = await aztecNode.getBlockData(setDelayBlockNumber); + // When *decreasing* the delay, ScheduledDelayChange::schedule_change sets the scheduled + // timestamp_of_change to `current_timestamp + (oldDelay - newDelay)` — not `current_timestamp + oldDelay`. + // See noir-protocol-circuits/crates/types/src/delayed_public_mutable/scheduled_delay_change.nr. + const timestampOfChange = setDelayBlock!.header.globalVariables.timestamp + (oldDelay - newDelay); + + // Advance the chain until the scheduled timestamp_of_change has been reached, so any future + // anchor block falls in the "post" branch of get_effective_minimum_delay_at and the effective + // delay equals newDelay - 1 (not the larger time_until_delay_change + newDelay - 1). We send + // no-op txs to push fresh blocks rather than relying on wall-clock time: the e2e fixture + // forces aztecSlotDuration=12s under pipelining (see fixtures/setup.ts), so a fixed + // `delay(N blocks)` cannot count for the schedule — block timestamp polling is the + // slot-duration-agnostic way to know we have crossed the schedule. + while ((await aztecNode.getBlockData('latest'))!.header.globalVariables.timestamp < timestampOfChange) { + await authContract.methods.get_authorized().send({ from: defaultAccountAddress }); + } - // We now call our AuthContract to see if the change in expiration timestamp has reflected our delay change + // We now call our AuthContract to see if the change in expiration timestamp has reflected our delay change. + // expirationTimestamp is `anchor.timestamp + effective_minimum_delay`, where the anchor is the + // historical header the PXE pinned at the start of proveTx. Compare directly against that anchor + // so the assertion isn't flaky against chain drift between the "latest" snapshot and proveTx's own sync. const tx = await proveInteraction(wallet, authContract.methods.get_authorized_in_private(), { from: defaultAccountAddress, }); - expect(tx.data.expirationTimestamp).toEqual(expectedModifiedExpirationTimestamp); + const anchorTimestamp = tx.data.constants.anchorBlockHeader.globalVariables.timestamp; + expect(tx.data.expirationTimestamp).toEqual(anchorTimestamp + newDelay - 1n); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_static_calls.test.ts b/yarn-project/end-to-end/src/e2e_static_calls.test.ts index 6bab6c4cbdf0..5039644c6373 100644 --- a/yarn-project/end-to-end/src/e2e_static_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_static_calls.test.ts @@ -3,7 +3,11 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { StaticChildContract } from '@aztec/noir-test-contracts.js/StaticChild'; import { StaticParentContract } from '@aztec/noir-test-contracts.js/StaticParent'; -import { STATIC_CALL_STATE_MODIFICATION_ERROR, STATIC_CONTEXT_ASSERTION_ERROR } from './fixtures/fixtures.js'; +import { + AUTOMINE_E2E_OPTS, + STATIC_CALL_STATE_MODIFICATION_ERROR, + STATIC_CONTEXT_ASSERTION_ERROR, +} from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_static_calls', () => { @@ -19,7 +23,7 @@ describe('e2e_static_calls', () => { teardown, wallet, accounts: [owner], - } = await setup()); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); sender = owner; ({ contract: parentContract } = await StaticParentContract.deploy(wallet).send({ from: owner })); ({ contract: childContract } = await StaticChildContract.deploy(wallet).send({ from: owner })); diff --git a/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts b/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts index 70c6ce8b0b8f..b3baf6a8ea67 100644 --- a/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts +++ b/yarn-project/end-to-end/src/e2e_storage_proof/e2e_storage_proof.test.ts @@ -2,6 +2,7 @@ import { StorageProofTestContract } from '@aztec/noir-test-contracts.js/StorageP import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { type EndToEndContext, setup, teardown } from '../fixtures/setup.js'; import { buildStorageProofCapsules, loadStorageProofArgs } from './fixtures/storage_proof_fixture.js'; @@ -12,7 +13,7 @@ describe('Storage proof', () => { let contract: StorageProofTestContract; beforeAll(async () => { - ctx = await setup(1); + ctx = await setup(1, { ...AUTOMINE_E2E_OPTS }); ({ contract } = await StorageProofTestContract.deploy(ctx.wallet).send({ from: ctx.accounts[0] })); }); diff --git a/yarn-project/end-to-end/src/e2e_synching.test.ts b/yarn-project/end-to-end/src/e2e_synching.test.ts index 54e278458161..2e00ab15bf9e 100644 --- a/yarn-project/end-to-end/src/e2e_synching.test.ts +++ b/yarn-project/end-to-end/src/e2e_synching.test.ts @@ -66,6 +66,7 @@ import * as fs from 'fs'; import { type MockProxy, mock } from 'jest-mock-extended'; import { getContract } from 'viem'; +import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; import { mintTokensToPrivate } from './fixtures/token_utils.js'; import { type EndToEndContext, setup, setupPXEAndGetWallet } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; @@ -340,6 +341,7 @@ describe('e2e_synching', () => { initialFundedAccounts, cheatCodes, } = await setup(1, { + ...PIPELINING_SETUP_OPTS, l1StartTime: START_TIME, l2StartTime: START_TIME + 200 * ETHEREUM_SLOT_DURATION, numberOfInitialFundedAccounts: variant.txCount + 1, @@ -422,6 +424,7 @@ describe('e2e_synching', () => { initialFundedAccounts, dateProvider, } = await setup(0, { + ...PIPELINING_SETUP_OPTS, l1StartTime: START_TIME, numberOfInitialFundedAccounts: 10, }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts index 50ac4a7f36be..bf1008cf4510 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts @@ -1,3 +1,4 @@ +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract access control', () => { @@ -5,7 +6,7 @@ describe('e2e_token_contract access control', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts index b9760a983627..c256dc91e27d 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR, U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR, U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract burn', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract burn', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, wallet, adminAddress, tokenSim, adminAddress, account1Address } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts index 46908a688eab..75320121fa15 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts @@ -1,4 +1,4 @@ -import { U128_OVERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, U128_OVERFLOW_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract minting', () => { @@ -7,7 +7,7 @@ describe('e2e_token_contract minting', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ asset, tokenSim, adminAddress, account1Address } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts index ffa5688df3b5..ee4b057ffb84 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts @@ -1,6 +1,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; import { TokenContract, type Transfer } from '@aztec/noir-contracts.js/Token'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { mintNotes } from '../fixtures/token_utils.js'; import { TokenContractTest } from './token_contract_test.js'; @@ -10,7 +11,7 @@ describe('e2e_token_contract private transfer recursion', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ asset, wallet, adminAddress, account1Address, node } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts index 185ac4231e8e..b58142beb64c 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts @@ -1,5 +1,6 @@ import { readFieldCompressedString } from '@aztec/aztec.js/utils'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract reading constants', () => { @@ -8,7 +9,7 @@ describe('e2e_token_contract reading constants', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts index bbc7f024fd19..74b8e590bf54 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts @@ -7,7 +7,14 @@ import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAcc import { jest } from '@jest/globals'; -import { type EndToEndContext, deployAccounts, publicDeployAccounts, setup, teardown } from '../fixtures/setup.js'; +import { + type EndToEndContext, + type SetupOptions, + deployAccounts, + publicDeployAccounts, + setup, + teardown, +} from '../fixtures/setup.js'; import { mintTokensToPrivate } from '../fixtures/token_utils.js'; import { TokenSimulator } from '../simulators/token_simulator.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; @@ -115,8 +122,9 @@ export class TokenContractTest { ); } - async setup() { + async setup(opts: Partial = {}) { this.context = await setup(0, { + ...opts, metricsPort: this.metricsPort, fundSponsoredFPC: true, skipAccountDeployment: true, diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts index 564707a74c77..900fb20af049 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts @@ -2,6 +2,7 @@ import { AztecAddress, CompleteAddress } from '@aztec/aztec.js/addresses'; import { BlockNumber } from '@aztec/foundation/branded-types'; import { TokenContract, type Transfer } from '@aztec/noir-contracts.js/Token'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer private', () => { @@ -11,7 +12,7 @@ describe('e2e_token_contract transfer private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ asset, adminAddress, wallet, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts index 385c912cec06..676285ea1b3f 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash, computeInnerAuthWitHashFromAction } from '@a import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer private', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract transfer private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); ({ asset, tokenSim, wallet, adminAddress, account1Address, badAccount } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts index f50c89d80b5a..550d34fbe0b3 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts @@ -1,6 +1,6 @@ import { Fr } from '@aztec/aztec.js/fields'; -import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { type AlertConfig, GrafanaClient } from '../quality_of_service/grafana_client.js'; import { TokenContractTest } from './token_contract_test.js'; @@ -25,7 +25,7 @@ describe('e2e_token_contract transfer public', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, tokenSim, wallet, adminAddress, account1Address, badAccount } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts index 2688fea57172..03bf880e7318 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts @@ -1,4 +1,4 @@ -import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer_to_private', () => { @@ -8,7 +8,7 @@ describe('e2e_token_contract transfer_to_private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, adminAddress, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts index 1ff6f31ef53b..debb3f2b0234 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { AUTOMINE_E2E_OPTS, DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer_to_public', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract transfer_to_public', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...AUTOMINE_E2E_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, wallet, adminAddress, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts b/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts index 3755a88e45e3..907439f12a75 100644 --- a/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts +++ b/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts @@ -19,6 +19,7 @@ import type { TxEffect, TxHash } from '@aztec/stdlib/tx'; import { jest } from '@jest/globals'; +import { AUTOMINE_E2E_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 120_000; @@ -48,7 +49,7 @@ describe('e2e tx effect oracle', () => { wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup(1)); + } = await setup(1, { ...AUTOMINE_E2E_OPTS })); const { contract: deployed, receipt } = await TxEffectOracleTestContract.deploy(wallet).send({ from: defaultAccountAddress, }); diff --git a/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts b/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts index a41d75782959..3e345cd6d98b 100644 --- a/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts +++ b/yarn-project/end-to-end/src/fixtures/e2e_prover_test.ts @@ -24,6 +24,7 @@ import { getACVMConfig } from './get_acvm_config.js'; import { getBBConfig } from './get_bb_config.js'; import { type EndToEndContext, + type SetupOptions, deployAccounts, getPrivateKeyFromIndex, getSponsoredFPCAddress, @@ -124,9 +125,10 @@ export class FullProverTest { ); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up subsystems from fresh'); this.context = await setup(0, { + ...opts, startProverNode: true, coinbase: this.coinbase, fundSponsoredFPC: true, diff --git a/yarn-project/end-to-end/src/fixtures/fixtures.ts b/yarn-project/end-to-end/src/fixtures/fixtures.ts index 0e4878212440..11c343e3a737 100644 --- a/yarn-project/end-to-end/src/fixtures/fixtures.ts +++ b/yarn-project/end-to-end/src/fixtures/fixtures.ts @@ -12,6 +12,70 @@ export const DEFAULT_MIN_FEE_PADDING = 5; */ export const LARGE_MIN_FEE_PADDING = 15; +/** + * Fee padding used by tests running under proposer pipelining. Under pipelining the fee-asset + * price modifier evolves faster across the build/publish gap, so client-set maxFeesPerGas (sized + * for the default 5x padding) was getting bumped past by the time the tx mined a few slots later. + * Observed worst case in CI: fee evolved ~20x between PXE snapshot and inclusion, exceeding even + * LARGE_MIN_FEE_PADDING (15x). + */ +export const PIPELINED_FEE_PADDING = 30; + +/** + * Setup option preset that opts a test into proposer pipelining. Use with `setup()`: + * + * await setup(N, { ...PIPELINING_SETUP_OPTS, ...otherOpts }); + * + * The preset sets: + * - `enableProposerPipelining: true` so the sequencer builds for `slot + 1`. + * - `inboxLag: 2` so the sequencer sources L1->L2 messages from checkpoint N-1 (already sealed), + * avoiding `L1ToL2MessagesNotReadyError` when building for slot N during slot N-1. + * - `minTxsPerBlock: 0` so empty checkpoints land even when a tx arrives late in the build window + * (otherwise the chain stalls on alternating slots). + * - `aztecSlotDuration: 12` / `ethereumSlotDuration: 4` so the pipelined cycle fits inside the + * default 300s Jest hook budget. Tests that depend on the env-default 72s/12s should override. + * - `walletMinFeePadding: PIPELINED_FEE_PADDING` (30x) to absorb the wider fee evolution window. + */ +export const PIPELINING_SETUP_OPTS = { + enableProposerPipelining: true, + inboxLag: 2, + minTxsPerBlock: 0, + aztecSlotDuration: 12, + ethereumSlotDuration: 4, + walletMinFeePadding: PIPELINED_FEE_PADDING, +} as const; + +/** + * Setup option preset that opts a test into the deterministic AutomineSequencer path. + * Use only for single-sequencer tests that don't exercise block-building or consensus + * (e.g. e2e_token, e2e_amm, e2e_authwit). Not compatible with `e2e_p2p/*`, + * `e2e_epochs/*`, `e2e_slashing/*`, `e2e_block_building`, or any multi-validator suite. + * + * await setup(N, { ...AUTOMINE_E2E_OPTS, ...otherOpts }); + * + * The preset: + * - Swaps the production Sequencer for an AutomineSequencer that builds one block per + * submitted tx, publishes synchronously to L1, and owns all time control through a + * serial queue (see `sequencer-client/src/sequencer/automine/automine_sequencer.ts`). + * - Disables the validator client and AnvilTestWatcher (the AutomineSequencer needs + * neither). + * - Disables proposer pipelining and uses `inboxLag: 1` (synchronous, non-pipelined). + * - Switches anvil into automine mode at setup time (no interval mining); each L1 tx + * mines an L1 block immediately. + * + * Requires `aztecTargetCommitteeSize: 0`, which is the e2e default at `setup.ts:317`. + */ +export const AUTOMINE_E2E_OPTS = { + useAutomineSequencer: true, + disableAnvilTestWatcher: true, + enableProposerPipelining: false, + inboxLag: 1, + minTxsPerBlock: 0, + aztecSlotDuration: 12, + ethereumSlotDuration: 4, + walletMinFeePadding: PIPELINED_FEE_PADDING, +} as const; + /** Returns worst-case predicted min fees with padding applied, mirroring the BaseWallet pattern. */ export async function getPaddedMaxFeesPerGas(node: AztecNode, padding = DEFAULT_MIN_FEE_PADDING): Promise { const predicted = await node.getPredictedMinFees(); diff --git a/yarn-project/end-to-end/src/fixtures/setup.ts b/yarn-project/end-to-end/src/fixtures/setup.ts index fb6b464defca..c83bcd3b5df6 100644 --- a/yarn-project/end-to-end/src/fixtures/setup.ts +++ b/yarn-project/end-to-end/src/fixtures/setup.ts @@ -213,6 +213,9 @@ export type SetupOptions = { /** Whether the initial node should be a lightweight RPC-only node (no sequencer, no validator). * Use for tests that create their own validator nodes and don't need the initial sequencer. */ skipInitialSequencer?: boolean; + /** Whether to swap the production Sequencer for the minimal AutomineSequencer. + * Use only for single-sequencer non-block-building tests. See AUTOMINE_E2E_OPTS in `fixtures.ts`. */ + useAutomineSequencer?: boolean; /** Options forwarded to PXE creation (e.g. execution hooks). */ pxeCreationOptions?: PXECreationOptions; } & Partial; @@ -457,6 +460,24 @@ export async function setup( Object.assign(config, deployL1ContractsValues.l1ContractAddresses); config.rollupVersion = deployL1ContractsValues.rollupVersion; + // Propagate L1-contracts-config overrides back to the node config so the archiver's + // `l1Constants` (and any other node-side consumer) agrees with what was actually deployed. + // Without this, a per-test override like `aztecEpochDuration: 4` lands on the rollup contract + // but the node config keeps the default (32), so `archiver.isEpochComplete(0)` computes + // `endSlot=31` and `EpochTestSettler`/`EpochMonitor` never fires — letting the + // `aztecProofSubmissionEpochs` window expire mid-test and prune the pending chain. + // Skip undefined values: callers (e.g. `P2PNetworkTest`) sometimes build `l1ContractsArgs` + // by spreading a partial `AztecNodeConfig`, which leaves unset fields (notably `dataDirectory`) + // as `undefined`. A blind Object.assign would then clobber the temp `dataDirectory` set earlier + // in this function and crash `setupSharedBlobStorage`. + if (opts.l1ContractsArgs) { + for (const [key, value] of Object.entries(opts.l1ContractsArgs)) { + if (value !== undefined) { + (config as unknown as Record)[key] = value; + } + } + } + if (enableAutomine) { await ethCheatCodes.setAutomine(false); await ethCheatCodes.setIntervalMining(config.ethereumSlotDuration); @@ -526,7 +547,11 @@ export async function setup( const shouldDeployAccounts = numberOfAccounts > 0 && !opts.skipAccountDeployment; // Only set minTxsPerBlock=0 if we need an empty block (no accounts at all, not skipped deployment) const needsEmptyBlock = numberOfAccounts === 0 && !opts.skipAccountDeployment; - config.minTxsPerBlock = shouldDeployAccounts ? 1 : needsEmptyBlock ? 0 : originalMinTxsPerBlock; + // Under proposer pipelining the sequencer builds during slot N-1 for slot N. A tx submitted at + // slot N start is too late -- it arrives after the build. Forcing minTxsPerBlock=1 then stalls + // the chain on alternating slots, so allow empty checkpoints under pipelining. + const accountsDeployMinTxs = config.enableProposerPipelining ? 0 : 1; + config.minTxsPerBlock = shouldDeployAccounts ? accountsDeployMinTxs : needsEmptyBlock ? 0 : originalMinTxsPerBlock; config.p2pEnabled = opts.mockGossipSubNetwork || config.p2pEnabled; config.p2pIp = opts.p2pIp ?? config.p2pIp ?? '127.0.0.1'; @@ -598,7 +623,12 @@ export async function setup( wallet.setMinFeePadding(opts.walletMinFeePadding); } - const cheatCodes = await CheatCodes.create(config.l1RpcUrls, aztecNodeService, dateProvider); + const cheatCodes = await CheatCodes.create( + config.l1RpcUrls, + aztecNodeService, + dateProvider, + aztecNodeService.getAutomineSequencer(), + ); if ( (opts.aztecTargetCommitteeSize && opts.aztecTargetCommitteeSize > 0) || @@ -627,6 +657,11 @@ export async function setup( accounts = accountManagers.map(accountManager => accountManager.address); } else if (needsEmptyBlock) { logger.info('No accounts are being deployed, waiting for an empty block 1 to be mined'); + // AutomineSequencer only builds on tx arrival; explicitly request an empty block. + const automine = aztecNodeService.getAutomineSequencer(); + if (automine) { + await automine.buildEmptyBlock(); + } while ((await aztecNodeService.getBlockNumber()) === 0) { await sleep(2000); } diff --git a/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts b/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts index 0e3c32f8d6e1..2bec4011d503 100644 --- a/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts +++ b/yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts @@ -88,6 +88,10 @@ export type CreateNodeConfig = AztecNodeConfig & { dontStartSequencer?: boolean; /** Override the private key (instead of deriving from addressIndex). */ validatorPrivateKey?: `0x${string}`; + /** Corrupt only the block proposal at this indexWithinCheckpoint (testing only). */ + invalidBlockProposalIndexWithinCheckpoint?: number; + /** Accept proposal gossip regardless of slot timing (testing only). */ + skipProposalSlotValidation?: boolean; }; /** Creates a P2P enabled instance of Aztec Node Service with a validator. */ diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index 0ed3abf104d7..b49e09322174 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -8,6 +8,7 @@ import { Schnorr } from '@aztec/foundation/crypto/schnorr'; import { SchnorrHardcodedAccountContractArtifact } from '@aztec/noir-contracts.js/SchnorrHardcodedAccount'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; +import { AUTOMINE_E2E_OPTS } from '../fixtures/fixtures.js'; import { setup } from '../fixtures/utils.js'; import { TestWallet } from '../test-wallet/test_wallet.js'; @@ -44,7 +45,7 @@ describe('guides/writing_an_account_contract', () => { let context: Awaited>; beforeEach(async () => { - context = await setup(1); + context = await setup(1, { ...AUTOMINE_E2E_OPTS }); }); afterEach(() => context.teardown()); diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index 1950d9925e4a..8a52e28d826d 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -32,7 +32,7 @@ import { CrossChainTestHarness } from './cross_chain_test_harness.js'; // anvil --fork-url https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c --fork-block-number 17514288 --chain-id 31337 // For CI, this is configured in `run_tests.sh` and `docker-compose-images.yml` -const TIMEOUT = 360_000; +const TIMEOUT = 15 * 60 * 1000; export const uniswapL1L2TestSuite = ( setup: () => Promise, diff --git a/yarn-project/end-to-end/src/simulators/lending_simulator.ts b/yarn-project/end-to-end/src/simulators/lending_simulator.ts index ae299b31e249..defcc7965273 100644 --- a/yarn-project/end-to-end/src/simulators/lending_simulator.ts +++ b/yarn-project/end-to-end/src/simulators/lending_simulator.ts @@ -7,6 +7,7 @@ import { SlotNumber } from '@aztec/foundation/branded-types'; import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon'; import type { TestDateProvider } from '@aztec/foundation/timer'; import type { LendingContract } from '@aztec/noir-contracts.js/Lending'; +import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client'; import type { TokenSimulator } from './token_simulator.js'; @@ -92,15 +93,25 @@ export class LendingSimulator { public stableCoin: TokenSimulator, ) {} - async prepare() { + prepare() { this.accumulator = BASE; - const slot = await this.rollup.getSlotAt( - BigInt(await this.cc.eth.lastBlockTimestamp()) + BigInt(this.ethereumSlotDuration), - ); - this.time = Number(await this.rollup.getTimestampForSlot(slot)); + this.time = 0; } - async progressSlots(diff: number, dateProvider?: TestDateProvider) { + /** + * Advances the simulator's accumulator and clock to match a block timestamp observed on chain. + * Call this BEFORE applying any accumulator-sensitive mutation (borrow/repay) so the mutation + * sees the same accumulator as the contract did during execution. + */ + observeBlockTimestamp(ts: number) { + const diff = ts - this.time; + if (diff > 0) { + this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(diff)), BASE); + } + this.time = ts; + } + + async progressSlots(diff: number, _dateProvider?: TestDateProvider, node?: AztecNode & AztecNodeDebug) { if (diff <= 1) { return; } @@ -108,16 +119,19 @@ export class LendingSimulator { const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp())); const targetSlot = SlotNumber(slot + diff); const ts = Number(await this.rollup.getTimestampForSlot(targetSlot)); - const timeDiff = ts - this.time; - this.time = ts; - // Mine ethereum blocks such that the next block will be in a new slot - await this.cc.eth.warp(this.time - this.ethereumSlotDuration); - if (dateProvider) { - dateProvider.setTime(this.time * 1000); + // Queue-aware warp under AutomineSequencer: atomic warp + mineBlock that advances L2 time to the + // target slot. The cheat code routes through the AutomineSequencer queue when one is installed, + // and otherwise falls back to a manual warp + mineBlock loop. + if (node) { + await this.cc.warpL2TimeAtLeastTo(node, ts); + } else { + await this.cc.eth.warp(ts - this.ethereumSlotDuration); } + + // Mark the latest checkpoint as proven so the rollup does not reorg pending checkpoints when + // time jumps far enough forward to cross an unproven epoch boundary. await this.cc.rollup.markAsProven(await this.rollup.getCheckpointNumber()); - this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE); } depositPrivate(from: AztecAddress, onBehalfOf: Fr, amount: bigint) { diff --git a/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts b/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts index 702e30d8ccc1..1a6d299dea6d 100644 --- a/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts +++ b/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts @@ -43,7 +43,7 @@ describe('invalidate blocks test', () => { let node: AztecNode; let origMinTxsPerBlock: number | undefined; let origSlashProposeInvalidAttestationsPenalty: bigint | undefined; - let origSlashAttestDescendantOfInvalidPenalty: bigint | undefined; + let origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: bigint | undefined; const health = new ChainHealth(config.NAMESPACE, logger); const waitForSequencersToApplyConfig = async (expected: Partial, description: string) => { @@ -78,7 +78,8 @@ describe('invalidate blocks test', () => { skipCollectingAttestations: false, minTxsPerBlock: origMinTxsPerBlock, slashProposeInvalidAttestationsPenalty: origSlashProposeInvalidAttestationsPenalty, - slashAttestDescendantOfInvalidPenalty: origSlashAttestDescendantOfInvalidPenalty, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: + origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, }; await updateSequencersConfig(config, restoreConfig); // Ensure config has actually propagated before the next scenario test starts @@ -107,7 +108,8 @@ describe('invalidate blocks test', () => { const first = configs?.[0]; origMinTxsPerBlock = first?.minTxsPerBlock ?? origMinTxsPerBlock; origSlashProposeInvalidAttestationsPenalty = first?.slashProposeInvalidAttestationsPenalty; - origSlashAttestDescendantOfInvalidPenalty = first?.slashAttestDescendantOfInvalidPenalty; + origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty = + first?.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty; const initialCheckpointNumber = (await monitor.run()).checkpointNumber; @@ -116,7 +118,7 @@ describe('invalidate blocks test', () => { await updateSequencersConfig(config, { skipCollectingAttestations: true, slashProposeInvalidAttestationsPenalty: 0n, - slashAttestDescendantOfInvalidPenalty: 0n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 0n, minTxsPerBlock: 0, }); diff --git a/yarn-project/end-to-end/src/spartan/n_tps.test.ts b/yarn-project/end-to-end/src/spartan/n_tps.test.ts index 16bda90b2799..e15ced7cb33f 100644 --- a/yarn-project/end-to-end/src/spartan/n_tps.test.ts +++ b/yarn-project/end-to-end/src/spartan/n_tps.test.ts @@ -6,6 +6,7 @@ import { SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee'; import { type AztecNode, createAztecNodeClient } from '@aztec/aztec.js/node'; import { AccountManager } from '@aztec/aztec.js/wallet'; import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants'; +import { BlockNumber } from '@aztec/foundation/branded-types'; import { times, timesParallel } from '@aztec/foundation/collection'; import { randomBigInt } from '@aztec/foundation/crypto/random'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -552,6 +553,34 @@ describe('sustained N TPS test', () => { })); const startedAt = new Date().toISOString(); + // Block-watcher: stamps wall-clock minedAtMs on each sent tx the first time + // its block becomes visible to this client. Runs throughout sending AND the + // post-window waitForTx tail so late blocks still get a true client-observed + // timestamp. recordMinedTx (in waitForTx) is the slow-path fallback for any + // tx the watcher misses. + let lastSeenBlock = await aztecNode.getBlockNumber(); + const blockWatcher = new RunningPromise( + async () => { + const current = await aztecNode.getBlockNumber(); + while (lastSeenBlock < current) { + const n = BlockNumber.add(lastSeenBlock, 1); + const block = await aztecNode.getBlock(n, { includeTransactions: true }); + lastSeenBlock = n; + if (!block) { + continue; + } + metrics.observeBlockForMinedTxs( + n, + block.body.txEffects.map(t => t.txHash), + Date.now(), + ); + } + }, + logger, + 1000, + ); + blockWatcher.start(); + sendTxsAtTps(logger, abortController.signal, lowValueLanes, lowValueTps, lowValueSendTx); const sentTxHashes = sendTxsAtTps(logger, abortController.signal, highValueLanes, highValueTps, highValueSendTx); @@ -564,11 +593,6 @@ describe('sustained N TPS test', () => { highValueSent: sentTxHashes.length, }); - // metadata about the test run for the scraper script - const metadataPath = '/tmp/n_tps_timing_data.json'; - await writeFile(metadataPath, JSON.stringify({ startedAt, endedAt, runId: process.env.BENCH_RUN_ID })); - logger.info('Wrote benchmark metadata', { path: metadataPath, startedAt, endedAt }); - const results: { success: boolean; txHash: string; error?: any }[] = []; const waitForTx = async (txHash: string, txName: string) => { try { @@ -607,6 +631,24 @@ describe('sustained N TPS test', () => { logger.debug('Processed tx batch', { processed: index, remaining: sentTxHashes.length }); } + await blockWatcher.stop(); + + // Metadata + per-tx inclusion records for the bench_scrape script. Records + // are filtered to the high-value group, so this is the authoritative + // client-observed inclusion-latency dataset for the run. + const inclusionRecords = metrics.getInclusionRecords('tx_inclusion_time'); + const metadataPath = '/tmp/n_tps_timing_data.json'; + await writeFile( + metadataPath, + JSON.stringify({ startedAt, endedAt, runId: process.env.BENCH_RUN_ID, inclusionRecords }), + ); + logger.info('Wrote benchmark metadata', { + path: metadataPath, + startedAt, + endedAt, + inclusionRecords: inclusionRecords.length, + }); + // Count successes and failures const successCount = results.filter(r => r.success).length; const failureCount = results.filter(r => !r.success).length; diff --git a/yarn-project/end-to-end/src/spartan/tx_metrics.ts b/yarn-project/end-to-end/src/spartan/tx_metrics.ts index e027926e0f72..bac38184aac7 100644 --- a/yarn-project/end-to-end/src/spartan/tx_metrics.ts +++ b/yarn-project/end-to-end/src/spartan/tx_metrics.ts @@ -134,9 +134,12 @@ export class ProvingMetrics { export type TxInclusionData = { txHash: string; - sentAt: number; - minedAt: number; - attestedAt: number; + /** Wall-clock at client when the tx was submitted, in ms (Date.now()). */ + sentAtMs: number; + /** Wall-clock at client when the block containing the tx first became visible, in ms (Date.now()). -1 if never observed. */ + minedAtMs: number; + /** Reserved for future attestation-observed-at signal; -1 today. */ + attestedAtMs: number; blocknumber: number; priorityFee: number; totalFee: number; @@ -174,9 +177,9 @@ export class TxInclusionMetrics { this.data.set(txHash, { txHash, - sentAt: Math.trunc(Date.now() / 1000), - minedAt: -1, - attestedAt: -1, + sentAtMs: Date.now(), + minedAtMs: -1, + attestedAtMs: -1, blocknumber: -1, priorityFee: Number(priorityFees.feePerDaGas + priorityFees.feePerL2Gas), totalFee: -1, @@ -186,6 +189,28 @@ export class TxInclusionMetrics { this.groups.add(group); } + /** + * Stamp mined-at metadata for any tracked tx contained in this block, using + * `observedAtMs` (caller-supplied wall-clock at the moment they first saw the + * block). Idempotent: existing minedAtMs is preserved so the first observer + * wins (typically the block-watcher; recordMinedTx is a fallback). + */ + observeBlockForMinedTxs( + blockNumber: number, + txHashes: ReadonlyArray<{ toString(): string }>, + observedAtMs: number, + ): void { + txHashes.forEach((txHash, position) => { + const data = this.data.get(txHash.toString()); + if (!data || data.minedAtMs !== -1) { + return; + } + data.blocknumber = blockNumber; + data.minedAtMs = observedAtMs; + data.positionInBlock = position; + }); + } + async recordMinedTx(txReceipt: TxReceipt): Promise { const { txHash, blockNumber } = txReceipt; if (!txReceipt.isMined() || !txReceipt.hasExecutionSucceeded() || !blockNumber) { @@ -197,26 +222,43 @@ export class TxInclusionMetrics { return; } - if (!this.blocks.has(blockNumber)) { - this.blocks.set(blockNumber, this.aztecNode.getBlock(blockNumber, { includeTransactions: true })); - } - - const block = await this.blocks.get(blockNumber)!; - if (!block) { - this.logger?.warn('Failed to load block for mined tx receipt', { txHash: txHash.toString(), blockNumber }); - return; - } const data = this.data.get(txHash.toString()); if (!data) { const message = `Missing sent tx record for mined tx ${txHash.toString()}`; this.logger?.warn(message, { txHash: txHash.toString(), blockNumber }); throw new Error(message); } - data.blocknumber = blockNumber; - data.minedAt = Number(block.header.globalVariables.timestamp); - data.attestedAt = -1; data.totalFee = Number(txReceipt.transactionFee ?? 0n); - data.positionInBlock = block.body.txEffects.findIndex(txEffect => txEffect.txHash.equals(txHash)); + + // Fallback path for txs the block-watcher missed (e.g. observed only after + // the watcher stopped). Stamp with the block's L2 slot timestamp; this is + // earlier than the true client-observed time by attestation+propagation + // lag, but it's the only deterministic timestamp available post-hoc. + if (data.minedAtMs === -1) { + if (!this.blocks.has(blockNumber)) { + this.blocks.set(blockNumber, this.aztecNode.getBlock(blockNumber, { includeTransactions: true })); + } + const block = await this.blocks.get(blockNumber)!; + if (!block) { + this.logger?.warn('Failed to load block for mined tx receipt', { txHash: txHash.toString(), blockNumber }); + return; + } + data.blocknumber = blockNumber; + data.minedAtMs = Number(block.header.globalVariables.timestamp) * 1000; + data.positionInBlock = block.body.txEffects.findIndex(txEffect => txEffect.txHash.equals(txHash)); + } + } + + /** Per-tx inclusion records for a group. Used to serialise out for downstream tooling. */ + getInclusionRecords(group?: string): TxInclusionData[] { + const out: TxInclusionData[] = []; + for (const tx of this.data.values()) { + if (group !== undefined && tx.group !== group) { + continue; + } + out.push({ ...tx }); + } + return out; } public inclusionTimeInSeconds(group: string): { @@ -231,19 +273,23 @@ export class TxInclusionMetrics { const histogram = createHistogram({}); let nonPositive = 0; for (const tx of this.data.values()) { - if (!tx.blocknumber || tx.group !== group || tx.minedAt === -1) { + if (!tx.blocknumber || tx.group !== group || tx.minedAtMs === -1) { continue; } - // `minedAt` is the block's L2 slot timestamp (seconds) while `sentAt` is the wall-clock - // send time. Because the slot timestamp can precede or equal the send time, the delta - // can be <= 0, which perf_hooks.createHistogram rejects. Skip those instead of crashing. - const delta = tx.minedAt - tx.sentAt; - if (delta <= 0) { + // Both timestamps are client wall-clock (ms). A negative delta should be + // impossible since the watcher stamps minedAtMs strictly after sentAtMs, + // but the fallback path (recordMinedTx via L2 slot timestamp) can stamp + // earlier than sentAtMs. perf_hooks.createHistogram rejects <=0; skip + // those instead of crashing. + const deltaMs = tx.minedAtMs - tx.sentAtMs; + if (deltaMs <= 0) { nonPositive++; continue; } - histogram.record(delta); + // Histogram is recorded in seconds (rounded) to match the existing + // toGithubActionBenchmarkJSON output unit; per-tx records carry the raw ms. + histogram.record(Math.max(1, Math.round(deltaMs / 1000))); } if (nonPositive > 0) { this.logger?.debug(`Dropped ${nonPositive} tx inclusion samples with non-positive delta`, { group }); diff --git a/yarn-project/end-to-end/src/test-wallet/utils.ts b/yarn-project/end-to-end/src/test-wallet/utils.ts index ec7b2554a414..de361a62823b 100644 --- a/yarn-project/end-to-end/src/test-wallet/utils.ts +++ b/yarn-project/end-to-end/src/test-wallet/utils.ts @@ -1,4 +1,5 @@ import { + BatchCall, ContractFunctionInteraction, DeployMethod, type DeployOptions, @@ -62,7 +63,7 @@ export class ProvenTx extends Tx { export async function proveInteraction( wallet: TestWallet, - interaction: ContractFunctionInteraction | DeployMethod, + interaction: ContractFunctionInteraction | DeployMethod | BatchCall, options: SendInteractionOptions | DeployOptions, ) { const execPayload = await interaction.request(options); diff --git a/yarn-project/ethereum/src/contracts/chain_state_override.test.ts b/yarn-project/ethereum/src/contracts/chain_state_override.test.ts index 77d3b79f2459..f88c6574d9b2 100644 --- a/yarn-project/ethereum/src/contracts/chain_state_override.test.ts +++ b/yarn-project/ethereum/src/contracts/chain_state_override.test.ts @@ -66,6 +66,30 @@ describe('SimulationOverridesBuilder', () => { expect(plan?.chainTipsOverride).toEqual({ pending: CheckpointNumber(7), proven: CheckpointNumber(3) }); }); + it('merge does not erase prior chain tip values when the incoming half is undefined', () => { + const builder = new SimulationOverridesBuilder().withChainTips({ + pending: CheckpointNumber(7), + proven: CheckpointNumber(5), + }); + builder.merge({ chainTipsOverride: { pending: undefined, proven: CheckpointNumber(6) } }); + const plan = builder.build(); + expect(plan?.chainTipsOverride).toEqual({ pending: CheckpointNumber(7), proven: CheckpointNumber(6) }); + }); + + it('merge does not erase prior pending checkpoint state when the incoming field is undefined', () => { + const archive = Fr.random(); + const builder = new SimulationOverridesBuilder() + .withChainTips({ pending: CheckpointNumber(7) }) + .withPendingArchive(archive); + builder.merge({ + chainTipsOverride: { pending: CheckpointNumber(7) }, + pendingCheckpointState: { archive: undefined, slotNumber: SlotNumber(42) }, + }); + const plan = builder.build(); + expect(plan?.pendingCheckpointState?.archive).toEqual(archive); + expect(plan?.pendingCheckpointState?.slotNumber).toEqual(SlotNumber(42)); + }); + it('attaches temp checkpoint log fields under the configured pending checkpoint', () => { const headerHash = Fr.random(); const outHash = Fr.random(); diff --git a/yarn-project/ethereum/src/contracts/chain_state_override.ts b/yarn-project/ethereum/src/contracts/chain_state_override.ts index 6358f0cde0e0..8693981098d0 100644 --- a/yarn-project/ethereum/src/contracts/chain_state_override.ts +++ b/yarn-project/ethereum/src/contracts/chain_state_override.ts @@ -1,6 +1,7 @@ import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer'; import type { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; import type { Buffer32 } from '@aztec/foundation/buffer'; +import { merge } from '@aztec/foundation/collection'; import type { Fr } from '@aztec/foundation/curves/bn254'; import type { StateOverride } from 'viem'; @@ -45,18 +46,22 @@ export class SimulationOverridesBuilder { return new SimulationOverridesBuilder().merge(plan); } - /** Merges another plan into this builder. Later values win on a per-half basis for chain tips. */ + /** + * Merges another plan into this builder. Later values win on a per-half basis for chain tips, + * but explicit `undefined` fields in the incoming plan are ignored so they cannot erase a + * previously-set value. + */ public merge(plan: SimulationOverridesPlan | undefined): this { if (!plan) { return this; } if (plan.chainTipsOverride) { - this.chainTipsOverride = { ...(this.chainTipsOverride ?? {}), ...plan.chainTipsOverride }; + this.chainTipsOverride = merge(this.chainTipsOverride ?? {}, plan.chainTipsOverride); + } + if (plan.pendingCheckpointState) { + this.pendingCheckpointState = merge(this.pendingCheckpointState ?? {}, plan.pendingCheckpointState); } - this.pendingCheckpointState = plan.pendingCheckpointState - ? { ...(this.pendingCheckpointState ?? {}), ...plan.pendingCheckpointState } - : this.pendingCheckpointState; this.disableBlobCheck = this.disableBlobCheck || (plan.disableBlobCheck ?? false); return this; @@ -87,15 +92,21 @@ export class SimulationOverridesBuilder { } /** - * Overrides the locally-derivable `tempCheckpointLogs` cell fields for the configured pending - * checkpoint. Callers populate these together because they all come from the same proposed - * checkpoint payload — there is no use case for setting them independently. + * Overrides one or more `tempCheckpointLogs` cell fields for the configured pending checkpoint. + * Fields are independent: any subset can be provided. The translator (`makeTempCheckpointLogOverride`) + * emits a stateDiff entry per field actually set, so unspecified fields stay at their on-chain + * values. + * + * `slotNumber` is load-bearing for `STFLib.canPruneAtTime`: when the simulation overrides `pending` + * to a checkpoint that has no on-chain `tempCheckpointLogs` entry yet, the missing slotNumber falls + * back to 0 and the contract treats the pending tip as belonging to epoch 0, triggering a phantom + * prune that silently undoes the `pending` override. */ public withPendingTempCheckpointLogFields(fields: { - headerHash: Fr; - outHash: Fr; - payloadDigest: Buffer32; - slotNumber: SlotNumber; + headerHash?: Fr; + outHash?: Fr; + payloadDigest?: Buffer32; + slotNumber?: SlotNumber; }): this { this.assertPendingCheckpointNumber(); this.pendingCheckpointState = { ...(this.pendingCheckpointState ?? {}), ...fields }; diff --git a/yarn-project/ethereum/src/contracts/governance_proposer.ts b/yarn-project/ethereum/src/contracts/governance_proposer.ts index 0210211bb28a..b9e169475854 100644 --- a/yarn-project/ethereum/src/contracts/governance_proposer.ts +++ b/yarn-project/ethereum/src/contracts/governance_proposer.ts @@ -20,6 +20,14 @@ import { ReadOnlyGovernanceContract, extractProposalIdFromLogs } from './governa export class GovernanceProposerContract implements IEmpireBase { private readonly proposer: GetContractReturnType; + /** + * Cache of bytecode-existence checks keyed by payload address. The check is stable for a + * contract's lifetime -- a contract either has code or it does not, and code cannot be removed + * after deployment (selfdestruct aside, which is not relevant here). Safe to memoize + * indefinitely for the lifetime of this instance. + */ + private readonly emptyPayloadCache: Map = new Map(); + constructor( public readonly client: ViemClient, address: Hex | EthAddress, @@ -133,6 +141,28 @@ export class GovernanceProposerContract implements IEmpireBase { return governance.hasActiveProposalWithPayload(payload); } + /** + * Returns true if the given payload address has no deployed bytecode. Used as a cheap + * pre-flight check before casting a governance signal — voting for a zero-code address + * is unrecoverable. + * + * We only cache the `false` result (address has bytecode). The `true` result is NOT + * cached because a CREATE2-redeployed address could go from empty to populated, and + * caching `true` would make us keep skipping a payload that later becomes valid. + */ + public async isPayloadEmpty(payload: EthAddress): Promise { + const key = payload.toString() as Hex; + if (this.emptyPayloadCache.get(key) === false) { + return false; + } + const code = await this.client.getCode({ address: key }); + const isEmpty = !code || code === '0x'; + if (!isEmpty) { + this.emptyPayloadCache.set(key, false); + } + return isEmpty; + } + public async submitRoundWinner( round: bigint, l1TxUtils: L1TxUtils, diff --git a/yarn-project/ethereum/src/contracts/multicall.test.ts b/yarn-project/ethereum/src/contracts/multicall.test.ts index 1804eaf1e307..c63077e1bb29 100644 --- a/yarn-project/ethereum/src/contracts/multicall.test.ts +++ b/yarn-project/ethereum/src/contracts/multicall.test.ts @@ -17,7 +17,6 @@ import { L1TxUtils, createL1TxUtils } from '../l1_tx_utils/index.js'; import type { Anvil } from '../test/start_anvil.js'; import { startAnvil } from '../test/start_anvil.js'; import type { ExtendedViemWalletClient } from '../types.js'; -import { FormattedViemError } from '../utils.js'; import { MULTI_CALL_3_ADDRESS, Multicall3, deployMulticall3 } from './multicall.js'; describe('Multicall3', () => { @@ -97,34 +96,65 @@ describe('Multicall3', () => { abi: GovernanceProposerAbi, }); - it('should be able to call multiple functions in a single transaction', async () => { + it('should not revert by default if a single call fails', async () => { await deployMulticall3(walletClient, logger); - const result = await Multicall3.forward( - [makeSuccessfulCall(), makeFailingCall()], - l1TxUtils, - undefined, - undefined, - deployed.l1ContractAddresses.rollupAddress.toString(), - logger, - { revertOnFailure: true }, - ); + const result = await Multicall3.forward([makeSuccessfulCall(), makeFailingCall()], l1TxUtils, undefined, undefined); expect(result).toBeDefined(); - expect(result).toBeInstanceOf(FormattedViemError); - const formattedError = result as FormattedViemError; - expect(formattedError.message).toContain('ValidatorSelection__InsufficientValidatorSetSize'); + expect(result.receipt.status).toBe('success'); }); - it('should not revert by default if a single call fails', async () => { - await deployMulticall3(walletClient, logger); - const result = await Multicall3.forward( - [makeSuccessfulCall(), makeFailingCall()], - l1TxUtils, - undefined, - undefined, - deployed.l1ContractAddresses.rollupAddress.toString(), - logger, - ); - expect(result).toBeDefined(); - expect('receipt' in result && result.receipt.status).toBe('success'); + describe('simulateAggregate3', () => { + beforeAll(async () => { + await deployMulticall3(walletClient, logger); + }); + + it('decodes per-entry results when all entries succeed', async () => { + const result = await Multicall3.simulateAggregate3([makeSuccessfulCall(), makeSuccessfulCall()], l1TxUtils); + expect(result.kind).toBe('decoded'); + if (result.kind !== 'decoded') { + return; + } + expect(result.entries).toHaveLength(2); + expect(result.entries[0].success).toBe(true); + expect(result.entries[1].success).toBe(true); + expect(result.gasUsed).toBeGreaterThan(0n); + }); + + it('marks reverted entries with a decoded revert reason', async () => { + const result = await Multicall3.simulateAggregate3([makeSuccessfulCall(), makeFailingCall()], l1TxUtils); + expect(result.kind).toBe('decoded'); + if (result.kind !== 'decoded') { + return; + } + expect(result.entries).toHaveLength(2); + expect(result.entries[0].success).toBe(true); + expect(result.entries[1].success).toBe(false); + expect(result.entries[1].revertReason).toContain('ValidatorSelection__InsufficientValidatorSetSize'); + }); + + it('honours fakeSenderBalance by overriding the sender balance for the simulate', async () => { + // Use a sender we have not funded so a real send would fail with insufficient funds. + const poorPrivateKey = '0x' + 'aa'.repeat(32); + const poorAccount = privateKeyToAccount(poorPrivateKey as `0x${string}`); + const poorClient = createExtendedL1Client([rpcUrl], poorAccount, foundry); + const poorL1TxUtils = createL1TxUtils(poorClient, { logger }); + + // Without fakeSenderBalance, the simulate would not fail on entry-level (call doesn't need + // value), but the eth_simulateV1 may still validate sender funds for gas. Either way, with + // fakeSenderBalance we explicitly cap balance high enough that no balance-related path can + // fail in the simulate. + const result = await Multicall3.simulateAggregate3([makeSuccessfulCall()], poorL1TxUtils, { + fakeSenderBalance: 10n ** 20n, + }); + expect(result.kind).toBe('decoded'); + if (result.kind !== 'decoded') { + return; + } + expect(result.entries[0].success).toBe(true); + }); + + it('reports hasCode() true after deployMulticall3', async () => { + expect(await Multicall3.hasCode(l1TxUtils)).toBe(true); + }); }); }); diff --git a/yarn-project/ethereum/src/contracts/multicall.ts b/yarn-project/ethereum/src/contracts/multicall.ts index 40e17970e5db..f0b22bf71dac 100644 --- a/yarn-project/ethereum/src/contracts/multicall.ts +++ b/yarn-project/ethereum/src/contracts/multicall.ts @@ -1,16 +1,37 @@ -import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer'; -import { TimeoutError } from '@aztec/foundation/error'; +import { EthAddress } from '@aztec/foundation/eth-address'; import type { Logger } from '@aztec/foundation/log'; -import { type Address, type EncodeFunctionDataParameters, type Hex, encodeFunctionData, multicall3Abi } from 'viem'; +import { + type Abi, + type Address, + type BlockOverrides, + type Hex, + type RequiredBy, + type StateOverride, + type TransactionReceipt, + decodeFunctionResult, + encodeFunctionData, + multicall3Abi, +} from 'viem'; import type { L1BlobInputs, L1TxConfig, L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js'; import type { ExtendedViemWalletClient } from '../types.js'; -import { FormattedViemError, formatViemError } from '../utils.js'; -import { RollupContract } from './rollup.js'; +import { tryDecodeRevertReason } from '../utils.js'; export const MULTI_CALL_3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11' as const; +/** + * Thrown by `Multicall3.forward` when the forwarder transaction lands but the receipt reports a + * reverted status. This is not expected (aggregate3 uses allowFailure: true), so callers should + * treat it as a fatal on-chain failure rather than retrying on a different publisher. + */ +export class MulticallForwarderRevertedError extends Error { + constructor(public readonly receipt: TransactionReceipt) { + super(`Multicall3 forwarder tx reverted: ${receipt.transactionHash}`); + this.name = 'MulticallForwarderRevertedError'; + } +} + /** ABI fragment for aggregate3Value — not included in viem's multicall3Abi. */ export const aggregate3ValueAbi = [ { @@ -44,116 +65,169 @@ export const aggregate3ValueAbi = [ }, ] as const; +/** A single call to embed inside an aggregate3 simulation. The abi is used to decode revert reasons. */ +export type SimulateAggregate3Request = { + to: Address; + data: Hex; + /** Optional ABI used to decode the revert reason if this entry reverts. */ + abi?: Abi; +}; + +export type SimulateAggregate3EntryResult = { + success: boolean; + /** Decoded revert reason text when `success === false` and a request abi was provided. */ + revertReason?: string; + /** Raw return data hex. `'0x'` for successful entries with void return. */ + returnData: Hex; +}; + +/** + * Outcome of a bundle simulation. + * - `decoded`: eth_simulateV1 ran and produced a per-entry Result[]. Use `entries` for filtering. + * - `fallback`: the node does not support eth_simulateV1; `fallbackGasEstimate` was returned and no + * per-entry info is available. Caller should send the bundle as-is with a conservative gas cap. + */ +export type SimulateAggregate3Result = + | { kind: 'decoded'; entries: SimulateAggregate3EntryResult[]; gasUsed: bigint } + | { kind: 'fallback'; gasUsed: bigint }; + +export type SimulateAggregate3Options = { + blockOverrides?: BlockOverrides; + stateOverrides?: StateOverride; + /** + * If set, append a state override that fakes the sender's balance during the simulation so a + * low or zero balance does not cause the simulate to fail with insufficient funds. The fake + * balance is applied to `l1TxUtils.getSenderAddress()`. + */ + fakeSenderBalance?: bigint; + /** Gas cap to pass on the simulate call itself (defaults to viem's behavior). */ + gas?: bigint; + /** When eth_simulateV1 is unavailable, fall back to this gas estimate instead of throwing. */ + fallbackGasEstimate?: bigint; +}; + export class Multicall3 { - static async forward( + /** + * Returns true iff Multicall3 bytecode is deployed at MULTI_CALL_3_ADDRESS. An empty result from + * a non-existent contract would otherwise silently validate any bundle that uses Multicall3. + */ + static async hasCode(l1TxUtils: L1TxUtils): Promise { + const code = await l1TxUtils.getCode(EthAddress.fromString(MULTI_CALL_3_ADDRESS)); + return !!code && code !== '0x'; + } + + /** + * Simulates an aggregate3 call composed of the given requests via eth_simulateV1 and decodes the + * per-entry Result[]. Entries that revert are returned with a decoded revertReason (if the request + * provided an abi). + * + * Use this to pre-validate a bundle before sending it through `Multicall3.forward`. The caller can + * drop reverted entries from the bundle and re-simulate with the reduced list to get an accurate + * `gasUsed`. + */ + static async simulateAggregate3( + requests: SimulateAggregate3Request[], + l1TxUtils: L1TxUtils, + opts: SimulateAggregate3Options = {}, + ): Promise { + const calldata = encodeFunctionData({ + abi: multicall3Abi, + functionName: 'aggregate3', + args: [ + requests.map(r => ({ + target: r.to, + callData: r.data, + allowFailure: true, + })), + ], + }); + + const stateOverrides: StateOverride = [...(opts.stateOverrides ?? [])]; + if (opts.fakeSenderBalance !== undefined) { + stateOverrides.push({ + address: l1TxUtils.getSenderAddress().toString(), + balance: opts.fakeSenderBalance, + }); + } + + const simResult = await l1TxUtils.simulate( + { to: MULTI_CALL_3_ADDRESS, data: calldata, gas: opts.gas }, + opts.blockOverrides, + stateOverrides, + multicall3Abi, + { fallbackGasEstimate: opts.fallbackGasEstimate }, + ); + + if (simResult.result === '0x') { + return { kind: 'fallback', gasUsed: simResult.gasUsed }; + } + + const decoded = decodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + data: simResult.result, + }) as readonly { success: boolean; returnData: `0x${string}` }[]; + + const entries: SimulateAggregate3EntryResult[] = decoded.map((entry, i) => { + if (entry.success) { + return { success: true, returnData: entry.returnData }; + } + const abi = requests[i].abi; + const revertReason = abi ? tryDecodeRevertReason(entry.returnData, abi) : undefined; + return { success: false, returnData: entry.returnData, revertReason }; + }); + + return { kind: 'decoded', entries, gasUsed: simResult.gasUsed }; + } + + /** + * Sends a batch of requests through aggregate3. Individual calls may fail (allowFailure: true), + * but the top-level multicall is expected to land successfully. Throws if the send fails or if + * the receipt reports a reverted status. + */ + static async forward( requests: L1TxRequest[], l1TxUtils: L1TxUtils, - gasConfig: L1TxConfig | undefined, + gasConfig: TOptGasLimitRequired extends true ? RequiredBy : L1TxConfig | undefined, blobConfig: L1BlobInputs | undefined, - rollupAddress: Hex, - logger: Logger, - opts: { revertOnFailure?: boolean } = {}, + opts: { gasLimitRequired?: TOptGasLimitRequired } = {}, ) { - requests = requests.filter(request => request.to !== null); - const args = requests.map(r => ({ - target: r.to!, - callData: r.data!, - allowFailure: !opts.revertOnFailure, - })); - const forwarderFunctionData: Required> = { + if (opts.gasLimitRequired && !gasConfig?.gasLimit) { + throw new Error('Multicall gasLimit is required when gasLimitRequired is true'); + } + + const args = requests + .filter(request => request.to !== null) + .map(r => ({ + target: r.to!, + callData: r.data!, + allowFailure: true, + })); + const encodedForwarderData = encodeFunctionData({ abi: multicall3Abi, functionName: 'aggregate3', args: [args], - }; - - const encodedForwarderData = encodeFunctionData(forwarderFunctionData); - try { - const { receipt, state } = await l1TxUtils.sendAndMonitorTransaction( - { - to: MULTI_CALL_3_ADDRESS, - data: encodedForwarderData, - abi: multicall3Abi, - }, - gasConfig, - blobConfig, - ); - - if (receipt.status === 'success') { - const stats = await l1TxUtils.getTransactionStats(receipt.transactionHash); - return { receipt, stats }; - } else { - logger.error('Forwarder transaction failed', undefined, { receipt }); - - const args = { - ...forwarderFunctionData, - address: MULTI_CALL_3_ADDRESS, - }; - - let errorMsg: string | undefined; - - if (blobConfig) { - const maxFeePerBlobGas = blobConfig.maxFeePerBlobGas ?? state.gasPrice.maxFeePerBlobGas; - if (maxFeePerBlobGas === undefined) { - errorMsg = 'maxFeePerBlobGas is required to get the error message'; - } else { - logger.debug('Trying to get error from reverted tx with blob config'); - errorMsg = await l1TxUtils.tryGetErrorFromRevertedTx( - encodedForwarderData, - args, - { - blobs: blobConfig.blobs, - kzg: blobConfig.kzg, - maxFeePerBlobGas, - }, - [ - { - address: rollupAddress, - stateDiff: [ - { - slot: toPaddedHex(RollupContract.checkBlobStorageSlot, true), - value: toPaddedHex(0n, true), - }, - ], - }, - ], - ); - } - } else { - logger.debug('Trying to get error from reverted tx without blob config'); - errorMsg = await l1TxUtils.tryGetErrorFromRevertedTx(encodedForwarderData, args, undefined, []); - } - - return { receipt, errorMsg }; - } - } catch (err) { - if (err instanceof TimeoutError) { - throw err; - } + }); - for (const request of requests) { - logger.debug('Simulating request', { request }); - const result = await l1TxUtils - .simulate(request, undefined, [ - { - address: rollupAddress, - stateDiff: [ - { slot: toPaddedHex(RollupContract.checkBlobStorageSlot, true), value: toPaddedHex(0n, true) }, - ], - }, - ]) - .catch(err => formatViemError(err, request.abi)); - if (result instanceof FormattedViemError) { - logger.error('Found error in simulation', result, { - to: request.to ?? 'null', - data: request.data, - }); - - return result; - } - } - logger.warn('Failed to get error from reverted tx', { err }); - throw err; + const { receipt } = await l1TxUtils.sendAndMonitorTransaction( + { + to: MULTI_CALL_3_ADDRESS, + data: encodedForwarderData, + abi: multicall3Abi, + }, + gasConfig, + blobConfig, + ); + + // This shouldn't happen. Any failure in individual calls is swallowed by forward since we set + // allowFailure to true for all calls, so a reverted status here would indicate a problem with + // the Multicall3 contract itself or the forwarder transaction (such as an out-of-gas). + if (receipt.status !== 'success') { + throw new MulticallForwarderRevertedError(receipt); } + + const stats = await l1TxUtils.getTransactionStats(receipt.transactionHash); + return { receipt, stats, multicallData: encodedForwarderData }; } /** Batch multiple value transfers into a single aggregate3Value call on Multicall3. */ diff --git a/yarn-project/ethereum/src/l1_tx_utils/l1_tx_utils.ts b/yarn-project/ethereum/src/l1_tx_utils/l1_tx_utils.ts index 3ca1526cecdb..8ed7825cd6b6 100644 --- a/yarn-project/ethereum/src/l1_tx_utils/l1_tx_utils.ts +++ b/yarn-project/ethereum/src/l1_tx_utils/l1_tx_utils.ts @@ -131,6 +131,14 @@ export class L1TxUtils extends ReadOnlyL1TxUtils { ); } + /** + * Clears the cached `lastSentNonce` so the next `sendTransaction` call fetches the real + * nonce from the chain. Call this after an L1 reorg to prevent stale nonce references. + */ + public resetNonce(): void { + this.lastSentNonce = undefined; + } + public getSenderAddress() { return this.address; } @@ -213,6 +221,19 @@ export class L1TxUtils extends ReadOnlyL1TxUtils { return await this.signTransaction(txRequest as TransactionSerializable); } + private async checkInterruptedOrTimedOut(gasConfig: Pick): Promise { + if (this.interrupted) { + throw new InterruptError(`Transaction sending is interrupted`); + } + const now = new Date(await this.getL1Timestamp()); + if (gasConfig.txTimeoutAt && now > gasConfig.txTimeoutAt) { + throw new TimeoutError( + `Transaction timed out before sending (now ${now.toISOString()} > timeoutAt ${gasConfig.txTimeoutAt.toISOString()})`, + ); + } + return now; + } + /** * Sends a transaction with gas estimation and pricing * @param request - The transaction request (to, data, value) @@ -225,14 +246,15 @@ export class L1TxUtils extends ReadOnlyL1TxUtils { blobInputs?: L1BlobInputs, stateChange: TxUtilsState = TxUtilsState.SENT, ): Promise<{ txHash: Hex; state: L1TxState }> { - if (this.interrupted) { - throw new InterruptError(`Transaction sending is interrupted`); - } - try { const gasConfig = merge(this.config, gasConfigOverrides); const account = this.getSenderAddress().toString(); + // Fail fast before doing any work (gas estimation, balance check) if we've been interrupted + // or if the caller's deadline has already passed. The same check is repeated after gas + // estimation in case it took long enough to push us past the deadline. + await this.checkInterruptedOrTimedOut(gasConfig); + let gasLimit: bigint; if (this.debugMaxGasLimit) { gasLimit = MAX_L1_TX_LIMIT; @@ -245,16 +267,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils { const gasPrice = await this.getGasPrice(gasConfig, !!blobInputs); - if (this.interrupted) { - throw new InterruptError(`Transaction sending is interrupted`); - } - - const now = new Date(await this.getL1Timestamp()); - if (gasConfig.txTimeoutAt && now > gasConfig.txTimeoutAt) { - throw new TimeoutError( - `Transaction timed out before sending (now ${now.toISOString()} > timeoutAt ${gasConfig.txTimeoutAt.toISOString()})`, - ); - } + const now = await this.checkInterruptedOrTimedOut(gasConfig); let txHash: Hex; let nonce: number; diff --git a/yarn-project/ethereum/src/test/eth_cheat_codes.ts b/yarn-project/ethereum/src/test/eth_cheat_codes.ts index b1cbdd199d6f..82f90873f77b 100644 --- a/yarn-project/ethereum/src/test/eth_cheat_codes.ts +++ b/yarn-project/ethereum/src/test/eth_cheat_codes.ts @@ -95,6 +95,16 @@ export class EthCheatCodes { return parseInt(res.timestamp, 16); } + /** + * Get the timestamp of the pending L1 block — the block that anvil will mine next. + * Reflects any prior `setNextBlockTimestamp` call or the configured block interval. + * @returns The pending block timestamp in seconds. + */ + public async nextBlockTimestamp(): Promise { + const res = await this.doRpcCall('eth_getBlockByNumber', ['pending', false]); + return parseInt(res.timestamp, 16); + } + /** * Advance the chain by a number of blocks * @param numberOfBlocks - The number of blocks to mine diff --git a/yarn-project/ethereum/src/test/rollup_cheat_codes.ts b/yarn-project/ethereum/src/test/rollup_cheat_codes.ts index 48ef7ad3df77..2c7343e56518 100644 --- a/yarn-project/ethereum/src/test/rollup_cheat_codes.ts +++ b/yarn-project/ethereum/src/test/rollup_cheat_codes.ts @@ -178,6 +178,21 @@ export class RollupCheatCodes { return [timestamp, nextSlot]; } + /** + * Warps L1 time to the start of an explicit absolute slot. Unlike `advanceSlots(N)` which is + * relative to the current L1 timestamp at call time and therefore races with real-time + * progression between query and warp, this lands at the slot regardless of latency. + * + * Throws if the requested slot is in the past relative to current L1 time (anvil cannot + * rewind). + */ + public async advanceToSlot(slot: SlotNumber) { + const timestamp = await this.rollup.read.getTimestampForSlot([BigInt(slot)]); + await this.ethCheatCodes.warp(Number(timestamp), { silent: true, resetBlockInterval: true }); + this.logger.warn(`Advanced to slot ${slot}`, { timestamp }); + return timestamp; + } + /** * Warps time in L1 equivalent to however many slots. * @param howMany - The number of slots to advance. diff --git a/yarn-project/ethereum/src/utils.ts b/yarn-project/ethereum/src/utils.ts index 81673660565f..3079fbaf457a 100644 --- a/yarn-project/ethereum/src/utils.ts +++ b/yarn-project/ethereum/src/utils.ts @@ -276,6 +276,24 @@ function stripAbis(obj: any) { }); } +/** + * Best-effort decode of a raw revert payload (`0x...`) against an ABI. + * Returns a human-readable `ErrorName(arg1, arg2, ...)` string, or `undefined` if the selector + * is unknown or the payload is empty. Use to surface decoded error names alongside the raw + * payload in log lines for operators. + */ +export function tryDecodeRevertReason(data: Hex | undefined, abi: Abi): string | undefined { + if (!data || data === '0x') { + return undefined; + } + try { + const decoded = decodeErrorResult({ abi, data }); + return `${decoded.errorName}(${decoded.args?.join(', ') ?? ''})`; + } catch { + return undefined; + } +} + export function tryGetCustomErrorName(err: any) { try { // See https://viem.sh/docs/contract/simulateContract#handling-custom-errors diff --git a/yarn-project/foundation/package.json b/yarn-project/foundation/package.json index 3b798a313bff..be856d8324ba 100644 --- a/yarn-project/foundation/package.json +++ b/yarn-project/foundation/package.json @@ -62,6 +62,7 @@ "./eth-signature": "./dest/eth-signature/index.js", "./queue": "./dest/queue/index.js", "./fifo": "./dest/fifo/index.js", + "./fifo-set": "./dest/fifo_set/index.js", "./fs": "./dest/fs/index.js", "./buffer": "./dest/buffer/index.js", "./json-rpc": "./dest/json-rpc/index.js", diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index 87728f041c20..c62136c29ca7 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -76,6 +76,7 @@ export type EnvVar = | 'DEBUG' | 'DEBUG_P2P_DISABLE_COLOCATION_PENALTY' | 'ENABLE_PROVER_NODE' + | 'USE_AUTOMINE_SEQUENCER' | 'ETHEREUM_HOSTS' | 'ETHEREUM_DEBUG_HOSTS' | 'ETHEREUM_ALLOW_NO_DEBUG_HOSTS' @@ -101,8 +102,10 @@ export type EnvVar = | 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT' | 'OTEL_EXPORTER_OTLP_LOGS_ENDPOINT' | 'OTEL_COLLECT_INTERVAL_MS' + | 'OTEL_BSP_MAX_QUEUE_SIZE' | 'OTEL_EXCLUDE_METRICS' | 'OTEL_INCLUDE_METRICS' + | 'OTEL_MIN_TRACE_DURATION_MS' | 'OTEL_EXPORT_TIMEOUT_MS' | 'PUBLIC_OTEL_EXPORTER_OTLP_METRICS_ENDPOINT' | 'PUBLIC_OTEL_INCLUDE_METRICS' @@ -159,7 +162,7 @@ export type EnvVar = | 'P2P_DROP_TX_CHANCE' | 'P2P_TX_POOL_DELETE_TXS_AFTER_REORG' | 'P2P_MIN_TX_POOL_AGE_MS' - | 'P2P_MISSING_TX_COLLECTION_DEADLINE_MS' + | 'P2P_MISSING_TX_COLLECTION_DEADLINE_SLOTS' | 'P2P_RPC_PRICE_BUMP_PERCENTAGE' | 'DEBUG_P2P_INSTRUMENT_MESSAGES' | 'PEER_ID_PRIVATE_KEY' @@ -210,7 +213,8 @@ export type EnvVar = | 'RPC_SIMULATE_PUBLIC_MAX_DEBUG_LOG_MEMORY_READS' | 'SENTINEL_ENABLED' | 'SENTINEL_HISTORY_LENGTH_IN_EPOCHS' - | 'SENTINEL_HISTORIC_PROVEN_PERFORMANCE_LENGTH_IN_EPOCHS' + | 'SENTINEL_HISTORIC_EPOCH_PERFORMANCE_LENGTH_IN_EPOCHS' + | 'SENTINEL_EPOCH_END_BUFFER_SLOTS' | 'SEQ_ENABLE_PROPOSER_PIPELINING' | 'SEQ_MAX_TX_PER_BLOCK' | 'SEQ_MAX_TX_PER_CHECKPOINT' @@ -240,17 +244,18 @@ export type EnvVar = | 'SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT' | 'SLASH_VALIDATORS_ALWAYS' | 'SLASH_VALIDATORS_NEVER' - | 'SLASH_PRUNE_PENALTY' | 'SLASH_DATA_WITHHOLDING_PENALTY' + | 'SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS' | 'SLASH_INACTIVITY_PENALTY' | 'SLASH_INACTIVITY_TARGET_PERCENTAGE' | 'SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD' | 'SLASH_INVALID_BLOCK_PENALTY' + | 'SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY' | 'SLASH_DUPLICATE_PROPOSAL_PENALTY' | 'SLASH_DUPLICATE_ATTESTATION_PENALTY' | 'SLASH_OVERRIDE_PAYLOAD' | 'SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY' - | 'SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY' + | 'SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY' | 'SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY' | 'SLASH_UNKNOWN_PENALTY' | 'SLASH_GRACE_PERIOD_L2_SLOTS' diff --git a/yarn-project/foundation/src/config/network_name.ts b/yarn-project/foundation/src/config/network_name.ts index e00dcb200ec7..7bde88ab1fa0 100644 --- a/yarn-project/foundation/src/config/network_name.ts +++ b/yarn-project/foundation/src/config/network_name.ts @@ -1,6 +1,5 @@ export type NetworkNames = | 'local' - | 'staging-ignition' | 'staging-public' | 'testnet' | 'mainnet' @@ -12,8 +11,6 @@ export function getActiveNetworkName(name?: string): NetworkNames { const network = name || process.env.NETWORK; if (!network || network === '' || network === 'local') { return 'local'; - } else if (network === 'staging-ignition') { - return network; } else if (network === 'staging-public') { return network; } else if (network === 'testnet' || network === 'alpha-testnet') { diff --git a/yarn-project/foundation/src/curves/grumpkin/point.test.ts b/yarn-project/foundation/src/curves/grumpkin/point.test.ts index 2adf80cf4543..e3569ae45b45 100644 --- a/yarn-project/foundation/src/curves/grumpkin/point.test.ts +++ b/yarn-project/foundation/src/curves/grumpkin/point.test.ts @@ -8,7 +8,7 @@ describe('Point', () => { it('always returns a valid point', async () => { for (let i = 0; i < 100; ++i) { const point = await Point.random(); - expect(point.isOnGrumpkin()).toEqual(true); + expect(point.isOnCurve()).toEqual(true); } }); @@ -26,7 +26,6 @@ describe('Point', () => { const p = new Point( new Fr(0x30426e64aee30e998c13c8ceecda3a77807dbead52bc2f3bf0eae851b4b710c1n), new Fr(0x113156a068f603023240c96b4da5474667db3b8711c521c748212a15bc034ea6n), - false, ); const [x, sign] = p.toXAndSign(); @@ -53,7 +52,6 @@ describe('Point', () => { const p = new Point( new Fr(0x1af41f5de96446dc3776a1eb2d98bb956b7acd9979a67854bec6fa7c2973bd73n), new Fr(0x07fc22c7f2c7057571f137fe46ea9c95114282bc95d37d71ec4bfb88de457d4an), - false, ); expect(p.toXAndSign()[1]).toBe(true); @@ -74,7 +72,6 @@ describe('Point', () => { const p = new Point( new Fr(0x247371652e55dd74c9af8dbe9fb44931ba29a9229994384bd7077796c14ee2b5n), new Fr(0x26441aec112e1ae4cee374f42556932001507ad46e255ffb27369c7e3766e5c0n), - false, ); expect(p.toXAndSign()[1]).toBe(false); diff --git a/yarn-project/foundation/src/curves/grumpkin/point.ts b/yarn-project/foundation/src/curves/grumpkin/point.ts index 05405446058d..6d798bb952ec 100644 --- a/yarn-project/foundation/src/curves/grumpkin/point.ts +++ b/yarn-project/foundation/src/curves/grumpkin/point.ts @@ -1,5 +1,4 @@ import { toBigIntBE } from '../../bigint-buffer/index.js'; -import { poseidon2Hash } from '../../crypto/poseidon/index.js'; import { randomBoolean } from '../../crypto/random/index.js'; import { hexSchemaFor } from '../../schemas/utils.js'; import { BufferReader, FieldReader, serializeToBuffer } from '../../serialize/index.js'; @@ -13,13 +12,16 @@ import { Fr } from '../bn254/field.js'; * TODO(#7386): Clean up this class. */ export class Point { - static ZERO = new Point(Fr.ZERO, Fr.ZERO, false); + static INFINITY = new Point(Fr.ZERO, Fr.ZERO); static SIZE_IN_BYTES = Fr.SIZE_IN_BYTES * 2; static COMPRESSED_SIZE_IN_BYTES = Fr.SIZE_IN_BYTES; /** Used to differentiate this class from AztecAddress */ public readonly kind = 'point'; + /** Whether the point is at infinity */ + public readonly isInfinite: boolean; + constructor( /** * The point's x coordinate @@ -29,12 +31,10 @@ export class Point { * The point's y coordinate */ public readonly y: Fr, - /** - * Whether the point is at infinity - */ - public readonly isInfinite: boolean, ) { // TODO(#7386): check if on curve + // NOTE: now there is no isInfinite in the struct, empty == inf, so an empty class would pass an on-curve check. This may be fine depending on the usage. + this.isInfinite = x.isZero() && y.isZero(); } toJSON() { @@ -61,7 +61,7 @@ export class Point { if (obj instanceof Buffer || Buffer.isBuffer(obj)) { return Point.fromBuffer(obj); } - return new Point(Fr.fromPlainObject(obj.x), Fr.fromPlainObject(obj.y), obj.isInfinite ?? false); + return new this(Fr.fromPlainObject(obj.x), Fr.fromPlainObject(obj.y)); } /** @@ -92,7 +92,7 @@ export class Point { */ static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new this(Fr.fromBuffer(reader), Fr.fromBuffer(reader), false); + return new this(Fr.fromBuffer(reader), Fr.fromBuffer(reader)); } /** @@ -125,19 +125,17 @@ export class Point { } /** - * Returns the contents of the point as an array of 3 fields. - * @returns The point as an array of 3 fields + * Returns the contents of the point as an array of 2 fields. + * @returns The point as an array of 2 fields */ - // TODO(F-553): Once we take the breaking change and drop the custom Noir `Point` wrapper in - // `noir-projects/noir-protocol-circuits/crates/types/src/point.nr`, revert this to serialize as `[x, y]` (2 fields) - // and drop the `is_infinite` flag from `fromFields` / `toNoirStruct` below. toFields() { - return [this.x, this.y, new Fr(this.isInfinite)]; + return [this.x, this.y]; } static fromFields(fields: Fr[] | FieldReader) { const reader = FieldReader.asReader(fields); - return new this(reader.readField(), reader.readField(), reader.readBoolean()); + const [x, y] = [reader.readField(), reader.readField()]; + return new this(x, y); } /** @@ -162,11 +160,12 @@ export class Point { const finalY = sign ? new Fr(yPositiveBigInt) : new Fr(yNegativeBigInt); // Create and return the new Point - return new this(x, finalY, false); + return new this(x, finalY); } /** - * @returns + * @param x - The x coordinate of the point + * @returns y^2 such that y^2 = x^3 - 17 */ static YFromX(x: Fr): Promise { // Calculate y^2 = x^3 - 17 (i.e. the Grumpkin curve equation) @@ -194,24 +193,15 @@ export class Point { return { x: this.x.toBigInt(), y: this.y.toBigInt(), - isInfinite: this.isInfinite ? 1n : 0n, }; } /** * Converts the Point instance to a Buffer representation of the coordinates. * @returns A Buffer representation of the Point instance. - * @dev Note that toBuffer does not include the isInfinite flag and other serialization methods do (e.g. toFields). - * This is because currently when we work with point as bytes we don't want to populate the extra bytes for - * isInfinite flag because: - * 1. Our Grumpkin BB API currently does not handle point at infinity, - * 2. we use toBuffer when serializing notes and events and there we only work with public keys and point at infinity - * is not considered a valid public key and the extra byte would raise DA cost. + * @dev Note that toBuffer does not include the isInfinite flag. The point at infinity is serialized as (0, 0). */ toBuffer() { - if (this.isInfinite) { - throw new Error('Cannot serialize infinite point with isInfinite flag'); - } const buf = serializeToBuffer([this.x, this.y]); if (buf.length !== Point.SIZE_IN_BYTES) { throw new Error(`Invalid buffer length for Point: ${buf.length}`); @@ -261,12 +251,10 @@ export class Point { } toNoirStruct() { - /* eslint-disable camelcase */ - return { x: this.x, y: this.y, is_infinite: this.isInfinite }; - /* eslint-enable camelcase */ + return { x: this.x, y: this.y }; } - // Used for IvpkM, OvpkM, NpkM and TpkM. TODO(#8124): Consider removing this method. + // Used for IvpkM. TODO(#8124): Consider removing this method. toWrappedNoirStruct() { return { inner: this.toNoirStruct() }; } @@ -286,21 +274,13 @@ export class Point { return this.x.isZero() && this.y.isZero(); } - hash() { - return poseidon2Hash(this.toFields()); - } - /** - * Check if this is point at infinity. - * Check this is consistent with how bb is encoding the point at infinity + * @param x - The x coordinate of the point + * @param y - The y coordinate of the point + * @returns Whether the point exists on Grumpkin */ - public get inf() { - return this.isInfinite; - } - - isOnGrumpkin() { - // TODO: Check this against how bb handles curve check and infinity point check - if (this.inf) { + isOnCurve() { + if (this.isInfinite) { return true; } diff --git a/yarn-project/foundation/src/fifo_set/fifo_set.test.ts b/yarn-project/foundation/src/fifo_set/fifo_set.test.ts new file mode 100644 index 000000000000..f0b4628131d1 --- /dev/null +++ b/yarn-project/foundation/src/fifo_set/fifo_set.test.ts @@ -0,0 +1,62 @@ +import { FifoSet } from './fifo_set.js'; + +describe('FifoSet', () => { + it('keeps entries up to the limit', () => { + const set = FifoSet.withLimit(3); + + set.add('a'); + set.add('b'); + set.add('c'); + + expect([...set]).toEqual(['a', 'b', 'c']); + expect(set.size).toBe(3); + expect(set.limit).toBe(3); + }); + + it('evicts the oldest entry when adding past the limit', () => { + const set = FifoSet.withLimit(2); + + set.add('a'); + set.add('b'); + set.add('c'); + + expect([...set]).toEqual(['b', 'c']); + }); + + it('compacts initial values to the newest entries', () => { + const set = FifoSet.withLimit(2, ['a', 'b', 'c']); + + expect([...set]).toEqual(['b', 'c']); + }); + + it('does not evict when adding a duplicate', () => { + const set = FifoSet.withLimit(2, ['a', 'b']); + + set.add('a'); + + expect([...set]).toEqual(['a', 'b']); + }); + + it('adds absent values and reports whether the set changed', () => { + const set = FifoSet.withLimit(2, ['a']); + + expect(set.addIfAbsent('a')).toBe(false); + expect(set.addIfAbsent('b')).toBe(true); + expect(set.addIfAbsent('c')).toBe(true); + expect([...set]).toEqual(['b', 'c']); + }); + + it('can evict undefined values', () => { + const set = FifoSet.withLimit(1, [undefined, 'a']); + + expect([...set]).toEqual(['a']); + + set.add(undefined); + + expect([...set]).toEqual([undefined]); + }); + + it.each([0, -1, 1.5, Number.NaN, Number.POSITIVE_INFINITY])('throws for invalid limit %s', limit => { + expect(() => FifoSet.withLimit(limit)).toThrow('FifoSet limit must be a positive safe integer'); + }); +}); diff --git a/yarn-project/foundation/src/fifo_set/fifo_set.ts b/yarn-project/foundation/src/fifo_set/fifo_set.ts new file mode 100644 index 000000000000..dcf8d494456c --- /dev/null +++ b/yarn-project/foundation/src/fifo_set/fifo_set.ts @@ -0,0 +1,52 @@ +/** A Set capped to a fixed number of entries, evicting the oldest inserted value when full. */ +export class FifoSet extends Set { + private _limit: number | undefined; + + private constructor(values?: Iterable) { + super(values); + } + + /** Creates a bounded set with a positive integer limit. */ + static withLimit(limit: number, values?: Iterable): FifoSet { + if (!Number.isSafeInteger(limit) || limit <= 0) { + throw new TypeError(`FifoSet limit must be a positive safe integer: ${limit}`); + } + + const set = new FifoSet(values); + set._limit = limit; + set.compact(); + + return set; + } + + override add(value: T): this { + super.add(value); + this.compact(); + return this; + } + + /** Maximum number of entries retained by this set. */ + public get limit(): number { + return this._limit ?? Infinity; + } + + /** Evicts oldest entries until the set is within its limit. */ + public compact(): void { + while (this.size > this.limit) { + const head = this.values().next(); + if (head.done) { + return; + } + this.delete(head.value); + } + } + + /** Adds a value only if it is absent, returning whether the set changed. */ + public addIfAbsent(value: T): boolean { + if (this.has(value)) { + return false; + } + this.add(value); + return true; + } +} diff --git a/yarn-project/foundation/src/fifo_set/index.ts b/yarn-project/foundation/src/fifo_set/index.ts new file mode 100644 index 000000000000..28d7234fc93a --- /dev/null +++ b/yarn-project/foundation/src/fifo_set/index.ts @@ -0,0 +1 @@ +export * from './fifo_set.js'; diff --git a/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.test.ts b/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.test.ts index faf3af004d14..0682209fcd23 100644 --- a/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.test.ts +++ b/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.test.ts @@ -91,6 +91,64 @@ describe('SafeJsonRpcServer', () => { expectError(response, 400, 'Test state failed'); }); + it('runs diagnostics around the dispatched RPC function', async () => { + const calls: string[] = []; + server = createSafeJsonRpcServer(testState, TestStateSchema, { + diagnostic: async (ctx, next) => { + calls.push(`start:${ctx.method}:${ctx.id}:${ctx.headers['x-test-header']}`); + await next(); + calls.push(`end:${ctx.method}`); + }, + }); + + const response = await request(server.getApp().callback()) + .post('/') + .send({ jsonrpc: '2.0', method: 'count', params: [], id: 42 }) + .set({ 'content-type': 'application/json', 'x-test-header': 'test-value' }); + + expect(response.status).toBe(200); + expect(response.text).toEqual(JSON.stringify({ jsonrpc, id: 42, result: 2 })); + expect(calls).toEqual(['start:count:42:test-value', 'end:count']); + }); + + it('runs diagnostics for each request in a batch', async () => { + const methods: string[] = []; + server = createSafeJsonRpcServer(testState, TestStateSchema, { + diagnostic: async (ctx, next) => { + methods.push(ctx.method); + await next(); + }, + maxBatchSize: 10, + }); + + const response = await sendBatch( + { jsonrpc: '2.0', method: 'getStatus', params: [], id: 42 }, + { jsonrpc: '2.0', method: 'clear', params: [], id: 43 }, + ); + + expect(response.status).toBe(200); + expect(methods).toEqual(['getStatus', 'clear']); + }); + + it('lets diagnostics observe handler failures', async () => { + const errors: string[] = []; + server = createSafeJsonRpcServer(testState, TestStateSchema, { + diagnostic: async (ctx, next) => { + try { + await next(); + } catch (err) { + errors.push(`${ctx.method}:${err instanceof Error ? err.message : String(err)}`); + throw err; + } + }, + }); + + const response = await send({ method: 'fail', params: [] }); + + expectError(response, 400, 'Test state failed'); + expect(errors).toEqual(['fail:Test state failed']); + }); + it('fails if sends invalid JSON', async () => { const response = await send('{'); expectError(response, 400, expect.stringContaining('Parse error')); diff --git a/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.ts b/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.ts index f1b0a6fa1105..a4bd066ba5be 100644 --- a/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.ts +++ b/yarn-project/foundation/src/json-rpc/server/safe_json_rpc_server.ts @@ -59,8 +59,10 @@ export class SafeJsonRpcServer { config: Partial = {}, /** Health check function */ private readonly healthCheck: StatusCheckFn = () => true, - /** Additional middlewares */ + /** Additional Koa middlewares */ private extraMiddlewares: Application.Middleware[] = [], + /** Additional per-request diagnostics middlewares */ + private diagnosticsMiddleware?: DiagnosticsMiddleware, /** Logger */ private log = createLogger('json-rpc:server'), ) { @@ -161,7 +163,7 @@ export class SafeJsonRpcServer { }; return; } - const resp = await this.processBatch(ctx.request.body); + const resp = await this.processBatch(ctx.request.body, ctx.request.headers); if (Array.isArray(resp)) { ctx.status = 200; ctx.body = resp; @@ -170,7 +172,7 @@ export class SafeJsonRpcServer { ctx.body = resp; } } else { - const resp = await this.processRequest(ctx.request.body); + const resp = await this.processRequest(ctx.request.body, ctx.request.headers); if ('error' in resp) { ctx.status = this.config.http200OnError ? 200 : 400; } @@ -182,11 +184,11 @@ export class SafeJsonRpcServer { return router; } - private async processBatch(requests: any[]) { + private async processBatch(requests: any[], headers: http.IncomingHttpHeaders = {}) { if (requests.length === 0) { return { jsonrpc: '2.0', error: { code: -32600, message: 'Invalid Request' }, id: null }; } - const results = await Promise.allSettled(requests.map(req => this.processRequest(req))); + const results = await Promise.allSettled(requests.map(req => this.processRequest(req, headers))); return results.map(res => { if (res.status === 'fulfilled') { return res.value; @@ -197,7 +199,7 @@ export class SafeJsonRpcServer { }); } - private async processRequest(request: any) { + private async processRequest(request: any, headers: http.IncomingHttpHeaders = {}) { if (!request || typeof request !== 'object') { return { jsonrpc: '2.0', error: { code: -32600, message: 'Invalid Request' }, id: null }; } @@ -212,7 +214,16 @@ export class SafeJsonRpcServer { return { jsonrpc, id, error: { code: -32601, message: `Method not found: ${method}` } }; } else { try { - const result = await this.proxy.call(method, params); + let result: any; + + if (this.diagnosticsMiddleware) { + await this.diagnosticsMiddleware({ id: id ?? null, method, params, headers }, async () => { + result = await this.proxy.call(method, params); + }); + } else { + result = await this.proxy.call(method, params); + } + return { jsonrpc, id, result }; } catch (err: any) { if (err && err instanceof ZodError) { @@ -383,6 +394,7 @@ function makeAggregateHealthcheck(namedHandlers: NamespacedApiHandlers, log?: Lo export type SafeJsonRpcServerOptions = Partial< SafeJsonRpcServerConfig & { healthCheck: StatusCheckFn; + diagnostic: DiagnosticsMiddleware; log: Logger; middlewares: Application.Middleware[]; } @@ -397,10 +409,10 @@ export function createNamespacedSafeJsonRpcServer( handlers: NamespacedApiHandlers, options: Omit = {}, ): SafeJsonRpcServer { - const { middlewares, log } = options; + const { diagnostic, middlewares, log } = options; const proxy = new NamespacedSafeJsonProxy(handlers); const healthCheck = makeAggregateHealthcheck(handlers, log); - return new SafeJsonRpcServer(proxy, options, healthCheck, middlewares, log); + return new SafeJsonRpcServer(proxy, options, healthCheck, middlewares, diagnostic, log); } export function createSafeJsonRpcServer( @@ -408,9 +420,9 @@ export function createSafeJsonRpcServer( schema: ApiSchemaFor, options: SafeJsonRpcServerOptions = {}, ) { - const { log, healthCheck, middlewares: extraMiddlewares } = options; + const { diagnostic, log, healthCheck, middlewares: extraMiddlewares } = options; const proxy = new SafeJsonProxy(handler, schema); - return new SafeJsonRpcServer(proxy, options, healthCheck, extraMiddlewares, log); + return new SafeJsonRpcServer(proxy, options, healthCheck, extraMiddlewares, diagnostic, log); } /** diff --git a/yarn-project/foundation/src/timer/index.ts b/yarn-project/foundation/src/timer/index.ts index f993d7adffd9..991c10ee9039 100644 --- a/yarn-project/foundation/src/timer/index.ts +++ b/yarn-project/foundation/src/timer/index.ts @@ -1,4 +1,4 @@ export * from './date.js'; export { elapsed, elapsedSync } from './elapsed.js'; -export { TimeoutTask, executeTimeout, timeoutPromise } from './timeout.js'; +export { TimeoutTask, execWithSignal, executeTimeout, timeoutPromise } from './timeout.js'; export { Timer } from './timer.js'; diff --git a/yarn-project/foundation/src/timer/timeout.test.ts b/yarn-project/foundation/src/timer/timeout.test.ts index 647341086919..6d8cda64d3ee 100644 --- a/yarn-project/foundation/src/timer/timeout.test.ts +++ b/yarn-project/foundation/src/timer/timeout.test.ts @@ -1,7 +1,7 @@ import { jest } from '@jest/globals'; import { sleep } from '../sleep/index.js'; -import { executeTimeout } from './timeout.js'; +import { execWithSignal, executeTimeout } from './timeout.js'; describe('timeout', () => { it('execs within timeout', async () => { @@ -25,4 +25,32 @@ describe('timeout', () => { /The value of .* is out of range/, ); }); + + it('execs with a non-aborted signal', async () => { + const controller = new AbortController(); + await expect(execWithSignal(() => sleep(20).then(() => 'ok'), controller.signal)).resolves.toEqual('ok'); + }); + + it('rejects with custom error when signal aborts', async () => { + const controller = new AbortController(); + const promise = execWithSignal( + () => sleep(500), + controller.signal, + () => new Error('Aborted!'), + ); + + controller.abort(); + + await expect(promise).rejects.toThrow('Aborted!'); + }); + + it('execs with AbortSignal.timeout', async () => { + await expect( + execWithSignal( + () => sleep(500), + AbortSignal.timeout(20), + signal => new Error(signal.reason?.name ?? 'Aborted'), + ), + ).rejects.toThrow('TimeoutError'); + }); }); diff --git a/yarn-project/foundation/src/timer/timeout.ts b/yarn-project/foundation/src/timer/timeout.ts index 91ac59e46bc4..b8c75ecef1b1 100644 --- a/yarn-project/foundation/src/timer/timeout.ts +++ b/yarn-project/foundation/src/timer/timeout.ts @@ -92,6 +92,37 @@ export async function executeTimeout( return await task.exec(); } +function defaultSignalError(signal: AbortSignal) { + if (signal.reason instanceof Error) { + return signal.reason; + } + + return new Error(signal.reason ? String(signal.reason) : 'Operation aborted'); +} + +/** Executes a function until it completes or the given signal aborts. */ +export async function execWithSignal( + fn: (signal: AbortSignal) => Promise, + signal: AbortSignal, + errorFn: (signal: AbortSignal) => Error = defaultSignalError, +) { + if (signal.aborted) { + throw errorFn(signal); + } + + const abortPromise = promiseWithResolvers(); + const abortListener = () => abortPromise.reject(errorFn(signal)); + signal.addEventListener('abort', abortListener, { once: true }); + + try { + return await Promise.race([fn(signal), abortPromise.promise]); + } finally { + if (abortListener) { + signal.removeEventListener('abort', abortListener); + } + } +} + /** Returns a promise that rejects after the given timeout */ export function timeoutPromise(timeoutMs: number, errorMessage?: string) { const promise = promiseWithResolvers(); diff --git a/yarn-project/key-store/src/key_store.test.ts b/yarn-project/key-store/src/key_store.test.ts index 01736543b080..4f83ae9023cd 100644 --- a/yarn-project/key-store/src/key_store.test.ts +++ b/yarn-project/key-store/src/key_store.test.ts @@ -1,7 +1,7 @@ import { Fr } from '@aztec/foundation/curves/bn254'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; -import { deriveKeys, derivePublicKeyFromSecretKey } from '@aztec/stdlib/keys'; +import { deriveKeys, derivePublicKeyFromSecretKey, hashPublicKey } from '@aztec/stdlib/keys'; import { KeyStore } from './key_store.js'; @@ -13,52 +13,45 @@ describe('KeyStore', () => { const sk = new Fr(8923n); const keys = await deriveKeys(sk); const derivedMasterNullifierPublicKey = await derivePublicKeyFromSecretKey(keys.masterNullifierHidingKey); - const computedMasterNullifierPublicKeyHash = await derivedMasterNullifierPublicKey.hash(); + const computedMasterNullifierPublicKeyHash = await hashPublicKey(derivedMasterNullifierPublicKey); + const computedMasterIncomingViewingPublicKeyHash = await hashPublicKey(keys.publicKeys.ivpkM); const partialAddress = new Fr(243523n); const { address: accountAddress } = await keyStore.addAccount(sk, partialAddress); expect(accountAddress.toString()).toMatchInlineSnapshot( - `"0x2e54c8067c410d03d417dddd51e1cad76cece48ff39fa0fe908782b93a209a52"`, + `"0x1751d51775aece66a86f69085a9003ac539fc5c3b225d49bd4e3a58247ec5700"`, ); - const { pkM: masterNullifierPublicKey } = await keyStore.getKeyValidationRequest( + const { pkMHash: returnedNpkMHash } = await keyStore.getKeyValidationRequest( computedMasterNullifierPublicKeyHash, await AztecAddress.random(), // Address is random because we are not interested in the app secret key here ); - expect(masterNullifierPublicKey.toString()).toMatchInlineSnapshot( - `"0x0d86b380f66ec74d32bb04d98f5b2dcef6d92f344e65604a21640f87fb6d078e2b68df4d20985b71c252746a3f2cc5af32b5f0c32739b94f166dfa230f50397b"`, - ); + expect(returnedNpkMHash.equals(computedMasterNullifierPublicKeyHash)).toBe(true); const masterIncomingViewingPublicKey = await keyStore.getMasterIncomingViewingPublicKey(accountAddress); - expect(masterIncomingViewingPublicKey.toString()).toMatchInlineSnapshot( - `"0x0e0eb5bc3eb9959d6e05cbc0e37b2fa4cfb113c1db651c384907547f1f8670101db2e49c6845619ba432a951d86de2d41680157b0f54556246916900c0fcdcf2"`, - ); + expect(masterIncomingViewingPublicKey.equals(keys.publicKeys.ivpkM)).toBe(true); const masterOutgoingViewingPublicKey = await keyStore.getMasterOutgoingViewingPublicKey(accountAddress); - expect(masterOutgoingViewingPublicKey.toString()).toMatchInlineSnapshot( - `"0x2721eaed30c0c9fae14c2ca4af7668a46278762d4a6066ab7a5defcc242f559c0bd0c4b0ec90ebafe511f20e818fb359a1322ab0f02fe3ebec95af5df502015d"`, - ); + expect(masterOutgoingViewingPublicKey.equals(keys.masterOutgoingViewingPublicKey)).toBe(true); const masterTaggingPublicKey = await keyStore.getMasterTaggingPublicKey(accountAddress); - expect(masterTaggingPublicKey.toString()).toMatchInlineSnapshot( - `"0x0fabb6adca7c2bf7f6202c65fe2785096efb317897bc545c427635a61d5369552cc356e6e5b68fd64d33c96fad7bb1394956c53930fefdf0bb536812ec604459"`, - ); + expect(masterTaggingPublicKey.equals(keys.masterTaggingPublicKey)).toBe(true); const masterIncomingViewingSecretKey = await keyStore.getMasterIncomingViewingSecretKey(accountAddress); - expect(masterIncomingViewingSecretKey.toString()).toMatchInlineSnapshot( - `"0x0d3e4402946f2f712d942e1a3962b12fc521effc39fe93777f91285f1ad414cb"`, - ); + expect(masterIncomingViewingSecretKey.equals(keys.masterIncomingViewingSecretKey)).toBe(true); // Arbitrary app contract address const appAddress = AztecAddress.fromBigInt(624n); - const { pkM: obtainedMasterNullifierPublicKey, skApp: appNullifierHidingKey } = - await keyStore.getKeyValidationRequest(computedMasterNullifierPublicKeyHash, appAddress); + const { pkMHash: obtainedNpkMHash, skApp: appNullifierHidingKey } = await keyStore.getKeyValidationRequest( + computedMasterNullifierPublicKeyHash, + appAddress, + ); expect(appNullifierHidingKey.toString()).toMatchInlineSnapshot( `"0x165cc265d187ed42f0e3f5adbb5a0055a77e205daeb68dd1735796ee402e502f"`, ); - expect(obtainedMasterNullifierPublicKey).toEqual(masterNullifierPublicKey); + expect(obtainedNpkMHash).toEqual(computedMasterNullifierPublicKeyHash); const appOutgoingViewingSecretKey = await keyStore.getAppOutgoingViewingSecretKey(accountAddress, appAddress); expect(appOutgoingViewingSecretKey.toString()).toMatchInlineSnapshot( @@ -68,20 +61,17 @@ describe('KeyStore', () => { // Returned accounts are as expected const accounts = await keyStore.getAccounts(); expect(accounts.toString()).toMatchInlineSnapshot( - `"0x2e54c8067c410d03d417dddd51e1cad76cece48ff39fa0fe908782b93a209a52"`, + `"0x1751d51775aece66a86f69085a9003ac539fc5c3b225d49bd4e3a58247ec5700"`, ); - // Manages to find master nullifier hiding key for pub key - const masterNullifierHidingKey = await keyStore.getMasterSecretKey(masterNullifierPublicKey); - expect(masterNullifierHidingKey.toString()).toMatchInlineSnapshot( - `"0x26dd6f83a99b5b1cea47692f40b7aece47756a1a5e93138c5b8f7e7afd36ed1a"`, - ); + // Manages to find master nullifier hiding key for the pk_m hash + const masterNullifierHidingKey = await keyStore.getMasterSecretKey(computedMasterNullifierPublicKeyHash); + expect(masterNullifierHidingKey.equals(keys.masterNullifierHidingKey)).toBe(true); - // Manages to find master incoming viewing secret key for pub key - const masterIncomingViewingSecretKeyFromPublicKey = - await keyStore.getMasterSecretKey(masterIncomingViewingPublicKey); - expect(masterIncomingViewingSecretKeyFromPublicKey.toString()).toMatchInlineSnapshot( - `"0x0d3e4402946f2f712d942e1a3962b12fc521effc39fe93777f91285f1ad414cb"`, + // Manages to find master incoming viewing secret key for the pk_m hash + const masterIncomingViewingSecretKeyFromPublicKey = await keyStore.getMasterSecretKey( + computedMasterIncomingViewingPublicKeyHash, ); + expect(masterIncomingViewingSecretKeyFromPublicKey.equals(keys.masterIncomingViewingSecretKey)).toBe(true); }); }); diff --git a/yarn-project/key-store/src/key_store.ts b/yarn-project/key-store/src/key_store.ts index 86cab0cc9752..a23f4f71befe 100644 --- a/yarn-project/key-store/src/key_store.ts +++ b/yarn-project/key-store/src/key_store.ts @@ -15,6 +15,7 @@ import { computeAppSecretKey, deriveKeys, derivePublicKeyFromSecretKey, + hashPublicKey, } from '@aztec/stdlib/keys'; /** Maps a key prefix to the storage suffix for the corresponding master secret key. */ @@ -57,17 +58,21 @@ export class KeyStore { masterIncomingViewingSecretKey, masterOutgoingViewingSecretKey, masterTaggingSecretKey, + masterNullifierPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, publicKeys, } = await deriveKeys(sk); - const completeAddress = await CompleteAddress.fromSecretKeyAndPartialAddress(sk, partialAddress); + const completeAddress = await CompleteAddress.fromPublicKeysAndPartialAddress(publicKeys, partialAddress); const { address: account } = completeAddress; - // Compute hashes before transaction - const masterNullifierPublicKeyHash = await publicKeys.masterNullifierPublicKey.hash(); - const masterIncomingViewingPublicKeyHash = await publicKeys.masterIncomingViewingPublicKey.hash(); - const masterOutgoingViewingPublicKeyHash = await publicKeys.masterOutgoingViewingPublicKey.hash(); - const masterTaggingPublicKeyHash = await publicKeys.masterTaggingPublicKey.hash(); + // The kernel cannot check that nhpk/ovpk/tpk are on-curve or non-infinity, so the PXE/key-store + // must guarantee it before persistence. By design, the above derivation produces points that are on + // the curve and not at infinity. + + // The npk/ovpk/tpk hashes are already in publicKeys; ivpk_m_hash is computed for indexing. + const masterIncomingViewingPublicKeyHash = await hashPublicKey(publicKeys.ivpkM); await this.#db.transactionAsync(async () => { // Naming of keys is as follows ${account}-${n/iv/ov/t}${sk/pk}_m @@ -76,17 +81,17 @@ export class KeyStore { await this.#keys.set(`${account.toString()}-tsk_m`, masterTaggingSecretKey.toBuffer()); await this.#keys.set(`${account.toString()}-nhk_m`, masterNullifierHidingKey.toBuffer()); - await this.#keys.set(`${account.toString()}-npk_m`, publicKeys.masterNullifierPublicKey.toBuffer()); - await this.#keys.set(`${account.toString()}-ivpk_m`, publicKeys.masterIncomingViewingPublicKey.toBuffer()); - await this.#keys.set(`${account.toString()}-ovpk_m`, publicKeys.masterOutgoingViewingPublicKey.toBuffer()); - await this.#keys.set(`${account.toString()}-tpk_m`, publicKeys.masterTaggingPublicKey.toBuffer()); + await this.#keys.set(`${account.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${account.toString()}-ivpk_m`, publicKeys.ivpkM.toBuffer()); + await this.#keys.set(`${account.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); + await this.#keys.set(`${account.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); // We store pk_m_hash under `account-{n/iv/ov/t}pk_m_hash` key to be able to obtain address and key prefix // using the #getKeyPrefixAndAccount function later on - await this.#keys.set(`${account.toString()}-npk_m_hash`, masterNullifierPublicKeyHash.toBuffer()); + await this.#keys.set(`${account.toString()}-npk_m_hash`, publicKeys.npkMHash.toBuffer()); await this.#keys.set(`${account.toString()}-ivpk_m_hash`, masterIncomingViewingPublicKeyHash.toBuffer()); - await this.#keys.set(`${account.toString()}-ovpk_m_hash`, masterOutgoingViewingPublicKeyHash.toBuffer()); - await this.#keys.set(`${account.toString()}-tpk_m_hash`, masterTaggingPublicKeyHash.toBuffer()); + await this.#keys.set(`${account.toString()}-ovpk_m_hash`, publicKeys.ovpkMHash.toBuffer()); + await this.#keys.set(`${account.toString()}-tpk_m_hash`, publicKeys.tpkMHash.toBuffer()); }); // At last, we return the newly derived account address @@ -120,7 +125,9 @@ export class KeyStore { return this.#db.transactionAsync(async () => { const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkMHash); - // Now we find the master public key for the account + // Load the stored master public key point. The returned KVR carries only the hash, but we + // use the point here as a witness for two integrity checks below: (1) it matches the supplied + // hash, and (2) it matches the value derived from the stored secret key. const pkMBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}pk_m`); if (!pkMBuffer) { throw new Error( @@ -142,7 +149,7 @@ export class KeyStore { const skM = GrumpkinScalar.fromBuffer(skMBuffer); // The remaining awaits are non-DB computations. They are safe because no further IDB operations follow them. - const computedPkMHash = await pkM.hash(); + const computedPkMHash = await hashPublicKey(pkM); if (!computedPkMHash.equals(pkMHash)) { throw new Error(`Could not find ${keyPrefix}pkM for ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`); } @@ -154,7 +161,7 @@ export class KeyStore { const skApp = await computeAppSecretKey(skM, contractAddress, keyPrefix!); - return new KeyValidationRequest(pkM, skApp); + return new KeyValidationRequest(pkMHash, skApp); }); } @@ -261,31 +268,36 @@ export class KeyStore { } /** - * Retrieves the sk_m corresponding to the pk_m. - * @throws If the provided public key is not associated with any of the registered accounts. - * @param pkM - The master public key to get secret key for. + * Retrieves the sk_m corresponding to the given pk_m hash. + * @throws If the provided hash is not associated with any of the registered accounts. + * @param pkMHash - The master public key hash to get secret key for. * @returns A Promise that resolves to sk_m. * @dev Used when feeding the sk_m to the kernel circuit for keys verification. */ - public getMasterSecretKey(pkM: PublicKey): Promise { + public getMasterSecretKey(pkMHash: Fr): Promise { return this.#db.transactionAsync(async () => { - const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkM); + const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkMHash); const skStorageSuffix = secretKeyStorageSuffix(keyPrefix); const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`); if (!secretKeyBuffer) { throw new Error( - `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`, + `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m_hash ${pkMHash.toString()}. This should not happen.`, ); } const skM = GrumpkinScalar.fromBuffer(secretKeyBuffer); // Non-DB computation — safe because no further IDB operations follow. - const derivedpkM = await derivePublicKeyFromSecretKey(skM); - if (!derivedpkM.equals(pkM)) { + // Integrity check: confirm the stored secret key still derives the requested hash. The check + // is hash-based rather than point-equal because the on-disk identifier is `pk_m_hash`; + // cryptographic collision resistance of `hashPublicKey` makes this equivalent to a + // direct point comparison in practice. + const derivedPkM = await derivePublicKeyFromSecretKey(skM); + const derivedPkMHash = await hashPublicKey(derivedPkM); + if (!derivedPkMHash.equals(pkMHash)) { throw new Error( - `Could not find ${skStorageSuffix} for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`, + `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m_hash ${pkMHash.toString()} in secret keys buffer.`, ); } diff --git a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap index ac3e1e5042d6..b6dec7a8b6c9 100644 --- a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap +++ b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap @@ -2,46 +2,46 @@ exports[`Data generation for noir tests Computes contract info for defaultContract 1`] = ` { - "address": "AztecAddress { inner: 0x136422d2d758eb9181240eee44720fa9bc433d3a16bc13163699dc4f47540b0d }", + "address": "AztecAddress { inner: 0x1599beafce80b22c56446667e1627d865bb87ea94b8f1bdc757979f78a596042 }", "artifact_hash": "0x0000000000000000000000000000000000000000000000000000000000003039", "contract_address_salt": "0x000000000000000000000000000000000000000000000000000000000000ddd5", "contract_class_id": "ContractClassId { inner: 0x2888d24c26f34b139f0f1d30278df8f9007d06da3b63cfe6eeb9a710d51f4f4a }", "deployer": "AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }", - "partial_address": "PartialAddress { inner: 0x1676695fc9a4f3bc8816e4dc82a8856b2ae565d4872691a6e944cc3ce8897e72 }", + "partial_address": "PartialAddress { inner: 0x13bf689e2b04d5a75694270c1872e74b0c998c3f7f2f3a0a95648f9f41600808 }", "private_functions_root": "0x2653ec1bf2be3a13fa9b645cec2557f2b543286fc39168ec42b705835a301bb6", "public_bytecode_commitment": "0x256abef672381d551191d5bbecf2dec6ac9cc2a81189f886ac22e29e5c58c49c", - "public_keys": "PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f }", - "salted_initialization_hash": "SaltedInitializationHash { inner: 0x1d83f43991ef3c393247a1796b194020c559aaf129e515adc6eace265f726452 }", + "public_keys": "PublicKeys { inner: 0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a2600c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1510e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0 }", + "salted_initialization_hash": "SaltedInitializationHash { inner: 0x20b8accdca7010cfebfcc932f55e3acf5136dfe57ba51d386dac8e9d110d9567 }", } `; exports[`Data generation for noir tests Computes contract info for parentContract 1`] = ` { - "address": "AztecAddress { inner: 0x2e90a78904fdb353ddf6eda97aedcfc2b8bf5a942f10f57a1e85373b740e7eca }", + "address": "AztecAddress { inner: 0x1ea25c8d3d0223005170fc2cc0a0e8e3593e322bfcdebc817cc2a02cc95fca9c }", "artifact_hash": "0x00000000000000000000000000000000000000000000000000000000000004bc", "contract_address_salt": "0x0000000000000000000000000000000000000000000000000000000000001618", "contract_class_id": "ContractClassId { inner: 0x2998b9cf4a582f068a01b43c141dbcc5fd8f5cd17a797484b5a5db2386cf7574 }", "deployer": "AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }", - "partial_address": "PartialAddress { inner: 0x2cfac19f0c29a86d17b4c60b205376bbd4c8e45d1dfd02dcd33820638d1d6d1e }", + "partial_address": "PartialAddress { inner: 0x09dba9fffbfd68d6828334a178433b7bfae9d07c3c6f424ee4afa0304655c5d3 }", "private_functions_root": "0x03cca4d59a01776df283eb2c8915cb144ad3f40a0b0ba06e9c24c532c59e3c43", "public_bytecode_commitment": "0x1cfb8e870870be1d102249b47923b63c2d54f33ca81e3028d74a06d8dd5944ca", - "public_keys": "PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f }", - "salted_initialization_hash": "SaltedInitializationHash { inner: 0x2bfefc4cfdd56352f0d6cf62ae70abe702d7d948f5ccff4eeb51f9aefaece295 }", + "public_keys": "PublicKeys { inner: 0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a2600c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1510e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0 }", + "salted_initialization_hash": "SaltedInitializationHash { inner: 0x1384ae0b0212cbeb6cd53d6c8d9dfc6334318553dd6f33fdaa97b5dae4ab9dbb }", } `; exports[`Data generation for noir tests Computes contract info for updatedContract 1`] = ` { - "address": "AztecAddress { inner: 0x1a56e3cef400d47addbbf65a95ea505b8f628a2d65a096d0e4d46a8cc9bd72c3 }", + "address": "AztecAddress { inner: 0x144f3aaae816b99f40fbea5b9f80fe4683bf68a14876e7379c4171c871a1ef09 }", "artifact_hash": "0x0000000000000000000000000000000000000000000000000000000000054501", "contract_address_salt": "0x0000000000000000000000000000000000000000000000000000000000000315", "contract_class_id": "ContractClassId { inner: 0x07a63b1343bb8515d1115202c71cdc95f9bcda9c2237bdfc25435b89ffa06b46 }", "deployer": "AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }", - "partial_address": "PartialAddress { inner: 0x04a4ed87aa4cff86962b974fe3f79d76e4bf3f034d4e2bde2bb50765927fad40 }", + "partial_address": "PartialAddress { inner: 0x12b89345d5d63f8bf9f73f5890d5caa0c5f023c61d313b1abeea40e300a83755 }", "private_functions_root": "0x2b26caef823c6be4c41ef1980dace9b61825f8e6a16792c765a2cd8cb2121e75", "public_bytecode_commitment": "0x225d884cfeaddc5292dadbf921e7699632336876c65a33459d3b2ad9b5ec0da3", - "public_keys": "PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f }", - "salted_initialization_hash": "SaltedInitializationHash { inner: 0x0bbf968b28a0a1fa3a90ceb4c7104d63e7a8dc845a9c885781d74018d1579e59 }", + "public_keys": "PublicKeys { inner: 0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a2600c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1510e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0 }", + "salted_initialization_hash": "SaltedInitializationHash { inner: 0x1f121db378dbceaf871eed1b9f0b20efcdca988e76f8abeaa11b2cdc80474189 }", } `; diff --git a/yarn-project/noir-protocol-circuits-types/src/conversion/client.ts b/yarn-project/noir-protocol-circuits-types/src/conversion/client.ts index 4e403b9f496d..fad43cd8d913 100644 --- a/yarn-project/noir-protocol-circuits-types/src/conversion/client.ts +++ b/yarn-project/noir-protocol-circuits-types/src/conversion/client.ts @@ -92,7 +92,6 @@ import { mapNullifierLeafPreimageToNoir, mapNumberFromNoir, mapNumberToNoir, - mapPointFromNoir, mapPointToNoir, mapPrivateLogFromNoir, mapPrivateLogToNoir, @@ -260,7 +259,7 @@ function mapScopedReadRequestFromNoir(scoped: Scoped>): Scope */ export function mapKeyValidationRequestToNoir(request: KeyValidationRequest): KeyValidationRequestsNoir { return { - pk_m: mapPointToNoir(request.pkM), + pk_m_hash: mapFieldToNoir(request.pkMHash), sk_app: mapFieldToNoir(request.skApp), }; } @@ -280,7 +279,7 @@ export function mapKeyValidationRequestAndSeparatorToNoir( * @returns The TS KeyValidationRequest. */ function mapKeyValidationRequestFromNoir(request: KeyValidationRequestsNoir): KeyValidationRequest { - return new KeyValidationRequest(mapPointFromNoir(request.pk_m), mapFieldFromNoir(request.sk_app)); + return new KeyValidationRequest(mapFieldFromNoir(request.pk_m_hash), mapFieldFromNoir(request.sk_app)); } function mapKeyValidationRequestAndSeparatorFromNoir( @@ -479,18 +478,12 @@ export function mapPrivateCircuitPublicInputsToNoir( export function mapPublicKeysToNoir(publicKeys: PublicKeys): PublicKeysNoir { return { - npk_m: { - inner: mapPointToNoir(publicKeys.masterNullifierPublicKey), - }, + npk_m_hash: mapFieldToNoir(publicKeys.npkMHash), ivpk_m: { - inner: mapPointToNoir(publicKeys.masterIncomingViewingPublicKey), - }, - ovpk_m: { - inner: mapPointToNoir(publicKeys.masterOutgoingViewingPublicKey), - }, - tpk_m: { - inner: mapPointToNoir(publicKeys.masterTaggingPublicKey), + inner: mapPointToNoir(publicKeys.ivpkM), }, + ovpk_m_hash: mapFieldToNoir(publicKeys.ovpkMHash), + tpk_m_hash: mapFieldToNoir(publicKeys.tpkMHash), }; } diff --git a/yarn-project/noir-protocol-circuits-types/src/conversion/common.ts b/yarn-project/noir-protocol-circuits-types/src/conversion/common.ts index a9a99d52f050..5868f473ca49 100644 --- a/yarn-project/noir-protocol-circuits-types/src/conversion/common.ts +++ b/yarn-project/noir-protocol-circuits-types/src/conversion/common.ts @@ -74,7 +74,7 @@ import type { AztecAddress as NoirAztecAddress, EthAddress as NoirEthAddress, Field as NoirField, - Point as NoirPoint, + EmbeddedCurvePoint as NoirPoint, NullifierLeafPreimage as NullifierLeafPreimageNoir, PartialStateReference as PartialStateReferenceNoir, Log as PrivateLogNoir, @@ -175,7 +175,6 @@ export function mapPointToNoir(point: Point): NoirPoint { return { x: mapFieldToNoir(point.x), y: mapFieldToNoir(point.y), - is_infinite: point.isInfinite, }; } @@ -185,7 +184,7 @@ export function mapPointToNoir(point: Point): NoirPoint { * @returns The point. */ export function mapPointFromNoir(point: NoirPoint): Point { - return new Point(mapFieldFromNoir(point.x), mapFieldFromNoir(point.y), point.is_infinite); + return new Point(mapFieldFromNoir(point.x), mapFieldFromNoir(point.y)); } /** diff --git a/yarn-project/noir-protocol-circuits-types/src/conversion/type_conversion.test.ts b/yarn-project/noir-protocol-circuits-types/src/conversion/type_conversion.test.ts index c6c569c61f83..f207bc9e3f1a 100644 --- a/yarn-project/noir-protocol-circuits-types/src/conversion/type_conversion.test.ts +++ b/yarn-project/noir-protocol-circuits-types/src/conversion/type_conversion.test.ts @@ -29,7 +29,7 @@ describe('Noir<>stdlib type conversion test suite', () => { expect(mapFieldFromNoir(mapFieldToNoir(field))).toEqual(field); }); - const point = new Point(new Fr(27n), new Fr(28n), false); + const point = new Point(new Fr(27n), new Fr(28n)); it('should map points', () => { expect(mapPointFromNoir(mapPointToNoir(point))).toEqual(point); diff --git a/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts b/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts index b5b9b31845f8..ee13d4afb7d3 100644 --- a/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts +++ b/yarn-project/noir-protocol-circuits-types/src/noir_test_gen.test.ts @@ -20,7 +20,7 @@ describe('Data generation for noir tests', () => { setupCustomSnapshotSerializers(expect); type FixtureContractData = Omit & - Pick & + Pick & Pick & { toString: () => string }; const defaultContract: FixtureContractData = { @@ -28,6 +28,7 @@ describe('Data generation for noir tests', () => { packedBytecode: Buffer.from([3, 4, 5, 6, 7]), publicKeys: PublicKeys.default(), salt: new Fr(56789), + immutablesHash: new Fr(7890), privateFunctions: [ { selector: FunctionSelector.fromField(new Fr(1010101)), vkHash: new Fr(123123) }, { selector: FunctionSelector.fromField(new Fr(2020202)), vkHash: new Fr(456456) }, @@ -40,6 +41,7 @@ describe('Data generation for noir tests', () => { packedBytecode: Buffer.from([3, 4, 3, 4]), publicKeys: PublicKeys.default(), salt: new Fr(5656), + immutablesHash: new Fr(7890), privateFunctions: [{ selector: FunctionSelector.fromField(new Fr(334455)), vkHash: new Fr(789789) }], toString: () => 'parentContract', }; @@ -49,6 +51,7 @@ describe('Data generation for noir tests', () => { packedBytecode: Buffer.from([5, 6, 7, 8, 9, 0]), publicKeys: PublicKeys.default(), salt: new Fr(789), + immutablesHash: new Fr(7890), privateFunctions: [ { selector: FunctionSelector.fromField(new Fr(1010101)), vkHash: new Fr(7788) }, { selector: FunctionSelector.fromField(new Fr(2020202)), vkHash: new Fr(9900) }, @@ -78,7 +81,7 @@ describe('Data generation for noir tests', () => { const deployer = AztecAddress.ZERO; const instance: ContractInstance = { ...contract, - version: 1, + version: 2, initializationHash, currentContractClassId: contractClassId, originalContractClassId: contractClassId, diff --git a/yarn-project/p2p/src/client/interface.ts b/yarn-project/p2p/src/client/interface.ts index b7bf5fb19d0c..636385ce92f2 100644 --- a/yarn-project/p2p/src/client/interface.ts +++ b/yarn-project/p2p/src/client/interface.ts @@ -9,11 +9,7 @@ import type { ENR } from '@nethermindeth/enr'; import type { P2PConfig } from '../config.js'; import type { AuthRequest, StatusMessage } from '../services/index.js'; -import type { - ReqRespSubProtocol, - ReqRespSubProtocolHandler, - ReqRespSubProtocolValidators, -} from '../services/reqresp/interface.js'; +import type { ReqRespSubProtocol, ReqRespSubProtocolHandler } from '../services/reqresp/interface.js'; import type { DuplicateAttestationInfo, DuplicateProposalInfo, @@ -228,11 +224,7 @@ export type P2P = P2PClient & { /** Clears the db. */ clear(): Promise; - addReqRespSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise; + addReqRespSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise; handleAuthRequestFromPeer(authRequest: AuthRequest, peerId: PeerId): Promise; diff --git a/yarn-project/p2p/src/client/p2p_client.test.ts b/yarn-project/p2p/src/client/p2p_client.test.ts index 86df6d146a25..01c03e0d206d 100644 --- a/yarn-project/p2p/src/client/p2p_client.test.ts +++ b/yarn-project/p2p/src/client/p2p_client.test.ts @@ -41,7 +41,6 @@ describe('P2P Client', () => { txPool.addPendingTxs.mockResolvedValue({ accepted: [], ignored: [], rejected: [] }); p2pService = mock(); - p2pService.sendBatchRequest.mockResolvedValue([]); l1Constants = EmptyL1RollupConstants; txCollection = mock(); @@ -50,6 +49,7 @@ describe('P2P Client', () => { epochCache = mock(); epochCache.getCurrentAndNextSlot.mockReturnValue({ currentSlot: SlotNumber(0), nextSlot: SlotNumber(1) }); epochCache.getTargetAndNextSlot.mockReturnValue({ targetSlot: SlotNumber(0), nextSlot: SlotNumber(1) }); + epochCache.getL1Constants.mockReturnValue(l1Constants); attestationPool = await createTestAttestationPool(); diff --git a/yarn-project/p2p/src/client/p2p_client.ts b/yarn-project/p2p/src/client/p2p_client.ts index a91755a81b00..8a4ba30a701f 100644 --- a/yarn-project/p2p/src/client/p2p_client.ts +++ b/yarn-project/p2p/src/client/p2p_client.ts @@ -24,6 +24,7 @@ import { type L2TipsStore, } from '@aztec/stdlib/block'; import type { ContractDataSource } from '@aztec/stdlib/contract'; +import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { type PeerInfo, tryStop } from '@aztec/stdlib/interfaces/server'; import { type BlockProposal, CheckpointAttestation, type CheckpointProposal, type TopicType } from '@aztec/stdlib/p2p'; import type { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx'; @@ -34,15 +35,11 @@ import type { ENR } from '@nethermindeth/enr'; import { type P2PConfig, getP2PDefaultConfig } from '../config.js'; import { TxPoolError } from '../errors/tx-pool.error.js'; -import type { AttestationPoolApi } from '../mem_pools/attestation_pool/attestation_pool.js'; +import type { AttestationPoolApi, ProposalsForSlot } from '../mem_pools/attestation_pool/attestation_pool.js'; import type { MemPools } from '../mem_pools/interface.js'; import type { TxPoolV2 } from '../mem_pools/tx_pool_v2/interfaces.js'; import type { AuthRequest, StatusMessage } from '../services/index.js'; -import { - ReqRespSubProtocol, - type ReqRespSubProtocolHandler, - type ReqRespSubProtocolValidators, -} from '../services/reqresp/interface.js'; +import { ReqRespSubProtocol, type ReqRespSubProtocolHandler } from '../services/reqresp/interface.js'; import type { DuplicateAttestationInfo, DuplicateProposalInfo, @@ -269,7 +266,6 @@ export class P2PClient extends WithTracer implements P2P { throw new Error('Block stream not initialized'); } this.blockStream.start(); - await this.txCollection.start(); this.txFileStore?.start(); // Start slot monitor to call prepareForSlot when the slot changes @@ -283,12 +279,8 @@ export class P2PClient extends WithTracer implements P2P { return this.syncPromise; } - addReqRespSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { - return this.p2pService.addReqRespSubProtocol(subProtocol, handler, validator); + addReqRespSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise { + return this.p2pService.addReqRespSubProtocol(subProtocol, handler); } private initBlockStream(startingBlock?: BlockNumber) { @@ -372,8 +364,21 @@ export class P2PClient extends WithTracer implements P2P { // Store our own last-block proposal so we can respond to req/resp requests for it. await this.attestationPool.tryAddBlockProposal(blockProposal); } + const checkpointCore = proposal.toCore(); + const { count } = await this.attestationPool.tryAddCheckpointProposal(checkpointCore); + if (count > 1) { + if (this.config.broadcastEquivocatedProposals) { + this.log.warn(`Broadcasting equivocated checkpoint proposal for slot ${proposal.slotNumber}`, { + slot: proposal.slotNumber, + archive: proposal.archive.toString(), + count, + }); + } else { + throw new Error(`Attempted to broadcast a duplicate checkpoint proposal for slot ${proposal.slotNumber}`); + } + } // Gossipsub doesn't deliver own messages, so fire the all-nodes handler locally - await this.p2pService.notifyOwnCheckpointProposal(proposal.toCore()); + await this.p2pService.notifyOwnCheckpointProposal(checkpointCore); return this.p2pService.propagate(proposal); } @@ -395,6 +400,10 @@ export class P2PClient extends WithTracer implements P2P { return this.attestationPool.addOwnCheckpointAttestations(attestations); } + public getProposalsForSlot(slot: SlotNumber): Promise { + return this.attestationPool.getProposalsForSlot(slot); + } + public hasBlockProposalsForSlot(slot: SlotNumber): Promise { return this.attestationPool.hasBlockProposalsForSlot(slot); } @@ -655,7 +664,16 @@ export class P2PClient extends WithTracer implements P2P { `Starting collection of ${missingTxHashes.length} missing txs for unproven mined block ${block.number}`, { missingTxHashes, blockNumber: block.number, blockHash: await block.hash().then(h => h.toString()) }, ); - const deadline = new Date(this._dateProvider.now() + this.config.p2pMissingTxCollectionDeadlineMs); + // Both `slashDataWithholdingToleranceSlots` and `p2pMissingTxCollectionDeadlineSlots` + // count *full slots after the block slot* — value N means collection runs until + // `slotStart(block.slot + N + 1)`. Take the larger of the two so collection never + // gives up before the data-withholding slash verdict is rendered. + const blockSlot = block.header.getSlot(); + const toleranceSlots = this.config.slashDataWithholdingToleranceSlots; + const configuredSlots = this.config.p2pMissingTxCollectionDeadlineSlots ?? 0; + const deadlineSlot = SlotNumber(blockSlot + Math.max(toleranceSlots, configuredSlots) + 1); + const deadlineSeconds = getTimestampForSlot(deadlineSlot, this.epochCache.getL1Constants()); + const deadline = new Date(Number(deadlineSeconds) * 1000); await this.txCollection.collectFastForBlock(block, missingTxHashes, { deadline }); } } diff --git a/yarn-project/p2p/src/client/test/tx_proposal_collector/README.md b/yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.README.md similarity index 71% rename from yarn-project/p2p/src/client/test/tx_proposal_collector/README.md rename to yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.README.md index 3a489503faab..50867738fbb6 100644 --- a/yarn-project/p2p/src/client/test/tx_proposal_collector/README.md +++ b/yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.README.md @@ -1,6 +1,6 @@ -# ProposalTxCollector Benchmarks +# BatchTxRequester Benchmarks -This benchmark suite measures **how quickly a proposer node can fetch missing transactions from P2P peers** when building a block proposal. It compares two alternative transaction-collection implementations under several controlled "who-has-which-txs" distributions. +This benchmark suite measures **how quickly a proposer node can fetch missing transactions from P2P peers** when building a block proposal under several controlled "who-has-which-txs" distributions. ## Purpose @@ -10,12 +10,6 @@ This benchmark answers: - How long does it take to fetch **N missing txs** (N ∈ **{10, 50, 100, 500}**)? - How do different **peer availability patterns** affect performance? -- Which collector strategy performs better under each pattern? - -The suite compares two collectors: - -- **`BatchTxRequesterCollector`** (collector type: `batch-requester`) -- **`SendBatchRequestCollector`** (collector type: `send-batch-request`) ## Architecture @@ -24,7 +18,7 @@ The benchmark runs a small simulated network on localhost: ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Test Process (Driver) │ -│ p2p_client.proposal_tx_collector.bench.test.ts │ +│ p2p_client.batch_tx_requester.bench.test.ts │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ WorkerClientManager │ │ │ │ (src/testbench/worker_client_manager.ts) │ │ @@ -34,7 +28,7 @@ The benchmark runs a small simulated network on localhost: │ ▼ ▼ ▼ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ Worker 0 │◄──────►│ Worker 1 │◄──────►│ Worker N-1│ │ -│ │ (Collector│ P2P │(Responder)│ P2P │(Responder)│ │ +│ │(Aggregator│ P2P │(Responder)│ P2P │(Responder)│ │ │ │ Node) │ │ │ │ │ │ │ │ TxPool:[] │ │ TxPool: │ │ TxPool: │ │ │ │ │ │ [txs...] │ │ [txs...] │ │ @@ -54,12 +48,12 @@ Using separate OS processes makes the setup closer to real networking behavior ( The network is intentionally asymmetric: -- **Worker 0 is the collector/proposer node** +- **Worker 0 is the aggregator/proposer node** - Starts with an **empty tx pool** (`[]`) - - Is the only worker instructed to run the collector for each `BENCH_REQRESP` command + - Is the only worker instructed to run `BatchTxRequester` for each `BENCH_REQRESP` command - **Workers 1..N-1 are responder peers** - Locally generate and filter txs according to the distribution pattern - - Respond to req/resp queries made by Worker 0's collector + - Respond to req/resp queries made by Worker 0's `BatchTxRequester` This models a proposer that has only `txHashes` in a proposal and must fetch the full tx bodies from the network. @@ -72,7 +66,7 @@ Each benchmark case generates `missingTxCount` mock txs and assigns them to peer **Every responder peer has every transaction.** - Simulates the best-case: high replication / high gossip success -- Expectation: collector should quickly succeed; differences mostly reflect collector overhead and batching strategy +- Expectation: the requester should quickly succeed; differences mostly reflect requester overhead and batching strategy ### `sparse` @@ -81,7 +75,7 @@ Each benchmark case generates `missingTxCount` mock txs and assigns them to peer Each responder is bucketed and holds txs whose index falls into its bucket or the "next" bucket (striped by tx index). - Simulates partial propagation, churn, or uneven mempool convergence -- Expectation: collector must query multiple peers and cope with "misses" +- Expectation: the requester must query multiple peers and cope with "misses" ### `pinned-only` @@ -92,33 +86,13 @@ Each responder is bucketed and holds txs whose index falls into its bucket or th > **Guardrail:** the pinned peer index must be within `(0, numberOfPeers)` (Worker 0 cannot be pinned). -## Collectors Under Test - -### `BatchTxRequesterCollector` (`batch-requester`) - -```typescript -new BatchTxRequesterCollector(p2pService, logger, new DateProvider()) -``` - -Uses the P2P service plus internal logic to fetch missing txs, coordinating requests in a batched or staged way. - -### `SendBatchRequestCollector` (`send-batch-request`) - -```typescript -const maxPeers = 10; -const maxRetryAttempts = Math.max(peerIds.length, 3); -new SendBatchRequestCollector(p2pService, maxPeers, maxRetryAttempts) -``` - -Explicitly caps the number of peers it will involve (`maxPeers`) and uses a retry budget derived from peer count. - ## Test Parameters | Parameter | Value | Description | |-----------|-------|-------------| | `PEERS_PER_RUN` | 30 | Number of worker processes spawned | | `MISSING_TX_COUNTS` | 10, 50, 100, 500 | Number of missing transactions to fetch | -| `TIMEOUT_MS` | 30,000 ms | Collector timeout per case | +| `TIMEOUT_MS` | 30,000 ms | Per-case timeout for the requester | | `TEST_TIMEOUT_MS` | 600,000 ms | Overall Jest timeout (10 minutes) | ## Running @@ -127,13 +101,13 @@ From the p2p package: ```bash cd yarn-project/p2p -yarn test src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts +yarn test src/client/test/p2p_client.batch_tx_requester.bench.test.ts ``` Or from repo root: ```bash -yarn test p2p_client.proposal_tx_collector.bench.test.ts +yarn test p2p_client.batch_tx_requester.bench.test.ts ``` The benchmark is intentionally long due to spawning many processes and running multiple cases. @@ -145,14 +119,12 @@ The benchmark is intentionally long due to spawning many processes and running m If no env vars are set, the suite prints a table: ``` -| Collector | Distribution | Missing | Duration (ms) | Fetched | Success | -|---------------------|--------------|---------|---------------|---------|---------| -| batch-requester | pinned-only | 10 | 123 | 10 | Yes | -| send-batch-request | pinned-only | 10 | 145 | 10 | Yes | +| Distribution | Missing | Duration (ms) | Fetched | Success | +|--------------|---------|---------------|---------|---------| +| pinned-only | 10 | 123 | 10 | Yes | +| pinned-only | 50 | 145 | 50 | Yes | ``` -Plus a comparison summary stating which collector was faster per `(distribution, missing)` pair. - ### JSON metrics (for CI/dashboards) ```bash @@ -160,8 +132,8 @@ BENCH_OUTPUT=/path/results.json yarn test ... ``` Writes JSON metrics like: -- `ProposalTxCollector///missing_/duration` (ms) -- `ProposalTxCollector///missing_/fetched` (txs) +- `BatchTxRequester//missing_/duration` (ms) +- `BatchTxRequester//missing_/fetched` (txs) ### Markdown file output @@ -175,14 +147,14 @@ Writes the pretty table + summary to disk. For each case the benchmark records: -- `durationMs`: wall-clock time spent inside the collector call -- `fetchedCount`: how many txs were returned by the collector +- `durationMs`: wall-clock time spent inside the requester call +- `fetchedCount`: how many txs were returned by the requester - `success`: `fetchedCount === missingTxCount` **Guidelines:** - **Always check `Success` first.** A faster run that fetched fewer txs is not a win. -- Compare collectors **within the same distribution + missing count** only. +- Compare runs **within the same distribution + missing count** only. - Expect `pinned-only` to highlight pinned-peer behavior (fast if pinned peer is used effectively; slow if the algorithm wastes time sampling other peers). - Expect `sparse` to be the most "network-like" stress case, since many peers won't have each requested tx. @@ -193,7 +165,7 @@ Inside each worker, the benchmark intentionally reduces variability: - **Unlimited rate limits** are installed so the req/resp rate limiter doesn't dominate results - **Deterministic tx generation** ensures all workers see the same tx set without large IPC payloads -This makes the benchmark better for *comparing collectors* (A vs B), but it is **not** a perfect model of production networking conditions. +This makes the benchmark better for tracking regressions, but it is **not** a perfect model of production networking conditions. ## Limitations @@ -207,9 +179,7 @@ This benchmark does **not** measure: | File | Purpose | |------|---------| -| `p2p_client.proposal_tx_collector.bench.test.ts` | Test suite (cases, distributions, output formatting) | -| `proposal_tx_collector_worker.ts` | Collector-specific worker implementation | -| `proposal_tx_collector_worker_protocol.ts` | IPC message types and serialization | +| `p2p_client.batch_tx_requester.bench.test.ts` | Test suite (cases, distributions, output formatting) | | `src/testbench/worker_client_manager.ts` | Worker process manager (forking, IPC, orchestration) | | `src/testbench/p2p_client_testbench_worker.ts` | General testbench worker implementation | | `src/test-helpers/testbench-utils.ts` | Shared mocks and utilities (InMemoryTxPool, InMemoryAttestationPool, etc.) | diff --git a/yarn-project/p2p/src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts b/yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.test.ts similarity index 96% rename from yarn-project/p2p/src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts rename to yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.test.ts index 148783fbd1ed..d14db02583a7 100644 --- a/yarn-project/p2p/src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts +++ b/yarn-project/p2p/src/client/test/p2p_client.batch_tx_requester.bench.test.ts @@ -9,7 +9,7 @@ import { type DistributionPattern, WorkerClientManager, testChainConfig, -} from '../../../testbench/worker_client_manager.js'; +} from '../../testbench/worker_client_manager.js'; const TEST_TIMEOUT_MS = 600_000; // 10 minutes jest.setTimeout(TEST_TIMEOUT_MS); @@ -75,7 +75,7 @@ const CASES: readonly BenchmarkCase[] = BASE_SCENARIOS.flatMap(base => })), ); -describe('ProposalTxCollector Benchmarks', () => { +describe('BatchTxRequester Benchmarks', () => { const results: BenchmarkResult[] = []; let logger: Logger; @@ -181,7 +181,7 @@ function toPrettyString(benchResults: BenchmarkResult[]): string { lines.push(''); lines.push('='.repeat(80)); - lines.push('ProposalTxCollector Benchmark Results'); + lines.push('BatchTxRequester Benchmark Results'); lines.push('='.repeat(80)); lines.push(''); lines.push('| Distribution | Missing | Duration (ms) | Fetched | Success |'); @@ -212,7 +212,7 @@ function toBenchmarkJSON(benchResults: BenchmarkResult[], indent = 2): string { const metrics: JsonBenchmarkResult[] = []; for (const result of benchResults) { - const baseName = `ProposalTxCollector/${result.distribution}/missing_${result.missingTxCount}`; + const baseName = `BatchTxRequester/${result.distribution}/missing_${result.missingTxCount}`; metrics.push( { name: `${baseName}/duration`, diff --git a/yarn-project/p2p/src/client/test/p2p_client.integration_batch_txs.test.ts b/yarn-project/p2p/src/client/test/p2p_client.integration_batch_txs.test.ts index 1858f94786ac..03cc0405c9ba 100644 --- a/yarn-project/p2p/src/client/test/p2p_client.integration_batch_txs.test.ts +++ b/yarn-project/p2p/src/client/test/p2p_client.integration_batch_txs.test.ts @@ -9,7 +9,7 @@ import { sleep } from '@aztec/foundation/sleep'; import { emptyChainConfig } from '@aztec/stdlib/config'; import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import { makeBlockHeader, makeBlockProposal, mockTx } from '@aztec/stdlib/testing'; -import { Tx, TxHash } from '@aztec/stdlib/tx'; +import { Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx'; import { describe, expect, it, jest } from '@jest/globals'; import { type MockProxy, mock } from 'jest-mock-extended'; @@ -20,7 +20,6 @@ import type { AttestationPool } from '../../mem_pools/attestation_pool/attestati import type { TxPoolV2 } from '../../mem_pools/tx_pool_v2/interfaces.js'; import { BatchTxRequester } from '../../services/reqresp/batch-tx-requester/batch_tx_requester.js'; import type { BatchTxRequesterLibP2PService } from '../../services/reqresp/batch-tx-requester/interface.js'; -import type { IBatchRequestTxValidator } from '../../services/reqresp/batch-tx-requester/tx_validator.js'; import type { ConnectionSampler } from '../../services/reqresp/connection-sampler/connection_sampler.js'; import { RequestTracker } from '../../services/tx_collection/request_tracker.js'; import { generatePeerIdPrivateKeys } from '../../test-helpers/generate-peer-id-private-keys.js'; @@ -39,7 +38,7 @@ describe('p2p client integration batch txs', () => { let mockP2PService: MockProxy; let connectionSampler: MockProxy; - let txValidator: IBatchRequestTxValidator; + let txValidator: TxValidator; let logger: Logger; let p2pBaseConfig: P2PConfig; @@ -53,10 +52,12 @@ describe('p2p client integration batch txs', () => { epochCache = mock(); worldState = mock(); connectionSampler = mock(); - mockP2PService = mock({ connectionSampler }); + mockP2PService = mock({ + connectionSampler, + validateRequestedBlockTxsConsistency: () => Promise.resolve(true), + }); txValidator = { - validateRequestedTx: () => Promise.resolve({ result: 'valid' }), - validateRequestedTxs: txs => Promise.resolve(txs.map(() => ({ result: 'valid' }))), + validateTx: () => Promise.resolve({ result: 'valid' }), }; logger = createLogger('p2p:test:integration:batch'); diff --git a/yarn-project/p2p/src/client/test/p2p_client.integration_reqresp.test.ts b/yarn-project/p2p/src/client/test/p2p_client.integration_reqresp.test.ts index c6454f17a1d2..ac3cc50c88e5 100644 --- a/yarn-project/p2p/src/client/test/p2p_client.integration_reqresp.test.ts +++ b/yarn-project/p2p/src/client/test/p2p_client.integration_reqresp.test.ts @@ -113,44 +113,6 @@ describe('p2p client integration reqresp', () => { return (p2pService as any).node.peerId; }; - it('can request txs from peers via mock reqresp', async () => { - const numberOfNodes = 2; - const mockGossipSubNetwork = new MockGossipSubNetwork(); - - const testConfig = { - p2pBaseConfig: { ...p2pBaseConfig, rollupVersion: 1 }, - mockAttestationPool: attestationPool, - mockTxPool: txPool, - mockEpochCache: epochCache, - mockWorldState: worldState, - alwaysTrueVerifier: true, - mockGossipSubNetwork, - logger, - }; - - const clientsAndConfig = await makeAndStartTestP2PClients(numberOfNodes, testConfig); - clients = clientsAndConfig.map(c => c.client); - - await sleep(1000); - - // Create a mock tx and configure the shared pool to return it - const tx = await createMockTxWithMetadata(testConfig.p2pBaseConfig); - const txHash = tx.getTxHash(); - - txPool.getTxByHash.mockImplementation((hash: TxHash) => Promise.resolve(hash.equals(txHash) ? tx : undefined)); - - // Request the tx from node-2, which will route to node-1 via the mock network - const reqresp = getReqResp(clients[1]); - const responses = await reqresp.sendBatchRequest(ReqRespSubProtocol.TX, [new TxHashArray(txHash)], undefined); - - expect(responses).toHaveLength(1); - const txArray = responses[0] as TxArray; - expect(txArray).toHaveLength(1); - - const receivedTxHash = txArray[0].getTxHash(); - expect(receivedTxHash.toString()).toEqual(txHash.toString()); - }); - it('sendRequestToPeer routes to the correct peer handler', async () => { const numberOfNodes = 2; const mockGossipSubNetwork = new MockGossipSubNetwork(); @@ -197,36 +159,4 @@ describe('p2p client integration reqresp', () => { expect(receivedTxHash.toString()).toEqual(txHash.toString()); } }); - - it('reqresp returns empty when peer has no matching txs', async () => { - const numberOfNodes = 2; - const mockGossipSubNetwork = new MockGossipSubNetwork(); - - const testConfig = { - p2pBaseConfig: { ...p2pBaseConfig, rollupVersion: 1 }, - mockAttestationPool: attestationPool, - mockTxPool: txPool, - mockEpochCache: epochCache, - mockWorldState: worldState, - alwaysTrueVerifier: true, - mockGossipSubNetwork, - logger, - }; - - const clientsAndConfig = await makeAndStartTestP2PClients(numberOfNodes, testConfig); - clients = clientsAndConfig.map(c => c.client); - - await sleep(1000); - - // Request a random tx hash that no peer has - const randomTxHash = TxHash.random(); - const reqresp = getReqResp(clients[1]); - const responses = await reqresp.sendBatchRequest(ReqRespSubProtocol.TX, [new TxHashArray(randomTxHash)], undefined); - - // The handler returns an empty TxArray (serialized as a 4-byte vector with count 0), - // so sendBatchRequest includes it as a response with an empty TxArray. - expect(responses).toHaveLength(1); - const txArray = responses[0] as TxArray; - expect(txArray).toHaveLength(0); - }); }); diff --git a/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts b/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts deleted file mode 100644 index ae8121da7d8d..000000000000 --- a/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +++ /dev/null @@ -1,345 +0,0 @@ -import { MockL2BlockSource } from '@aztec/archiver/test'; -import { SecretValue } from '@aztec/foundation/config'; -import { createLogger } from '@aztec/foundation/log'; -import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider, Timer, executeTimeout } from '@aztec/foundation/timer'; -import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; -import type { L2BlockSource } from '@aztec/stdlib/block'; -import type { ContractDataSource } from '@aztec/stdlib/contract'; -import { GasFees } from '@aztec/stdlib/gas'; -import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server'; -import type { DataStoreConfig } from '@aztec/stdlib/kv-store'; -import { PeerErrorSeverity } from '@aztec/stdlib/p2p'; -import type { Tx, TxValidationResult } from '@aztec/stdlib/tx'; -import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client'; - -import type { PeerId } from '@libp2p/interface'; -import { peerIdFromString } from '@libp2p/peer-id'; - -import type { P2PConfig } from '../../../config.js'; -import { BatchTxRequester } from '../../../services/reqresp/batch-tx-requester/batch_tx_requester.js'; -import type { IBatchRequestTxValidator } from '../../../services/reqresp/batch-tx-requester/tx_validator.js'; -import { RateLimitStatus } from '../../../services/reqresp/rate-limiter/rate_limiter.js'; -import { RequestTracker } from '../../../services/tx_collection/request_tracker.js'; -import { - AlwaysTrueCircuitVerifier, - BENCHMARK_CONSTANTS, - InMemoryAttestationPool, - InMemoryTxPool, - UNLIMITED_RATE_LIMIT_QUOTA, - calculateInternalTimeout, - createMockEpochCache, - createMockWorldStateSynchronizer, -} from '../../../test-helpers/index.js'; -import { createP2PClient } from '../../index.js'; -import type { P2PClient } from '../../p2p_client.js'; -import { - type WorkerCommand, - type WorkerResponse, - deserializeBlockProposal, - deserializeTx, - deserializeTxHash, -} from './proposal_tx_collector_worker_protocol.js'; - -let client: P2PClient | undefined; -let txPool: InMemoryTxPool | undefined; -let attestationPool: InMemoryAttestationPool | undefined; -let logger = createLogger('p2p:proposal-bench'); -let kvStore: Awaited> | undefined; -let ipcDisconnected = false; - -function ensureClient(): P2PClient { - if (!client || !txPool) { - throw new Error('Worker client not started'); - } - return client; -} - -function isIpcDisconnectError(err: unknown): boolean { - const code = (err as NodeJS.ErrnoException | undefined)?.code; - return code === 'EPIPE' || code === 'ERR_IPC_CHANNEL_CLOSED'; -} - -function sendMessage(message: WorkerResponse): Promise { - const send = process.send; - if (!send || !process.connected || ipcDisconnected) { - return Promise.resolve(); - } - - return new Promise(resolve => { - const fallbackTimeout = setTimeout(() => resolve(), 2000); - try { - send.call(process, message, undefined, undefined, err => { - clearTimeout(fallbackTimeout); - if (!err) { - resolve(); - return; - } - if (isIpcDisconnectError(err)) { - ipcDisconnected = true; - resolve(); - return; - } - logger.warn('Failed to send IPC message', { error: err?.message ?? String(err) }); - resolve(); - }); - } catch (err: any) { - clearTimeout(fallbackTimeout); - if (isIpcDisconnectError(err)) { - ipcDisconnected = true; - resolve(); - return; - } - logger.warn('Failed to send IPC message', { error: err?.message ?? String(err) }); - resolve(); - } - }); -} - -async function startClient(config: P2PConfig, clientIndex: number) { - txPool = new InMemoryTxPool(); - attestationPool = new InMemoryAttestationPool(); - const epochCache = createMockEpochCache(); - const worldState = createMockWorldStateSynchronizer(); - const l2BlockSource = new MockL2BlockSource(); - const proofVerifier = new AlwaysTrueCircuitVerifier(); - kvStore = await openTmpStore(`proposal-bench-${clientIndex}`, true, BENCHMARK_CONSTANTS.KV_STORE_MAP_SIZE_KB); - logger = createLogger(`p2p:proposal-bench:${clientIndex}`); - - const telemetry = getTelemetryClient(); - const deps = { - txPool, - attestationPool, - store: kvStore, - logger, - }; - - client = await createP2PClient( - config as P2PConfig & DataStoreConfig, - l2BlockSource as L2BlockSource & ContractDataSource, - proofVerifier as ClientProtocolCircuitVerifier, - worldState, - epochCache, - { getCurrentMinFees: () => Promise.resolve(GasFees.empty()) }, - 'proposal-tx-collector-bench-worker', - new DateProvider(), - telemetry as TelemetryClient, - deps, - await l2BlockSource.getInitialHeader().hash(), - ); - - await client.start(); - installUnlimitedRateLimits(); - - for (let i = 0; i < 120; i++) { - if (client.isReady()) { - return; - } - await sleep(500); - } - - throw new Error('Timed out waiting for P2P client readiness'); -} - -function installSamplerOverrides(peerList: ReturnType[]) { - const reqResp = (ensureClient() as any).p2pService.reqresp as any; - const sampler = reqResp.connectionSampler as any; - - sampler.getPeerListSortedByConnectionCountAsc = (excluding?: Set) => { - if (!excluding || excluding.size === 0) { - return peerList; - } - return peerList.filter(peerId => !excluding.has(peerId.toString())); - }; - sampler.samplePeersBatch = (numberToSample: number, excluding?: Map) => { - const filtered = peerList.filter(peerId => !excluding?.has(peerId.toString())); - return filtered.slice(0, Math.min(numberToSample, filtered.length)); - }; - sampler.getPeer = (excluding?: Map) => { - const filtered = peerList.filter(peerId => !excluding?.has(peerId.toString())); - return filtered[0]; - }; -} - -function installUnlimitedRateLimits() { - const reqResp = (ensureClient() as any).p2pService.reqresp as any; - const rateLimiter = reqResp.rateLimiter as any; - - rateLimiter.getRateLimits = () => UNLIMITED_RATE_LIMIT_QUOTA; - rateLimiter.allow = () => RateLimitStatus.Allowed; -} - -async function runCollector(cmd: Extract) { - const { txHashes, blockProposal, pinnedPeerId, peerIds, timeoutMs } = cmd; - const reqResp = (ensureClient() as any).p2pService.reqresp as any; - const peerList = peerIds.map(peerId => peerIdFromString(peerId)); - - installSamplerOverrides(peerList); - installUnlimitedRateLimits(); - - const p2pService = { - reqResp, - connectionSampler: { - getPeerListSortedByConnectionCountAsc: () => peerList, - }, - txValidatorConfig: { - l1ChainId: 1, - rollupVersion: 1, - proofVerifier: { - verifyProof: () => Promise.resolve({ valid: true, durationMs: 0, totalDurationMs: 0 }), - stop: () => Promise.resolve(), - }, - }, - peerScoring: { - penalizePeer: (_peerId: PeerId, _penalty: PeerErrorSeverity) => {}, - }, - }; - - const parsedTxHashes = txHashes.map(deserializeTxHash); - const parsedProposal = deserializeBlockProposal(blockProposal); - const pinnedPeer = pinnedPeerId ? peerIdFromString(pinnedPeerId) : undefined; - - const timer = new Timer(); - let fetchedCount = 0; - - const internalTimeoutMs = calculateInternalTimeout(timeoutMs); - - const noopTxValidator: IBatchRequestTxValidator = { - validateRequestedTx: (_tx: Tx): Promise => Promise.resolve({ result: 'valid' }), - validateRequestedTxs: (txs: Tx[]): Promise => - Promise.resolve(txs.map(() => ({ result: 'valid' }))), - }; - - try { - const fetched = await executeTimeout( - (_signal: AbortSignal) => { - const tracker = RequestTracker.create(parsedTxHashes, new Date(Date.now() + internalTimeoutMs)); - const batchRequester = new BatchTxRequester( - tracker, - parsedProposal, - pinnedPeer, - p2pService, - logger, - new DateProvider(), - { txValidator: noopTxValidator }, - ); - return BatchTxRequester.collectAllTxs(batchRequester.run()); - }, - timeoutMs, - () => new Error(`Collector timed out after ${timeoutMs}ms`), - ); - fetchedCount = fetched.length; - } catch (err: any) { - logger.warn(`Collector error: ${err?.message ?? String(err)}`); - } - - return { durationMs: timer.ms(), fetchedCount }; -} - -async function stopClient() { - if (!client) { - return; - } - await client.stop(); - if (kvStore?.close) { - await kvStore.close(); - } - client = undefined; - txPool = undefined; - attestationPool = undefined; -} - -function gracefulExit(code: number = 0) { - try { - if (process.connected) { - process.disconnect(); - } - } catch { - // IPC channel already closed - } - setTimeout(() => process.exit(code), 5000).unref(); -} - -process.on('disconnect', () => { - ipcDisconnected = true; - void stopClient(); -}); - -process.on('error', err => { - if (isIpcDisconnectError(err)) { - ipcDisconnected = true; - return; - } - logger.warn('Worker process error', { error: err?.message ?? String(err) }); -}); - -process.on('message', (msg: WorkerCommand) => { - void (async () => { - if (!msg || typeof msg !== 'object') { - return; - } - - const requestId = msg.requestId; - - try { - switch (msg.type) { - case 'START': { - const rawConfig = msg.config; - const config: P2PConfig = { - ...rawConfig, - peerIdPrivateKey: rawConfig.peerIdPrivateKey ? new SecretValue(rawConfig.peerIdPrivateKey) : undefined, - } as P2PConfig; - - await startClient(config, msg.clientIndex); - const peerId = (ensureClient() as any).p2pService.node.peerId.toString(); - await sendMessage({ type: 'READY', requestId, peerId }); - break; - } - case 'SET_TXS': { - if (!txPool) { - throw new Error('Tx pool not initialized'); - } - const txs = msg.txs.map(deserializeTx); - const count = msg.mode === 'append' ? txPool.appendTxs(txs) : txPool.setTxs(txs); - await sendMessage({ type: 'TXS_SET', requestId, count }); - break; - } - case 'SET_BLOCK_PROPOSAL': { - if (!attestationPool) { - throw new Error('Attestation pool not initialized'); - } - const proposal = deserializeBlockProposal(msg.blockProposal); - await attestationPool.tryAddBlockProposal(proposal); - await sendMessage({ type: 'BLOCK_PROPOSAL_SET', requestId, archiveRoot: proposal.archive.toString() }); - break; - } - case 'RUN_COLLECTOR': { - const { durationMs, fetchedCount } = await runCollector(msg); - await sendMessage({ type: 'COLLECTOR_RESULT', requestId, durationMs, fetchedCount }); - break; - } - case 'GET_PEER_COUNT': { - const peers = await ensureClient().getPeers(); - await sendMessage({ type: 'PEER_COUNT', requestId, count: peers.length }); - break; - } - case 'STOP': { - await stopClient(); - await sendMessage({ type: 'STOPPED', requestId }); - gracefulExit(0); - break; - } - default: { - const _exhaustive: never = msg; - throw new Error(`Unknown command: ${(msg as { type?: string }).type}`); - } - } - } catch (err: any) { - await sendMessage({ type: 'ERROR', requestId, error: err?.message ?? String(err) }); - if (msg.type === 'START') { - await stopClient(); - gracefulExit(1); - } - } - })(); -}); diff --git a/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts b/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts deleted file mode 100644 index 9db03cdcfb7d..000000000000 --- a/yarn-project/p2p/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { BlockProposal } from '@aztec/stdlib/p2p'; -import { Tx, TxHash } from '@aztec/stdlib/tx'; - -import type { P2PConfig } from '../../../config.js'; - -export type SerializedP2PConfig = Omit & { peerIdPrivateKey?: string }; - -export type WorkerCommand = - | { type: 'START'; requestId: string; clientIndex: number; config: SerializedP2PConfig } - | { type: 'SET_TXS'; requestId: string; txs: string[]; mode?: 'replace' | 'append' } - | { type: 'SET_BLOCK_PROPOSAL'; requestId: string; blockProposal: string } - | { - type: 'RUN_COLLECTOR'; - requestId: string; - txHashes: string[]; - blockProposal: string; - pinnedPeerId?: string; - peerIds: string[]; - timeoutMs: number; - } - | { type: 'GET_PEER_COUNT'; requestId: string } - | { type: 'STOP'; requestId: string }; - -export type WorkerResponse = - | { type: 'READY'; requestId: string; peerId: string } - | { type: 'TXS_SET'; requestId: string; count: number } - | { type: 'BLOCK_PROPOSAL_SET'; requestId: string; archiveRoot: string } - | { type: 'COLLECTOR_RESULT'; requestId: string; durationMs: number; fetchedCount: number } - | { type: 'PEER_COUNT'; requestId: string; count: number } - | { type: 'STOPPED'; requestId: string } - | { type: 'ERROR'; requestId: string; error: string }; - -export const serializeTx = (tx: Tx) => tx.toBuffer().toString('hex'); -export const deserializeTx = (hex: string) => Tx.fromBuffer(Buffer.from(hex, 'hex')); - -export const serializeTxHash = (txHash: TxHash) => txHash.toString(); -export const deserializeTxHash = (hex: string) => TxHash.fromString(hex); - -export const serializeBlockProposal = (proposal: BlockProposal) => proposal.toBuffer().toString('hex'); -export const deserializeBlockProposal = (hex: string) => BlockProposal.fromBuffer(Buffer.from(hex, 'hex')); diff --git a/yarn-project/p2p/src/config.ts b/yarn-project/p2p/src/config.ts index 4986a0602b13..b8e388b98747 100644 --- a/yarn-project/p2p/src/config.ts +++ b/yarn-project/p2p/src/config.ts @@ -221,14 +221,28 @@ export interface P2PConfig /** Minimum age (ms) a transaction must have been in the pool before it's eligible for block building. */ minTxPoolAgeMs: number; - /** Deadline in ms used when collecting missing txs for unproven mined blocks. */ - p2pMissingTxCollectionDeadlineMs: number; + /** + * Number of full L2 slots to wait after a checkpoint's slot before declaring its txs missing + * for data-withholding slashing. + */ + slashDataWithholdingToleranceSlots: number; + + /** + * Number of L2 slots after a mined block's slot to keep collecting its missing txs. Clamped + * up so that collection always runs at least until the data-withholding slash verdict is + * rendered (`block.slot + slashDataWithholdingToleranceSlots + 1`). Defaults to undefined, + * in which case the tolerance window is used directly. + */ + p2pMissingTxCollectionDeadlineSlots?: number; /** Minimum percentage fee increase required to replace an existing tx via RPC (0 = no bump). */ priceBumpPercentage: bigint; /** Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only) */ skipIncomingProposals?: boolean; + + /** Accept proposal gossip regardless of slot timing (for testing only). */ + skipProposalSlotValidation?: boolean; } export const DEFAULT_P2P_PORT = 40400; @@ -554,15 +568,26 @@ export const p2pConfigMappings: ConfigMappingsType = { description: 'Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only)', ...booleanConfigHelper(false), }, + skipProposalSlotValidation: { + description: 'Accept proposal gossip regardless of slot timing (for testing only)', + ...booleanConfigHelper(false), + }, minTxPoolAgeMs: { env: 'P2P_MIN_TX_POOL_AGE_MS', description: 'Minimum age (ms) a transaction must have been in the pool before it is eligible for block building.', ...numberConfigHelper(2_000), }, - p2pMissingTxCollectionDeadlineMs: { - env: 'P2P_MISSING_TX_COLLECTION_DEADLINE_MS', - description: 'Deadline in ms used when collecting missing txs for unproven mined blocks.', - ...numberConfigHelper(72_000), + slashDataWithholdingToleranceSlots: { + env: 'SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS', + description: + 'L2 slots to wait after a checkpoint slot before declaring its txs missing. Drives both the data-withholding slasher check and the missing-tx collection deadline.', + ...numberConfigHelper(3), + }, + p2pMissingTxCollectionDeadlineSlots: { + env: 'P2P_MISSING_TX_COLLECTION_DEADLINE_SLOTS', + description: + 'Optional deadline (in L2 slots after the block slot) for collecting missing txs for unproven mined blocks. Clamped up to the data-withholding tolerance window so collection never gives up before the slash verdict.', + ...optionalNumberConfigHelper(), }, priceBumpPercentage: { env: 'P2P_RPC_PRICE_BUMP_PERCENTAGE', diff --git a/yarn-project/p2p/src/errors/reqresp.error.ts b/yarn-project/p2p/src/errors/reqresp.error.ts index 21749b7473d2..23827d882b9e 100644 --- a/yarn-project/p2p/src/errors/reqresp.error.ts +++ b/yarn-project/p2p/src/errors/reqresp.error.ts @@ -8,28 +8,3 @@ export class IndividualReqRespTimeoutError extends Error { super(`Request to peer timed out`); } } - -/** Collective request timeout error - * - * This error will be thrown when a req resp request times out regardless of the peer. - * @category Errors - */ -export class CollectiveReqRespTimeoutError extends Error { - constructor() { - super(`Request to all peers timed out`); - } -} - -/** Invalid response error - * - * This error will be thrown when a response is received that is not valid. - * - * This error does not need to be punished as message validators will handle punishing invalid - * requests - * @category Errors - */ -export class InvalidResponseError extends Error { - constructor() { - super(`Invalid response received`); - } -} diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts index 109e472aa35f..b2491ebee79d 100644 --- a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts @@ -14,7 +14,7 @@ import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instru /** Result of trying to add an item (proposal or attestation) to the pool */ export type TryAddResult = { - /** Whether the item was added to a main store. False when the slot/position/(slot,signer) already had a stored entry, even if a new equivocation hash was tracked. */ + /** Whether the item was accepted into pool state. False when it already existed, was invalid, or hit a cap. */ added: boolean; /** Whether the exact signed payload (matched by payload hash) already existed in the pool. */ alreadyExists: boolean; @@ -25,6 +25,11 @@ export type TryAddResult = { count: number; }; +export type ProposalsForSlot = { + blockProposals: BlockProposal[]; + checkpointProposals: CheckpointProposalCore[]; +}; + export const MAX_CHECKPOINT_PROPOSALS_PER_SLOT = 2; export const MAX_BLOCK_PROPOSALS_PER_POSITION = 2; /** Maximum attestations a single signer can make per slot before being rejected. */ @@ -35,6 +40,7 @@ export type AttestationPoolApi = Pick< AttestationPool, | 'tryAddBlockProposal' | 'getBlockProposalByArchive' + | 'getProposalsForSlot' | 'tryAddCheckpointProposal' | 'getCheckpointProposal' | 'addOwnCheckpointAttestations' @@ -52,11 +58,11 @@ export type AttestationPoolApi = Pick< * Attestations and proposals observed via the p2p network are stored for requests * from the validator to produce a block, or to serve to other peers. * - * Equivocation detection: each main store holds at most one entry per equivocation - * position (one checkpoint proposal per slot, one block proposal per (slot, position), - * one attestation per (slot, signer)). Distinct *signed payload hashes* arriving at - * the same position are tracked in the matching index multimap so the equivocation - * count reaches 2 even when archive collides on `feeAssetPriceModifier` variants. + * Equivocation detection: distinct *signed payload hashes* arriving at the same + * position are tracked in the matching index multimap so the equivocation count + * reaches 2 even when archive collides on `feeAssetPriceModifier` variants. + * Proposal bytes are retained per accepted payload hash, up to the same equivocation + * caps, for slashing watchers that need signed P2P proposals. */ export class AttestationPool { private metrics: PoolInstrumentation; @@ -71,26 +77,25 @@ export class AttestationPool { // Key: `${paddedSlot}-${signerAddress}`, Value: CheckpointProposalHash (`0x`-prefixed hex) private attestationHashesPerSlotAndSigner: AztecAsyncMultiMap; - // Checkpoint proposals from slot number to serialized CheckpointProposal. - // Stores the first proposal seen per slot. - private checkpointProposalPerSlot: AztecAsyncMap; + // Checkpoint proposals from `${paddedSlot}-${payloadHash}` to serialized CheckpointProposalCore. + // Stores every accepted distinct payload up to MAX_CHECKPOINT_PROPOSALS_PER_SLOT. + private checkpointProposalsPerSlotAndHash: AztecAsyncMap; // Distinct payload hashes seen per slot. Hash collision = duplicate. // Hash count reaching 2 = equivocation. // Key: slot number, Value: CheckpointProposalHash (`0x`-prefixed hex) private checkpointProposalHashesPerSlot: AztecAsyncMultiMap; - // Block proposals from positionKey to serialized BlockProposal. - // Stores the first proposal seen per (slot, indexWithinCheckpoint). - private blockProposalPerSlotAndIndex: AztecAsyncMap; + // Block proposals from `${paddedSlot}-${paddedIndex}-${payloadHash}` to serialized BlockProposal. + // Stores every accepted distinct payload up to MAX_BLOCK_PROPOSALS_PER_POSITION. + private blockProposalsPerSlotIndexAndHash: AztecAsyncMap; // Distinct payload hashes seen per (slot, indexWithinCheckpoint). // Key: slot * (1 << INDEX_BITS) + indexWithinCheckpoint, Value: BlockProposalHash (`0x`-prefixed hex) private blockProposalHashesPerSlotAndIndex: AztecAsyncMultiMap; - // Secondary index from archive root to positionKey, so that the block-txs req/resp - // handler can still resolve a stored proposal by archive root. - private blockProposalSlotAndIndexPerArchive: AztecAsyncMap; + // Secondary index from archive root to all retained block proposal keys. + private blockProposalKeysPerArchive: AztecAsyncMultiMap; constructor( private store: AztecAsyncKVStore, @@ -98,16 +103,16 @@ export class AttestationPool { private log = createLogger('aztec:attestation_pool'), ) { // Initialize block proposal storage - this.blockProposalPerSlotAndIndex = store.openMap('proposals'); + this.blockProposalsPerSlotIndexAndHash = store.openMap('block_proposals_by_slot_index_and_hash'); this.blockProposalHashesPerSlotAndIndex = store.openMultiMap('block_proposals_for_slot_and_index'); - this.blockProposalSlotAndIndexPerArchive = store.openMap('block_proposals_by_archive'); + this.blockProposalKeysPerArchive = store.openMultiMap('block_proposals_by_archive'); // Initialize checkpoint attestations storage this.attestationPerSlotAndSigner = store.openMap('checkpoint_attestations'); this.attestationHashesPerSlotAndSigner = store.openMultiMap('checkpoint_attestations_per_slot_and_signer'); // Initialize checkpoint proposal storage - this.checkpointProposalPerSlot = store.openMap('checkpoint_proposals'); + this.checkpointProposalsPerSlotAndHash = store.openMap('checkpoint_proposals_by_slot_and_hash'); this.checkpointProposalHashesPerSlot = store.openMultiMap('checkpoint_proposals_for_slot'); this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL, this.poolStats); @@ -121,13 +126,13 @@ export class AttestationPool { /** Returns whether the pool is empty. */ public async isEmpty(): Promise { - for await (const _ of this.attestationPerSlotAndSigner.entriesAsync()) { - return false; - } - for await (const _ of this.blockProposalPerSlotAndIndex.entriesAsync()) { - return false; - } - return true; + const [attestationCount, blockProposalCount, checkpointProposalCount] = await Promise.all([ + this.attestationPerSlotAndSigner.sizeAsync(), + this.blockProposalsPerSlotIndexAndHash.sizeAsync(), + this.checkpointProposalsPerSlotAndHash.sizeAsync(), + ]); + + return attestationCount === 0 && blockProposalCount === 0 && checkpointProposalCount === 0; } /** Number of bits reserved for indexWithinCheckpoint in position keys. */ @@ -143,6 +148,35 @@ export class AttestationPool { return slot.toString().padStart(AttestationPool.SLOT_PAD_DIGITS, '0'); } + /** Fixed-width decimal index string for use in composite string keys. */ + private indexPaddedKey(indexWithinCheckpoint: number): string { + return indexWithinCheckpoint.toString().padStart(4, '0'); + } + + /** Key for retained block proposals. */ + private getBlockProposalKey( + slot: SlotNumber | number, + indexWithinCheckpoint: number, + payloadHash: BlockProposalHash, + ): string { + return `${this.slotPaddedKey(slot)}-${this.indexPaddedKey(indexWithinCheckpoint)}-${payloadHash}`; + } + + /** Range bounds for all retained block proposals in a slot. */ + private getBlockProposalKeyRangeForSlot(slot: SlotNumber): { start: string; end: string } { + return { start: `${this.slotPaddedKey(slot)}-`, end: `${this.slotPaddedKey(slot + 1)}-` }; + } + + /** Key for retained checkpoint proposals. */ + private getCheckpointProposalKey(slot: SlotNumber | number, payloadHash: CheckpointProposalHash): string { + return `${this.slotPaddedKey(slot)}-${payloadHash}`; + } + + /** Range bounds for all retained checkpoint proposals in a slot. */ + private getCheckpointProposalKeyRangeForSlot(slot: SlotNumber): { start: string; end: string } { + return { start: `${this.slotPaddedKey(slot)}-`, end: `${this.slotPaddedKey(slot + 1)}-` }; + } + /** Key for the per-(slot, signer) attestation main store and equivocation index. */ private getSlotSignerKey(slot: SlotNumber, signerAddress: string): string { return `${this.slotPaddedKey(slot)}-${signerAddress}`; @@ -185,8 +219,7 @@ export class AttestationPool { * - Detects duplicates by signed-payload hash (not archive); a re-broadcast of the * exact same signed payload returns `alreadyExists: true`. * - Distinct payload hashes at the same `(slot, indexWithinCheckpoint)` are tracked - * in the equivocation index. The first hash also stores the proposal bytes; later - * distinct hashes only bump `count` so libp2p can fire its duplicate callback. + * in the equivocation index and retained up to the cap. * * @param blockProposal - The block proposal to add * @returns Result indicating whether the proposal was added and duplicate detection info @@ -210,14 +243,13 @@ export class AttestationPool { // Track the new payload hash for equivocation detection. await this.blockProposalHashesPerSlotAndIndex.set(positionKey, payloadHash); - - // Only the first distinct payload at this position is stored; later equivocations - // are detected via the multimap but their payload bytes are not retained. - const alreadyHasStored = await this.blockProposalPerSlotAndIndex.hasAsync(positionKey); - if (!alreadyHasStored) { - await this.blockProposalPerSlotAndIndex.set(positionKey, blockProposal.withoutSignedTxs().toBuffer()); - await this.blockProposalSlotAndIndexPerArchive.set(blockProposal.archive.toString(), positionKey); - } + const proposalKey = this.getBlockProposalKey( + blockProposal.slotNumber, + blockProposal.indexWithinCheckpoint, + payloadHash, + ); + await this.blockProposalsPerSlotIndexAndHash.set(proposalKey, blockProposal.withoutSignedTxs().toBuffer()); + await this.blockProposalKeysPerArchive.set(blockProposal.archive.toString(), proposalKey); this.log.debug( `Added block proposal for slot ${blockProposal.slotNumber} and index ${blockProposal.indexWithinCheckpoint}`, @@ -226,7 +258,6 @@ export class AttestationPool { payloadHash, slotNumber: blockProposal.slotNumber, indexWithinCheckpoint: blockProposal.indexWithinCheckpoint, - stored: !alreadyHasStored, }, ); @@ -237,40 +268,57 @@ export class AttestationPool { /** * Get block proposal by archive root. * - * Resolves the archive root to its `(slot, indexWithinCheckpoint)` via a secondary - * index, then fetches the stored proposal (if any). Returns the *first* proposal - * seen at that position, even if a later equivocating payload was tracked. - * Validates that the stored proposal's archive matches the requested one before - * returning, guarding against secondary-index corruption or position-key reuse. + * Resolves the archive root through the archive index and returns the first + * retained proposal for that archive. This lookup is used by block-txs req/resp, + * where any retained proposal for the requested archive gives the tx hash list. * * @param archiveRoot - The archive root to look up * @return The block proposal if it exists and its archive matches, otherwise undefined. */ public async getBlockProposalByArchive(archiveRoot: string): Promise { - const positionKey = await this.blockProposalSlotAndIndexPerArchive.getAsync(archiveRoot); - if (positionKey === undefined) { - return undefined; - } - const buffer = await this.blockProposalPerSlotAndIndex.getAsync(positionKey); - if (!buffer || buffer.length === 0) { - return undefined; + for await (const proposalKey of this.blockProposalKeysPerArchive.getValuesAsync(archiveRoot)) { + const buffer = await this.blockProposalsPerSlotIndexAndHash.getAsync(proposalKey); + if (!buffer || buffer.length === 0) { + continue; + } + try { + const proposal = BlockProposal.fromBuffer(buffer); + if (proposal.archive.toString() === archiveRoot) { + return proposal; + } + } catch { + continue; + } } - let proposal: BlockProposal; - try { - proposal = BlockProposal.fromBuffer(buffer); - } catch { - return undefined; + return undefined; + } + + /** Returns retained signed proposals for a slot. */ + public async getProposalsForSlot(slot: SlotNumber): Promise { + const blockProposals: BlockProposal[] = []; + const checkpointProposals: CheckpointProposalCore[] = []; + + for await (const [_, buffer] of this.blockProposalsPerSlotIndexAndHash.entriesAsync( + this.getBlockProposalKeyRangeForSlot(slot), + )) { + try { + blockProposals.push(BlockProposal.fromBuffer(buffer)); + } catch { + continue; + } } - const storedArchive = proposal.archive.toString(); - if (storedArchive !== archiveRoot) { - this.log.warn(`Stored block proposal archive does not match requested archive root`, { - requestedArchive: archiveRoot, - storedArchive, - positionKey, - }); - return undefined; + + for await (const [_, buffer] of this.checkpointProposalsPerSlotAndHash.entriesAsync( + this.getCheckpointProposalKeyRangeForSlot(slot), + )) { + try { + checkpointProposals.push(CheckpointProposal.fromBuffer(buffer)); + } catch { + continue; + } } - return proposal; + + return { blockProposals, checkpointProposals }; } /** Checks if any block proposals exist for a given slot (at index 0). */ @@ -286,8 +334,8 @@ export class AttestationPool { * - Detects duplicates by signed-payload hash (not archive); a re-broadcast of the * exact same signed payload returns `alreadyExists: true`. * - Distinct payload hashes at the same slot are tracked in the equivocation index. - * Only the first distinct payload's bytes are stored; later distinct hashes bump - * `count` so libp2p can fire its duplicate callback. + * Distinct payload bytes are retained up to the same cap so slashing watchers + * can recover signed proposals. * * Note: This method only handles the CheckpointProposalCore. If the original * CheckpointProposal contains a lastBlock, the caller should extract it via @@ -313,19 +361,15 @@ export class AttestationPool { // Track the new payload hash for equivocation detection. await this.checkpointProposalHashesPerSlot.set(slot, payloadHash); - - // Only the first distinct payload at this slot is stored; later equivocations - // are detected via the multimap but their payload bytes are not retained. - const alreadyHasStored = await this.checkpointProposalPerSlot.hasAsync(slot); - if (!alreadyHasStored) { - await this.checkpointProposalPerSlot.set(slot, proposal.toBuffer()); - } + await this.checkpointProposalsPerSlotAndHash.set( + this.getCheckpointProposalKey(slot, payloadHash), + proposal.toBuffer(), + ); this.log.debug(`Added checkpoint proposal for slot ${slot}`, { archive: proposal.archive.toString(), payloadHash, slotNumber: slot, - stored: !alreadyHasStored, }); return { added: true, alreadyExists: false, count: count + 1 }; @@ -333,7 +377,9 @@ export class AttestationPool { } /** - * Get the (first) checkpoint proposal stored for the given slot. + * Get a retained checkpoint proposal stored for the given slot. + * If multiple proposals were retained for an equivocation, returns the lowest + * payload hash deterministically. * * Returns a CheckpointProposalCore (without lastBlock info) since the lastBlock * is extracted and stored separately as a BlockProposal when added. @@ -342,13 +388,16 @@ export class AttestationPool { * @return The checkpoint proposal core if one is stored, otherwise undefined. */ public async getCheckpointProposal(slot: SlotNumber): Promise { - const buffer = await this.checkpointProposalPerSlot.getAsync(slot); - try { - if (buffer && buffer.length > 0) { - return CheckpointProposal.fromBuffer(buffer); + for await (const [_, buffer] of this.checkpointProposalsPerSlotAndHash.entriesAsync( + this.getCheckpointProposalKeyRangeForSlot(slot), + )) { + try { + if (buffer && buffer.length > 0) { + return CheckpointProposal.fromBuffer(buffer); + } + } catch { + continue; } - } catch { - return undefined; } return undefined; @@ -465,10 +514,13 @@ export class AttestationPool { // Delete checkpoint proposals for slots < oldestSlot. for await (const slot of this.checkpointProposalHashesPerSlot.keysAsync({ end: oldestSlot })) { await this.checkpointProposalHashesPerSlot.delete(slot); - if (await this.checkpointProposalPerSlot.hasAsync(slot)) { - await this.checkpointProposalPerSlot.delete(slot); - numberOfCheckpointProposals++; - } + } + + for await (const key of this.checkpointProposalsPerSlotAndHash.keysAsync({ + end: `${oldestSlotPadded}-`, + })) { + await this.checkpointProposalsPerSlotAndHash.delete(key); + numberOfCheckpointProposals++; } // Delete block proposals for slots < oldestSlot, using blockProposalHashesPerSlotAndIndex as index. @@ -476,17 +528,19 @@ export class AttestationPool { const blockPositionEndKey = oldestSlot * (1 << AttestationPool.INDEX_BITS); for await (const positionKey of this.blockProposalHashesPerSlotAndIndex.keysAsync({ end: blockPositionEndKey })) { await this.blockProposalHashesPerSlotAndIndex.delete(positionKey); - const stored = await this.blockProposalPerSlotAndIndex.getAsync(positionKey); - if (stored) { - try { - const proposal = BlockProposal.fromBuffer(stored); - await this.blockProposalSlotAndIndexPerArchive.delete(proposal.archive.toString()); - } catch { - // ignore decode errors when cleaning up - } - await this.blockProposalPerSlotAndIndex.delete(positionKey); - numberOfBlockProposals++; + } + + for await (const [key, buffer] of this.blockProposalsPerSlotIndexAndHash.entriesAsync({ + end: `${oldestSlotPadded}-`, + })) { + try { + const proposal = BlockProposal.fromBuffer(buffer); + await this.blockProposalKeysPerArchive.deleteValue(proposal.archive.toString(), key); + } catch { + // ignore decode errors when cleaning up } + await this.blockProposalsPerSlotIndexAndHash.delete(key); + numberOfBlockProposals++; } }); diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts index 7265d2e52a42..19180d9d156d 100644 --- a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts @@ -246,6 +246,45 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer()); expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString()); }); + + it('should retain an exact duplicate block proposal only once', async () => { + const slotNumber = 420; + const proposal = await mockBlockProposalForPool(signers[0], slotNumber); + + await ap.tryAddBlockProposal(proposal); + await ap.tryAddBlockProposal(proposal); + + const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber)); + expect(proposals.blockProposals.map(proposal => proposal.toBuffer())).toEqual([ + proposal.withoutSignedTxs().toBuffer(), + ]); + }); + + it('should retain all accepted block proposals at a position', async () => { + const slotNumber = 420; + const blockHeader = makeBlockHeader(1, { slotNumber: SlotNumber(slotNumber) }); + const proposal1 = await makeBlockProposal({ + signer: signers[0], + blockHeader, + archiveRoot: Fr.random(), + indexWithinCheckpoint: IndexWithinCheckpoint(1), + }); + const proposal2 = await makeBlockProposal({ + signer: signers[0], + blockHeader, + archiveRoot: Fr.random(), + indexWithinCheckpoint: IndexWithinCheckpoint(1), + }); + + await ap.tryAddBlockProposal(proposal1); + await ap.tryAddBlockProposal(proposal2); + + const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber)); + expect(proposals.blockProposals.map(proposal => proposal.toBuffer())).toEqual( + expect.arrayContaining([proposal1.withoutSignedTxs().toBuffer(), proposal2.withoutSignedTxs().toBuffer()]), + ); + expect(await ap.getBlockProposalByArchive(proposal2.archive.toString())).toBeDefined(); + }); }); describe('CheckpointProposal in attestation pool', () => { @@ -346,13 +385,21 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo const result2 = await ap.tryAddCheckpointProposal(proposal2); // The second distinct payload is tracked as an equivocation, count goes to 2, - // but its bytes are not retained — the first proposal stays in the main store. + // and both accepted payloads are retained by payload hash. expect(result2.added).toBe(true); expect(result2.alreadyExists).toBe(false); expect(result2.count).toBe(2); const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber)); - expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer()); + const expectedProposal = [proposal1, proposal2].sort((a, b) => + a.getPayloadHash().localeCompare(b.getPayloadHash()), + )[0]; + expect(retrievedProposal!.toBuffer()).toEqual(expectedProposal.toBuffer()); + + const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber)); + expect(proposals.checkpointProposals.map(proposal => proposal.toBuffer())).toEqual( + expect.arrayContaining([proposal1.toBuffer(), proposal2.toBuffer()]), + ); }); it('should detect equivocation when only feeAssetPriceModifier differs', async () => { @@ -385,6 +432,34 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo expect(result2.count).toBe(2); }); + it('should delete retained proposals older than a given slot', async () => { + const oldSlot = 100; + const newSlot = 200; + const oldBlock = await mockBlockProposalForPool(signers[0], oldSlot); + const newBlock = await mockBlockProposalForPool(signers[1], newSlot); + const oldCheckpoint = await mockCheckpointProposalForPool(signers[0], oldSlot); + const newCheckpoint = await mockCheckpointProposalForPool(signers[1], newSlot); + + await ap.tryAddBlockProposal(oldBlock); + await ap.tryAddBlockProposal(newBlock); + await ap.tryAddCheckpointProposal(oldCheckpoint); + await ap.tryAddCheckpointProposal(newCheckpoint); + + await ap.deleteOlderThan(SlotNumber(newSlot)); + + expect(await ap.getProposalsForSlot(SlotNumber(oldSlot))).toEqual({ + blockProposals: [], + checkpointProposals: [], + }); + const newProposals = await ap.getProposalsForSlot(SlotNumber(newSlot)); + expect(newProposals.blockProposals.map(proposal => proposal.toBuffer())).toContainEqual( + newBlock.withoutSignedTxs().toBuffer(), + ); + expect(newProposals.checkpointProposals.map(proposal => proposal.toBuffer())).toContainEqual( + newCheckpoint.toBuffer(), + ); + }); + it('should return added=false when exceeding capacity', async () => { const slotNumber = 420; diff --git a/yarn-project/p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts b/yarn-project/p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts index 51283ab6ecc5..d45e6668489c 100644 --- a/yarn-project/p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +++ b/yarn-project/p2p/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts @@ -1,4 +1,5 @@ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { FifoSet } from '@aztec/foundation/fifo-set'; import type { Logger } from '@aztec/foundation/log'; import type { DateProvider } from '@aztec/foundation/timer'; import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store'; @@ -82,7 +83,7 @@ export class TxPoolV2Impl { #evictionManager: EvictionManager; #dateProvider: DateProvider; #instrumentation: TxPoolV2Instrumentation; - #evictedTxHashes: Set = new Set(); + #evictedTxHashes: FifoSet; #log: Logger; #callbacks: TxPoolV2Callbacks; @@ -105,6 +106,7 @@ export class TxPoolV2Impl { this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls; this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config }; + this.#evictedTxHashes = FifoSet.withLimit(this.#config.evictedTxCacheSize); this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log); this.#deletedPool = new DeletedPool(store, this.#txsDB, log); this.#dateProvider = dateProvider; @@ -903,21 +905,11 @@ export class TxPoolV2Impl { this.#instrumentation.recordEvictions(txHashes.length, reason); for (const txHashStr of txHashes) { this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason }); - this.#addToEvictedCache(txHashStr); + this.#evictedTxHashes.add(txHashStr); } await this.#deleteTxsBatch(txHashes); } - /** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */ - #addToEvictedCache(txHashStr: string): void { - if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) { - // FIFO eviction: remove the first (oldest) entry - const oldest = this.#evictedTxHashes.values().next().value!; - this.#evictedTxHashes.delete(oldest); - } - this.#evictedTxHashes.add(txHashStr); - } - // ============================================================================ // PRIVATE HELPERS - Validation & Conflict Resolution // ============================================================================ diff --git a/yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts b/yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts index 8d19408b94d1..f4e67469f975 100644 --- a/yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts +++ b/yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts @@ -13,6 +13,7 @@ export class BlockProposalValidator implements P2PValidator { maxTxsPerBlock?: number; maxBlocksPerCheckpoint?: number; p2pPropagationTime?: number; + skipSlotValidation?: boolean; signatureContext: CoordinationSignatureContext; }, ) { diff --git a/yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts b/yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts index 2a3eb9013c67..3e0057b96d90 100644 --- a/yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +++ b/yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts @@ -18,6 +18,7 @@ export class CheckpointProposalValidator implements P2PValidator { /** * Builds a PrivateLog encoding a ContractInstancePublishedEvent. - * Layout: [tag, address, version, salt, contractClassId, initializationHash, ...publicKeys(8 fields), deployer] + * Layout: [tag, address, version, salt, contractClassId, initializationHash, immutablesHash, ...publicKeys(5 fields), deployer] */ async function buildContractInstanceLog(opts?: { address?: AztecAddress }): Promise { const salt = Fr.random(); @@ -40,13 +40,15 @@ describe('ContractInstanceTxValidator', () => { const initializationHash = Fr.random(); const publicKeys = await PublicKeys.random(); const deployer = await AztecAddress.random(); + const immutablesHash = Fr.random(); const instance = { - version: 1 as const, + version: 2 as const, salt, currentContractClassId: contractClassId, originalContractClassId: contractClassId, initializationHash, + immutablesHash, publicKeys, deployer, }; @@ -55,8 +57,9 @@ describe('ContractInstanceTxValidator', () => { const address = opts?.address ?? correctAddress; // Serialize the event into fields matching the format expected by ContractInstancePublishedEvent.fromLog. - // fromLog reads from a buffer: [tag(32 bytes) | address(32) | version(32) | salt(32) | classId(32) | initHash(32) | publicKeys(4*64=256 bytes) | deployer(32)] - // PublicKeys serializes as 4 Points, each Point is 2 Fr (x, y) = 64 bytes. Total: 8 Fr fields. + // fromLog reads from a buffer: + // [tag(32) | address(32) | version(32) | salt(32) | classId(32) | initHash(32) | publicKeys(160) | deployer(32)] + // where publicKeys = npkMHash(32) + ivpkM(64 = x|y, no is_infinite) + ovpkMHash(32) + tpkMHash(32) = 5 Fr fields. const publicKeysBuffer = publicKeys.toBuffer(); const publicKeysFields: Fr[] = []; for (let i = 0; i < publicKeysBuffer.length; i += 32) { @@ -66,10 +69,11 @@ describe('ContractInstanceTxValidator', () => { const emittedFields: Fr[] = [ CONTRACT_INSTANCE_PUBLISHED_EVENT_TAG, address.toField(), - new Fr(1), // version + new Fr(2), // version salt, contractClassId, initializationHash, + immutablesHash, ...publicKeysFields, deployer.toField(), ]; diff --git a/yarn-project/p2p/src/services/dummy_service.ts b/yarn-project/p2p/src/services/dummy_service.ts index d89cfcc59635..6078c3e484cd 100644 --- a/yarn-project/p2p/src/services/dummy_service.ts +++ b/yarn-project/p2p/src/services/dummy_service.ts @@ -18,7 +18,6 @@ import type { ReqRespSubProtocol, ReqRespSubProtocolHandler, ReqRespSubProtocolHandlers, - ReqRespSubProtocolValidators, SubProtocolMap, } from './reqresp/interface.js'; import type { GoodByeReason } from './reqresp/protocols/goodbye.js'; @@ -38,6 +37,8 @@ import { * A dummy implementation of the P2P Service. */ export class DummyP2PService implements P2PService { + private allNodesCheckpointReceivedCallback?: P2PCheckpointReceivedCallback; + updateConfig(_config: Partial): void {} /** Returns an empty array for peers. */ @@ -88,10 +89,14 @@ export class DummyP2PService implements P2PService { * Register a callback into the validator client for when a checkpoint proposal is received */ public registerValidatorCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {} - public registerAllNodesCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {} + public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) { + this.allNodesCheckpointReceivedCallback = callback; + } - public notifyOwnCheckpointProposal(_checkpoint: CheckpointProposalCore): Promise { - return Promise.resolve(); + // Mirror libp2p's own-proposal loopback so the proposer's pipelined `canProposeAt` override sees its own + // in-flight parent checkpoint when running in p2p-disabled (single-node e2e) mode. + public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise { + await this.allNodesCheckpointReceivedCallback?.(checkpoint, undefined as unknown as PeerId); } /** @@ -119,19 +124,6 @@ export class DummyP2PService implements P2PService { return Promise.resolve(undefined); } - /** - * Sends a batch request to a peer. - * @param _protocol - The protocol to send the request on. - * @param _requests - The requests to send. - * @returns The responses from the peer, otherwise undefined. - */ - public sendBatchRequest( - _protocol: Protocol, - _requests: InstanceType[], - ): Promise[]> { - return Promise.resolve([]); - } - public sendRequestToPeer( _peerId: PeerId, _subProtocol: ReqRespSubProtocol, @@ -153,11 +145,7 @@ export class DummyP2PService implements P2PService { return Promise.resolve(); } - addReqRespSubProtocol( - _subProtocol: ReqRespSubProtocol, - _handler: ReqRespSubProtocolHandler, - _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { + addReqRespSubProtocol(_subProtocol: ReqRespSubProtocol, _handler: ReqRespSubProtocolHandler): Promise { return Promise.resolve(); } @@ -186,6 +174,7 @@ export class DummyP2PService implements P2PService { peerScoring: { penalizePeer: (_peerId, _penalty) => {}, }, + validateRequestedBlockTxsConsistency: () => Promise.resolve(true), }; } } @@ -291,10 +280,7 @@ export class DummyPeerManager implements PeerManagerInterface { export class DummyReqResp implements ReqRespInterface { updateConfig(_config: Partial): void {} setShouldRejectPeer(): void {} - start( - _subProtocolHandlers: ReqRespSubProtocolHandlers, - _subProtocolValidators: ReqRespSubProtocolValidators, - ): Promise { + start(_subProtocolHandlers: ReqRespSubProtocolHandlers): Promise { return Promise.resolve(); } stop(): Promise { @@ -306,16 +292,6 @@ export class DummyReqResp implements ReqRespInterface { ): Promise | undefined> { return Promise.resolve(undefined); } - sendBatchRequest( - _subProtocol: SubProtocol, - _requests: InstanceType[], - _pinnedPeer: PeerId | undefined, - _timeoutMs?: number, - _maxPeers?: number, - _maxRetryAttempts?: number, - ): Promise[]> { - return Promise.resolve([]); - } public sendRequestToPeer( _peerId: PeerId, _subProtocol: ReqRespSubProtocol, @@ -334,11 +310,7 @@ export class DummyReqResp implements ReqRespInterface { }; } - addSubProtocol( - _subProtocol: ReqRespSubProtocol, - _handler: ReqRespSubProtocolHandler, - _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { + addSubProtocol(_subProtocol: ReqRespSubProtocol, _handler: ReqRespSubProtocolHandler): Promise { return Promise.resolve(); } } diff --git a/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts b/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts index d7e78cbd4d49..3aaf4c97b9ce 100644 --- a/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts +++ b/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts @@ -19,7 +19,7 @@ import { makeCheckpointProposal, mockTx, } from '@aztec/stdlib/testing'; -import { type Tx, TxArray, TxHashArray, type TxValidator } from '@aztec/stdlib/tx'; +import { TxArray, TxHashArray } from '@aztec/stdlib/tx'; import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client'; import { ServerWorldStateSynchronizer } from '@aztec/world-state'; @@ -316,7 +316,7 @@ describe('LibP2PService', () => { }); }); - describe('validateRequestedBlockTxs', () => { + describe('validateRequestedBlockTxsConsistency', () => { function makeRequest(archiveRoot: Fr, length: number, indices: number[]): BlockTxsRequest { return new BlockTxsRequest(archiveRoot, new TxHashArray(), BitVector.init(length, indices)); } @@ -347,7 +347,7 @@ describe('LibP2PService', () => { const request = makeRequest(reqHash, 5, [0, 2]); const response = makeResponse(otherHash, 5, [0, 2], []); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -357,7 +357,7 @@ describe('LibP2PService', () => { const request = makeRequest(hash, 5, [0, 2]); const response = makeResponse(hash, 4, [0, 2], []); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -367,7 +367,7 @@ describe('LibP2PService', () => { const request = makeRequest(hash, 5, [0, 2, 3]); const response = makeResponse(hash, 5, [0, 2, 3], ['0xaaa', '0xaaa']); // duplicate - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -378,7 +378,7 @@ describe('LibP2PService', () => { const request = makeRequest(hash, 3, [0, 2]); const response = makeResponse(hash, 3, [0], ['0x1', '0x2']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -390,7 +390,7 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xgood2', '0xgood4', '0xother', '0xother2']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.LowToleranceError); }); @@ -404,7 +404,7 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.LowToleranceError); }); @@ -416,9 +416,8 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(true); - expect(service.validateRequestedTxMock).toHaveBeenCalledTimes(3); }); it('should accept partial subset when proposal exists and order matches requested indices', async () => { @@ -429,9 +428,8 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(true); - expect(service.validateRequestedTxMock).toHaveBeenCalledTimes(2); expect(mockPeerManager.penalizePeer).not.toHaveBeenCalled(); }); @@ -443,9 +441,8 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xother4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(true); - expect(service.validateRequestedTxMock).toHaveBeenCalledTimes(0); expect(mockPeerManager.penalizePeer).not.toHaveBeenCalled(); }); @@ -455,7 +452,7 @@ describe('LibP2PService', () => { const request = makeRequest(hash, 3, [1]); const response = makeResponse(hash, 3, [], ['0xsome']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.MidToleranceError); }); @@ -468,7 +465,7 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.LowToleranceError); }); @@ -481,7 +478,7 @@ describe('LibP2PService', () => { setProposalTxHashes(service, ['0xgood0', '0xother1', '0xgood2', '0xother3', '0xgood4']); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).toHaveBeenCalledWith(mockPeerId, PeerErrorSeverity.LowToleranceError); }); @@ -498,7 +495,7 @@ describe('LibP2PService', () => { }; service.setAttestationPool(mockAttestationPool); - const ok = await service.validateRequestedBlockTxs(request, response, mockPeerId); + const ok = await service.validateRequestedBlockTxsConsistency(request, response, mockPeerId); expect(ok).toBe(false); expect(mockPeerManager.penalizePeer).not.toHaveBeenCalled(); }); @@ -1315,9 +1312,6 @@ interface CreateTestLibP2PServiceOptions { * and allows construction with mocked dependencies. */ class TestLibP2PService extends LibP2PService { - /** Mocked validateRequestedTx for testing. */ - public validateRequestedTxMock: jest.Mock; - /** Controls whether first-stage gossip validation passes. Set to false to simulate first-stage failure. */ public firstStageValidationPasses = true; @@ -1330,9 +1324,6 @@ class TestLibP2PService extends LibP2PService { /** Controls the severity returned by the failing first-stage validator. */ public firstStageSeverity: PeerErrorSeverity = PeerErrorSeverity.LowToleranceError; - /** Stub validator returned by createRequestedTxValidator. */ - private stubValidator: TxValidator; - /** Exposed epoch cache for test configuration. */ public testEpochCache: MockProxy; @@ -1387,10 +1378,6 @@ class TestLibP2PService extends LibP2PService { this.mockPeerDiscoveryService = resolvedPeerDiscoveryService; this.testEpochCache = epochCache; - this.validateRequestedTxMock = jest.fn(() => Promise.resolve()); - this.stubValidator = { - validateTx: () => Promise.resolve({ result: 'valid' as const }), - }; } /** Exposes the protected handleNewGossipMessage for testing. */ @@ -1429,13 +1416,13 @@ class TestLibP2PService extends LibP2PService { }; } - /** Exposes the protected validateRequestedBlockTxs for testing. */ - public override validateRequestedBlockTxs( + /** Exposes the protected validateRequestedBlockTxsConsistency for testing. */ + public override validateRequestedBlockTxsConsistency( request: BlockTxsRequest, response: BlockTxsResponse, peerId: PeerId, ): Promise { - return super.validateRequestedBlockTxs(request, response, peerId); + return super.validateRequestedBlockTxsConsistency(request, response, peerId); } /** Exposes the protected processBlockFromPeer for testing. */ @@ -1453,21 +1440,6 @@ class TestLibP2PService extends LibP2PService { return super.validateAndStoreCheckpointAttestation(peerId, attestation); } - /** Override to use the mock. */ - protected override async validateRequestedTx( - tx: Tx, - peerId: PeerId, - _txValidator: TxValidator, - _requested?: Set<`0x${string}`>, - ): Promise { - await this.validateRequestedTxMock(tx, peerId); - } - - /** Override to return the stub validator. */ - protected override createRequestedTxValidator(): TxValidator { - return this.stubValidator; - } - /** Sets the attestation pool on the mempools for test setup. */ public setAttestationPool(attestationPool: MockAttestationPoolForTests): void { (this.mempools as any).attestationPool = attestationPool; diff --git a/yarn-project/p2p/src/services/libp2p/libp2p_service.ts b/yarn-project/p2p/src/services/libp2p/libp2p_service.ts index 1cf314d4c835..9c00dc517ba6 100644 --- a/yarn-project/p2p/src/services/libp2p/libp2p_service.ts +++ b/yarn-project/p2p/src/services/libp2p/libp2p_service.ts @@ -25,7 +25,7 @@ import { metricsTopicStrToLabels, } from '@aztec/stdlib/p2p'; import { MerkleTreeId } from '@aztec/stdlib/trees'; -import { Tx, type TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx'; +import { Tx, type TxValidationResult } from '@aztec/stdlib/tx'; import type { UInt64 } from '@aztec/stdlib/types'; import { compressComponentVersions } from '@aztec/stdlib/versioning'; import { @@ -74,7 +74,6 @@ import { createFirstStageTxValidationsForGossipedTransactions, createSecondStageTxValidationsForGossipedTransactions, createTxValidatorForBlockProposalReceivedTxs, - createTxValidatorForOnDemandReceivedTxs, } from '../../msg_validators/tx_validator/factory.js'; import { GossipSubEvent } from '../../types/index.js'; import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js'; @@ -93,15 +92,12 @@ import { AuthRequest, BlockTxsRequest, BlockTxsResponse, - DEFAULT_SUB_PROTOCOL_VALIDATORS, type ReqRespInterface, type ReqRespResponse, ReqRespSubProtocol, type ReqRespSubProtocolHandler, type ReqRespSubProtocolHandlers, - type ReqRespSubProtocolValidators, StatusMessage, - type SubProtocolMap, ValidationError, pingHandler, reqGoodbyeHandler, @@ -241,6 +237,7 @@ export class LibP2PService extends WithTracer implements P2PService { maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint, maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint, p2pPropagationTime, + skipSlotValidation: config.skipProposalSlotValidation, signatureContext: { chainId: config.l1ChainId, rollupAddress: config.rollupAddress, @@ -568,16 +565,9 @@ export class LibP2PService extends WithTracer implements P2PService { requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this); } - // Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function - const reqrespSubProtocolValidators = { - ...DEFAULT_SUB_PROTOCOL_VALIDATORS, - [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this), - [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this), - }; - await this.peerManager.initializePeers(); - await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators); + await this.reqresp.start(requestResponseHandlers); await this.node.start(); @@ -669,12 +659,8 @@ export class LibP2PService extends WithTracer implements P2PService { this.logger.info('LibP2P service stopped'); } - addReqRespSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { - return this.reqresp.addSubProtocol(subProtocol, handler, validator); + addReqRespSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise { + return this.reqresp.addSubProtocol(subProtocol, handler); } public registerThisValidatorAddresses(address: EthAddress[]): void { @@ -702,20 +688,6 @@ export class LibP2PService extends WithTracer implements P2PService { setImmediate(() => void safeJob()); } - /** - * Send a batch of requests to peers, and return the responses - * @param protocol - The request response protocol to use - * @param requests - The requests to send to the peers - * @returns The responses to the requests - */ - sendBatchRequest( - protocol: SubProtocol, - requests: InstanceType[], - pinnedPeerId: PeerId | undefined, - ): Promise[]> { - return this.reqresp.sendBatchRequest(protocol, requests, pinnedPeerId); - } - public sendRequestToPeer( peerId: PeerId, subProtocol: ReqRespSubProtocol, @@ -1535,22 +1507,21 @@ export class LibP2PService extends WithTracer implements P2PService { } /** - * Validate the requested block transactions. Allow partial returns. + * Validate the requested block transactions request-response consistency. + * It does NOT validate the transactions themselves. * @param request - The block transactions request. * @param response - The block transactions response. * @param peerId - The ID of the peer that made the request. - * @returns True if the requested block transactions are valid, false otherwise. + * @returns True if the request-response is consistent, false otherwise. */ - @trackSpan('Libp2pService.validateRequestedBlockTxs', request => ({ + @trackSpan('Libp2pService.validateRequestedBlockTxsConsistency', request => ({ [Attributes.BLOCK_ARCHIVE]: request.archiveRoot.toString(), })) - protected async validateRequestedBlockTxs( + protected async validateRequestedBlockTxsConsistency( request: BlockTxsRequest, response: BlockTxsResponse, peerId: PeerId, ): Promise { - const requestedTxValidator = this.createRequestedTxValidator(); - try { if (!response.archiveRoot.equals(request.archiveRoot)) { this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError); @@ -1610,7 +1581,6 @@ export class LibP2PService extends WithTracer implements P2PService { return false; } - await Promise.all(response.txs.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator))); return true; } catch (e: any) { if (e instanceof ValidationError) { @@ -1623,69 +1593,6 @@ export class LibP2PService extends WithTracer implements P2PService { } } - /** - * Validate a collection of txs that has been requested from a peer. - * - * The core component of this validator is that each tx hash MUST match the requested tx hash, - * In order to perform this check, the tx proof must be verified. - * - * Note: This function is called from within `ReqResp.sendRequest` as part of the - * ReqRespSubProtocol.TX subprotocol validation. - * - * @param requestedTxHash - The collection of the txs that was requested. - * @param responseTx - The collection of txs that was received as a response to the request. - * @param peerId - The peer ID of the peer that sent the tx. - * @returns True if the whole collection of txs is valid, false otherwise. - */ - @trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx) => ({ - [Attributes.TX_HASH]: requestedTxHash.toString(), - })) - private async validateRequestedTxs(requestedTxHash: TxHash[], responseTx: Tx[], peerId: PeerId): Promise { - const requested = new Set(requestedTxHash.map(h => h.toString())); - const requestedTxValidator = this.createRequestedTxValidator(); - - //TODO: (mralj) - this is somewhat naive implementation, if single tx is invalid we consider the whole response invalid. - // I think we should still extract the valid txs and return them, so that we can still use the response. - try { - await Promise.all(responseTx.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator, requested))); - return true; - } catch (e: any) { - if (e instanceof ValidationError) { - this.logger.warn(`Failed to validate requested txs from peer ${peerId.toString()}, reason ${e.message}`); - } else { - this.logger.error(`Error during validation of requested txs`, e); - } - - return false; - } - } - - protected async validateRequestedTx( - tx: Tx, - peerId: PeerId, - txValidator: TxValidator, - requested?: Set<`0x${string}`>, - ) { - const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity); - if (requested && !requested.has(tx.getTxHash().toString())) { - penalize(PeerErrorSeverity.MidToleranceError); - throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`); - } - - const { result } = await txValidator.validateTx(tx); - if (result === 'invalid') { - penalize(PeerErrorSeverity.LowToleranceError); - throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`); - } - } - - protected createRequestedTxValidator(): TxValidator { - return createTxValidatorForOnDemandReceivedTxs(this.proofVerifier, { - l1ChainId: this.config.l1ChainId, - rollupVersion: this.config.rollupVersion, - }); - } - private getGasFees(): Promise { return this.blockMinFeesProvider.getCurrentMinFees(); } @@ -1703,6 +1610,7 @@ export class LibP2PService extends WithTracer implements P2PService { proofVerifier: this.proofVerifier, }, peerScoring: this.peerManager, + validateRequestedBlockTxsConsistency: this.validateRequestedBlockTxsConsistency.bind(this), }; } diff --git a/yarn-project/p2p/src/services/reqresp/README.md b/yarn-project/p2p/src/services/reqresp/README.md index 982e00a28e74..fcd67f06899b 100644 --- a/yarn-project/p2p/src/services/reqresp/README.md +++ b/yarn-project/p2p/src/services/reqresp/README.md @@ -46,7 +46,6 @@ Per-protocol size limits checked via preamble before decompression. | Error Type | Severity | |------------|----------| | GOODBYE subprotocol errors | None | -| `CollectiveReqRespTimeoutError` / `InvalidResponseError` | None | | `AbortError` / connection close / muxer closed | None | | `ECONNRESET` / `EPIPE` / `ECONNREFUSED` / `ERR_UNEXPECTED_EOF` | HighToleranceError | | `ERR_UNSUPPORTED_PROTOCOL` | HighToleranceError | @@ -183,19 +182,6 @@ Protected peers (private/trusted/preferred) are always considered "authenticated Conditional registration: BLOCK_TXS handler only registered when `config.disableTransactions` is false. Otherwise peers get `ERR_UNSUPPORTED_PROTOCOL`. -**Requester side via `sendBatchRequest`** (Snappy limit: `max(N, 1) * 512 + 1` KB): - -| Rule | Consequence | File | -|------|-------------|------| -| Archive root must match request | MidToleranceError | `libp2p_service.ts` (`validateRequestedBlockTxs`) | -| BitVector length must match request | MidToleranceError | same | -| No duplicate tx hashes | MidToleranceError | same | -| Tx count within bounds | MidToleranceError | same | -| Local block proposal must exist for archive root | Rejected (no penalty) | same | -| All tx hashes must be in proposal's tx list at allowed indices | LowToleranceError | same | -| Txs in strictly increasing index order | LowToleranceError | same | -| Each tx passes well-formedness (Metadata [4 fields], Size, Data, Proof) | LowToleranceError | same | - **Requester side via `BatchTxRequester`** (separate validation path): | Rule | Consequence | File | diff --git a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.test.ts b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.test.ts index a26e1d79c872..dfbf178e6e78 100644 --- a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.test.ts +++ b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.test.ts @@ -10,7 +10,7 @@ import { sleep } from '@aztec/foundation/sleep'; import { DateProvider } from '@aztec/foundation/timer'; import { type BlockProposal, PeerErrorSeverity } from '@aztec/stdlib/p2p'; import { makeBlockHeader, makeBlockProposal } from '@aztec/stdlib/testing'; -import { Tx, TxArray, TxHash, type TxValidationResult } from '@aztec/stdlib/tx'; +import { Tx, TxArray, TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx'; import { describe, expect, it, jest } from '@jest/globals'; import type { PeerId } from '@libp2p/interface'; @@ -26,16 +26,12 @@ import { BatchTxRequester } from './batch_tx_requester.js'; import { DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD, DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE } from './config.js'; import type { BatchTxRequesterLibP2PService, IPeerPenalizer } from './interface.js'; import { type IPeerCollection, PeerCollection, RATE_LIMIT_EXCEEDED_PEER_CACHE_TTL } from './peer_collection.js'; -import type { IBatchRequestTxValidator } from './tx_validator.js'; /** Mock tx validator for testing that always returns valid */ -class AlwaysValidTxValidator implements IBatchRequestTxValidator { - validateRequestedTx(_tx: Tx): Promise { +class AlwaysValidTxValidator implements TxValidator { + validateTx(_tx: Tx): Promise { return Promise.resolve({ result: 'valid' }); } - validateRequestedTxs(txs: Tx[]): Promise { - return Promise.resolve(txs.map(() => ({ result: 'valid' }))); - } } const TEST_TIMEOUT = 15_000; @@ -49,7 +45,7 @@ describe('BatchTxRequester', () => { let connectionSampler: MockProxy; let reqResp: MockProxy; let mockP2PService: MockProxy; - let txValidator: IBatchRequestTxValidator; + let txValidator: TxValidator; beforeEach(async () => { logger = createLogger('test'); @@ -61,6 +57,7 @@ describe('BatchTxRequester', () => { reqResp, peerScoring, }); + mockP2PService.validateRequestedBlockTxsConsistency.mockResolvedValue(true); txValidator = new AlwaysValidTxValidator(); const signer = Secp256k1Signer.random(); @@ -1190,13 +1187,12 @@ describe('BatchTxRequester', () => { const invalidTxIndices = new Set([2, 3, 7]); // Mark transactions at indices 2, 3, and 7 as invalid - const customValidator: IBatchRequestTxValidator = { - validateRequestedTx: (tx: Tx) => { + const customValidator: TxValidator = { + validateTx: (tx: Tx) => { const txIndex = missing.findIndex(h => h.equals(tx.txHash)); const isInvalid = invalidTxIndices.has(txIndex); return Promise.resolve(isInvalid ? { result: 'invalid', reason: ['test invalid'] } : { result: 'valid' }); }, - validateRequestedTxs: (txs: Tx[]) => Promise.all(txs.map(tx => customValidator.validateRequestedTx(tx))), }; const { mockImplementation } = createRequestLogger(blockProposal, new Set(), peerTransactions); @@ -1270,13 +1266,12 @@ describe('BatchTxRequester', () => { // Validator that rejects transactions at specific indices // Even indices are rejected, odd indices are accepted const invalidTxIndices = new Set([0, 2, 4, 6, 8, 10]); - const mixedValidator: IBatchRequestTxValidator = { - validateRequestedTx: (tx: Tx) => { + const mixedValidator: TxValidator = { + validateTx: (tx: Tx) => { const txIndex = missing.findIndex(h => h.equals(tx.txHash)); const isInvalid = invalidTxIndices.has(txIndex); return Promise.resolve(isInvalid ? { result: 'invalid', reason: ['test invalid'] } : { result: 'valid' }); }, - validateRequestedTxs: (txs: Tx[]) => Promise.all(txs.map(tx => mixedValidator.validateRequestedTx(tx))), }; const { mockImplementation } = createRequestLogger(blockProposal, new Set(), peerTransactions); @@ -1328,8 +1323,8 @@ describe('BatchTxRequester', () => { connectionSampler.getPeerListSortedByConnectionCountAsc.mockReturnValue([peer]); // Validator that throws errors for specific transactions - const throwingValidator: IBatchRequestTxValidator = { - validateRequestedTx: (tx: Tx) => { + const throwingValidator: TxValidator = { + validateTx: (tx: Tx) => { const txIndex = missing.findIndex(h => h.equals(tx.txHash)); // Throw error for transactions at indices 1 and 3 @@ -1344,7 +1339,6 @@ describe('BatchTxRequester', () => { return Promise.resolve({ result: 'valid' }); }, - validateRequestedTxs: (txs: Tx[]) => Promise.all(txs.map(tx => throwingValidator.validateRequestedTx(tx))), }; const peerTransactions = new Map([[peer.toString(), Array.from({ length: txCount }, (_, i) => i)]]); @@ -1697,13 +1691,12 @@ describe('BatchTxRequester', () => { const invalidTxIndices = new Set([1, 6]); // Mark some transactions as invalid - const customValidator: IBatchRequestTxValidator = { - validateRequestedTx: (tx: Tx) => { + const customValidator: TxValidator = { + validateTx: (tx: Tx) => { const txIndex = missing.findIndex(h => h.equals(tx.txHash)); const isInvalid = invalidTxIndices.has(txIndex); return Promise.resolve(isInvalid ? { result: 'invalid', reason: ['test invalid'] } : { result: 'valid' }); }, - validateRequestedTxs: (txs: Tx[]) => Promise.all(txs.map(tx => customValidator.validateRequestedTx(tx))), }; const { mockImplementation } = createRequestLogger(blockProposal, new Set(), peerTransactions); @@ -2019,6 +2012,82 @@ describe('BatchTxRequester', () => { expect(peer0Penalties.length).toBeGreaterThan(0); }); }); + + describe('Response consistency validation', () => { + it('marks peer dumb (without penalising) when validateRequestedBlockTxsConsistency rejects the response', async () => { + const txCount = TX_BATCH_SIZE; + const deadline = 5_000; + const missing = Array.from({ length: txCount }, () => TxHash.random()); + + blockProposal = await makeBlockProposal({ + signer: Secp256k1Signer.random(), + blockHeader: makeBlockHeader(1, { blockNumber: BlockNumber(1) }), + archiveRoot: Fr.random(), + txHashes: missing, + }); + + const peers = await Promise.all([createSecp256k1PeerId(), createSecp256k1PeerId()]); + connectionSampler.getPeerListSortedByConnectionCountAsc.mockReturnValue(peers); + + const peerCollection = new TestPeerCollection( + new PeerCollection(connectionSampler, undefined, new DateProvider()), + ); + + // peer0's responses are rejected by consistency validation; peer1's responses pass. + const consistencyCallPeerIds: string[] = []; + mockP2PService.validateRequestedBlockTxsConsistency.mockImplementation((_req, _resp, peerId) => { + consistencyCallPeerIds.push(peerId.toString()); + return Promise.resolve(peerId.toString() !== peers[0].toString()); + }); + + // Both peers return well-formed responses with the requested txs; + // the consistency mock is what decides whether the response is accepted. + reqResp.sendRequestToPeer.mockImplementation((_peerId: any, _sub: any, data: any) => { + const request = BlockTxsRequest.fromBuffer(data); + const requestedIndices = request.txIndices.getTrueIndices(); + const availableTxs = requestedIndices.map(idx => makeTx(blockProposal.txHashes[idx])); + + return Promise.resolve({ + status: ReqRespStatus.SUCCESS, + data: new BlockTxsResponse( + blockProposal.archive, + new TxArray(...availableTxs), + BitVector.init(txCount, requestedIndices), + ).toBuffer(), + }); + }); + + const requester = new BatchTxRequester( + RequestTracker.create(missing, new Date(Date.now() + deadline)), + blockProposal, + undefined, + mockP2PService, + logger, + new DateProvider(), + { + smartParallelWorkerCount: 0, + dumbParallelWorkerCount: 2, + peerCollection, + txValidator, + }, + ); + + const results = await BatchTxRequester.collectAllTxs(requester.run()); + + // All txs eventually fetched (via peer1). + expect(results).toHaveLength(txCount); + + // Consistency validation was invoked for peer0's response. + expect(consistencyCallPeerIds).toContain(peers[0].toString()); + + // peer0 marked dumb (INTERNAL_ERROR path in handleFailResponseFromPeer)… + expect(peerCollection.peersMarkedDumb).toContain(peers[0].toString()); + + // …but NOT penalised — failed consistency yields INTERNAL_ERROR, not a penalty cause. + const peer0Penalties = peerCollection.peersPenalised.filter(e => e.peerId === peers[0].toString()); + expect(peer0Penalties).toHaveLength(0); + }); + }); }); describe('PeerCollection - Dynamic peer list', () => { diff --git a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts index 77c7f99e2c81..0da0d14b58db 100644 --- a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +++ b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts @@ -4,7 +4,7 @@ import { FifoMemoryQueue, type ISemaphore, Semaphore } from '@aztec/foundation/q import { sleep } from '@aztec/foundation/sleep'; import { DateProvider } from '@aztec/foundation/timer'; import { PeerErrorSeverity } from '@aztec/stdlib/p2p'; -import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx'; +import { Tx, TxArray, TxHash, type TxValidator } from '@aztec/stdlib/tx'; import type { PeerId } from '@libp2p/interface'; @@ -21,7 +21,7 @@ import { import type { BatchTxRequesterLibP2PService, BatchTxRequesterOptions, ITxMetadataCollection } from './interface.js'; import { MissingTxMetadataCollection } from './missing_txs.js'; import { type IPeerCollection, PeerCollection } from './peer_collection.js'; -import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_validator.js'; +import { createBatchRequestTxValidator } from './tx_validator.js'; /* * Tries to fetch all missing transaction until deadline is hit. @@ -51,7 +51,7 @@ export class BatchTxRequester { private readonly txsMetadata: ITxMetadataCollection; private readonly smartRequesterSemaphore: ISemaphore; private readonly txQueue: FifoMemoryQueue; - private readonly txValidator: IBatchRequestTxValidator; + private readonly txValidator: TxValidator; private readonly smartParallelWorkerCount: number; private readonly dumbParallelWorkerCount: number; private readonly txBatchSize: number; @@ -78,7 +78,7 @@ export class BatchTxRequester { this.opts.dumbParallelWorkerCount ?? DEFAULT_BATCH_TX_REQUESTER_DUMB_PARALLEL_WORKER_COUNT; this.txBatchSize = this.opts.txBatchSize ?? DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE; this.txQueue = new FifoMemoryQueue(this.logger); - this.txValidator = this.opts.txValidator ?? new BatchRequestTxValidator(this.p2pService.txValidatorConfig); + this.txValidator = this.opts.txValidator ?? createBatchRequestTxValidator(this.p2pService.txValidatorConfig); if (this.opts.peerCollection) { this.peers = this.opts.peerCollection; @@ -428,6 +428,15 @@ export class BatchTxRequester { } const blockResponse = BlockTxsResponse.fromBuffer(response.data); + + // Validate response. Peers will be penalised by the validator if they send invalid response. + const isValid = await this.p2pService.validateRequestedBlockTxsConsistency(request, blockResponse, peerId); + if (!isValid) { + this.logger.debug(`Peer ${peerId.toString()} sent invalid response`); + this.handleFailResponseFromPeer(peerId, ReqRespStatus.INTERNAL_ERROR); + return; + } + await this.handleSuccessResponseFromPeer(peerId, blockResponse); } catch (err: any) { this.logger.error(`Failed to get valid response from peer ${peerId.toString()}: ${err.message}`, { @@ -445,6 +454,7 @@ export class BatchTxRequester { * Handles failed response form the peer * There are 3 scenarios * - RATE_LIMIT_EXCEEDED: We mark this and don't query this peer again for some_time + * - INTERNAL_ERROR: We use this to cover cases where the request-response consistency validation fails. * - FAILURE and UNKNOWN: We penalise this, if peer has been penalised this way N times they are not queried again * this implies we will query these peers couple of more times and give them a chance to "redeem" themselves before completely ignoring them */ @@ -458,7 +468,8 @@ export class BatchTxRequester { // NOT_FOUND means the peer pruned its block proposal — it can no longer serve // index-based requests, but this is a legitimate state so we don't penalize. - if (responseStatus === ReqRespStatus.NOT_FOUND) { + // We use INTERNAL_ERROR to cover cases where the request-response consistency validation fails. + if (responseStatus === ReqRespStatus.NOT_FOUND || responseStatus === ReqRespStatus.INTERNAL_ERROR) { this.peers.markPeerDumb(peerId); this.txsMetadata.clearPeerData(peerId); return; @@ -485,7 +496,7 @@ export class BatchTxRequester { * Handles received txs. * Transactions are validated and then put on async queue * to be yielded by main running loop - * */ + */ private async handleReceivedTxs(peerId: PeerId, txs: TxArray) { const newTxs = txs.filter(tx => !this.txsMetadata.alreadyFetched(tx.txHash)); @@ -493,12 +504,12 @@ export class BatchTxRequester { return; } - //TODO: this validation can be slow, maybe spawn worker just for validation + // TODO: this validation can be slow, maybe spawn worker just for validation // We could use the async queue for communication. const validationResults = await Promise.allSettled( newTxs.map(async tx => ({ tx, - isValid: (await this.txValidator.validateRequestedTx(tx)).result === 'valid', + isValid: (await this.txValidator.validateTx(tx)).result === 'valid', })), ); diff --git a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/interface.ts b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/interface.ts index f7b503c9dae9..13304adf7cd4 100644 --- a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/interface.ts +++ b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/interface.ts @@ -1,13 +1,14 @@ import type { ISemaphore } from '@aztec/foundation/queue'; import type { PeerErrorSeverity } from '@aztec/stdlib/p2p'; -import type { Tx, TxHash } from '@aztec/stdlib/tx'; +import type { Tx, TxHash, TxValidator } from '@aztec/stdlib/tx'; import type { PeerId } from '@libp2p/interface'; import type { ConnectionSampler } from '../connection-sampler/connection_sampler.js'; +import type { BlockTxsRequest, BlockTxsResponse } from '../index.js'; import type { ReqRespInterface } from '../interface.js'; import type { IPeerCollection } from './peer_collection.js'; -import type { BatchRequestTxValidatorConfig, IBatchRequestTxValidator } from './tx_validator.js'; +import type { BatchRequestTxValidatorConfig } from './tx_validator.js'; export interface IPeerPenalizer { penalizePeer(peerId: PeerId, penalty: PeerErrorSeverity): void; @@ -39,6 +40,12 @@ export interface BatchTxRequesterLibP2PService { txValidatorConfig: BatchRequestTxValidatorConfig; /** Peer scoring for penalizing peers */ peerScoring: IPeerPenalizer; + /** Validate the requested block transactions request-response consistency */ + validateRequestedBlockTxsConsistency: ( + request: BlockTxsRequest, + response: BlockTxsResponse, + peerId: PeerId, + ) => Promise; } export interface BatchTxRequesterOptions { @@ -50,5 +57,5 @@ export interface BatchTxRequesterOptions { semaphore?: ISemaphore; peerCollection?: IPeerCollection; /** Optional tx validator for testing - if not provided, one is created from p2pService.txValidatorConfig */ - txValidator?: IBatchRequestTxValidator; + txValidator?: TxValidator; } diff --git a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/tx_validator.ts b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/tx_validator.ts index db15fda34e01..dd8015a76a8a 100644 --- a/yarn-project/p2p/src/services/reqresp/batch-tx-requester/tx_validator.ts +++ b/yarn-project/p2p/src/services/reqresp/batch-tx-requester/tx_validator.ts @@ -1,5 +1,5 @@ import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server'; -import { Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx'; +import type { TxValidator } from '@aztec/stdlib/tx'; import { createTxValidatorForOnDemandReceivedTxs } from '../../../msg_validators/index.js'; @@ -9,29 +9,9 @@ export interface BatchRequestTxValidatorConfig { proofVerifier: ClientProtocolCircuitVerifier; } -export interface IBatchRequestTxValidator { - validateRequestedTx(tx: Tx): Promise; - validateRequestedTxs(txs: Tx[]): Promise; -} - -export class BatchRequestTxValidator implements IBatchRequestTxValidator { - readonly txValidator: TxValidator; - constructor(private readonly config: BatchRequestTxValidatorConfig) { - this.txValidator = BatchRequestTxValidator.createRequestedTxValidator(this.config); - } - - public async validateRequestedTx(tx: Tx): Promise { - return await this.txValidator.validateTx(tx); - } - - public async validateRequestedTxs(txs: Tx[]): Promise { - return await Promise.all(txs.map(tx => this.validateRequestedTx(tx))); - } - - static createRequestedTxValidator(config: BatchRequestTxValidatorConfig): TxValidator { - return createTxValidatorForOnDemandReceivedTxs(config.proofVerifier, { - l1ChainId: config.l1ChainId, - rollupVersion: config.rollupVersion, - }); - } +export function createBatchRequestTxValidator(config: BatchRequestTxValidatorConfig): TxValidator { + return createTxValidatorForOnDemandReceivedTxs(config.proofVerifier, { + l1ChainId: config.l1ChainId, + rollupVersion: config.rollupVersion, + }); } diff --git a/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.test.ts b/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.test.ts deleted file mode 100644 index 9432ac297e22..000000000000 --- a/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.test.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { describe, expect, it, jest } from '@jest/globals'; -import { createSecp256k1PeerId } from '@libp2p/peer-id-factory'; -import type { Libp2p } from 'libp2p'; - -import { BatchConnectionSampler } from './batch_connection_sampler.js'; -import { ConnectionSampler, type RandomSampler } from './connection_sampler.js'; - -describe('BatchConnectionSampler', () => { - const mockRandomSampler = { - random: jest.fn(), - } as jest.Mocked; - - let peers: Awaited>[]; - let libp2p: jest.Mocked; - let connectionSampler: ConnectionSampler; - - beforeEach(async () => { - jest.clearAllMocks(); - - // Create a set of test peers - peers = await Promise.all(new Array(5).fill(0).map(() => createSecp256k1PeerId())); - - // Mock libp2p to return our test peers - libp2p = { - getPeers: jest.fn().mockImplementation(() => [...peers]), - } as unknown as jest.Mocked; - - // Create a real connection sampler with mocked random sampling - connectionSampler = new ConnectionSampler(libp2p, mockRandomSampler, undefined, { cleanupIntervalMs: 1000 }); - }); - - afterEach(async () => { - await connectionSampler.stop(); - }); - - it('initializes with correct number of peers and request distribution', () => { - // Mock random to return sequential indices - mockRandomSampler.random.mockImplementation(_ => 0); - - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 10, /* maxPeers */ 3); - - expect(sampler.activePeerCount).toBe(3); - expect(sampler.requestsPerBucket).toBe(3); // floor(10/3) = 3 - }); - - it('assigns requests to peers deterministically with wraparound', () => { - // Mock to return first two peers - mockRandomSampler.random.mockImplementation(() => 0); - - // With 5 requests and 2 peers: - // floor(5/2) = 2 requests per peer - // Peer 0: 0,1,4 (gets extra from wraparound) - // Peer 1: 2,3 - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 5, /* maxPeers */ 2); - const assignments = new Array(5).fill(0).map((_, i) => sampler.getPeerForRequest(i)); - - // First peer gets first bucket and wraparound - expect(assignments[0]).toBe(peers[0]); // First bucket - expect(assignments[1]).toBe(peers[0]); // First bucket - expect(assignments[4]).toBe(peers[0]); // Wraparound - - // Second peer gets middle bucket - expect(assignments[2]).toBe(peers[1]); - expect(assignments[3]).toBe(peers[1]); - }); - - it('handles peer removal and replacement', () => { - mockRandomSampler.random.mockImplementation(_ => 0); - - // With 4 requests and 2 peers: - // floor(4/2) = 2 requests per peer - // Initial distribution: - // Peer 0: 0,1 - // Peer 1: 2,3 - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - - const initialPeer = sampler.getPeerForRequest(0); - expect(initialPeer).toBe(peers[0]); - - // Mock random to return the third peer - mockRandomSampler.random.mockImplementation(_ => 2); - sampler.removePeerAndReplace(peers[0]); - - // After replacement: - // Replacement peer should handle the same bucket - const newPeer = sampler.getPeerForRequest(0); - expect(newPeer).toBe(peers[2]); - expect(sampler.getPeerForRequest(1)).toBe(peers[2]); - - // Other peer's bucket remains unchanged - expect(sampler.getPeerForRequest(2)).toBe(peers[1]); - expect(sampler.getPeerForRequest(3)).toBe(peers[1]); - }); - - it('handles peer removal and replacement - no replacement available', () => { - mockRandomSampler.random.mockImplementation(() => 0); - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - - expect(sampler.activePeerCount).toBe(2); - expect(sampler.getPeerForRequest(0)).toBe(peers[0]); - - // Will sample no peers - libp2p.getPeers.mockReturnValue([]); - - // Remove peer 0, its requests will be distributed to peer 1 - sampler.removePeerAndReplace(peers[0]); - // Decrease the number of active peers - expect(sampler.activePeerCount).toBe(1); - - expect(sampler.getPeerForRequest(0)).toBe(peers[1]); - }); - - it('distributes requests according to documentation example', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // Example from doc comment: - // Peers: [P1] [P2] [P3] - // Requests: 0,1,2,9 | 3,4,5 | 6,7,8 - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 10, /* maxPeers */ 3); - - expect(sampler.activePeerCount).toBe(3); - expect(sampler.requestsPerBucket).toBe(3); // floor(10/3) = 3 - - // P1's bucket (0-2) plus wraparound (9) - expect(sampler.getPeerForRequest(0)).toBe(peers[0]); - expect(sampler.getPeerForRequest(1)).toBe(peers[0]); - expect(sampler.getPeerForRequest(2)).toBe(peers[0]); - expect(sampler.getPeerForRequest(9)).toBe(peers[0]); // Wraparound - - // P2's bucket (3-5) - expect(sampler.getPeerForRequest(3)).toBe(peers[1]); - expect(sampler.getPeerForRequest(4)).toBe(peers[1]); - expect(sampler.getPeerForRequest(5)).toBe(peers[1]); - - // P3's bucket (6-8) - expect(sampler.getPeerForRequest(6)).toBe(peers[2]); - expect(sampler.getPeerForRequest(7)).toBe(peers[2]); - expect(sampler.getPeerForRequest(8)).toBe(peers[2]); - }); - - it('same number of requests per peers', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 2, /* maxPeers */ 2); - expect(sampler.requestsPerBucket).toBe(1); - expect(sampler.activePeerCount).toBe(2); - - expect(sampler.getPeerForRequest(0)).toBe(peers[0]); - expect(sampler.getPeerForRequest(1)).toBe(peers[1]); - }); - - it('handles edge cases, 0 peers, smaller batch than max peers', () => { - mockRandomSampler.random.mockImplementation(() => 0); - libp2p.getPeers.mockReturnValue([]); - - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 5, /* maxPeers */ 2); - expect(sampler.activePeerCount).toBe(0); - expect(sampler.getPeerForRequest(0)).toBeUndefined(); - - mockRandomSampler.random.mockImplementation(() => 0); - - libp2p.getPeers.mockImplementation(() => [...peers]); - const samplerWithMorePeers = new BatchConnectionSampler(connectionSampler, /* batchSize */ 2, /* maxPeers */ 3); - expect(samplerWithMorePeers.requestsPerBucket).toBe(1); // floor(2/3) = 0 - // First two requests go to first two peers - expect(samplerWithMorePeers.getPeerForRequest(0)).toBe(peers[0]); - expect(samplerWithMorePeers.getPeerForRequest(1)).toBe(peers[1]); - }); - - it('skips failed peer-index combinations and tries next peer', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // 6 requests across 3 peers (2 per peer) - // Peer 0: 0,1 Peer 1: 2,3 Peer 2: 4,5 - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 6, /* maxPeers */ 3); - - // Initially, request 0 goes to peer 0 - expect(sampler.getPeerForRequest(0)).toBe(peers[0]); - - // Mark peer 0 as failed for index 0 - sampler.markPeerFailedForIndex(peers[0], 0); - - // Now request 0 should go to the next peer (peer 1) - expect(sampler.getPeerForRequest(0)).toBe(peers[1]); - - // Mark peer 1 as also failed for index 0 - sampler.markPeerFailedForIndex(peers[1], 0); - - // Now request 0 should go to peer 2 - expect(sampler.getPeerForRequest(0)).toBe(peers[2]); - - // Request 1 should still go to peer 0 (only index 0 was failed) - expect(sampler.getPeerForRequest(1)).toBe(peers[0]); - }); - - it('samples new peer when all batch peers have failed for an index', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // 4 requests across 2 peers (peers[0] and peers[1]) - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - expect(sampler.activePeerCount).toBe(2); - - // Mark both batch peers as failed for index 0 - sampler.markPeerFailedForIndex(peers[0], 0); - sampler.markPeerFailedForIndex(peers[1], 0); - - // Should sample a new peer (peers[2]) and return it - mockRandomSampler.random.mockImplementation(() => 2); - expect(sampler.getPeerForRequest(0)).toBe(peers[2]); - expect(sampler.activePeerCount).toBe(3); // New peer was added to batch - - // Other indices still work with original peers - expect(sampler.getPeerForRequest(1)).toBe(peers[0]); - expect(sampler.getPeerForRequest(2)).toBe(peers[1]); - }); - - it('returns undefined when all peers exhausted and no new peers available', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // 4 requests across 2 peers - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - - // Mark both peers as failed for index 0 - sampler.markPeerFailedForIndex(peers[0], 0); - sampler.markPeerFailedForIndex(peers[1], 0); - - // No more peers available to sample - libp2p.getPeers.mockReturnValue([peers[0], peers[1]]); // Only return already-used peers - - // No peer available for index 0 - expect(sampler.getPeerForRequest(0)).toBeUndefined(); - }); - - it('failed peer-index tracking survives peer replacement', () => { - mockRandomSampler.random.mockImplementation(() => 0); - - // 4 requests across 2 peers - const sampler = new BatchConnectionSampler(connectionSampler, /* batchSize */ 4, /* maxPeers */ 2); - - // Mark peer 0 as failed for index 0 - sampler.markPeerFailedForIndex(peers[0], 0); - - // Request 0 now goes to peer 1 - expect(sampler.getPeerForRequest(0)).toBe(peers[1]); - - // Replace peer 0 with peer 2 - mockRandomSampler.random.mockImplementation(() => 2); - sampler.removePeerAndReplace(peers[0]); - - // Request 0 should still go to peer 1 (the replacement peer 2 is now in slot 0, - // but peer 0's failure record should not affect the new peer) - // Actually, the failure is tracked by peer ID, so peer 2 is a fresh peer - // Request 0's primary is now peer 2 (in slot 0), which hasn't failed - expect(sampler.getPeerForRequest(0)).toBe(peers[2]); - }); -}); diff --git a/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.ts b/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.ts deleted file mode 100644 index 42424551e696..000000000000 --- a/yarn-project/p2p/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { createLogger } from '@aztec/foundation/log'; - -import type { PeerId } from '@libp2p/interface'; - -import type { ConnectionSampler } from './connection_sampler.js'; - -/** - * Manages batches of peers for parallel request processing. - * Tracks active peers and provides deterministic peer assignment for requests. - * - * Example with 3 peers and 10 requests: - * - * Peers: [P1] [P2] [P3] - * ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ - * Requests: 0,1,2,9 | 3,4,5 | 6,7,8 - * - * Each peer handles a bucket of consecutive requests. - * If a peer fails, it is replaced while maintaining the same bucket. - */ -export class BatchConnectionSampler { - private readonly batch: PeerId[] = []; - private readonly requestsPerPeer: number; - /** Tracks peer-index combinations that returned empty/invalid responses */ - private readonly failedPeerIndices: Map> = new Map(); - - constructor( - private readonly connectionSampler: ConnectionSampler, - batchSize: number, - maxPeers: number, - exclude?: PeerId[], - private readonly logger = createLogger('p2p:reqresp:batch-connection-sampler'), - ) { - if (maxPeers <= 0) { - throw new Error('Max peers cannot be 0'); - } - if (batchSize <= 0) { - throw new Error('Batch size cannot be 0'); - } - - // Calculate how many requests each peer should handle, cannot be 0 - this.requestsPerPeer = Math.max(1, Math.floor(batchSize / maxPeers)); - - // Sample initial peers - const excluding = exclude && new Map(exclude.map(peerId => [peerId.toString(), true] as const)); - this.batch = this.connectionSampler.samplePeersBatch(maxPeers, excluding); - } - - /** - * Gets the peer responsible for handling a specific request index. - * If the primary peer has previously failed for this index, tries other peers. - * If all batch peers have failed, attempts to sample a new peer. - * - * @param index - The request index - * @returns The peer assigned to handle this request, or undefined if no peer available - */ - getPeerForRequest(index: number): PeerId | undefined { - if (this.batch.length === 0) { - return undefined; - } - - // Calculate which peer bucket this index belongs to - const primaryPeerIndex = Math.floor(index / this.requestsPerPeer) % this.batch.length; - - // Try peers starting from primary, wrapping around - for (let offset = 0; offset < this.batch.length; offset++) { - const peerIndex = (primaryPeerIndex + offset) % this.batch.length; - const peer = this.batch[peerIndex]; - const peerKey = peer.toString(); - - const failedIndices = this.failedPeerIndices.get(peerKey); - if (!failedIndices || !failedIndices.has(index)) { - return peer; - } - } - - // All batch peers have failed for this index - try to sample a new peer - const newPeer = this.sampleNewPeer(); - if (newPeer) { - return newPeer; - } - - return undefined; - } - - /** - * Attempts to sample a new peer that isn't already in the batch. - * If successful, adds the peer to the batch. - * - * @returns The new peer if one was sampled, undefined otherwise - */ - private sampleNewPeer(): PeerId | undefined { - // Exclude all current batch peers - const excluding = new Map(this.batch.map(p => [p.toString(), true] as const)); - const newPeer = this.connectionSampler.getPeer(excluding); - - if (newPeer) { - this.batch.push(newPeer); - this.logger.trace('Sampled new peer for exhausted index', { newPeer: newPeer.toString() }); - return newPeer; - } - - return undefined; - } - - /** - * Marks that a peer returned an empty/invalid response for a specific request index. - * The peer will not be assigned this index again. - * - * @param peerId - The peer that failed - * @param index - The request index that failed - */ - markPeerFailedForIndex(peerId: PeerId, index: number): void { - const peerKey = peerId.toString(); - let failedIndices = this.failedPeerIndices.get(peerKey); - if (!failedIndices) { - failedIndices = new Set(); - this.failedPeerIndices.set(peerKey, failedIndices); - } - failedIndices.add(index); - this.logger.trace('Marked peer failed for index', { peerId: peerKey, index }); - } - - /** - * Removes a peer and replaces it with a new one, maintaining the same position - * in the batch array to keep request distribution consistent - * - * @param peerId - The peer to remove and replace - */ - removePeerAndReplace(peerId: PeerId): void { - const index = this.batch.findIndex(p => p === peerId); - if (index === -1) { - return; - } - - const excluding = new Map([[peerId.toString(), true]]); - const newPeer = this.connectionSampler.getPeer(excluding); // Q: Shouldn't we accumulate all excluded peers? Otherwise the sampler could return us a previously excluded peer? - - if (newPeer) { - this.batch[index] = newPeer; - this.logger.trace('Replaced peer', { peerId, newPeer }); - } else { - // If we couldn't get a replacement, remove the peer and compact the array - this.batch.splice(index, 1); - this.logger.trace('Removed peer', { peerId }); - } - } - - /** - * Gets the number of active peers - */ - get activePeerCount(): number { - return this.batch.length; - } - - /** - * Gets the number of requests each peer is assigned to handle - */ - get requestsPerBucket(): number { - return this.requestsPerPeer; - } -} diff --git a/yarn-project/p2p/src/services/reqresp/interface.ts b/yarn-project/p2p/src/services/reqresp/interface.ts index 016525a98919..bcdc58e37a43 100644 --- a/yarn-project/p2p/src/services/reqresp/interface.ts +++ b/yarn-project/p2p/src/services/reqresp/interface.ts @@ -78,23 +78,11 @@ export interface ProtocolRateLimitQuota { globalLimit: RateLimitQuota; } -export const noopValidator = () => Promise.resolve(true); - /** * A type mapping from supprotocol to it's handling function */ export type ReqRespSubProtocolHandlers = Record; -type ResponseValidator = ( - request: RequestIdentifier, - response: Response, - peerId: PeerId, -) => Promise; - -export type ReqRespSubProtocolValidators = { - [S in ReqRespSubProtocol]: ResponseValidator; -}; - /** * Protocols that are always allowed without authentication, even when p2pAllowOnlyValidators is enabled. * These are needed for the handshake and connection management flow. @@ -113,15 +101,6 @@ export const UNAUTHENTICATED_ALLOWED_PROTOCOLS: ReadonlySet */ export type ShouldRejectPeer = (peerId: string) => boolean; -export const DEFAULT_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = { - [ReqRespSubProtocol.PING]: noopValidator, - [ReqRespSubProtocol.STATUS]: noopValidator, - [ReqRespSubProtocol.TX]: noopValidator, - [ReqRespSubProtocol.GOODBYE]: noopValidator, - [ReqRespSubProtocol.AUTH]: noopValidator, - [ReqRespSubProtocol.BLOCK_TXS]: noopValidator, -}; - /* * Helper class to sub-protocol validation error*/ export class ValidationError extends Error { @@ -244,24 +223,9 @@ export const subProtocolSizeCalculators: Record, - subProtocolValidators: ReqRespSubProtocolValidators, - ): Promise; - addSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise; + start(subProtocolHandlers: Partial): Promise; + addSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise; stop(): Promise; - sendBatchRequest( - subProtocol: SubProtocol, - requests: InstanceType[], - pinnedPeer: PeerId | undefined, - timeoutMs?: number, - maxPeers?: number, - maxRetryAttempts?: number, - ): Promise[]>; sendRequestToPeer( peerId: PeerId, subProtocol: ReqRespSubProtocol, diff --git a/yarn-project/p2p/src/services/reqresp/reqresp.test.ts b/yarn-project/p2p/src/services/reqresp/reqresp.test.ts index 2ddf4d9a2cbe..e72926f21c31 100644 --- a/yarn-project/p2p/src/services/reqresp/reqresp.test.ts +++ b/yarn-project/p2p/src/services/reqresp/reqresp.test.ts @@ -1,4 +1,3 @@ -import { times } from '@aztec/foundation/collection'; import { sleep } from '@aztec/foundation/sleep'; import { PeerErrorSeverity } from '@aztec/stdlib/p2p'; import { mockTx } from '@aztec/stdlib/testing'; @@ -18,7 +17,7 @@ import { } from '../../test-helpers/reqresp-nodes.js'; import type { PeerManager } from '../peer-manager/peer_manager.js'; import type { PeerScoring } from '../peer-manager/peer_scoring.js'; -import { type ReqRespResponse, ReqRespSubProtocol, RequestableBuffer } from './interface.js'; +import { type ReqRespResponse, ReqRespSubProtocol } from './interface.js'; import { GoodByeReason, reqGoodbyeHandler } from './protocols/goodbye.js'; import { ReqRespStatus } from './status.js'; @@ -465,133 +464,6 @@ describe('ReqResp', () => { expectSuccess(txResp); }); }); - - describe('Batch requests', () => { - it('should send a batch request between many peers', async () => { - const batchSize = 9; - nodes = await createNodes(peerScoring, 3); - - await startNodes(nodes); - await sleep(500); - await connectToPeers(nodes); - await sleep(500); - - const sendRequestToPeerSpy = jest.spyOn(nodes[0].req, 'sendRequestToPeer'); - - const requests = Array.from({ length: batchSize }, _ => RequestableBuffer.fromBuffer(Buffer.from(`ping`))); - const expectResponses = Array.from({ length: batchSize }, _ => RequestableBuffer.fromBuffer(Buffer.from(`pong`))); - - const res = await nodes[0].req.sendBatchRequest(ReqRespSubProtocol.PING, requests, undefined); - expect(res).toEqual(expectResponses); - - // Expect one request to have been sent to each peer - expect(sendRequestToPeerSpy).toHaveBeenCalledTimes(batchSize); - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ - publicKey: nodes[1].p2p.peerId.publicKey, - }), - ReqRespSubProtocol.PING, - Buffer.from('ping'), - ); - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ - publicKey: nodes[2].p2p.peerId.publicKey, - }), - ReqRespSubProtocol.PING, - Buffer.from('ping'), - ); - }); - - it('should send a batch request with a pinned peer', async () => { - const batchSize = 9; - nodes = await createNodes(peerScoring, 4, { - // Bump rate limits so the pinned peer can respond - [ReqRespSubProtocol.PING]: { - peerLimit: { quotaTimeMs: 1000, quotaCount: 50 }, - globalLimit: { quotaTimeMs: 1000, quotaCount: 50 }, - }, - }); - - await startNodes(nodes); - await sleep(500); - await connectToPeers(nodes); - await sleep(500); - - const sendRequestToPeerSpy = jest.spyOn(nodes[0].req, 'sendRequestToPeer'); - - const requests = times(batchSize, i => RequestableBuffer.fromBuffer(Buffer.from(`ping${i}`))); - const expectResponses = times(batchSize, _ => RequestableBuffer.fromBuffer(Buffer.from(`pong`))); - - const res = await nodes[0].req.sendBatchRequest(ReqRespSubProtocol.PING, requests, nodes[1].p2p.peerId); - expect(res).toEqual(expectResponses); - - // Expect pinned peer to have received all requests - for (let i = 0; i < batchSize; i++) { - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ publicKey: nodes[1].p2p.peerId.publicKey }), - ReqRespSubProtocol.PING, - Buffer.from(`ping${i}`), - ); - } - - // Expect at least one request to have been sent to each other peer - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ publicKey: nodes[2].p2p.peerId.publicKey }), - ReqRespSubProtocol.PING, - expect.any(Buffer), - ); - - expect(sendRequestToPeerSpy).toHaveBeenCalledWith( - expect.objectContaining({ publicKey: nodes[3].p2p.peerId.publicKey }), - ReqRespSubProtocol.PING, - expect.any(Buffer), - ); - }); - - it('should stop after max retry attempts', async () => { - const batchSize = 12; - const failedIndices = [10, 11]; - nodes = await createNodes(peerScoring, 3); - - await startNodes(nodes); - await sleep(500); - await connectToPeers(nodes); - await sleep(500); - - const requests = Array.from({ length: batchSize }, (_, i) => - RequestableBuffer.fromBuffer(Buffer.from(`ping${i}`)), - ); - - // Mock sendRequestToPeer so that specific requests always fail with RATE_LIMIT_EXCEEDED, - // regardless of which peer they're sent to. This removes the timing dependency on the - // GCRA rate limiter leaking tokens between retries. - const originalSend = nodes[0].req.sendRequestToPeer.bind(nodes[0].req); - const sendSpy = jest - .spyOn(nodes[0].req, 'sendRequestToPeer') - .mockImplementation((peer: PeerId, protocol: ReqRespSubProtocol, buffer: Buffer) => { - const msg = buffer.toString(); - if (failedIndices.some(i => msg === `ping${i}`)) { - return Promise.resolve({ status: ReqRespStatus.RATE_LIMIT_EXCEEDED, data: Buffer.alloc(0) }); - } - return originalSend(peer, protocol, buffer); - }); - - const res = await nodes[0].req.sendBatchRequest(ReqRespSubProtocol.PING, requests, undefined); - - // 10 succeed, 2 permanently fail after all retry attempts are exhausted - const successes = res.filter(r => r !== undefined); - expect(successes).toHaveLength(batchSize - failedIndices.length); - expect(successes).toEqual( - times(batchSize - failedIndices.length, () => RequestableBuffer.fromBuffer(Buffer.from(`pong`))), - ); - - // Verify retries actually happened — those 2 requests were attempted more than once - const failedCalls = sendSpy.mock.calls.filter(([, , buf]) => - failedIndices.some(i => (buf as Buffer).toString() === `ping${i}`), - ); - expect(failedCalls.length).toBeGreaterThan(failedIndices.length); - }); - }); }); function expectSuccess(res: ReqRespResponse): asserts res is { status: ReqRespStatus.SUCCESS; data: Buffer } { diff --git a/yarn-project/p2p/src/services/reqresp/reqresp.ts b/yarn-project/p2p/src/services/reqresp/reqresp.ts index ba3fe8e518f5..efeb51d82a1f 100644 --- a/yarn-project/p2p/src/services/reqresp/reqresp.ts +++ b/yarn-project/p2p/src/services/reqresp/reqresp.ts @@ -1,5 +1,4 @@ // @attribution: lodestar impl for inspiration -import { compactArray } from '@aztec/foundation/collection'; import { AbortError, TimeoutError } from '@aztec/foundation/error'; import { createLogger } from '@aztec/foundation/log'; import { executeTimeout } from '@aztec/foundation/timer'; @@ -11,11 +10,7 @@ import type { Libp2p } from 'libp2p'; import { pipeline } from 'node:stream/promises'; import type { Uint8ArrayList } from 'uint8arraylist'; -import { - CollectiveReqRespTimeoutError, - IndividualReqRespTimeoutError, - InvalidResponseError, -} from '../../errors/reqresp.error.js'; +import { IndividualReqRespTimeoutError } from '../../errors/reqresp.error.js'; import { OversizedSnappyResponseError, SnappyTransform } from '../encoding.js'; import type { PeerScoring } from '../peer-manager/peer_scoring.js'; import { @@ -23,21 +18,16 @@ import { DEFAULT_REQRESP_DIAL_TIMEOUT_MS, type P2PReqRespConfig, } from './config.js'; -import { BatchConnectionSampler } from './connection-sampler/batch_connection_sampler.js'; import { ConnectionSampler, RandomSampler } from './connection-sampler/connection_sampler.js'; import { - DEFAULT_SUB_PROTOCOL_VALIDATORS, type ReqRespInterface, type ReqRespResponse, ReqRespSubProtocol, type ReqRespSubProtocolHandler, type ReqRespSubProtocolHandlers, type ReqRespSubProtocolRateLimits, - type ReqRespSubProtocolValidators, type ShouldRejectPeer, - type SubProtocolMap, UNAUTHENTICATED_ALLOWED_PROTOCOLS, - responseFromBuffer, subProtocolSizeCalculators, } from './interface.js'; import { ReqRespMetrics } from './metrics.js'; @@ -46,13 +36,13 @@ import { RequestResponseRateLimiter, prettyPrintRateLimitStatus, } from './rate-limiter/rate_limiter.js'; -import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqRespStatus } from './status.js'; +import { ReqRespStatus, ReqRespStatusError, parseStatusChunk } from './status.js'; /** * The Request Response Service * * It allows nodes to request specific information from their peers, its use case covers recovering - * information that was missed during a syncronisation or a gossip event. + * information that was missed during a synchronisation or a gossip event. * * This service implements the request response sub protocol, it is heavily inspired from * ethereum implementations of the same name. @@ -67,7 +57,6 @@ export class ReqResp implements ReqRespInterface { private dialTimeoutMs: number = DEFAULT_REQRESP_DIAL_TIMEOUT_MS; private subProtocolHandlers: Partial = {}; - private subProtocolValidators: Partial = {}; private connectionSampler: ConnectionSampler; private rateLimiter: RequestResponseRateLimiter; @@ -130,11 +119,11 @@ export class ReqResp implements ReqRespInterface { /** * Start the reqresp service */ - async start(subProtocolHandlers: ReqRespSubProtocolHandlers, subProtocolValidators: ReqRespSubProtocolValidators) { + async start(subProtocolHandlers: ReqRespSubProtocolHandlers) { Object.assign(this.subProtocolHandlers, subProtocolHandlers); - Object.assign(this.subProtocolValidators, subProtocolValidators); - // Register all protocol handlers + // Register streamHandler with libp2p. + // The streamHandler is responsible for reading the incoming stream, determining the protocol, then triggering the appropriate handler. for (const subProtocol of Object.keys(subProtocolHandlers)) { this.logger.debug(`Registering handler for sub protocol ${subProtocol}`); await this.libp2p.handle( @@ -148,13 +137,8 @@ export class ReqResp implements ReqRespInterface { this.rateLimiter.start(); } - async addSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator: ReqRespSubProtocolValidators[ReqRespSubProtocol] = DEFAULT_SUB_PROTOCOL_VALIDATORS[subProtocol], - ): Promise { + async addSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise { this.subProtocolHandlers[subProtocol] = handler; - this.subProtocolValidators[subProtocol] = validator; this.logger.debug(`Registering handler for sub protocol ${subProtocol}`); await this.libp2p.handle( subProtocol, @@ -188,225 +172,6 @@ export class ReqResp implements ReqRespInterface { // NOTE: We assume libp2p instance is managed by the caller } - /** - * Request multiple messages over the same sub protocol, balancing the requests across peers. - * - * @devnote - * - The function prioritizes sending requests to free peers using a batch sampling strategy. - * - If a peer fails to respond or returns an invalid response, it is removed from the sampling pool and replaced. - * - The function stops retrying once all requests are processed, no active peers remain, or the maximum retry attempts are reached. - * - Responses are validated using a custom validator for the sub-protocol.* - * - * Requests are sent in parallel to each peer, but multiple requests are sent to the same peer in series - * - If a peer fails to respond or returns an invalid response, it is removed from the sampling pool and replaced. - * - The function stops retrying once all requests are processed, no active peers remain, or the maximum retry attempts are reached. - * - Responses are validated using a custom validator for the sub-protocol.* - * - * @param subProtocol - * @param requests - * @param timeoutMs - * @param maxPeers - * @returns - * - * @throws {CollectiveReqRespTimeoutError} - If the request batch exceeds the specified timeout (`timeoutMs`). - */ - @trackSpan( - 'ReqResp.sendBatchRequest', - (subProtocol: ReqRespSubProtocol, requests: InstanceType[]) => ({ - [Attributes.P2P_REQ_RESP_PROTOCOL]: subProtocol, - [Attributes.P2P_REQ_RESP_BATCH_REQUESTS_COUNT]: requests.length, - }), - ) - async sendBatchRequest( - subProtocol: SubProtocol, - requests: InstanceType[], - pinnedPeer: PeerId | undefined, - timeoutMs = 10000, - maxPeers = Math.max(10, Math.ceil(requests.length / 3)), - maxRetryAttempts = 3, - ): Promise[]> { - const responseValidator = this.subProtocolValidators[subProtocol] ?? DEFAULT_SUB_PROTOCOL_VALIDATORS[subProtocol]; - const responses: InstanceType[] = new Array(requests.length); - const requestBuffers = requests.map(req => req.toBuffer()); - const isEmptyResponse = (value: unknown): boolean => { - // Some responses serialize to a non-empty buffer even when they contain no items (e.g., empty TxArray). - if (!value || typeof value !== 'object') { - return false; - } - const length = (value as { length?: number }).length; - return typeof length === 'number' && length === 0; - }; - - const requestFunction = async (signal: AbortSignal) => { - // Track which requests still need to be processed - const pendingRequestIndices = new Set(requestBuffers.map((_, i) => i)); - - // Create batch sampler with the total number of requests and max peers - const batchSampler = new BatchConnectionSampler( - this.connectionSampler, - requests.length, - maxPeers, - compactArray([pinnedPeer]), // Exclude pinned peer from sampling, we will forcefully send all requests to it - createLogger(`${this.logger.module}:batch-connection-sampler`), - ); - - if (batchSampler.activePeerCount === 0 && !pinnedPeer) { - this.logger.warn('No active peers to send requests to'); - return []; - } - - // This is where it gets fun - // The outer loop is the retry loop, we will continue to retry until we process all indices we have - // not received a response for, or we have reached the max retry attempts - - // The inner loop is the batch loop, we will process all requests for each peer in parallel - // We will then process the results of the requests, and resample any peers that failed to respond - // We will continue to retry until we have processed all indices, or we have reached the max retry attempts - - let retryAttempts = 0; - while (pendingRequestIndices.size > 0 && batchSampler.activePeerCount > 0 && retryAttempts < maxRetryAttempts) { - if (signal.aborted) { - throw new AbortError('Batch request aborted'); - } - // Process requests in parallel for each available peer - type BatchEntry = { peerId: PeerId; indices: number[] }; - const requestBatches = new Map(); - - // Group requests by peer - for (const requestIndex of pendingRequestIndices) { - const peer = batchSampler.getPeerForRequest(requestIndex); - if (!peer) { - // No peer available for this specific index (all peers exhausted for it) - // Skip this index for now - it stays in pendingRequestIndices for retry - continue; - } - const peerAsString = peer.toString(); - if (!requestBatches.has(peerAsString)) { - requestBatches.set(peerAsString, { peerId: peer, indices: [] }); - } - requestBatches.get(peerAsString)!.indices.push(requestIndex); - } - - // If there is a pinned peer, we will always send every request to that peer - // We use the default limits for the subprotocol to avoid hitting the rate limiter - if (pinnedPeer) { - const limit = this.rateLimiter.getRateLimits(subProtocol).peerLimit.quotaCount; - requestBatches.set(pinnedPeer.toString(), { - peerId: pinnedPeer, - indices: Array.from(pendingRequestIndices.values()).slice(0, limit), - }); - } - - // If no requests could be assigned (all peers exhausted for all indices), exit early - if (requestBatches.size === 0) { - this.logger.warn('No peers available for any pending request indices, stopping batch request'); - break; - } - - // Make parallel requests for each peer's batch - // A batch entry will look something like this: - // PeerId0: [0, 1, 2, 3] - // PeerId1: [4, 5, 6, 7] - - // Peer Id 0 will send requests 0, 1, 2, 3 in serial - // while simultaneously Peer Id 1 will send requests 4, 5, 6, 7 in serial - - const batchResults = await Promise.all( - Array.from(requestBatches.entries()).map(async ([peerAsString, { peerId: peer, indices }]) => { - try { - const markIndexFailed = (index: number) => batchSampler.markPeerFailedForIndex(peer, index); - // Requests all going to the same peer are sent synchronously - const peerResults: { index: number; response: InstanceType }[] = - []; - let shouldReplacePeer = false; - const handleFailure = (status: ReqRespStatus, index: number) => { - this.logger.warn( - `Request to peer ${peerAsString} failed with status ${prettyPrintReqRespStatus(status)}`, - ); - markIndexFailed(index); - return status === ReqRespStatus.RATE_LIMIT_EXCEEDED; - }; - - for (const index of indices) { - this.logger.trace(`Sending request ${index} to peer ${peerAsString}`); - const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffers[index]); - - // Check the status of the response buffer - if (response.status !== ReqRespStatus.SUCCESS) { - shouldReplacePeer = handleFailure(response.status, index); - if (shouldReplacePeer) { - break; - } - continue; - } - - if (response.data.length === 0) { - markIndexFailed(index); - continue; - } - - const object = responseFromBuffer(subProtocol, response.data); - if (isEmptyResponse(object)) { - markIndexFailed(index); - continue; - } - - const isValid = await responseValidator(requests[index], object, peer); - if (!isValid) { - markIndexFailed(index); - continue; - } - - peerResults.push({ index, response: object }); - } - - // If peer had a hard failure (rate limit), replace it for future iterations - if (shouldReplacePeer) { - this.logger.warn(`Peer ${peerAsString} hit a hard failure, removing from sampler`); - batchSampler.removePeerAndReplace(peer); - } - - return { peer, results: peerResults }; - } catch (error) { - this.logger.warn(`Failed batch request to peer ${peerAsString}:`, error); - batchSampler.removePeerAndReplace(peer); - return { peer, results: [] }; - } - }), - ); - - // Process results - for (const { results } of batchResults) { - for (const { index, response } of results) { - if (response) { - responses[index] = response; - pendingRequestIndices.delete(index); - } - } - } - - retryAttempts++; - } - - if (retryAttempts >= maxRetryAttempts) { - this.logger.warn(`Max retry attempts ${maxRetryAttempts} reached for batch request`); - } - - return responses; - }; - - try { - return await executeTimeout[]>( - requestFunction, - timeoutMs, - () => new CollectiveReqRespTimeoutError(), - ); - } catch (e: any) { - this.logger.warn(`${e.message} | subProtocol: ${subProtocol}`); - return []; - } - } - /** * Sends a request to a specific peer * @@ -757,13 +522,13 @@ export class ReqResp implements ReqRespInterface { ): PeerErrorSeverity | undefined { const logTags = { peerId: peerId.toString(), subProtocol }; - //Punishable error - peer should never send badly formed request + // Punishable error - peer should never send badly formed request if (e instanceof ReqRespStatusError && e.status === ReqRespStatus.BADLY_FORMED_REQUEST) { this.logger.debug(`Punishable error in ${subProtocol}: ${e.cause}`, logTags); return PeerErrorSeverity.LowToleranceError; } - //TODO: (mralj): think if we should penalize peer here based on connection errors + // TODO: (mralj): think if we should penalize peer here based on connection errors return undefined; } @@ -785,12 +550,6 @@ export class ReqResp implements ReqRespInterface { return undefined; } - // We do not punish a collective timeout, as the node triggers this interupt, independent of the peer's behaviour - if (e instanceof CollectiveReqRespTimeoutError || e instanceof InvalidResponseError) { - this.logger.debug(`Non-punishable error in ${subProtocol}: ${e.message}`, logTags); - return undefined; - } - // Invalid status byte: the peer sent a status byte that doesn't match any known status code. // This is a protocol violation, penalize harshly. if (e instanceof ReqRespStatusError) { @@ -810,7 +569,8 @@ export class ReqResp implements ReqRespInterface { /* * Errors specific to connection handling - * These can happen both when sending request and response*/ + * These can happen both when sending request and response. + */ private categorizeConnectionErrors( e: any, peerId: PeerId, diff --git a/yarn-project/p2p/src/services/service.ts b/yarn-project/p2p/src/services/service.ts index e3b7590e83b1..f5428c9a9f19 100644 --- a/yarn-project/p2p/src/services/service.ts +++ b/yarn-project/p2p/src/services/service.ts @@ -17,12 +17,7 @@ import type EventEmitter from 'events'; import type { BatchTxRequesterLibP2PService } from './reqresp/batch-tx-requester/interface.js'; import type { P2PReqRespConfig } from './reqresp/config.js'; import type { StatusMessage } from './reqresp/index.js'; -import type { - ReqRespSubProtocol, - ReqRespSubProtocolHandler, - ReqRespSubProtocolValidators, - SubProtocolMap, -} from './reqresp/interface.js'; +import type { ReqRespSubProtocol, ReqRespSubProtocolHandler } from './reqresp/interface.js'; import type { AuthRequest, AuthResponse } from './reqresp/protocols/auth.js'; export enum PeerDiscoveryState { @@ -100,22 +95,6 @@ export interface P2PService { */ propagate(message: T): Promise; - /** - * Send a batch of requests to peers, and return the responses - * - * @param protocol - The request response protocol to use - * @param requests - The requests to send to the peers - * @returns The responses to the requests - */ - sendBatchRequest( - protocol: Protocol, - requests: InstanceType[], - pinnedPeerId?: PeerId, - timeoutMs?: number, - maxPeers?: number, - maxRetryAttempts?: number, - ): Promise[]>; - // Leaky abstraction: fix https://github.com/AztecProtocol/aztec-packages/issues/7963 registerBlockReceivedCallback(callback: P2PBlockReceivedCallback): void; @@ -150,11 +129,7 @@ export interface P2PService { validateTxsReceivedInBlockProposal(txs: Tx[]): Promise; - addReqRespSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise; + addReqRespSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise; handleAuthRequestFromPeer(authRequest: AuthRequest, peerId: PeerId): Promise; diff --git a/yarn-project/p2p/src/services/tx_collection/config.ts b/yarn-project/p2p/src/services/tx_collection/config.ts index f8f5ceeea81f..68de3db09303 100644 --- a/yarn-project/p2p/src/services/tx_collection/config.ts +++ b/yarn-project/p2p/src/services/tx_collection/config.ts @@ -14,7 +14,7 @@ export type TxCollectionConfig = { txCollectionNodeRpcMaxBatchSize: number; /** A comma-separated list of file store URLs (s3://, gs://, file://, http://) for tx collection */ txCollectionFileStoreUrls: string[]; - /** Delay in ms before file store collection starts after fast collection is triggered */ + /** Delay in ms from reqresp start before file store collection begins */ txCollectionFileStoreFastDelayMs: number; /** Number of concurrent workers for fast file store collection */ txCollectionFileStoreFastWorkerCount: number; @@ -68,7 +68,7 @@ export const txCollectionConfigMappings: ConfigMappingsType }, txCollectionFileStoreFastDelayMs: { env: 'TX_COLLECTION_FILE_STORE_FAST_DELAY_MS', - description: 'Delay before file store collection starts after fast collection', + description: 'Delay in ms from reqresp start before file store collection begins', ...numberConfigHelper(2_000), }, txCollectionFileStoreFastWorkerCount: { diff --git a/yarn-project/p2p/src/services/tx_collection/fast_tx_collection.ts b/yarn-project/p2p/src/services/tx_collection/fast_tx_collection.ts deleted file mode 100644 index 7bcb1366342b..000000000000 --- a/yarn-project/p2p/src/services/tx_collection/fast_tx_collection.ts +++ /dev/null @@ -1,379 +0,0 @@ -import { BlockNumber } from '@aztec/foundation/branded-types'; -import { times } from '@aztec/foundation/collection'; -import { type Logger, createLogger } from '@aztec/foundation/log'; -import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider, elapsed } from '@aztec/foundation/timer'; -import type { L2BlockInfo } from '@aztec/stdlib/block'; -import { type Tx, TxHash } from '@aztec/stdlib/tx'; - -import type { PeerId } from '@libp2p/interface'; - -import { BatchTxRequester } from '../reqresp/batch-tx-requester/batch_tx_requester.js'; -import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js'; -import type { BlockTxsSource } from '../reqresp/index.js'; -import type { TxCollectionConfig } from './config.js'; -import { type IRequestTracker, RequestTracker } from './request_tracker.js'; -import type { FastCollectionRequest, FastCollectionRequestInput } from './tx_collection.js'; -import type { TxAddContext, TxCollectionSink } from './tx_collection_sink.js'; -import type { TxSource } from './tx_source.js'; - -/** - * Collect missing transactions for a block or proposal via reqresp. - * @param requestTracker - The missing transactions tracker - * @param blockTxsSource - The block or proposal containing the transactions - * @param pinnedPeer - Optional peer expected to have the transactions - * @returns The collected transactions - */ -export type IReqRespTxsCollector = ( - requestTracker: IRequestTracker, - blockTxsSource: BlockTxsSource, - pinnedPeer: PeerId | undefined, -) => Promise; - -export class FastTxCollection { - // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections - protected requests: Set = new Set(); - - constructor( - private readonly p2pService: BatchTxRequesterLibP2PService, - private nodes: TxSource[], - private txCollectionSink: TxCollectionSink, - private config: TxCollectionConfig, - private dateProvider: DateProvider = new DateProvider(), - private log: Logger = createLogger('p2p:tx_collection_service'), - protected reqRespTxsCollector?: IReqRespTxsCollector, - ) { - if (!this.reqRespTxsCollector) { - this.reqRespTxsCollector = (requestTracker, blockTxsSource, pinnedPeer) => - BatchTxRequester.collectAllTxs( - new BatchTxRequester( - requestTracker, - blockTxsSource, - pinnedPeer, - this.p2pService, - this.log, - this.dateProvider, - ).run(), - ); - } - } - - public async stop() { - this.requests.forEach(request => { - request.requestTracker.cancel(); - }); - await Promise.resolve(); - } - - public getFastCollectionRequests() { - return this.requests; - } - - public async collectFastFor( - input: FastCollectionRequestInput, - txHashes: TxHash[] | string[], - opts: { deadline: Date; pinnedPeer?: PeerId }, - ) { - const timeout = opts.deadline.getTime() - this.dateProvider.now(); - if (timeout <= 0) { - this.log.warn(`Deadline for fast tx collection is in the past (${timeout}ms)`, { - deadline: opts.deadline.getTime(), - now: this.dateProvider.now(), - }); - return []; - } - - const blockInfo: L2BlockInfo = - input.type === 'proposal' - ? { ...input.blockProposal.toBlockInfo(), blockNumber: input.blockNumber } - : { ...input.block.toBlockInfo() }; - - const request: FastCollectionRequest = { - ...input, - blockInfo, - requestTracker: RequestTracker.create(txHashes, opts.deadline, this.dateProvider), - }; - - const [duration] = await elapsed(() => this.collectFast(request, { ...opts })); - - this.log.verbose( - `Collected ${request.requestTracker.collectedTxs.length} txs out of ${txHashes.length} for ${input.type} at slot ${blockInfo.slotNumber}`, - { - ...blockInfo, - duration, - requestType: input.type, - missingTxs: [...request.requestTracker.missingTxHashes], - }, - ); - return request.requestTracker.collectedTxs; - } - - protected async collectFast(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) { - this.requests.add(request); - const { blockInfo } = request; - - this.log.debug( - `Starting fast collection of ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`, - { ...blockInfo, requestType: request.type, deadline: request.requestTracker.deadline }, - ); - - try { - // Start blasting all nodes for the txs. We give them a little time to respond before we start reqresp. - // We race against the cancellation token to exit as soon as all txs are collected, the deadline expires, - // or the request is externally cancelled. - const nodeCollectionPromise = this.collectFastFromNodes(request); - const waitBeforeReqResp = sleep(this.config.txCollectionFastNodesTimeoutBeforeReqRespMs); - await Promise.race([request.requestTracker.cancellationToken, waitBeforeReqResp]); - - // If we have collected all txs or the request was cancelled, we can stop here. - // Wait for node collection to settle so inner tasks finish before we return. - if (request.requestTracker.checkCancelled()) { - if (request.requestTracker.allFetched()) { - this.log.debug(`All txs collected for slot ${blockInfo.slotNumber} without reqresp`, blockInfo); - } - await nodeCollectionPromise; - return; - } - - // Start blasting reqresp for the remaining txs. Note that node collection keeps running in parallel. - // We stop when we have collected all txs, timed out, or both node collection and reqresp have given up. - // Inner tasks observe requestTracker.checkCancelled() and stop themselves, so this settles shortly after cancellation. - await Promise.allSettled([this.collectFastViaReqResp(request, opts), nodeCollectionPromise]); - } catch (err) { - this.log.error(`Error collecting txs for ${request.type} for slot ${blockInfo.slotNumber}`, err, { - ...blockInfo, - missingTxs: request.requestTracker.missingTxHashes.values().map(txHash => txHash.toString()), - }); - } finally { - // Ensure no unresolved promises and remove the request from the set - request.requestTracker.cancel(); - this.requests.delete(request); - } - } - - /** - * Starts collecting txs from all configured nodes. We send `txCollectionFastMaxParallelRequestsPerNode` requests - * in parallel to each node. We keep track of the number of attempts made to collect each tx, so we can prioritize - * the txs that have been requested less often whenever we need to send a new batch of requests. We ensure that no - * tx is requested more than once at the same time to the same node. - */ - private async collectFastFromNodes(request: FastCollectionRequest): Promise { - if (this.nodes.length === 0) { - return; - } - - // Keep a shared priority queue of all txs pending to be requested, sorted by the number of attempts made to collect them. - const attemptsPerTx = [...request.requestTracker.missingTxHashes].map(txHash => ({ - txHash, - attempts: 0, - found: false, - })); - - // Returns once we have finished all node loops. Each loop finishes when the deadline is hit, or all txs have been collected. - await Promise.allSettled(this.nodes.map(node => this.collectFastFromNode(request, node, attemptsPerTx))); - } - - private async collectFastFromNode( - request: FastCollectionRequest, - node: TxSource, - attemptsPerTx: { txHash: string; attempts: number; found: boolean }[], - ) { - const notFinished = () => !request.requestTracker.checkCancelled(); - - const maxParallelRequests = this.config.txCollectionFastMaxParallelRequestsPerNode; - const maxBatchSize = this.config.txCollectionNodeRpcMaxBatchSize; - const activeRequestsToThisNode = new Set(); // Track the txs being actively requested to this node - - const processBatch = async () => { - while (notFinished()) { - // Pull tx hashes from the attemptsPerTx array, which is sorted by attempts, - // so we prioritize txs that have been requested less often. - const batch = []; - let index = 0; - while (batch.length < maxBatchSize) { - const txToRequest = attemptsPerTx[index++]; - if (!txToRequest) { - // No more txs to process - break; - } else if (!request.requestTracker.isMissing(txToRequest.txHash)) { - // Mark as found if it was found somewhere else, we'll then remove it from the array. - // We don't delete it now since 'array.splice' is pretty expensive, so we do it after sorting. - txToRequest.found = true; - } else if (!activeRequestsToThisNode.has(txToRequest.txHash)) { - // If the tx is not alredy being requested to this node, add it to the current batch and increase attempts. - // Note that we increase the attempts *before* making the request, so the next `collectFastFromNode` that - // needs to grab txs to send, will pick txs that have been requested less often, instead of all requesting - // the same txs at the same time. - batch.push(txToRequest); - activeRequestsToThisNode.add(txToRequest.txHash); - txToRequest.attempts++; - } - } - - // After modifying the array by removing txs or updating attempts, re-sort it and trim the found txs from the end. - attemptsPerTx.sort((a, b) => - a.found === b.found ? a.attempts - b.attempts : Number(a.found) - Number(b.found), - ); - const firstFoundTxIndex = attemptsPerTx.findIndex(tx => tx.found); - if (firstFoundTxIndex !== -1) { - attemptsPerTx.length = firstFoundTxIndex; - } - - // If we see no more txs to request, we can stop this "process" loop - if (batch.length === 0) { - return; - } - - const txHashes = batch.map(({ txHash }) => txHash); - // Collect this batch from the node - await this.txCollectionSink.collect( - async () => { - const result = await node.getTxsByHash(txHashes.map(TxHash.fromString)); - for (const tx of result.validTxs) { - request.requestTracker.markFetched(tx); - } - return result; - }, - txHashes, - { - description: `fast ${node.getInfo()}`, - node: node.getInfo(), - method: 'fast-node-rpc', - ...request.blockInfo, - }, - this.getAddContext(request), - ); - - // Clear from the active requests the txs we just requested - for (const requestedTx of batch) { - activeRequestsToThisNode.delete(requestedTx.txHash); - } - - // Sleep a bit until hitting the node again, but wake up immediately on cancellation - if (notFinished()) { - await Promise.race([ - sleep(this.config.txCollectionFastNodeIntervalMs), - request.requestTracker.cancellationToken, - ]); - } - } - }; - - // Kick off N parallel requests to the node, up to the maxParallelRequests limit - await Promise.all(times(maxParallelRequests, processBatch)); - } - - private async collectFastViaReqResp(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) { - const pinnedPeer = opts.pinnedPeer; - const blockInfo = request.blockInfo; - const slotNumber = blockInfo.slotNumber; - if (request.requestTracker.timeoutMs < 100) { - this.log.warn( - `Not initiating fast reqresp for txs for ${request.type} at slot ${blockInfo.slotNumber} due to timeout`, - { timeoutMs: request.requestTracker.timeoutMs, ...blockInfo }, - ); - return; - } - - this.log.debug( - `Starting fast reqresp for ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`, - { ...blockInfo, timeoutMs: request.requestTracker.timeoutMs, pinnedPeer }, - ); - - try { - await this.txCollectionSink.collect( - async () => { - let blockTxsSource: BlockTxsSource; - if (request.type === 'proposal') { - blockTxsSource = request.blockProposal; - } else if (request.type === 'block') { - blockTxsSource = { - txHashes: request.block.body.txEffects.map(e => e.txHash), - archive: request.block.archive.root, - }; - } else { - throw new Error(`Unknown request type: ${(request as { type: string }).type}`); - } - - const result = await this.reqRespTxsCollector!(request.requestTracker, blockTxsSource, pinnedPeer); - return { validTxs: result, invalidTxHashes: [] }; - }, - Array.from(request.requestTracker.missingTxHashes), - { description: `reqresp for slot ${slotNumber}`, method: 'fast-req-resp', ...opts, ...request.blockInfo }, - this.getAddContext(request), - ); - } catch (err) { - this.log.error(`Error sending fast reqresp request for txs`, err, { - txs: [...request.requestTracker.missingTxHashes], - ...blockInfo, - }); - } - } - - /** Returns the TxAddContext for the given request, used by the sink to add txs to the pool correctly. */ - private getAddContext(request: FastCollectionRequest): TxAddContext { - if (request.type === 'proposal') { - return { type: 'proposal', blockHeader: request.blockProposal.blockHeader }; - } else { - return { type: 'mined', block: request.block }; - } - } - - /** - * Handle txs by marking them as found for the requests that are waiting for them, and resolves the request if all its txs have been found. - * Called internally and from the main tx collection manager whenever the tx pool emits a tx-added event. - */ - public foundTxs(txs: Tx[]) { - for (const request of this.requests) { - for (const tx of txs) { - const txHash = tx.txHash.toString(); - // Remove the tx hash from the missing set, and add it to the found set. - if (request.requestTracker.markFetched(tx)) { - this.log.trace(`Found tx ${txHash} for fast collection request`, { - ...request.blockInfo, - txHash: tx.txHash.toString(), - type: request.type, - }); - if (request.requestTracker.allFetched()) { - this.log.trace(`All txs found for fast collection request`, { - ...request.blockInfo, - type: request.type, - }); - break; - } - } - } - } - } - - /** Returns the tx hashes that are still missing (from all requests). */ - public getMissingTxHashes(): TxHash[] { - return Array.from(this.requests.values()).flatMap(request => - Array.from(request.requestTracker.missingTxHashes).map(TxHash.fromString), - ); - } - - /** - * Stop collecting all txs for blocks less than or requal to the block number specified. - * To be called when we no longer care about gathering txs up to a certain block, eg when they become proven or finalized. - */ - public stopCollectingForBlocksUpTo(blockNumber: BlockNumber): void { - for (const request of this.requests) { - if (request.blockInfo.blockNumber <= blockNumber) { - request.requestTracker.cancel(); - } - } - } - - /** - * Stop collecting all txs for blocks greater than the block number specified. - * To be called when there is a chain prune and previously mined txs are no longer relevant. - */ - public stopCollectingForBlocksAfter(blockNumber: BlockNumber): void { - for (const request of this.requests) { - if (request.blockInfo.blockNumber > blockNumber) { - request.requestTracker.cancel(); - } - } - } -} diff --git a/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.test.ts b/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.test.ts index eacef127cfb2..f41512a1dbca 100644 --- a/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.test.ts +++ b/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.test.ts @@ -12,6 +12,7 @@ import { type MockProxy, mock } from 'jest-mock-extended'; import type { TxPoolV2 } from '../../mem_pools/tx_pool_v2/interfaces.js'; import { type FileStoreCollectionConfig, FileStoreTxCollection } from './file_store_tx_collection.js'; import type { FileStoreTxSource } from './file_store_tx_source.js'; +import { type IRequestTracker, RequestTracker } from './request_tracker.js'; import { type TxAddContext, TxCollectionSink } from './tx_collection_sink.js'; describe('FileStoreTxCollection', () => { @@ -26,6 +27,11 @@ describe('FileStoreTxCollection', () => { let txs: Tx[]; let txHashes: TxHash[]; + let requestTracker: IRequestTracker; + + // Track in-flight startCollecting invocations so afterEach can shut them down cleanly. + let activeTrackers: IRequestTracker[]; + let activePromises: Promise[]; const makeFileStoreSource = (name: string) => { const source = mock(); @@ -49,6 +55,14 @@ describe('FileStoreTxCollection', () => { }); }; + /** Spawns a collection run and registers it for afterEach cleanup. */ + const startCollecting = (tracker: IRequestTracker, ctx: TxAddContext): Promise => { + activeTrackers.push(tracker); + const promise = fileStoreCollection.startCollecting(tracker, ctx); + activePromises.push(promise); + return promise; + }; + /** Waits for the sink to emit txs-added events for the expected number of txs. */ const waitForTxsAdded = (expectedCount: number) => { const { promise, resolve } = promiseWithResolvers(); @@ -102,33 +116,38 @@ describe('FileStoreTxCollection', () => { const block = await L2Block.random(BlockNumber(1)); context = { type: 'mined', block }; deadline = new Date(dateProvider.now() + 60 * 60 * 1000); + requestTracker = RequestTracker.create(txHashes, deadline, dateProvider); + + activeTrackers = []; + activePromises = []; }); afterEach(async () => { - await fileStoreCollection.stop(); + for (const t of activeTrackers) { + t.cancel(); + } + await Promise.allSettled(activePromises); jest.restoreAllMocks(); }); it('downloads txs when startCollecting is called', async () => { setFileStoreTxs(fileStoreSources[0], txs); - fileStoreCollection.start(); - const txsAddedPromise = waitForTxsAdded(txs.length); - fileStoreCollection.startCollecting(txHashes, context, deadline); + void startCollecting(requestTracker, context); await txsAddedPromise; expect(fileStoreSources[0].getTxsByHash).toHaveBeenCalled(); expect(txPool.addMinedTxs).toHaveBeenCalled(); }); - it('skips txs marked as found', async () => { + it('skips txs already marked fetched on the tracker', async () => { setFileStoreTxs(fileStoreSources[0], txs); - fileStoreCollection.start(); + // Mark first tx as found before queueing so it's never queued in the first place + requestTracker.markFetched(txs[0]); - fileStoreCollection.startCollecting(txHashes, context, deadline); - fileStoreCollection.foundTxs([txs[0]]); + void startCollecting(requestTracker, context); const txsAddedPromise = waitForTxsAdded(2); await txsAddedPromise; @@ -145,53 +164,25 @@ describe('FileStoreTxCollection', () => { // Pin random so we always start at source 0, ensuring we test the fallback to source 1 jest.spyOn(Math, 'random').mockReturnValue(0); - fileStoreCollection.start(); - + const tracker = RequestTracker.create([txHashes[0]], deadline, dateProvider); const txsAddedPromise = waitForTxsAdded(1); - fileStoreCollection.startCollecting([txHashes[0]], context, deadline); + void startCollecting(tracker, context); await txsAddedPromise; // Both stores should have been tried expect(fileStoreSources[0].getTxsByHash).toHaveBeenCalled(); expect(fileStoreSources[1].getTxsByHash).toHaveBeenCalled(); expect(txPool.addMinedTxs).toHaveBeenCalled(); - - jest.restoreAllMocks(); }); - it('does not start workers if no file store sources are configured', () => { + it('does not start workers if no file store sources are configured', async () => { const log = createLogger('test'); fileStoreCollection = new FileStoreTxCollection([], txCollectionSink, config, dateProvider, log); - fileStoreCollection.start(); - fileStoreCollection.startCollecting(txHashes, context, deadline); - - // With no sources, start() is a no-op (no workers spawned) and startCollecting() returns - // immediately, so no calls should have been made synchronously. - expect(fileStoreSources[0].getTxsByHash).not.toHaveBeenCalled(); - }); - - it('does not re-queue txs that are already pending', async () => { - setFileStoreTxs(fileStoreSources[0], txs); - setFileStoreTxs(fileStoreSources[1], txs); - - // Use single worker for deterministic behavior - const log = createLogger('test'); - config = { workerCount: 1, backoffBaseMs: 1000, backoffMaxMs: 5000 }; - fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); - - fileStoreCollection.start(); - - const txsAddedPromise = waitForTxsAdded(txs.length); - fileStoreCollection.startCollecting(txHashes, context, deadline); - fileStoreCollection.startCollecting(txHashes, context, deadline); // Duplicate call + // With no sources, startCollecting resolves immediately without making any calls. + await startCollecting(requestTracker, context); - await txsAddedPromise; - - // With 1 worker processing sequentially, each tx should be found on the first source. - // Duplicate startCollecting should not create extra entries. - const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); - expect(allCalls.length).toBe(txHashes.length); + expect(fileStoreSources[0].getTxsByHash).not.toHaveBeenCalled(); }); it('retries across sources when tx is not found initially', async () => { @@ -200,10 +191,9 @@ describe('FileStoreTxCollection', () => { config = { workerCount: 1, backoffBaseMs: 100, backoffMaxMs: 500 }; fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); - fileStoreCollection.start(); - // Initially both sources return empty - fileStoreCollection.startCollecting([txHashes[0]], context, deadline); + const tracker = RequestTracker.create([txHashes[0]], deadline, dateProvider); + void startCollecting(tracker, context); // Wait for first full cycle (2 sources = 2 calls) await waitForSourceCalls(fileStoreSources, 2); @@ -220,88 +210,54 @@ describe('FileStoreTxCollection', () => { expect(txPool.addMinedTxs).toHaveBeenCalled(); }); - it('expires entries past deadline', async () => { - const log = createLogger('test'); - config = { workerCount: 1, backoffBaseMs: 50, backoffMaxMs: 100 }; - fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); - - // Set a very short deadline - const shortDeadline = new Date(dateProvider.now() + 100); - - fileStoreCollection.start(); - fileStoreCollection.startCollecting([txHashes[0]], context, shortDeadline); - - // Wait for first full cycle (2 sources = 2 calls) - await waitForSourceCalls(fileStoreSources, 2); - - // Advance time past the deadline - dateProvider.setTime(dateProvider.now() + 200); - - // Clear mocks so we can distinguish new calls from old ones - jest.clearAllMocks(); - - // Add a new entry with a valid deadline and set up source to return it. - // This proves the worker is alive and the expired entry was cleaned up. - setFileStoreTxs(fileStoreSources[0], [txs[1]]); - const txsAddedPromise = waitForTxsAdded(1); - fileStoreCollection.startCollecting([txHashes[1]], context, deadline); - await txsAddedPromise; - - // Only txHashes[1] should have been requested after clearing mocks - const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); - const requestedHashes = allCalls.flat().flat(); - expect(requestedHashes).not.toContainEqual(txHashes[0]); - expect(requestedHashes).toContainEqual(txHashes[1]); - }); - - it('does not start collecting if deadline is in the past', () => { - const pastDeadline = new Date(dateProvider.now() - 1000); + it('does not start collecting if tracker is already cancelled', async () => { + requestTracker.cancel(); - fileStoreCollection.start(); - fileStoreCollection.startCollecting(txHashes, context, pastDeadline); + await startCollecting(requestTracker, context); - // startCollecting returns immediately without adding entries when deadline is past + // startCollecting returns immediately without spawning workers when tracker is cancelled expect(fileStoreSources[0].getTxsByHash).not.toHaveBeenCalled(); }); - it('foundTxs stops retry for found txs', async () => { + it('stops trying for txs marked fetched on the tracker after queuing', async () => { const log = createLogger('test'); config = { workerCount: 1, backoffBaseMs: 50, backoffMaxMs: 100 }; fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); setFileStoreTxs(fileStoreSources[0], [txs[1]]); - fileStoreCollection.start(); - fileStoreCollection.startCollecting(txHashes, context, deadline); + void startCollecting(requestTracker, context); - // Mark first tx as found - fileStoreCollection.foundTxs([txs[0]]); + // Externally mark tx[0] as found via the tracker (simulating node/reqresp/gossip finding it). + // startCollecting yields before spawning workers, so this runs before any source call is made. + requestTracker.markFetched(txs[0]); const txsAddedPromise = waitForTxsAdded(1); await txsAddedPromise; - // tx[0] should never have been attempted + // tx[0] should never have been attempted by the file store const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); const requestedHashes = allCalls.flat().flat(); expect(requestedHashes).not.toContainEqual(txHashes[0]); }); - it('clearPending removes all entries', async () => { - fileStoreCollection.start(); - fileStoreCollection.startCollecting(txHashes, context, deadline); - fileStoreCollection.clearPending(); + it('workers exit when tracker is cancelled', async () => { + // Long backoff so workers spend most of their time sleeping after a single attempt + const log = createLogger('test'); + config = { workerCount: 2, backoffBaseMs: 60_000, backoffMaxMs: 60_000 }; + fileStoreCollection = new FileStoreTxCollection(fileStoreSources, txCollectionSink, config, dateProvider, log); + + // Pre-set the tracker timer so a cancellation does not require real-time deadline expiry + const tracker = RequestTracker.create(txHashes, deadline, dateProvider); + const promise = startCollecting(tracker, context); - // Verify workers are alive but the cleared entries are gone by adding - // a new entry and confirming only it gets processed. - setFileStoreTxs(fileStoreSources[0], [txs[0]]); - const txsAddedPromise = waitForTxsAdded(1); - fileStoreCollection.startCollecting([txHashes[0]], context, deadline); - await txsAddedPromise; + // Let workers do at least one round of attempts + await waitForSourceCalls(fileStoreSources, 2); - // Only the newly added tx[0] should have been requested, not all 3 original txs - const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); - const requestedHashes = allCalls.flat().flat(); - expect(requestedHashes).not.toContainEqual(txHashes[1]); - expect(requestedHashes).not.toContainEqual(txHashes[2]); + tracker.cancel(); + + // The startCollecting promise resolves once all workers settle. Without this guarantee, the + // test would either hang or leak workers — both are caught by Jest's default timeout. + await promise; }); }); diff --git a/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.ts b/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.ts index 165ba3d9928a..abaf1b64ad6e 100644 --- a/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.ts +++ b/yarn-project/p2p/src/services/tx_collection/file_store_tx_collection.ts @@ -1,10 +1,11 @@ +import { times } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; -import { type PromiseWithResolvers, promiseWithResolvers } from '@aztec/foundation/promise'; import { sleep } from '@aztec/foundation/sleep'; import { DateProvider } from '@aztec/foundation/timer'; -import { Tx, TxHash } from '@aztec/stdlib/tx'; +import { TxHash } from '@aztec/stdlib/tx'; import type { FileStoreTxSource } from './file_store_tx_source.js'; +import type { IRequestTracker } from './request_tracker.js'; import type { TxAddContext, TxCollectionSink } from './tx_collection_sink.js'; /** Configuration for a FileStoreTxCollection instance. */ @@ -16,8 +17,6 @@ export type FileStoreCollectionConfig = { type FileStoreTxEntry = { txHash: string; - context: TxAddContext; - deadline: Date; attempts: number; lastAttemptTime: number; nextSourceIndex: number; @@ -25,96 +24,60 @@ type FileStoreTxEntry = { /** * Collects txs from file stores as a fallback after P2P methods have been tried. - * Uses a shared worker pool that pulls entries with priority (fewest attempts first), - * retries with round-robin across sources, and applies exponential backoff between - * full cycles through all sources. + * Each call to startCollecting spins up its own worker pool which pulls entries with priority + * (fewest attempts first), retries with round-robin across sources, and applies exponential + * backoff between full cycles through all sources. Workers self-terminate when the request + * tracker is cancelled (deadline / all-fetched / external) or when there is nothing left to do. */ export class FileStoreTxCollection { - /** Map from tx hash string to entry for all pending downloads. */ - private entries = new Map(); - - /** Worker promises for the shared worker pool. */ - private workers: Promise[] = []; - - /** Whether the worker pool is running. */ - private running = false; - - /** Signal used to wake sleeping workers when new entries arrive or stop is called. */ - private wakeSignal: PromiseWithResolvers; - constructor( private readonly sources: FileStoreTxSource[], private readonly txCollectionSink: TxCollectionSink, private readonly config: FileStoreCollectionConfig, private readonly dateProvider: DateProvider = new DateProvider(), private readonly log: Logger = createLogger('p2p:file_store_tx_collection'), - ) { - this.wakeSignal = promiseWithResolvers(); - } - - /** Starts the shared worker pool. */ - public start(): void { - if (this.sources.length === 0) { - this.log.debug('No file store sources configured'); - return; - } - this.running = true; - for (let i = 0; i < this.config.workerCount; i++) { - this.workers.push(this.workerLoop()); - } - } - - /** Stops all workers and clears state. */ - public async stop(): Promise { - this.running = false; - this.wake(); - await Promise.all(this.workers); - this.workers = []; - this.entries.clear(); - } - - /** Adds entries to the shared map and wakes workers. */ - public startCollecting(txHashes: TxHash[], context: TxAddContext, deadline: Date): void { - if (this.sources.length === 0 || txHashes.length === 0) { - return; - } - if (+deadline <= this.dateProvider.now()) { + ) {} + + /** + * Spins up workers to download all txs still missing from the tracker, racing across the + * configured file store sources. Resolves once all workers settle. + */ + public async startCollecting(requestTracker: IRequestTracker, context: TxAddContext): Promise { + if (this.sources.length === 0 || requestTracker.checkCancelled()) { return; } - for (const txHash of txHashes) { - const hashStr = txHash.toString(); - if (!this.entries.has(hashStr)) { - this.entries.set(hashStr, { - txHash: hashStr, - context, - deadline, - attempts: 0, - lastAttemptTime: 0, - nextSourceIndex: Math.floor(Math.random() * this.sources.length), - }); - } + // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + const entries: Set = new Set(); + for (const hashStr of requestTracker.missingTxHashes) { + entries.add({ + txHash: hashStr, + attempts: 0, + lastAttemptTime: 0, + nextSourceIndex: Math.floor(Math.random() * this.sources.length), + }); } - this.wake(); - } - /** Removes entries for txs that have been found elsewhere. */ - public foundTxs(txs: Tx[]): void { - for (const tx of txs) { - this.entries.delete(tx.getTxHash().toString()); + // Yield before spawning so the synchronous caller can finish any follow-up (eg. marking a tx + // as fetched on the tracker, or cancelling it) before workers begin scanning entries. + await Promise.resolve(); + if (requestTracker.checkCancelled()) { + return; } - } - /** Clears all pending entries. */ - public clearPending(): void { - this.entries.clear(); + await Promise.allSettled(times(this.config.workerCount, () => this.workerLoop(entries, requestTracker, context))); } - private async workerLoop(): Promise { - while (this.running) { - const action = this.getNextAction(); + private async workerLoop( + // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + entries: Set, + requestTracker: IRequestTracker, + context: TxAddContext, + ): Promise { + while (!requestTracker.checkCancelled() && entries.size > 0) { + const action = this.getNextAction(entries, requestTracker); if (action.type === 'sleep') { - await action.promise; + await Promise.race([sleep(action.ms), requestTracker.cancellationToken]); continue; } @@ -133,10 +96,10 @@ export class FileStoreTxCollection { method: 'file-store', fileStore: source.getInfo(), }, - entry.context, + context, ); if (result.txs.length > 0) { - this.entries.delete(entry.txHash); + entries.delete(entry); } } catch (err) { this.log.trace(`Error downloading tx ${entry.txHash} from ${source.getInfo()}`, { err }); @@ -144,15 +107,20 @@ export class FileStoreTxCollection { } } - /** Single-pass scan: removes expired entries, finds the best ready entry, or computes sleep time. */ - private getNextAction(): { type: 'process'; entry: FileStoreTxEntry } | { type: 'sleep'; promise: Promise } { + /** Single-pass scan: removes stale entries, finds the best ready entry, or computes sleep time. */ + private getNextAction( + // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + entries: Set, + requestTracker: IRequestTracker, + ): { type: 'process'; entry: FileStoreTxEntry } | { type: 'sleep'; ms: number } { const now = this.dateProvider.now(); let best: FileStoreTxEntry | undefined; let earliestReadyAt = Infinity; - for (const [key, entry] of this.entries) { - if (+entry.deadline <= now) { - this.entries.delete(key); + for (const entry of entries) { + // Drop entries whose tx was already found via another collection path. + if (!requestTracker.isMissing(entry.txHash)) { + entries.delete(entry); continue; } const backoffMs = this.getBackoffMs(entry); @@ -169,10 +137,9 @@ export class FileStoreTxCollection { if (best) { return { type: 'process', entry: best }; } - if (earliestReadyAt < Infinity) { - return { type: 'sleep', promise: this.sleepOrWake(earliestReadyAt - now) }; - } - return { type: 'sleep', promise: this.waitForWake() }; + // earliestReadyAt is finite whenever there are surviving entries; if entries became empty, + // the outer worker loop will exit on its next iteration via entries.size === 0. + return { type: 'sleep', ms: earliestReadyAt === Infinity ? 0 : earliestReadyAt - now }; } /** Computes backoff for an entry. Backoff applies after a full cycle through all sources. */ @@ -183,20 +150,4 @@ export class FileStoreTxCollection { } return Math.min(this.config.backoffBaseMs * Math.pow(2, fullCycles - 1), this.config.backoffMaxMs); } - - /** Resolves the current wake signal and creates a new one. */ - private wake(): void { - this.wakeSignal.resolve(); - this.wakeSignal = promiseWithResolvers(); - } - - /** Waits until the wake signal is resolved. */ - private async waitForWake(): Promise { - await this.wakeSignal.promise; - } - - /** Sleeps for the given duration or until the wake signal is resolved. */ - private async sleepOrWake(ms: number): Promise { - await Promise.race([sleep(ms), this.wakeSignal.promise]); - } } diff --git a/yarn-project/p2p/src/services/tx_collection/index.ts b/yarn-project/p2p/src/services/tx_collection/index.ts index 4f151c32e27f..293ebdde7ab3 100644 --- a/yarn-project/p2p/src/services/tx_collection/index.ts +++ b/yarn-project/p2p/src/services/tx_collection/index.ts @@ -1,4 +1,3 @@ -export { TxCollection, type FastCollectionRequestInput } from './tx_collection.js'; -export { type IReqRespTxsCollector } from './fast_tx_collection.js'; +export { TxCollection, type FastCollectionRequestInput, type IReqRespTxsCollector } from './tx_collection.js'; export { type TxSource, createNodeRpcTxSources, NodeRpcTxSource } from './tx_source.js'; export { FileStoreTxSource, createFileStoreTxSources } from './file_store_tx_source.js'; diff --git a/yarn-project/p2p/src/services/tx_collection/tx_collection.test.ts b/yarn-project/p2p/src/services/tx_collection/tx_collection.test.ts index 750e09e34fb3..5cb61cbeedd9 100644 --- a/yarn-project/p2p/src/services/tx_collection/tx_collection.test.ts +++ b/yarn-project/p2p/src/services/tx_collection/tx_collection.test.ts @@ -16,9 +16,8 @@ import type { TxPoolV2, TxPoolV2Events } from '../../mem_pools/tx_pool_v2/interf import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js'; import type { BlockTxsSource } from '../reqresp/protocols/block_txs/block_txs_reqresp.js'; import { type TxCollectionConfig, txCollectionConfigMappings } from './config.js'; -import { FastTxCollection, type IReqRespTxsCollector } from './fast_tx_collection.js'; import type { FileStoreTxSource } from './file_store_tx_source.js'; -import { type FastCollectionRequest, TxCollection } from './tx_collection.js'; +import { type FastCollectionRequest, type IReqRespTxsCollector, TxCollection } from './tx_collection.js'; import type { TxSource } from './tx_source.js'; describe('TxCollection', () => { @@ -95,7 +94,7 @@ describe('TxCollection', () => { const setReqRespResponse = (promise: Promise) => { let lastArgs: Parameters | undefined; - txCollection.fastCollection.reqRespTxsCollector = jest.fn().mockImplementation((...x) => { + txCollection.reqRespTxsCollector = jest.fn().mockImplementation((...x) => { lastArgs = x; return promise; }); @@ -147,16 +146,16 @@ describe('TxCollection', () => { setReqRespTxs([]); }); - afterEach(async () => { - await txCollection.stop(); + afterEach(() => { + txCollection.stop(); }); - describe('fast collection', () => { + describe('fast tx collection', () => { it('collects txs from nodes only', async () => { setNodeTxs(nodes[0], txs); const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); expect(nodes[0].getTxsByHash).toHaveBeenCalledWith(txHashes); - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); expectTxsMinedInPool(txs); expect(collected).toEqual(txs); }); @@ -191,7 +190,7 @@ describe('TxCollection', () => { const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); expect(nodes[0].getTxsByHash).toHaveBeenCalledWith(txHashes); expect(nodes[1].getTxsByHash).toHaveBeenCalledWith(txHashes); - expect(txCollection.fastCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); + expect(txCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); expectLastReqRespCollectorArgs(argsGetter); expectTxsMinedInPool([txs[0]]); expectTxsMinedInPool([txs[1]]); @@ -203,12 +202,26 @@ describe('TxCollection', () => { txCollection = new TestTxCollection(mockP2PService, [], constants, txPool, config, [], dateProvider); const argsGetter = setReqRespTxs(txs); const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); - expect(txCollection.fastCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); + expect(txCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); expectLastReqRespCollectorArgs(argsGetter); expectTxsMinedInPool(txs); expect(collected).toEqual(txs); }); + it('starts reqresp immediately when no nodes are configured', async () => { + // Large initial wait — if reqresp were gated by it, the collection would take ~10s. + config = { ...config, txCollectionFastNodesTimeoutBeforeReqRespMs: 10_000 }; + txCollection = new TestTxCollection(mockP2PService, [], constants, txPool, config, [], dateProvider); + setReqRespTxs(txs); + + const startTime = dateProvider.now(); + const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); + + expect(txCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); + expect(dateProvider.now() - startTime).toBeLessThan(1000); + expect(collected).toEqual(txs); + }); + it('keeps retrying txs not found until deadline', async () => { deadline = new Date(dateProvider.now() + 2000); setNodeTxs(nodes[0], [txs[0]]); @@ -219,7 +232,7 @@ describe('TxCollection', () => { expect(dateProvider.now()).toBeGreaterThanOrEqual(+deadline - 5); expect(nodes[0].getTxsByHash).toHaveBeenCalledWith(txHashes); expect(nodes[0].getTxsByHash).toHaveBeenCalledWith([txHashes[2]]); - expect(txCollection.fastCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); + expect(txCollection.reqRespTxsCollector).toHaveBeenCalledTimes(1); expectLastReqRespCollectorArgs(argsGetter); expectTxsMinedInPool([txs[0]]); expectTxsMinedInPool([txs[1]]); @@ -274,15 +287,15 @@ describe('TxCollection', () => { const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); expect(collected).toEqual([]); expect(nodes[0].getTxsByHash).not.toHaveBeenCalled(); - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); }); describe('cancellation signals', () => { /** Captures the FastCollectionRequest during collectFast, before it's removed in finally. */ const captureRequest = () => { let captured: FastCollectionRequest | undefined; - const origCollectFast = txCollection.fastCollection.collectFast.bind(txCollection.fastCollection); - jest.spyOn(txCollection.fastCollection, 'collectFast').mockImplementation((request, opts) => { + const origCollectFast = txCollection.collectFast.bind(txCollection); + jest.spyOn(txCollection, 'collectFast').mockImplementation((request, opts) => { captured = request; return origCollectFast(request, opts); }); @@ -319,7 +332,7 @@ describe('TxCollection', () => { setReqRespTxs([]); const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); expect(collected).toEqual(txs); }); @@ -332,7 +345,7 @@ describe('TxCollection', () => { const collected = await txCollection.collectFastForBlock(block, txHashes, { deadline }); - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); expect(dateProvider.now()).toBeGreaterThanOrEqual(+deadline - 5); expect(collected).toEqual([]); }); @@ -382,13 +395,13 @@ describe('TxCollection', () => { const request = getRequest(); expect(request).toBeDefined(); // Reqresp should not have started yet — we're still in the initial wait - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); request.requestTracker.cancel(); await collectionPromise; // Should have exited without ever starting reqresp - expect(txCollection.fastCollection.reqRespTxsCollector).not.toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).not.toHaveBeenCalled(); expect(dateProvider.now()).toBeLessThan(+deadline); }); @@ -406,7 +419,7 @@ describe('TxCollection', () => { const collectionPromise = txCollection.collectFastForBlock(block, txHashes, { deadline }); await sleep(200); - expect(txCollection.fastCollection.reqRespTxsCollector).toHaveBeenCalled(); + expect(txCollection.reqRespTxsCollector).toHaveBeenCalled(); getRequest().requestTracker.cancel(); collectorPromise.resolve([]); @@ -439,7 +452,7 @@ describe('TxCollection', () => { expect(request).toBeDefined(); expect(request.requestTracker.checkCancelled()).toBe(false); - await txCollection.stop(); + txCollection.stop(); expect(request.requestTracker.checkCancelled()).toBe(true); collectorPromise.resolve([]); @@ -489,13 +502,13 @@ describe('TxCollection', () => { const collectionPromise = txCollection.collectFastForBlock(block, txHashes, { deadline }); await sleep(100); - expect(txCollection.fastCollection.requests.size).toBe(1); + expect(txCollection.requests.size).toBe(1); txCollection.stopCollectingForBlocksUpTo(block.number); collectorPromise.resolve([]); await collectionPromise; - expect(txCollection.fastCollection.requests.size).toBe(0); + expect(txCollection.requests.size).toBe(0); }); }); }); @@ -529,17 +542,15 @@ describe('TxCollection', () => { it('collects txs from file store after configured delay', async () => { setFileStoreTxs(fileStoreSources[0], txs); - await txCollection.start(); - deadline = new Date(dateProvider.now() + 500); + // Long deadline so the collection ends when file store finds the txs (not when deadline fires) + deadline = new Date(dateProvider.now() + 5000); const collectionPromise = txCollection.collectFastForBlock(block, txHashes, { deadline }); - // File store should not have been called yet (delay hasn't elapsed) + // File store should not have been called yet (delays haven't elapsed) expect(fileStoreSources[0].getTxsByHash).not.toHaveBeenCalled(); - // Advance time past the configured file store delay - dateProvider.setTime(dateProvider.now() + 200); - // Allow the async sleep resolution and worker processing to complete - await sleep(200); + // Wait for: node wait (200ms default) + file store delay (100ms) + worker processing + await sleep(500); await collectionPromise; // File store should now have been called for each tx @@ -549,34 +560,28 @@ describe('TxCollection', () => { it('does not download txs from file store if found via P2P before delay expires', async () => { setFileStoreTxs(fileStoreSources[0], txs); - await txCollection.start(); - deadline = new Date(dateProvider.now() + 500); + // Long deadline so the collection ends when all txs are found (not when deadline fires) + deadline = new Date(dateProvider.now() + 5000); const collectionPromise = txCollection.collectFastForBlock(block, txHashes, { deadline }); - // Simulate all txs found via P2P before delay expires + // Simulate all txs found via P2P before delay expires — this cancels the tracker immediately txCollection.handleTxsAddedToPool({ txs, source: 'test' }); - // Now advance time past the delay - dateProvider.setTime(dateProvider.now() + 200); await sleep(100); await collectionPromise; - // File store should not have downloaded any txs because they were all found + // File store should not have downloaded any txs because they were all found before the delay const allCalls = fileStoreSources.flatMap(s => s.getTxsByHash.mock.calls); expect(allCalls.length).toBe(0); }); }); }); -class TestFastTxCollection extends FastTxCollection { +class TestTxCollection extends TxCollection { // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections declare requests: Set; - declare collectFast: (request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) => Promise; - declare reqRespTxsCollector?: IReqRespTxsCollector; -} - -class TestTxCollection extends TxCollection { - declare fastCollection: TestFastTxCollection; declare fileStoreFastCollection: TxCollection['fileStoreFastCollection']; declare handleTxsAddedToPool: TxPoolV2Events['txs-added']; + declare collectFast: (request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) => Promise; + declare reqRespTxsCollector?: IReqRespTxsCollector; } diff --git a/yarn-project/p2p/src/services/tx_collection/tx_collection.ts b/yarn-project/p2p/src/services/tx_collection/tx_collection.ts index 9a609fb408a3..30814392650c 100644 --- a/yarn-project/p2p/src/services/tx_collection/tx_collection.ts +++ b/yarn-project/p2p/src/services/tx_collection/tx_collection.ts @@ -1,7 +1,8 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; +import { times } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider } from '@aztec/foundation/timer'; +import { DateProvider, elapsed } from '@aztec/foundation/timer'; import type { L2Block, L2BlockInfo } from '@aztec/stdlib/block'; import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; import type { BlockProposal } from '@aztec/stdlib/p2p'; @@ -12,12 +13,13 @@ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-clien import type { PeerId } from '@libp2p/interface'; import type { TxPoolV2, TxPoolV2Events } from '../../mem_pools/tx_pool_v2/interfaces.js'; +import { BatchTxRequester } from '../reqresp/batch-tx-requester/batch_tx_requester.js'; import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js'; +import type { BlockTxsSource } from '../reqresp/index.js'; import type { TxCollectionConfig } from './config.js'; -import { FastTxCollection } from './fast_tx_collection.js'; import { FileStoreTxCollection } from './file_store_tx_collection.js'; import type { FileStoreTxSource } from './file_store_tx_source.js'; -import type { IRequestTracker } from './request_tracker.js'; +import { type IRequestTracker, RequestTracker } from './request_tracker.js'; import { type TxAddContext, TxCollectionSink } from './tx_collection_sink.js'; import type { TxSource } from './tx_source.js'; @@ -32,20 +34,36 @@ export type FastCollectionRequest = FastCollectionRequestInput & { blockInfo: L2BlockInfo; }; +/** + * Collect missing transactions for a block or proposal via reqresp. + * @param requestTracker - The missing transactions tracker + * @param blockTxsSource - The block or proposal containing the transactions + * @param pinnedPeer - Optional peer expected to have the transactions + * @returns The collected transactions + */ +export type IReqRespTxsCollector = ( + requestTracker: IRequestTracker, + blockTxsSource: BlockTxsSource, + pinnedPeer: PeerId | undefined, +) => Promise; + /** * Coordinates tx collection from remote RPC nodes, reqresp, and file store. * - * The fast collection methods quickly gather txs from RPC nodes and reqresp, usually for attesting - * to block proposals or preparing to prove an epoch. A delayed file-store fallback can also fetch - * txs if configured. Both paths send txs to the collection sink, which handles metrics and adds - * them to the tx pool. Whenever a tx is added to either the sink or the pool, this service is - * notified via events and stops collecting that tx across all in-flight requests. + * Runs a sequential pipeline: node RPC → reqresp → file store. Node collection starts immediately, + * reqresp starts after a configured delay, and file store (if configured) starts after a further + * delay. All paths send txs to the collection sink, which handles metrics and adds them to the + * tx pool. Whenever a tx is added to the sink or the pool, this service is notified and stops + * collecting that tx across all in-flight requests. */ export class TxCollection { - /** Fast collection methods */ - protected readonly fastCollection: FastTxCollection; + // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + protected requests: Set = new Set(); - /** File store collection for fast (proposal/proving) path */ + /** The collector for txs via reqresp */ + protected reqRespTxsCollector?: IReqRespTxsCollector; + + /** File store collection for the fast (proposal/proving) path */ protected readonly fileStoreFastCollection: FileStoreTxCollection; /** Handles txs found by collection paths before adding to the pool */ @@ -57,12 +75,6 @@ export class TxCollection { /** Handler for the txs-added event from the tx collection sink */ protected readonly handleTxsFound: TxPoolV2Events['txs-added']; - /** Whether the service has been started. */ - private started = false; - - /** Whether file store sources are configured. */ - private readonly hasFileStoreSources: boolean; - constructor( private readonly p2pService: BatchTxRequesterLibP2PService, private readonly nodes: TxSource[], @@ -76,16 +88,18 @@ export class TxCollection { ) { this.txCollectionSink = new TxCollectionSink(this.txPool, telemetryClient, this.log); - this.fastCollection = new FastTxCollection( - this.p2pService, - this.nodes, - this.txCollectionSink, - this.config, - this.dateProvider, - this.log, - ); + this.reqRespTxsCollector = (requestTracker, blockTxsSource, pinnedPeer) => + BatchTxRequester.collectAllTxs( + new BatchTxRequester( + requestTracker, + blockTxsSource, + pinnedPeer, + this.p2pService, + this.log, + this.dateProvider, + ).run(), + ); - this.hasFileStoreSources = fileStoreSources.length > 0; this.fileStoreFastCollection = new FileStoreTxCollection( fileStoreSources, this.txCollectionSink, @@ -112,19 +126,11 @@ export class TxCollection { this.txPool.on('txs-added', this.handleTxsAddedToPool); } - /** Starts all collection loops. */ - public start(): Promise { - this.started = true; - this.fileStoreFastCollection.start(); - - // TODO(palla/txs): Collect mined unproven tx hashes for txs we dont have in the pool and populate missingTxs on startup - return Promise.resolve(); - } - - /** Stops all activity. */ - public async stop() { - this.started = false; - await Promise.all([this.fastCollection.stop(), this.fileStoreFastCollection.stop()]); + /** Stops all activity. Cancels in-flight requests; file store workers self-terminate. */ + public stop() { + this.requests.forEach(request => { + request.requestTracker.cancel(); + }); this.txPool.removeListener('txs-added', this.handleTxsAddedToPool); this.txCollectionSink.removeListener('txs-added', this.handleTxsFound); @@ -145,48 +151,295 @@ export class TxCollection { } /** Collects the set of txs for the given proposal or block as fast as possible */ - public collectFastFor( + public async collectFastFor( input: FastCollectionRequestInput, txHashes: TxHash[] | string[], opts: { deadline: Date; pinnedPeer?: PeerId }, ) { + const timeout = opts.deadline.getTime() - this.dateProvider.now(); + if (timeout <= 0) { + this.log.warn(`Deadline for fast tx collection is in the past (${timeout}ms)`, { + deadline: opts.deadline.getTime(), + now: this.dateProvider.now(), + }); + return []; + } + const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : h)); - // Delay file store collection to give P2P methods time to find txs first - if (this.hasFileStoreSources) { - const context = this.getAddContextForInput(input); - sleep(this.config.txCollectionFileStoreFastDelayMs) - .then(() => { - if (!this.started) { - return; - } + const blockInfo: L2BlockInfo = + input.type === 'proposal' + ? { ...input.blockProposal.toBlockInfo(), blockNumber: input.blockNumber } + : { ...input.block.toBlockInfo() }; + + const request: FastCollectionRequest = { + ...input, + blockInfo, + requestTracker: RequestTracker.create(hashes, opts.deadline, this.dateProvider), + }; + + const [duration] = await elapsed(() => this.collectFast(request, { pinnedPeer: opts.pinnedPeer })); + + this.log.verbose( + `Collected ${request.requestTracker.collectedTxs.length} txs out of ${hashes.length} for ${input.type} at slot ${blockInfo.slotNumber}`, + { + ...blockInfo, + duration, + requestType: input.type, + missingTxs: [...request.requestTracker.missingTxHashes], + }, + ); + return request.requestTracker.collectedTxs; + } + + protected async collectFast(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) { + this.requests.add(request); + const { blockInfo } = request; + + this.log.debug( + `Starting fast collection of ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`, + { ...blockInfo, requestType: request.type, deadline: request.requestTracker.deadline }, + ); + + try { + // 1. Start node collection in the background. + // Note: this will be a noop if no nodes are configured. + const nodeCollectionPromise = this.collectFastFromNodes(request); + + // 2. Wait before starting reqresp, interruptible by cancellation or node exhaustion. + await Promise.race([ + request.requestTracker.cancellationToken, + sleep(this.config.txCollectionFastNodesTimeoutBeforeReqRespMs), + nodeCollectionPromise, // If node collection has finished (or if there are no nodes configured), we can exit early. + ]); + + // 3. Start reqresp in the background (runs in parallel with node collection). + // Note: this will be a noop if all TXs were already found. + const reqRespPromise = this.collectFastViaReqResp(request, opts); + + // 4. Wait before starting file store, interruptible by cancellation. + await Promise.race([ + request.requestTracker.cancellationToken, + sleep(this.config.txCollectionFileStoreFastDelayMs), + reqRespPromise, // If reqresp has finished, we can exit early. + ]); + + // 5. Start file store collection in the background. Self-terminates on tracker cancel / all-found. + // Note: this will be a noop if all TXs were already found. + const fileStorePromise = this.fileStoreFastCollection.startCollecting( + request.requestTracker, + this.getAddContext(request), + ); + + // 6. Wait for all paths to settle. + // NOTE: The request will automatically be cancelled after `opt.deadline` is reached. + await Promise.allSettled([reqRespPromise, nodeCollectionPromise, fileStorePromise]); + } catch (err) { + this.log.error(`Error collecting txs for ${request.type} for slot ${blockInfo.slotNumber}`, err, { + ...blockInfo, + missingTxs: request.requestTracker.missingTxHashes.values().map(txHash => txHash.toString()), + }); + } finally { + request.requestTracker.cancel(); + this.requests.delete(request); + } + } - // Only queue txs that are still missing after the delay. - const missingTxHashStrings = new Set(this.fastCollection.getMissingTxHashes().map(hash => hash.toString())); - const missingTxHashesToCollect = hashes.filter(hash => missingTxHashStrings.has(hash.toString())); - if (missingTxHashesToCollect.length > 0) { - this.fileStoreFastCollection.startCollecting(missingTxHashesToCollect, context, opts.deadline); + /** + * Starts collecting txs from all configured nodes. We send `txCollectionFastMaxParallelRequestsPerNode` requests + * in parallel to each node. We keep track of the number of attempts made to collect each tx, so we can prioritize + * the txs that have been requested less often whenever we need to send a new batch of requests. We ensure that no + * tx is requested more than once at the same time to the same node. + */ + private async collectFastFromNodes(request: FastCollectionRequest): Promise { + if (this.nodes.length === 0) { + return; + } + + // Keep a shared priority queue of all txs pending to be requested, sorted by the number of attempts made to collect them. + const attemptsPerTx = [...request.requestTracker.missingTxHashes].map(txHash => ({ + txHash, + attempts: 0, + found: false, + })); + + // Returns once we have finished all node loops. Each loop finishes when the deadline is hit, or all txs have been collected. + await Promise.allSettled(this.nodes.map(node => this.collectFastFromNode(request, node, attemptsPerTx))); + } + + private async collectFastFromNode( + request: FastCollectionRequest, + node: TxSource, + attemptsPerTx: { txHash: string; attempts: number; found: boolean }[], + ) { + const notFinished = () => !request.requestTracker.checkCancelled(); + + const maxParallelRequests = this.config.txCollectionFastMaxParallelRequestsPerNode; + const maxBatchSize = this.config.txCollectionNodeRpcMaxBatchSize; + const activeRequestsToThisNode = new Set(); // Track the txs being actively requested to this node + + const processBatch = async () => { + while (notFinished()) { + // Pull tx hashes from the attemptsPerTx array, which is sorted by attempts, + // so we prioritize txs that have been requested less often. + const batch = []; + let index = 0; + while (batch.length < maxBatchSize) { + const txToRequest = attemptsPerTx[index++]; + if (!txToRequest) { + // No more txs to process + break; + } else if (!request.requestTracker.isMissing(txToRequest.txHash)) { + // Mark as found if it was found somewhere else, we'll then remove it from the array. + // We don't delete it now since 'array.splice' is pretty expensive, so we do it after sorting. + txToRequest.found = true; + } else if (!activeRequestsToThisNode.has(txToRequest.txHash)) { + // If the tx is not already being requested to this node, add it to the current batch and increase attempts. + // Note that we increase the attempts *before* making the request, so the next `collectFastFromNode` that + // needs to grab txs to send, will pick txs that have been requested less often, instead of all requesting + // the same txs at the same time. + batch.push(txToRequest); + activeRequestsToThisNode.add(txToRequest.txHash); + txToRequest.attempts++; } - }) - .catch(err => this.log.error('Error in file store fast delay', err)); + } + + // After modifying the array by removing txs or updating attempts, re-sort it and trim the found txs from the end. + attemptsPerTx.sort((a, b) => + a.found === b.found ? a.attempts - b.attempts : Number(a.found) - Number(b.found), + ); + const firstFoundTxIndex = attemptsPerTx.findIndex(tx => tx.found); + if (firstFoundTxIndex !== -1) { + attemptsPerTx.length = firstFoundTxIndex; + } + + // If we see no more txs to request, we can stop this "process" loop + if (batch.length === 0) { + return; + } + + const txHashes = batch.map(({ txHash }) => txHash); + // Collect this batch from the node + await this.txCollectionSink.collect( + async () => { + const result = await node.getTxsByHash(txHashes.map(TxHash.fromString)); + for (const tx of result.validTxs) { + request.requestTracker.markFetched(tx); + } + return result; + }, + txHashes, + { + description: `fast ${node.getInfo()}`, + node: node.getInfo(), + method: 'fast-node-rpc', + ...request.blockInfo, + }, + this.getAddContext(request), + ); + + // Clear from the active requests the txs we just requested + for (const requestedTx of batch) { + activeRequestsToThisNode.delete(requestedTx.txHash); + } + + // Sleep a bit until hitting the node again, but wake up immediately on cancellation + if (notFinished()) { + await Promise.race([ + sleep(this.config.txCollectionFastNodeIntervalMs), + request.requestTracker.cancellationToken, + ]); + } + } + }; + + // Kick off N parallel requests to the node, up to the maxParallelRequests limit + await Promise.all(times(maxParallelRequests, processBatch)); + } + + private async collectFastViaReqResp(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) { + const pinnedPeer = opts.pinnedPeer; + const blockInfo = request.blockInfo; + const slotNumber = blockInfo.slotNumber; + if (request.requestTracker.timeoutMs < 100) { + this.log.warn( + `Not initiating fast reqresp for txs for ${request.type} at slot ${blockInfo.slotNumber} due to timeout`, + { timeoutMs: request.requestTracker.timeoutMs, ...blockInfo }, + ); + return; + } + + if (request.requestTracker.checkCancelled()) { + this.log.debug(`No txs to collect via reqresp for ${request.type} at slot ${blockInfo.slotNumber}`, { + ...blockInfo, + }); + return; } - return this.fastCollection.collectFastFor(input, txHashes, opts); + this.log.debug( + `Starting fast reqresp for ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`, + { ...blockInfo, timeoutMs: request.requestTracker.timeoutMs, pinnedPeer }, + ); + + try { + await this.txCollectionSink.collect( + async () => { + let blockTxsSource: BlockTxsSource; + if (request.type === 'proposal') { + blockTxsSource = request.blockProposal; + } else if (request.type === 'block') { + blockTxsSource = { + txHashes: request.block.body.txEffects.map(e => e.txHash), + archive: request.block.archive.root, + }; + } else { + throw new Error(`Unknown request type: ${(request as { type: string }).type}`); + } + + const result = await this.reqRespTxsCollector!(request.requestTracker, blockTxsSource, pinnedPeer); + return { validTxs: result, invalidTxHashes: [] }; + }, + Array.from(request.requestTracker.missingTxHashes), + { description: `reqresp for slot ${slotNumber}`, method: 'fast-req-resp', ...opts, ...request.blockInfo }, + this.getAddContext(request), + ); + } catch (err) { + this.log.error(`Error sending fast reqresp request for txs`, err, { + txs: [...request.requestTracker.missingTxHashes], + ...blockInfo, + }); + } } - /** Returns the TxAddContext for the given fast collection request input */ - private getAddContextForInput(input: FastCollectionRequestInput): TxAddContext { - if (input.type === 'proposal') { - return { type: 'proposal', blockHeader: input.blockProposal.blockHeader }; + /** Returns the TxAddContext for the given request, used by the sink to add txs to the pool correctly. */ + private getAddContext(request: FastCollectionRequest): TxAddContext { + if (request.type === 'proposal') { + return { type: 'proposal', blockHeader: request.blockProposal.blockHeader }; } else { - return { type: 'mined', block: input.block }; + return { type: 'mined', block: request.block }; } } - /** Mark the given txs as found. Stops collecting them. */ + /** Mark the given txs as found. Stops collecting them across all in-flight requests. */ private foundTxs(txs: Tx[]) { - this.fastCollection.foundTxs(txs); - this.fileStoreFastCollection.foundTxs(txs); + for (const request of this.requests) { + for (const tx of txs) { + if (request.requestTracker.markFetched(tx)) { + this.log.trace(`Found tx ${tx.txHash.toString()} for fast collection request`, { + ...request.blockInfo, + txHash: tx.txHash.toString(), + type: request.type, + }); + if (request.requestTracker.allFetched()) { + this.log.trace(`All txs found for fast collection request`, { + ...request.blockInfo, + type: request.type, + }); + break; + } + } + } + } } /** @@ -194,8 +447,11 @@ export class TxCollection { * To be called when we no longer care about gathering txs up to a certain block, eg when they become proven or finalized. */ public stopCollectingForBlocksUpTo(blockNumber: BlockNumber): void { - this.fastCollection.stopCollectingForBlocksUpTo(blockNumber); - this.fileStoreFastCollection.clearPending(); + for (const request of this.requests) { + if (request.blockInfo.blockNumber <= blockNumber) { + request.requestTracker.cancel(); + } + } } /** @@ -203,7 +459,10 @@ export class TxCollection { * To be called when there is a chain prune and previously mined txs are no longer relevant. */ public stopCollectingForBlocksAfter(blockNumber: BlockNumber): void { - this.fastCollection.stopCollectingForBlocksAfter(blockNumber); - this.fileStoreFastCollection.clearPending(); + for (const request of this.requests) { + if (request.blockInfo.blockNumber > blockNumber) { + request.requestTracker.cancel(); + } + } } } diff --git a/yarn-project/p2p/src/services/tx_file_store/tx_file_store.ts b/yarn-project/p2p/src/services/tx_file_store/tx_file_store.ts index 063c6256680f..25b7d995c63e 100644 --- a/yarn-project/p2p/src/services/tx_file_store/tx_file_store.ts +++ b/yarn-project/p2p/src/services/tx_file_store/tx_file_store.ts @@ -1,3 +1,4 @@ +import { FifoSet } from '@aztec/foundation/fifo-set'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { RunningPromise } from '@aztec/foundation/promise'; import { makeBackoff, retry } from '@aztec/foundation/retry'; @@ -10,6 +11,8 @@ import type { TxPoolV2 } from '../../mem_pools/index.js'; import type { TxFileStoreConfig } from './config.js'; import { TxFileStoreInstrumentation } from './instrumentation.js'; +const MAX_RECENT_UPLOADS = 1000; + /** * Uploads validated transactions to a file store as a fallback retrieval mechanism. * Listens to TxPool txs-added events and uploads txs asynchronously with bounded concurrency. @@ -21,9 +24,7 @@ export class TxFileStore { private readonly handleTxsAdded: (args: { txs: Tx[]; source?: string }) => void; /** Recently uploaded tx hashes for deduplication. */ - private recentUploads: Set = new Set(); - private recentUploadsOrder: string[] = []; - private readonly maxRecentUploads = 1000; + private recentUploads = FifoSet.withLimit(MAX_RECENT_UPLOADS); private constructor( private readonly fileStore: FileStore, @@ -127,24 +128,11 @@ export class TxFileStore { const path = `${this.basePath}/txs/${txHash}.bin`; const timer = new Timer(); - if (this.recentUploads.has(txHash)) { + if (!this.recentUploads.addIfAbsent(txHash)) { return; } try { - this.recentUploads.add(txHash); - this.recentUploadsOrder.push(txHash); - - if (this.recentUploadsOrder.length > this.maxRecentUploads) { - // delete old entries in recentUploads - for (const txHashToRemove of this.recentUploadsOrder.splice( - 0, - this.recentUploadsOrder.length - this.maxRecentUploads, - )) { - this.recentUploads.delete(txHashToRemove); - } - } - await retry( () => this.fileStore.save(path, tx.toBuffer(), { compress: true }), `Uploading tx ${txHash}`, diff --git a/yarn-project/p2p/src/services/tx_provider.ts b/yarn-project/p2p/src/services/tx_provider.ts index 311e31162351..5004ba6eb532 100644 --- a/yarn-project/p2p/src/services/tx_provider.ts +++ b/yarn-project/p2p/src/services/tx_provider.ts @@ -32,6 +32,11 @@ export class TxProvider implements ITxProvider { this.instrumentation = new TxProviderInstrumentation(client, 'TxProvider'); } + /** Returns whether each tx hash is currently in the local tx pool. */ + public hasTxs(txHashes: TxHash[]): Promise { + return this.txPool.hasTxs(txHashes); + } + /** Returns txs from the tx pool given their hashes.*/ public async getAvailableTxs(txHashes: TxHash[]): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> { const response = await this.txPool.getTxsByHash(txHashes); diff --git a/yarn-project/p2p/src/test-helpers/mock-pubsub.ts b/yarn-project/p2p/src/test-helpers/mock-pubsub.ts index a537a25c5e35..ac1f1109b9ac 100644 --- a/yarn-project/p2p/src/test-helpers/mock-pubsub.ts +++ b/yarn-project/p2p/src/test-helpers/mock-pubsub.ts @@ -23,15 +23,12 @@ import type { MemPools } from '../mem_pools/interface.js'; import { DummyPeerDiscoveryService, DummyPeerManager, LibP2PService } from '../services/index.js'; import type { P2PReqRespConfig } from '../services/reqresp/config.js'; import type { ConnectionSampler } from '../services/reqresp/connection-sampler/connection_sampler.js'; -import { - type ReqRespInterface, - type ReqRespResponse, - type ReqRespSubProtocol, - type ReqRespSubProtocolHandler, - type ReqRespSubProtocolHandlers, - type ReqRespSubProtocolValidators, - type SubProtocolMap, - responseFromBuffer, +import type { + ReqRespInterface, + ReqRespResponse, + ReqRespSubProtocol, + ReqRespSubProtocolHandler, + ReqRespSubProtocolHandlers, } from '../services/reqresp/interface.js'; import { ReqRespStatus } from '../services/reqresp/status.js'; import { GossipSubEvent } from '../types/index.js'; @@ -89,8 +86,8 @@ export function getMockPubSubP2PServiceFactory( /** * Mock implementation of ReqRespInterface that routes requests to other peers' handlers through the mock network. - * When a peer calls sendBatchRequest, the mock iterates over network peers and invokes their registered handler - * for the sub-protocol, simulating the request-response protocol without actual libp2p streams. + * When a peer calls sendRequestToPeer, the mock looks up the target peer's registered handler for the + * sub-protocol and invokes it, simulating the request-response protocol without actual libp2p streams. */ class MockReqResp implements ReqRespInterface { private handlers: Partial = {}; @@ -106,19 +103,12 @@ class MockReqResp implements ReqRespInterface { updateConfig(_config: Partial): void {} setShouldRejectPeer(): void {} - start( - subProtocolHandlers: Partial, - _subProtocolValidators: ReqRespSubProtocolValidators, - ): Promise { + start(subProtocolHandlers: Partial): Promise { Object.assign(this.handlers, subProtocolHandlers); return Promise.resolve(); } - addSubProtocol( - subProtocol: ReqRespSubProtocol, - handler: ReqRespSubProtocolHandler, - _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { + addSubProtocol(subProtocol: ReqRespSubProtocol, handler: ReqRespSubProtocolHandler): Promise { this.handlers[subProtocol] = handler; return Promise.resolve(); } @@ -132,46 +122,6 @@ class MockReqResp implements ReqRespInterface { return this.handlers[subProtocol]; } - async sendBatchRequest( - subProtocol: SubProtocol, - requests: InstanceType[], - pinnedPeer: PeerId | undefined, - _timeoutMs?: number, - _maxPeers?: number, - _maxRetryAttempts?: number, - ): Promise[]> { - const responses: InstanceType[] = []; - const peers = this.network.getReqRespPeers().filter(p => !p.peerId.equals(this.peerId)); - const targetPeers = pinnedPeer ? peers.filter(p => p.peerId.equals(pinnedPeer)) : peers; - const delayMs = this.network.getPropagationDelayMs(); - - if (delayMs > 0) { - await sleep(delayMs); - } - - for (const request of requests) { - const requestBuffer = request.toBuffer(); - for (const peer of targetPeers) { - const handler = peer.getHandler(subProtocol); - if (!handler) { - continue; - } - try { - const responseBuffer = await handler(this.peerId, requestBuffer); - if (responseBuffer.length > 0) { - const response = responseFromBuffer(subProtocol, responseBuffer); - responses.push(response as InstanceType); - break; - } - } catch (err) { - this.logger.debug(`Mock reqresp handler error from peer ${peer.peerId}`, { err }); - } - } - } - - return responses; - } - async sendRequestToPeer( peerId: PeerId, subProtocol: ReqRespSubProtocol, diff --git a/yarn-project/p2p/src/test-helpers/reqresp-nodes.ts b/yarn-project/p2p/src/test-helpers/reqresp-nodes.ts index 8c6d75faa637..8f9bbbbda460 100644 --- a/yarn-project/p2p/src/test-helpers/reqresp-nodes.ts +++ b/yarn-project/p2p/src/test-helpers/reqresp-nodes.ts @@ -43,8 +43,6 @@ import { ReqRespSubProtocol, type ReqRespSubProtocolHandlers, type ReqRespSubProtocolRateLimits, - type ReqRespSubProtocolValidators, - noopValidator, } from '../services/reqresp/interface.js'; import { pingHandler } from '../services/reqresp/protocols/index.js'; import { ReqResp } from '../services/reqresp/reqresp.js'; @@ -199,17 +197,6 @@ export const MOCK_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers = { [ReqRespSubProtocol.BLOCK_TXS]: (_msg: any) => Promise.resolve(Buffer.from('block_txs')), }; -// By default, all requests are valid -// If you want to test an invalid response, you can override the validator -export const MOCK_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = { - [ReqRespSubProtocol.PING]: noopValidator, - [ReqRespSubProtocol.STATUS]: noopValidator, - [ReqRespSubProtocol.TX]: noopValidator, - [ReqRespSubProtocol.GOODBYE]: noopValidator, - [ReqRespSubProtocol.AUTH]: noopValidator, - [ReqRespSubProtocol.BLOCK_TXS]: noopValidator, -}; - /** * @param numberOfNodes - the number of nodes to create * @returns An array of the created nodes @@ -222,13 +209,9 @@ export const createNodes = ( return timesParallel(numberOfNodes, () => createReqResp(peerScoring, rateLimits)); }; -export const startNodes = async ( - nodes: ReqRespNode[], - subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS, - subProtocolValidators = MOCK_SUB_PROTOCOL_VALIDATORS, -) => { +export const startNodes = async (nodes: ReqRespNode[], subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS) => { for (const node of nodes) { - await node.req.start(subProtocolHandlers, subProtocolValidators); + await node.req.start(subProtocolHandlers); } }; diff --git a/yarn-project/p2p/src/test-helpers/test_tx_provider.ts b/yarn-project/p2p/src/test-helpers/test_tx_provider.ts index 20ae98e634f2..6e4ae3a9b91a 100644 --- a/yarn-project/p2p/src/test-helpers/test_tx_provider.ts +++ b/yarn-project/p2p/src/test-helpers/test_tx_provider.ts @@ -31,6 +31,11 @@ export class TestTxProvider implements ITxProvider { return this.getTxsByHashes(txHashes); } + /** Returns whether each tx hash is in the seeded collection. */ + hasTxs(txHashes: TxHash[]): Promise { + return Promise.resolve(txHashes.map(h => this.txs.has(h.toString()))); + } + /** Get txs for a block proposal, returning any seeded txs that match the requested hashes. */ getTxsForBlockProposal( blockProposal: BlockProposal, diff --git a/yarn-project/p2p/src/test-helpers/testbench-utils.ts b/yarn-project/p2p/src/test-helpers/testbench-utils.ts index 17bd755a724c..2c1d982f92fb 100644 --- a/yarn-project/p2p/src/test-helpers/testbench-utils.ts +++ b/yarn-project/p2p/src/test-helpers/testbench-utils.ts @@ -4,12 +4,7 @@ import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; import type { Logger } from '@aztec/foundation/log'; import type { L2Block, L2BlockId } from '@aztec/stdlib/block'; import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import type { - BlockProposal, - CheckpointAttestation, - CheckpointProposal, - CheckpointProposalCore, -} from '@aztec/stdlib/p2p'; +import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore } from '@aztec/stdlib/p2p'; import { type BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx'; import EventEmitter from 'events'; @@ -215,6 +210,7 @@ export class InMemoryTxPool extends EventEmitter implements TxPoolV2 { */ export class InMemoryAttestationPool { private proposals = new Map(); + private checkpoints = new Map(); tryAddBlockProposal(blockProposal: BlockProposal): Promise { const id = blockProposal.archive.toString(); @@ -230,12 +226,25 @@ export class InMemoryAttestationPool { return Promise.resolve(this.proposals.get(id)); } - tryAddCheckpointProposal(_proposal: CheckpointProposal): Promise { + tryAddCheckpointProposal(proposal: CheckpointProposalCore): Promise { + const proposals = this.checkpoints.get(proposal.slotNumber) ?? []; + proposals.push(proposal); + this.checkpoints.set(proposal.slotNumber, proposals); return Promise.resolve({ added: true, alreadyExists: false, count: 1 }); } - getCheckpointProposal(_slot: SlotNumber): Promise { - return Promise.resolve(undefined); + getCheckpointProposal(slot: SlotNumber): Promise { + return Promise.resolve(this.checkpoints.get(slot)?.[0]); + } + + getProposalsForSlot(slot: SlotNumber): Promise<{ + blockProposals: BlockProposal[]; + checkpointProposals: CheckpointProposalCore[]; + }> { + return Promise.resolve({ + blockProposals: [...this.proposals.values()].filter(proposal => proposal.slotNumber === slot), + checkpointProposals: this.checkpoints.get(slot) ?? [], + }); } async addOwnCheckpointAttestations(_attestations: CheckpointAttestation[]): Promise {} @@ -262,11 +271,12 @@ export class InMemoryAttestationPool { } isEmpty(): Promise { - return Promise.resolve(this.proposals.size === 0); + return Promise.resolve(this.proposals.size === 0 && this.checkpoints.size === 0); } resetState(): void { this.proposals.clear(); + this.checkpoints.clear(); } } diff --git a/yarn-project/p2p/src/testbench/p2p_client_testbench_worker.ts b/yarn-project/p2p/src/testbench/p2p_client_testbench_worker.ts index 0ad602106c6a..274c86272f13 100644 --- a/yarn-project/p2p/src/testbench/p2p_client_testbench_worker.ts +++ b/yarn-project/p2p/src/testbench/p2p_client_testbench_worker.ts @@ -23,7 +23,7 @@ import type { DataStoreConfig } from '@aztec/stdlib/kv-store'; import { type BlockProposal, P2PMessage } from '@aztec/stdlib/p2p'; import { ChonkProof } from '@aztec/stdlib/proofs'; import { makeAztecAddress, makeBlockHeader, makeBlockProposal, mockTx } from '@aztec/stdlib/testing'; -import { Tx, TxHash, type TxValidationResult } from '@aztec/stdlib/tx'; +import { Tx, TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx'; import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client'; import type { Message, PeerId } from '@libp2p/interface'; @@ -38,7 +38,6 @@ import { LibP2PService } from '../services/index.js'; import type { PeerManager } from '../services/peer-manager/peer_manager.js'; import { BatchTxRequester } from '../services/reqresp/batch-tx-requester/batch_tx_requester.js'; import type { BatchTxRequesterLibP2PService } from '../services/reqresp/batch-tx-requester/interface.js'; -import type { IBatchRequestTxValidator } from '../services/reqresp/batch-tx-requester/tx_validator.js'; import { RateLimitStatus } from '../services/reqresp/rate-limiter/rate_limiter.js'; import type { ReqResp } from '../services/reqresp/reqresp.js'; import type { PeerDiscoveryService } from '../services/service.js'; @@ -276,10 +275,8 @@ async function runAggregatorBenchmark( } } - const noopTxValidator: IBatchRequestTxValidator = { - validateRequestedTx: (_tx: Tx): Promise => Promise.resolve({ result: 'valid' }), - validateRequestedTxs: (txs: Tx[]): Promise => - Promise.resolve(txs.map(() => ({ result: 'valid' }))), + const noopTxValidator: TxValidator = { + validateTx: (_tx: Tx): Promise => Promise.resolve({ result: 'valid' }), }; timer = new Timer(); diff --git a/yarn-project/protocol-contracts/fixtures/ContractClassPublishedEventData.hex b/yarn-project/protocol-contracts/fixtures/ContractClassPublishedEventData.hex index 6619699e7cb2..efa62eb0bde0 100644 --- a/yarn-project/protocol-contracts/fixtures/ContractClassPublishedEventData.hex +++ b/yarn-project/protocol-contracts/fixtures/ContractClassPublishedEventData.hex @@ -1 +1 @@ -000000000000000000000000000000000000000000000000000000000000000320f5895a4e837356c2d551743df6bf642756dcd93cd31cbd37c556c90bf7f2441c2459719688b73599862bb4192cf567006eaf1fd7382d84f842a6f3616b326c0000000000000000000000000000000000000000000000000000000000000001237dfcd925241181677bde88f3ea51653dd144811eda2d9f208eee7c6b42f50a07be998ba5208ae3c3c9329157a2c586b26d7489a3e4be5af66e6a1b70e4357a0000000000000000000000000000000000000000000000000000000000000e04002700020401280000010480472700000447250000004127020304012702040400001f0a0003000400462d0846022500000075270202044727020304003b0e00000300022c0000430030644e72e131a029b85045b68181585d2833e84879b970009143e1f593f00000002900004404ffffffff2700450403262902000300324d00e62f0a2a02030427020504002702070403002a0507062d080103000801060100270303040100220302062d0e050600220602062d0e05062702060403002a030006052702050401270206040227020704002702080101270209010027020a0000002902000b00c732f9772b02000c0000000000000000020000000000000000002b02000d00000000000000000300000000000000002902000e00d9b5157824000200040000012323000006202d08010427020f04030008010f01270304040100002204020f1f3a00060005000f002a04050f2d0b0f0f002a0406102d0b1010001e020004001e020011001e020011002d080112270213040300080113012703001204010022120213360e0011001300002a1205132d0b1313002a1206142d0b0014141c0a131200042a12141524020013000001b027021204003c0612012d080001122702130403000801130127031204010022120213360e0011001302002a001205112d0b1111002a1206132d0b13131c0a111200042a1213142402001100000001fc27021204003c0612012d0801112702120402000801120127031104010000221102121f3a000500070012002a1105122d0b12121c0a1213041c0a131100002d08011227021304030008011301270312040100221202131f3a00060005000013002a1205132d0b1313002a1206162d0b16162902001200d52de36b2d0800011727021804050008011801270317040100221702182d0a18192d0e12190000221902192d0e131900221902192d0e161900221902192d0e0d192d08011227000213040500080113012703120401002217021300221202163f0f0013001600002a1205132d0b1313290200120016f8af272d0801162702170405000801170100270316040100221602172d0a17182d0e121800221802182d0e11180022180200182d0e131800221802182d0e0d182d08011127021204050008011201270311000401002216021200221102133f0f00120013002a1105122d0b12120a2a1412001124020011000003532500000d540a2a150a111e020012010a22124313160a0013141c0a141600042a1612140a2a130912240200120000038627021604003c000616010a2a151412122a111213240200130000039d2500000d662d0801112700021204040008011201270311040100221102122d0a12132d0e0e130022130200132d0e0f1300221302132d0e1013002211020f390320004400440004004500000f200200042102000f2d080111270210040000221102132d0b1313270214040003002a111412223a000f000700122d0a0f13270311040100221102142d0e13001400221402142d0e13142702150403002a131514000801140127021404002d000a131506221502150a2a1014162d0a1510240200160000045a2d0a10102402000016000004740a2a10151724020017000004742500000d782402000400000400aa23000004812d0b110400220402042d0e0411002211020f2d0b0f0f270212000403002a1112043c0e0f0423000004aa0a2a10070424020004000004c02702000f04003c060f011e020004002d08010f2702100403000801100127030f04010000220f0210360e0004001002002a0f05102d0b1010002a0f06112d0b11111c000a100f00042a0f1112240200100000051127020f04003c060f012902000f0000ede022762d08011027021104050008011101270310040100221002112d0a1100132d0e0f1300221302132d0e041300221302132d0e121300221302132d0e0d00132d08010427020f04050008010f012703040401002210020f00220402113f000f000f0011002a04050f2d0b0f0f3402000f1e020004002d08010f270210040005000801100127030f040100220f02102d0a10112d0e0b1100221102112d0e00041100221102112d0e0a1100221102112d0e0c112d0801042702100405000800011001270304040100220f021000220402113f0f00100011002a04050f2d0b000f0f3402000f2d0b030400220402042d0e0403002203020f2d0b0f0f270210000403002a0310043b0e000f0004230000062029020004005bd9f2da0a2a0204000f27020400022902001000ef52534d2402000f00000649230000083a2d0801000f2702110403000801110127030f040100220f02111f3a000600050011002a000f05112d0b1111002a0f06122d0b12121e02000f001e02000f001e02000f00002d08011327021404050008011401270313040100221302142d0a14152d0e0b001500221502152d0e0f1500221502152d0e0a1500221502152d0e0c152d0801000f2702140405000801140127030f0401002213021400220f02153f0f0014000015002a0f05132d0b13131e02000f002902001400036d527f2d0801152702160004050008011601270315040100221502162d0a16172d0e141700221702172d000e0f1700221702172d0e131700221702172d0e0d172d08010f270213040500000801130127030f0401002215021300220f02143f0f00130014002a0f05132d000b1313330a0013000f2402000f000007792500000d8a2d08010f270213040500000801130127030f040100220f02132d0a13142d0e101400221402142d0e04001400221402142d0e111400221402142d0e0d142d0801112702130405000801001301270311040100220f021300221102143f0f00130014002a11050f2d0b0f000f0a2a0f0a110a2a11091324020013000007f72500000d9c1e020011002f2a00000f00110013002a131211300a0011000f2d0b030f00220f020f2d0e0f030000220302112d0b11112702120403002a03120f3b0e0011000f230000083a0a2a00020e0f2402000f0000084c23000009492d08010e27020f04030008010f012700030e040100220e020f1f3a00060005000f002a0e050f2d0b0f0f002a0e0611002d0b11111e020006001e020006002d08010627020e04050008010e01270306000401002206020e2d0a0e122d0e101200221202122d0e041200221202122d0e000f1200221202122d0e0d122d08010e27020f04050008010f0127030e040100002206020f00220e02123f0f000f0012002a0e05062d0b06060a2a060a0e0a2a000e090f2402000f000009062500000d9c1e02000e002f2a0006000e000f002a000f110e300a000e00062d0b030600220602062d0e0603002203020e2d0b0e0e0027020f0403002a030f063b0e000e000623000009492902000600bb19097e0a002a02060e2402000e000009642300000a932d08010627020e04020008010e01002703060401002206020e1f3a00050005000e002a06050e2d0b0e0e1e02000600001e020006001e0200060924020006000009a92500000dae2d08010627020f0004050008010f012703060401002206020f2d0a0f112d0e101100221102112d000e041100221102112d0e0e1100221102112d0e0d112d08010427020d0405000008010d012703040401002206020d002204020e3f0f000d000e002a0405062d000b06060a2a060a040a2a04090d2402000d00000a272500000d9c1e02000400002f2a00060004000d270206040127020f0403002a060f0e2d0801040008010e00012703040401002204020e2d0e060e00220e020e2d0e060e27020e0403002a00040e062d0a060e2d0e0d0e002204020d2d0b0d0d27020e0403002a040e063b000e000d00062300000a932902000400ee21e57b0a2a0204062402000600000a00ae2300000b8e1e020004010a22044306160a060d1c0a0d0e00042a0e040d0a002a0609042402000400000adc27020e04003c060e011e020004000a2a0d0406002402000600000af32500000dc01e020004002d08010627020d04050008010d00012703060401002206020d2d0a0d0e2d0e0b0e00220e020e2d0e040e00220e00020e2d0e0a0e00220e020e2d0e0c0e2d08010427020a04050008010a01270300040401002206020a002204020b3f0f000a000b002a0405062d0b060634020000062d0b030400220402042d0e040300220302052d0b05052702060403002a030006043b0e000500042300000b8e2702030255270204026e270205026b27020600026f270207027727020a022027020b027327020c026527020d026c27020e02006327020f02742702100272270211027b270212027d2d080113270214041c000008011401270313040100221302142d0a14152d0e031500221502152d0e04150000221502152d0e051500221502152d0e041500221502152d0e06150022150200152d0e071500221502152d0e041500221502152d0e0a1500221502152d0e0b001500221502152d0e0c1500221502152d0e0d1500221502152d0e0c150022150002152d0e0e1500221502152d0e0f1500221502152d0e061500221502152d0e00101500221502152d0e0a1500221502152d0e111500221502152d0e0b150022001502152d0e0c1500221502152d0e0d1500221502152d0e0c1500221502152d000e0e1500221502152d0e0f1500221502152d0e061500221502152d0e10150000221502152d0e121527020300010a2a0908042402000400000d54270205041e002d080106270207041e00080107012d0a06072a030007059b5bbff74a5bff19000022070207002213020a27020b041b2d020a032d0207042d020b052500000d00d227020a041b002a070a072d0e030700220702072d0e020700220702073c0e0005062a010001058a553a2c2b67c8ef3c040201262a01000105c80d73736ecd00b4e13c040201262a0100010575fef108377c8a4f3c040201262a010001050600613b3d0b9dbd333c040201262a01000105babb21d7823318643c040201262a0001000105c5cc62b50ed35c303c040201262a010001052ab9ecbeb3430ae13c000402012600000305072d0003082d0004092300000df62d0108062d04060900000008020800000902090c0008070a2400000a00000de42600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a \ No newline at end of file +000000000000000000000000000000000000000000000000000000000000000320f5895a4e837356c2d551743df6bf642756dcd93cd31cbd37c556c90bf7f244135e3e6dff88ef7e69c592472939cddff00850a0886c416e47720573cf94db4c000000000000000000000000000000000000000000000000000000000000000124c6b040ea6c3ec2ecf9d6b0c0c709239696f66ea8d27d3bc064852a8bfb579c10b89e84a594728151d2054d9e41999f109fca6895e8bec7894445886adaa5c10000000000000000000000000000000000000000000000000000000000000e1c0027000204012800000104804d270000044d250000004127020304012702040400001f0a00030004004c2d084c0225000000b7270202044d27020304003b0e00000300022c0000430030644e72e131a029b85045b68181585d2833e84879b970009143e1f593f00000002900004404ffffffff2700450403270046000027004700010127004804012900004900c732f9772b00004a0000000000000000020000000000000000002b00004b000000000000000003000000000000000026290200000300324de62f0a2a02030427020504002702070403002a0507062d080103000008010601270303040100220302062d0e050600220602062d0e0506270206040003002a0306052702050402270206040027020701002902000800d9b5157824000200040000012323000006202d0801042702090403000801090127030404010000220402091f3200050048000900220448092d0b0909002a04050a2d0b0a0a001e020004001e02000b001e02000b002d08010c27020d04030008010d012703000c040100220c020d360e000b000d0000220c480d2d0b0d0d002a0c050e2d0b000e0e1c0a0d0c00042a0c0e0f2402000d000001b027020c04003c060c012d0800010c27020d04030008010d0127030c040100220c020d360e000b000d020022000c480b2d0b0b0b002a0c050d2d0b0d0d1c0a0b0c00042a0c0d0e2402000b00000001fc27020c04003c060c012d08010b27020c04020008010c0127030b04010000220b020c1f3800480006000c00220b480c2d0b0c0c1c0a0c0d041c0a0d0b00002d08010c27020d04030008010d0127030c040100220c020d1f320005004800000d00220c480d2d0b0d0d002a0c05102d0b10102902000c00d52de36b2d0800011127021204050008011201270311040100221102122d0a12132d0e0c130000221302132d0e0d1300221302132d0e101300221302132d0c4b132d08010c2700020d04050008010d0127030c0401002211020d00220c02103f0f000d00100000220c480d2d0b0d0d2902000c0016f8af272d0801102702110405000801110100270310040100221002112d0a11122d0e0c1200221202122d0e0b120022120200122d0e0d1200221202122d0c4b122d08010b27020c04050008010c0127030b000401002210020c00220b020d3f0f000c000d00220b480c2d0b0c0c0a2a0e0c000b2402000b000003532500000c770a220f460b1e02000c010a220c430d160a000d0e1c0a0e1000042a100c0e0a2a0d070c2402000c0000038627021004003c000610010a2a0f0e0c122a0b0c0d2402000d0000039d2500000c892d08010b2700020c04040008010c0127030b040100220b020c2d0a0c0d2d0e080d00220d02000d2d0e090d00220d020d2d0e0a0d00220b0209390320004400440004004500000920020004210200092d08010b27020a040000220b020d2d0b0d0d27020e040003002a0b0e0c223a00090006000c2d0a090d27030b040100220b020e2d0e0d000e00220e020e2d0e0d0e27020f0403002a0d0f0e0008010e0127020e04002d000a0d0f06220f020f0a2a0a0e102d0a0f0a240200100000045a2d0a0a0a2402000010000004740a2a0a0f1124020011000004742500000c9b2402000400000400aa23000004812d0b0b0400220402042d0e040b00220b02092d0b090927020c000403002a0b0c043c0e090423000004aa0a2a0a060424020004000004c02702000904003c0609011e020004002d08010927020a04030008010a01270309040100002209020a360e0004000a02002209480a2d0b0a0a002a09050b2d0b0b0b1c000a0a0900042a090b0c2402000a0000051127020904003c060901290200090000ede022762d08010a27020b04050008010b0127030a040100220a020b2d0a0b000d2d0e090d00220d020d2d0e040d00220d020d2d0e0c0d00220d020d2d0c4b000d2d08010427020904050008010901270304040100220a0209002204020b3f000f0009000b00220448092d0b0909340200091e020004002d08010927020a0400050008010a012703090401002209020a2d0a0a0b2d0c490b00220b020b2d0e00040b00220b020b2d0c460b00220b020b2d0c4a0b2d08010427020a0405000800010a012703040401002209020a002204020b3f0f000a000b00220448092d0b000909340200092d0b030400220402042d0e040300220302092d0b090927020a000403002a030a043b0e00090004230000062029020004005bd9f2da0a2a0204000927020400022902000a00ef52534d2402000900000649230000075d2d0801000927020b04030008010b012703090401002209020b1f3200050048000b00220009480b2d0b0b0b002a09050c2d0b0c0c1e020009001e02000900270209040d002d08000d00080009002500000cad2d0200002d08010927020d04050008010d00012703090401002209020d2d0a0d0e2d0e0a0e00220e020e2d0e040e00220e00020e2d0e0b0e00220e020e2d0c4b0e2d08010b27020d04050008010d012703000b0401002209020d00220b020e3f0f000d000e00220b48092d0b09090a220900460b0a2a0b070d2402000d0000071a2500000da21e02000b002f2a0009000b00000d002a0d0c0b300a000b00092d0b030900220902092d0e0903002203020b002d0b0b0b27020c0403002a030c093b0e000b0009230000075d0a2a02080924000200090000076f230000086c2d0801082702090403000801090127030804010000220802091f3200050048000900220848092d0b0909002a08050b2d0b0b0b001e020005001e020005002d0801052702080405000801080127030504010022000502082d0a080c2d0e0a0c00220c020c2d0e040c00220c020c2d0e090c0022000c020c2d0c4b0c2d080108270209040500080109012703080401002205020900002208020c3f0f0009000c00220848052d0b05050a220546080a2a0807092400020009000008292500000da21e020008002f2a000500080009002a090b0830000a000800052d0b030500220502052d0e050300220302082d0b0808270209040003002a0309053b0e00080005230000086c2902000500bb19097e0a2a02050800240200080000088723000009b62d0801052702080402000801080127030504000100220502081f3000480048000800220548082d0b08081e020005001e02000005001e0200050924020005000008cc2500000db42d0801052702090405000800010901270305040100220502092d0a090b2d0e0a0b00220b020b2d0e040b0000220b020b2d0e080b00220b020b2d0c4b0b2d08010427020804050008010801002703040401002205020800220402093f0f0008000900220448052d0b05050a00220546040a2a040708240200080000094a2500000da21e020004002f2a00050000040008270205040127020a0403002a050a092d080104000801090127030400040100220402092d0e050900220902092d0e05092702090403002a0409052d000a05092d0e080900220402082d0b08082702090403002a0409053b0e000800000523000009b62902000400ee21e57b0a2a02040524020005000009d1230000000ab11e020004010a22044305160a05081c0a080900042a0904080a2a0507040024020004000009ff27020904003c0609011e020004000a2a080405240200050000000a162500000dc61e020004002d0801052702080405000801080127030500040100220502082d0a08092d0c490900220902092d0e040900220902092d0c00460900220902092d0c4a092d08010427020804050008010801270304040100002205020800220402093f0f0008000900220448052d0b0505340200052d0b03000400220402042d0e040300220302052d0b05052702080403002a0308043b0e00000500042300000ab12702030255270204026e270205026b270206026f270200080277270209022027020a027327020b026527020c026c27020d026327020e00027427020f0272270210027b270211027d2d080112270213041c000801130100270312040100221202132d0a13142d0e031400221402142d0e04140022140200142d0e051400221402142d0e041400221402142d0e061400221402142d0e08001400221402142d0e041400221402142d0e091400221402142d0e0a140022140002142d0e0b1400221402142d0e0c1400221402142d0e0b1400221402142d0e000d1400221402142d0e0e1400221402142d0e061400221402142d0e0f140022001402142d0e091400221402142d0e101400221402142d0e0a1400221402142d000e0b1400221402142d0e0c1400221402142d0e0b1400221402142d0e0d140000221402142d0e0e1400221402142d0e061400221402142d0e0f140022140214002d0e111427020300010a220747042402000400000c77270205041e2d08010600270208041e00080108012d0a06082a030008059b5bbff74a5bff19002208020008002212020927020a041b2d0209032d0208042d020a052500000dd827020900041b002a0809082d0e030800220802082d0e020800220802083c0e05062a01000001058a553a2c2b67c8ef3c040201262a01000105c80d73736ecdb4e13c04000201262a0100010575fef108377c8a4f3c040201261e020002002d0801032700020404050008010401270303040100220302042d0a04052d0c49050022050200052d0e020500220502052d0c460500220502052d0c4a052d08010227020404000500080104012703020401002203020400220202053f0f000400050022024800032d0b03031e020002002902000400036d527f2d0801052702060405000801000601270305040100220502062d0a06072d0e040700220702072d0e02070022000702072d0e030700220702072d0c4b072d08010227020304050008010301270003020401002205020300220202043f0f0003000400220248032d0b0303330a00000300022402000200000da12500000e0a262a01000105babb21d782331864003c040201262a01000105c5cc62b50ed35c303c040201262a010001052ab9ec00beb3430ae13c0402012600000305072d0003082d0004092300000dfc2d010800062d040609000008020800000902090c0008070a2400000a00000dea262a010000010506613b3d0b9dbd333c04020126000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b \ No newline at end of file diff --git a/yarn-project/protocol-contracts/fixtures/ContractInstancePublishedEventData.hex b/yarn-project/protocol-contracts/fixtures/ContractInstancePublishedEventData.hex index 91be7f65a8fd..8c62e70d96ce 100644 --- a/yarn-project/protocol-contracts/fixtures/ContractInstancePublishedEventData.hex +++ b/yarn-project/protocol-contracts/fixtures/ContractInstancePublishedEventData.hex @@ -1 +1 @@ -1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a821e212810f887382b564c453919235ecc04ff03f9c5127ac9a630a3fc62cfbbb0000000000000000000000000000000000000000000000000000000000000001108abf493e0af91750b53cd462defc3373f1a522e982af55b0c8ec7d20cf03931c2459719688b73599862bb4192cf567006eaf1fd7382d84f842a6f3616b326c0fb36d433fc86c98e17d214b1024303def3bb1e8fa412bc6e796eb1366b5f55b1366c504bbb3b3bb5d7246d9e082468eae37d93c38705b9eb4ef8bb76dc9b98005c6d6a962e4d7a458aa232dab86841ebcfe4d342556f270f6b2452fd87581bb1e415b163a4af0578cf70ab19e836504a74de9ea3e0c94373ca781436155bfc31fe218da6de686b7a39b092364894c6c2246fee50d0ff9832294cd6b792b8f421aa402e7eafa5c5d6ed9454c794e744eabf3b0c5ed84a35567fbe7509552181808afab9b331786e21a60f1f237a7a0f5457ce547160b82ace9a58a800b170fc1289752f4904779a603001cd6fab021079a04e18f0740eb0e1009088199178d1f26814d31374c3e5c551e28a5467feb67155bb2be160d80ca851babfa60501e61000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f \ No newline at end of file +1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a81a0d9f0f131e602239f499207c271b6319cb33a45b8f917a7c35d8a52a60d2cb00000000000000000000000000000000000000000000000000000000000000022d906f112c4a0f17792dbb184f229b5e5fe22d3ae04eb78736ce9ae0e35e49fc14cc2f3a2417ec81f84c15b1517cef38654c29ace9d54f5a4a22ce1709cc5fc90dad6f31fca9cac105434c9d0071a24a38da659700aee09d285b5ceae94ff5fe00000000000000000000000000000000000000000000000000000000000000002f6b4b954efabd4f61fe64c1704e82f62760c1a0b5ec1ab88e272fae2f3f0d6c21f72071d5882ea13df29918cbaad0d60a11f61309ece108e61d7102b62ec1b50460480b46dcfd5c3262004f191fecf11f321d74618d761e6bcadc691078b4210c0e28c4de1167675c811c52defc32dae2245315682dd349b26ef9c3161b1f96222398ec917e21cb0cbac7050610c2bcb0c2fedfc637bf03d59094b7fd9ce18600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d \ No newline at end of file diff --git a/yarn-project/protocol-contracts/src/class-registry/__snapshots__/contract_class_published_event.test.ts.snap b/yarn-project/protocol-contracts/src/class-registry/__snapshots__/contract_class_published_event.test.ts.snap index 82c511c761eb..7a1833ae133f 100644 --- a/yarn-project/protocol-contracts/src/class-registry/__snapshots__/contract_class_published_event.test.ts.snap +++ b/yarn-project/protocol-contracts/src/class-registry/__snapshots__/contract_class_published_event.test.ts.snap @@ -2,10 +2,10 @@ exports[`ContractClassPublishedEvent parses an event as emitted by the ContractClassRegistry 1`] = ` ContractClassPublishedEvent { - "artifactHash": Fr<0x237dfcd925241181677bde88f3ea51653dd144811eda2d9f208eee7c6b42f50a>, - "contractClassId": Fr<0x1c2459719688b73599862bb4192cf567006eaf1fd7382d84f842a6f3616b326c>, - "packedPublicBytecode": Buffer<0x27000204012800000104804727000004472500000041270203040127020404001f0a0003000400462d0846022500000075270202044727020304003b0e000300022c0000430030644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000002900004404ffffffff2700450403262902000300324de62f0a2a02030427020504002702070403002a0507062d0801030008010601270303040100220302062d0e050600220602062d0e05062702060403002a0306052702050401270206040227020704002702080101270209010027020a00002902000b00c732f9772b02000c00000000000000000200000000000000002b02000d00000000000000000300000000000000002902000e00d9b51578240200040000012323000006202d08010427020f04030008010f012703040401002204020f1f3a00060005000f002a04050f2d0b0f0f002a0406102d0b10101e020004001e020011001e020011002d0801122702130403000801130127031204010022120213360e0011001300002a1205132d0b1313002a1206142d0b14141c0a131200042a12141524020013000001b027021204003c0612012d0801122702130403000801130127031204010022120213360e0011001302002a1205112d0b1111002a1206132d0b13131c0a111200042a12131424020011000001fc27021204003c0612012d08011127021204020008011201270311040100221102121f3a000500070012002a1105122d0b12121c0a1213041c0a1311002d08011227021304030008011301270312040100221202131f3a000600050013002a1205132d0b1313002a1206162d0b16162902001200d52de36b2d08011727021804050008011801270317040100221702182d0a18192d0e121900221902192d0e131900221902192d0e161900221902192d0e0d192d080112270213040500080113012703120401002217021300221202163f0f00130016002a1205132d0b1313290200120016f8af272d08011627021704050008011701270316040100221602172d0a17182d0e121800221802182d0e111800221802182d0e131800221802182d0e0d182d080111270212040500080112012703110401002216021200221102133f0f00120013002a1105122d0b12120a2a14121124020011000003532500000d540a2a150a111e020012010a22124313160a13141c0a141600042a1612140a2a130912240200120000038627021604003c0616010a2a151412122a111213240200130000039d2500000d662d08011127021204040008011201270311040100221102122d0a12132d0e0e1300221302132d0e0f1300221302132d0e1013002211020f3903200044004400040045000f200200042102000f2d080111270210040000221102132d0b13132702140403002a111412223a000f000700122d0a0f13270311040100221102142d0e131400221402142d0e13142702150403002a131514000801140127021404002d0a131506221502150a2a1014162d0a1510240200160000045a2d0a101024020016000004740a2a10151724020017000004742500000d7824020004000004aa23000004812d0b110400220402042d0e0411002211020f2d0b0f0f2702120403002a1112043c0e0f0423000004aa0a2a10070424020004000004c027020f04003c060f011e020004002d08010f2702100403000801100127030f040100220f0210360e0004001002002a0f05102d0b1010002a0f06112d0b11111c0a100f00042a0f1112240200100000051127020f04003c060f012902000f00ede022762d08011027021104050008011101270310040100221002112d0a11132d0e0f1300221302132d0e041300221302132d0e121300221302132d0e0d132d08010427020f04050008010f012703040401002210020f00220402113f0f000f0011002a04050f2d0b0f0f3402000f1e020004002d08010f2702100405000801100127030f040100220f02102d0a10112d0e0b1100221102112d0e041100221102112d0e0a1100221102112d0e0c112d08010427021004050008011001270304040100220f021000220402113f0f00100011002a04050f2d0b0f0f3402000f2d0b030400220402042d0e0403002203020f2d0b0f0f2702100403002a0310043b0e000f0004230000062029020004005bd9f2da0a2a02040f27020400022902001000ef52534d2402000f00000649230000083a2d08010f2702110403000801110127030f040100220f02111f3a000600050011002a0f05112d0b1111002a0f06122d0b12121e02000f001e02000f001e02000f002d08011327021404050008011401270313040100221302142d0a14152d0e0b1500221502152d0e0f1500221502152d0e0a1500221502152d0e0c152d08010f2702140405000801140127030f0401002213021400220f02153f0f00140015002a0f05132d0b13131e02000f002902001400036d527f2d08011527021604050008011601270315040100221502162d0a16172d0e141700221702172d0e0f1700221702172d0e131700221702172d0e0d172d08010f2702130405000801130127030f0401002215021300220f02143f0f00130014002a0f05132d0b1313330a0013000f2402000f000007792500000d8a2d08010f2702130405000801130127030f040100220f02132d0a13142d0e101400221402142d0e041400221402142d0e111400221402142d0e0d142d08011127021304050008011301270311040100220f021300221102143f0f00130014002a11050f2d0b0f0f0a2a0f0a110a2a11091324020013000007f72500000d9c1e020011002f2a000f00110013002a131211300a0011000f2d0b030f00220f020f2d0e0f0300220302112d0b11112702120403002a03120f3b0e0011000f230000083a0a2a020e0f2402000f0000084c23000009492d08010e27020f04030008010f0127030e040100220e020f1f3a00060005000f002a0e050f2d0b0f0f002a0e06112d0b11111e020006001e020006002d08010627020e04050008010e012703060401002206020e2d0a0e122d0e101200221202122d0e041200221202122d0e0f1200221202122d0e0d122d08010e27020f04050008010f0127030e0401002206020f00220e02123f0f000f0012002a0e05062d0b06060a2a060a0e0a2a0e090f2402000f000009062500000d9c1e02000e002f2a0006000e000f002a0f110e300a000e00062d0b030600220602062d0e0603002203020e2d0b0e0e27020f0403002a030f063b0e000e000623000009492902000600bb19097e0a2a02060e2402000e000009642300000a932d08010627020e04020008010e012703060401002206020e1f3a00050005000e002a06050e2d0b0e0e1e020006001e020006001e0200060924020006000009a92500000dae2d08010627020f04050008010f012703060401002206020f2d0a0f112d0e101100221102112d0e041100221102112d0e0e1100221102112d0e0d112d08010427020d04050008010d012703040401002206020d002204020e3f0f000d000e002a0405062d0b06060a2a060a040a2a04090d2402000d00000a272500000d9c1e020004002f2a00060004000d270206040127020f0403002a060f0e2d0801040008010e012703040401002204020e2d0e060e00220e020e2d0e060e27020e0403002a040e062d0a060e2d0e0d0e002204020d2d0b0d0d27020e0403002a040e063b0e000d00062300000a932902000400ee21e57b0a2a0204062402000600000aae2300000b8e1e020004010a22044306160a060d1c0a0d0e00042a0e040d0a2a0609042402000400000adc27020e04003c060e011e020004000a2a0d04062402000600000af32500000dc01e020004002d08010627020d04050008010d012703060401002206020d2d0a0d0e2d0e0b0e00220e020e2d0e040e00220e020e2d0e0a0e00220e020e2d0e0c0e2d08010427020a04050008010a012703040401002206020a002204020b3f0f000a000b002a0405062d0b0606340200062d0b030400220402042d0e040300220302052d0b05052702060403002a0306043b0e000500042300000b8e2702030255270204026e270205026b270206026f270207027727020a022027020b027327020c026527020d026c27020e026327020f02742702100272270211027b270212027d2d080113270214041c0008011401270313040100221302142d0a14152d0e031500221502152d0e041500221502152d0e051500221502152d0e041500221502152d0e061500221502152d0e071500221502152d0e041500221502152d0e0a1500221502152d0e0b1500221502152d0e0c1500221502152d0e0d1500221502152d0e0c1500221502152d0e0e1500221502152d0e0f1500221502152d0e061500221502152d0e101500221502152d0e0a1500221502152d0e111500221502152d0e0b1500221502152d0e0c1500221502152d0e0d1500221502152d0e0c1500221502152d0e0e1500221502152d0e0f1500221502152d0e061500221502152d0e101500221502152d0e121527020300010a2a0908042402000400000d54270205041e2d080106270207041e00080107012d0a06072a030007059b5bbff74a5bff190022070207002213020a27020b041b2d020a032d0207042d020b052500000dd227020a041b002a070a072d0e030700220702072d0e020700220702073c0e05062a010001058a553a2c2b67c8ef3c040201262a01000105c80d73736ecdb4e13c040201262a0100010575fef108377c8a4f3c040201262a0100010506613b3d0b9dbd333c040201262a01000105babb21d7823318643c040201262a01000105c5cc62b50ed35c303c040201262a010001052ab9ecbeb3430ae13c0402012600000305072d0003082d0004092300000df62d0108062d040609000008020800000902090c0008070a2400000a00000de426>, - "privateFunctionsRoot": Fr<0x07be998ba5208ae3c3c9329157a2c586b26d7489a3e4be5af66e6a1b70e4357a>, + "artifactHash": Fr<0x24c6b040ea6c3ec2ecf9d6b0c0c709239696f66ea8d27d3bc064852a8bfb579c>, + "contractClassId": Fr<0x135e3e6dff88ef7e69c592472939cddff00850a0886c416e47720573cf94db4c>, + "packedPublicBytecode": Buffer<0x27000204012800000104804d270000044d2500000041270203040127020404001f0a00030004004c2d084c0225000000b7270202044d27020304003b0e000300022c0000430030644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000002900004404ffffffff27004504032700460000270047010127004804012900004900c732f9772b00004a00000000000000000200000000000000002b00004b0000000000000000030000000000000000262902000300324de62f0a2a02030427020504002702070403002a0507062d0801030008010601270303040100220302062d0e050600220602062d0e05062702060403002a0306052702050402270206040027020701002902000800d9b51578240200040000012323000006202d08010427020904030008010901270304040100220402091f3200050048000900220448092d0b0909002a04050a2d0b0a0a1e020004001e02000b001e02000b002d08010c27020d04030008010d0127030c040100220c020d360e000b000d0000220c480d2d0b0d0d002a0c050e2d0b0e0e1c0a0d0c00042a0c0e0f2402000d000001b027020c04003c060c012d08010c27020d04030008010d0127030c040100220c020d360e000b000d0200220c480b2d0b0b0b002a0c050d2d0b0d0d1c0a0b0c00042a0c0d0e2402000b000001fc27020c04003c060c012d08010b27020c04020008010c0127030b040100220b020c1f3800480006000c00220b480c2d0b0c0c1c0a0c0d041c0a0d0b002d08010c27020d04030008010d0127030c040100220c020d1f3200050048000d00220c480d2d0b0d0d002a0c05102d0b10102902000c00d52de36b2d08011127021204050008011201270311040100221102122d0a12132d0e0c1300221302132d0e0d1300221302132d0e101300221302132d0c4b132d08010c27020d04050008010d0127030c0401002211020d00220c02103f0f000d001000220c480d2d0b0d0d2902000c0016f8af272d08011027021104050008011101270310040100221002112d0a11122d0e0c1200221202122d0e0b1200221202122d0e0d1200221202122d0c4b122d08010b27020c04050008010c0127030b0401002210020c00220b020d3f0f000c000d00220b480c2d0b0c0c0a2a0e0c0b2402000b000003532500000c770a220f460b1e02000c010a220c430d160a0d0e1c0a0e1000042a100c0e0a2a0d070c2402000c0000038627021004003c0610010a2a0f0e0c122a0b0c0d2402000d0000039d2500000c892d08010b27020c04040008010c0127030b040100220b020c2d0a0c0d2d0e080d00220d020d2d0e090d00220d020d2d0e0a0d00220b02093903200044004400040045000920020004210200092d08010b27020a040000220b020d2d0b0d0d27020e0403002a0b0e0c223a00090006000c2d0a090d27030b040100220b020e2d0e0d0e00220e020e2d0e0d0e27020f0403002a0d0f0e0008010e0127020e04002d0a0d0f06220f020f0a2a0a0e102d0a0f0a240200100000045a2d0a0a0a24020010000004740a2a0a0f1124020011000004742500000c9b24020004000004aa23000004812d0b0b0400220402042d0e040b00220b02092d0b090927020c0403002a0b0c043c0e090423000004aa0a2a0a060424020004000004c027020904003c0609011e020004002d08010927020a04030008010a012703090401002209020a360e0004000a02002209480a2d0b0a0a002a09050b2d0b0b0b1c0a0a0900042a090b0c2402000a0000051127020904003c0609012902000900ede022762d08010a27020b04050008010b0127030a040100220a020b2d0a0b0d2d0e090d00220d020d2d0e040d00220d020d2d0e0c0d00220d020d2d0c4b0d2d08010427020904050008010901270304040100220a0209002204020b3f0f0009000b00220448092d0b0909340200091e020004002d08010927020a04050008010a012703090401002209020a2d0a0a0b2d0c490b00220b020b2d0e040b00220b020b2d0c460b00220b020b2d0c4a0b2d08010427020a04050008010a012703040401002209020a002204020b3f0f000a000b00220448092d0b0909340200092d0b030400220402042d0e040300220302092d0b090927020a0403002a030a043b0e00090004230000062029020004005bd9f2da0a2a02040927020400022902000a00ef52534d2402000900000649230000075d2d08010927020b04030008010b012703090401002209020b1f3200050048000b002209480b2d0b0b0b002a09050c2d0b0c0c1e020009001e02000900270209040d2d08000d00080009002500000cad2d0200002d08010927020d04050008010d012703090401002209020d2d0a0d0e2d0e0a0e00220e020e2d0e040e00220e020e2d0e0b0e00220e020e2d0c4b0e2d08010b27020d04050008010d0127030b0401002209020d00220b020e3f0f000d000e00220b48092d0b09090a2209460b0a2a0b070d2402000d0000071a2500000da21e02000b002f2a0009000b000d002a0d0c0b300a000b00092d0b030900220902092d0e0903002203020b2d0b0b0b27020c0403002a030c093b0e000b0009230000075d0a2a020809240200090000076f230000086c2d08010827020904030008010901270308040100220802091f3200050048000900220848092d0b0909002a08050b2d0b0b0b1e020005001e020005002d08010527020804050008010801270305040100220502082d0a080c2d0e0a0c00220c020c2d0e040c00220c020c2d0e090c00220c020c2d0c4b0c2d0801082702090405000801090127030804010022050209002208020c3f0f0009000c00220848052d0b05050a220546080a2a08070924020009000008292500000da21e020008002f2a000500080009002a090b08300a000800052d0b030500220502052d0e050300220302082d0b08082702090403002a0309053b0e00080005230000086c2902000500bb19097e0a2a020508240200080000088723000009b62d08010527020804020008010801270305040100220502081f3000480048000800220548082d0b08081e020005001e020005001e0200050924020005000008cc2500000db42d08010527020904050008010901270305040100220502092d0a090b2d0e0a0b00220b020b2d0e040b00220b020b2d0e080b00220b020b2d0c4b0b2d080104270208040500080108012703040401002205020800220402093f0f0008000900220448052d0b05050a220546040a2a040708240200080000094a2500000da21e020004002f2a000500040008270205040127020a0403002a050a092d0801040008010901270304040100220402092d0e050900220902092d0e05092702090403002a0409052d0a05092d0e080900220402082d0b08082702090403002a0409053b0e0008000523000009b62902000400ee21e57b0a2a02040524020005000009d12300000ab11e020004010a22044305160a05081c0a080900042a0904080a2a05070424020004000009ff27020904003c0609011e020004000a2a0804052402000500000a162500000dc61e020004002d08010527020804050008010801270305040100220502082d0a08092d0c490900220902092d0e040900220902092d0c460900220902092d0c4a092d080104270208040500080108012703040401002205020800220402093f0f0008000900220448052d0b0505340200052d0b030400220402042d0e040300220302052d0b05052702080403002a0308043b0e000500042300000ab12702030255270204026e270205026b270206026f2702080277270209022027020a027327020b026527020c026c27020d026327020e027427020f0272270210027b270211027d2d080112270213041c0008011301270312040100221202132d0a13142d0e031400221402142d0e041400221402142d0e051400221402142d0e041400221402142d0e061400221402142d0e081400221402142d0e041400221402142d0e091400221402142d0e0a1400221402142d0e0b1400221402142d0e0c1400221402142d0e0b1400221402142d0e0d1400221402142d0e0e1400221402142d0e061400221402142d0e0f1400221402142d0e091400221402142d0e101400221402142d0e0a1400221402142d0e0b1400221402142d0e0c1400221402142d0e0b1400221402142d0e0d1400221402142d0e0e1400221402142d0e061400221402142d0e0f1400221402142d0e111427020300010a220747042402000400000c77270205041e2d080106270208041e00080108012d0a06082a030008059b5bbff74a5bff190022080208002212020927020a041b2d0209032d0208042d020a052500000dd8270209041b002a0809082d0e030800220802082d0e020800220802083c0e05062a010001058a553a2c2b67c8ef3c040201262a01000105c80d73736ecdb4e13c040201262a0100010575fef108377c8a4f3c040201261e020002002d08010327020404050008010401270303040100220302042d0a04052d0c490500220502052d0e020500220502052d0c460500220502052d0c4a052d080102270204040500080104012703020401002203020400220202053f0f0004000500220248032d0b03031e020002002902000400036d527f2d08010527020604050008010601270305040100220502062d0a06072d0e040700220702072d0e020700220702072d0e030700220702072d0c4b072d080102270203040500080103012703020401002205020300220202043f0f0003000400220248032d0b0303330a000300022402000200000da12500000e0a262a01000105babb21d7823318643c040201262a01000105c5cc62b50ed35c303c040201262a010001052ab9ecbeb3430ae13c0402012600000305072d0003082d0004092300000dfc2d0108062d040609000008020800000902090c0008070a2400000a00000dea262a0100010506613b3d0b9dbd333c04020126>, + "privateFunctionsRoot": Fr<0x10b89e84a594728151d2054d9e41999f109fca6895e8bec7894445886adaa5c1>, "version": 1, } `; diff --git a/yarn-project/protocol-contracts/src/instance-registry/__snapshots__/contract_instance_published_event.test.ts.snap b/yarn-project/protocol-contracts/src/instance-registry/__snapshots__/contract_instance_published_event.test.ts.snap index f74640794bf0..fc855b12b4a2 100644 --- a/yarn-project/protocol-contracts/src/instance-registry/__snapshots__/contract_instance_published_event.test.ts.snap +++ b/yarn-project/protocol-contracts/src/instance-registry/__snapshots__/contract_instance_published_event.test.ts.snap @@ -2,17 +2,18 @@ exports[`ContractInstancePublishedEvent parses an event as emitted by the ClassInstanceRegistry 1`] = ` ContractInstancePublishedEvent { - "address": "0x21e212810f887382b564c453919235ecc04ff03f9c5127ac9a630a3fc62cfbbb", - "contractClassId": "0x1c2459719688b73599862bb4192cf567006eaf1fd7382d84f842a6f3616b326c", + "address": "0x1a0d9f0f131e602239f499207c271b6319cb33a45b8f917a7c35d8a52a60d2cb", + "contractClassId": "0x14cc2f3a2417ec81f84c15b1517cef38654c29ace9d54f5a4a22ce1709cc5fc9", "deployer": "0x0000000000000000000000000000000000000000000000000000000000000000", - "initializationHash": "0x0fb36d433fc86c98e17d214b1024303def3bb1e8fa412bc6e796eb1366b5f55b", + "immutablesHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "initializationHash": "0x0dad6f31fca9cac105434c9d0071a24a38da659700aee09d285b5ceae94ff5fe", "publicKeys": PublicKeys { - "masterIncomingViewingPublicKey": "0x1e415b163a4af0578cf70ab19e836504a74de9ea3e0c94373ca781436155bfc31fe218da6de686b7a39b092364894c6c2246fee50d0ff9832294cd6b792b8f42", - "masterNullifierPublicKey": "0x1366c504bbb3b3bb5d7246d9e082468eae37d93c38705b9eb4ef8bb76dc9b98005c6d6a962e4d7a458aa232dab86841ebcfe4d342556f270f6b2452fd87581bb", - "masterOutgoingViewingPublicKey": "0x1aa402e7eafa5c5d6ed9454c794e744eabf3b0c5ed84a35567fbe7509552181808afab9b331786e21a60f1f237a7a0f5457ce547160b82ace9a58a800b170fc1", - "masterTaggingPublicKey": "0x289752f4904779a603001cd6fab021079a04e18f0740eb0e1009088199178d1f26814d31374c3e5c551e28a5467feb67155bb2be160d80ca851babfa60501e61", + "ivpkM": "0x21f72071d5882ea13df29918cbaad0d60a11f61309ece108e61d7102b62ec1b50460480b46dcfd5c3262004f191fecf11f321d74618d761e6bcadc691078b421", + "npkMHash": "0x2f6b4b954efabd4f61fe64c1704e82f62760c1a0b5ec1ab88e272fae2f3f0d6c", + "ovpkMHash": "0x0c0e28c4de1167675c811c52defc32dae2245315682dd349b26ef9c3161b1f96", + "tpkMHash": "0x222398ec917e21cb0cbac7050610c2bcb0c2fedfc637bf03d59094b7fd9ce186", }, - "salt": "0x108abf493e0af91750b53cd462defc3373f1a522e982af55b0c8ec7d20cf0393", - "version": 1, + "salt": "0x2d906f112c4a0f17792dbb184f229b5e5fe22d3ae04eb78736ce9ae0e35e49fc", + "version": 2, } `; diff --git a/yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts b/yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts index 35857a0f852b..d69ae3c2b683 100644 --- a/yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts +++ b/yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts @@ -15,6 +15,7 @@ export class ContractInstancePublishedEvent { public readonly salt: Fr, public readonly contractClassId: Fr, public readonly initializationHash: Fr, + public readonly immutablesHash: Fr, public readonly publicKeys: PublicKeys, public readonly deployer: AztecAddress, ) {} @@ -31,6 +32,7 @@ export class ContractInstancePublishedEvent { const salt = reader.readObject(Fr); const contractClassId = reader.readObject(Fr); const initializationHash = reader.readObject(Fr); + const immutablesHash = reader.readObject(Fr); const publicKeys = reader.readObject(PublicKeys); const deployer = reader.readObject(AztecAddress); @@ -40,13 +42,14 @@ export class ContractInstancePublishedEvent { salt, contractClassId, initializationHash, + immutablesHash, publicKeys, deployer, ); } toContractInstance(): ContractInstanceWithAddress { - if (this.version !== 1) { + if (this.version !== 2) { throw new Error(`Unexpected contract instance version ${this.version}`); } @@ -56,6 +59,7 @@ export class ContractInstancePublishedEvent { currentContractClassId: this.contractClassId, originalContractClassId: this.contractClassId, initializationHash: this.initializationHash, + immutablesHash: this.immutablesHash, publicKeys: this.publicKeys, salt: this.salt, deployer: this.deployer, diff --git a/yarn-project/protocol-contracts/src/make_protocol_contract.ts b/yarn-project/protocol-contracts/src/make_protocol_contract.ts index 87215bcb3c20..d921be733ef2 100644 --- a/yarn-project/protocol-contracts/src/make_protocol_contract.ts +++ b/yarn-project/protocol-contracts/src/make_protocol_contract.ts @@ -1,3 +1,4 @@ +import { Fr } from '@aztec/foundation/curves/bn254'; import type { ContractArtifact } from '@aztec/stdlib/abi'; import { PublicKeys } from '@aztec/stdlib/keys'; @@ -34,10 +35,11 @@ export function makeProtocolContract(name: ProtocolContractName, artifact: Contr }; const instance = { - version: 1 as const, + version: 2 as const, currentContractClassId: classId, originalContractClassId: classId, initializationHash, + immutablesHash: Fr.ZERO, // Protocol Contracts Have No Immutables publicKeys: PublicKeys.default(), salt, deployer: address, diff --git a/yarn-project/protocol-contracts/src/scripts/generate_data.ts b/yarn-project/protocol-contracts/src/scripts/generate_data.ts index 58b8d8aa14c7..9bd43ff78210 100644 --- a/yarn-project/protocol-contracts/src/scripts/generate_data.ts +++ b/yarn-project/protocol-contracts/src/scripts/generate_data.ts @@ -89,10 +89,11 @@ async function computeContractData(artifact: NoirCompiledContract, deployer: Azt const constructorArtifact = loaded.functions.find(f => f.name === 'constructor'); const initializationHash = await computeInitializationHash(constructorArtifact, []); const instance = { - version: 1 as const, + version: 2 as const, currentContractClassId: contractClass.id, originalContractClassId: contractClass.id, initializationHash, + immutablesHash: Fr.ZERO, // Protocol Contracts Have No Immutables publicKeys: PublicKeys.default(), salt, deployer, diff --git a/yarn-project/prover-client/package.json b/yarn-project/prover-client/package.json index 1340a4433c20..d55946bd264a 100644 --- a/yarn-project/prover-client/package.json +++ b/yarn-project/prover-client/package.json @@ -28,7 +28,7 @@ "clean": "rm -rf ./dest .tsbuildinfo", "bb": "node --no-warnings ./dest/bb/index.js", "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --testTimeout=3500000", - "test:debug": "LOG_LEVEL=debug NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --testTimeout=1500000 --testNamePattern prover/bb_prover/parity" + "test:debug": "LOG_LEVEL=\"debug; info: json-rpc, simulator\" NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --testTimeout=1500000 --testNamePattern prover/bb_prover/parity" }, "jest": { "moduleNameMapper": { diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.ts index 2fb617696015..19951893c916 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.ts @@ -89,7 +89,7 @@ export class ProvingOrchestrator extends TopTreeProvingScheduler implements Epoc protected provingPromise: Promise | undefined = undefined; private metrics: ProvingOrchestratorMetrics; - // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections + private dbs: Map = new Map(); constructor( diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts b/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts index 34fc09fe7b06..4652413271d4 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts @@ -856,7 +856,7 @@ describe.each([ await assertJobTransition(id, 'in-progress', 'in-queue'); }); - it('cancel stale jobs that time out', async () => { + it('cleans up stale in-progress jobs before deleting their epoch database', async () => { const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, @@ -887,10 +887,9 @@ describe.each([ inputsUri: makeInputsUri(), }); - // advance time again so job times out. Since the job was in-progress, it won't be cleaned up as stale - // but will be rejected when it times out - await sleep(jobTimeoutMs + brokerIntervalMs); - await assertJobStatus(id, 'rejected'); + // the epoch-1 database is old enough to delete, so the broker closes any remaining epoch-1 jobs + await (broker as any).cleanupPass(); + await assertJobStatus(id, 'not-found'); }); it('rejects jobs that time out more than maxRetries times', async () => { @@ -1070,13 +1069,15 @@ describe.each([ inputsUri: makeInputsUri(), }); - await sleep(brokerIntervalMs); + await (broker as any).cleanupPass(); + await assertJobStatus(id, 'not-found'); - // job was in-progress so it won't be cleaned up as stale, but will be rejected on error + // the epoch-1 database has been deleted, so late worker reports are ignored + jest.spyOn(database, 'setProvingJobError'); await broker.reportProvingJobError(id, 'test error', true); + expect(database.setProvingJobError).not.toHaveBeenCalled(); await expect(broker.getProvingJobStatus(id)).resolves.toEqual({ - status: 'rejected', - reason: 'test error', + status: 'not-found', }); }); }); diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker.ts b/yarn-project/prover-client/src/proving_broker/proving_broker.ts index decb4835eff3..27364938d5e1 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker.ts @@ -319,6 +319,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr } private cleanUpProvingJobState(ids: ProvingJobId[]) { + const idsToClean = new Set(ids); for (const id of ids) { this.jobsCache.delete(id); const deferred = this.promises.get(id); @@ -331,6 +332,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr this.retries.delete(id); this.enqueuedAt.delete(id); } + this.completedJobNotifications = this.completedJobNotifications.filter(id => !idsToClean.has(id)); } #getProvingJobStatus(id: ProvingJobId): ProvingJobStatus { @@ -598,21 +600,21 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr } private async cleanupPass() { - this.cleanupStaleJobs(); this.reEnqueueExpiredJobs(); const oldestEpochToKeep = this.oldestEpochToKeep(); if (oldestEpochToKeep > 0) { + this.cleanupJobsOlderThanEpoch(EpochNumber(oldestEpochToKeep)); await this.database.deleteAllProvingJobsOlderThanEpoch(EpochNumber(oldestEpochToKeep)); this.logger.trace(`Deleted all epochs older than ${oldestEpochToKeep}`); } } - private cleanupStaleJobs() { + private cleanupJobsOlderThanEpoch(epochNumber: EpochNumber) { const jobIds = Array.from(this.jobsCache.keys()); const jobsToClean: ProvingJobId[] = []; for (const id of jobIds) { const job = this.jobsCache.get(id)!; - if (this.isJobStale(job) && !this.inProgress.has(id) && !this.resultsCache.has(id)) { + if (job.epochNumber < epochNumber) { jobsToClean.push(id); } } diff --git a/yarn-project/prover-node/src/job/epoch-proving-job.test.ts b/yarn-project/prover-node/src/job/epoch-proving-job.test.ts index d6b6fcd8739f..cc6c7b6f7aa0 100644 --- a/yarn-project/prover-node/src/job/epoch-proving-job.test.ts +++ b/yarn-project/prover-node/src/job/epoch-proving-job.test.ts @@ -26,6 +26,12 @@ import type { EpochProvingJobData } from './epoch-proving-job-data.js'; import { EpochProvingJob } from './epoch-proving-job.js'; describe('epoch-proving-job', () => { + const mockFork = () => { + const fork = mock(); + fork[Symbol.asyncDispose].mockImplementation(() => fork.close()); + return fork; + }; + // Dependencies let prover: MockProxy; let publisher: MockProxy; @@ -86,7 +92,7 @@ describe('epoch-proving-job', () => { l2BlockSource = mock(); worldState = mock(); publicProcessorFactory = mock(); - db = mock(); + db = mockFork(); publicProcessor = mock(); metrics = new ProverNodeJobMetrics( getTelemetryClient().getMeter('EpochProvingJob'), @@ -199,6 +205,62 @@ describe('epoch-proving-job', () => { expect(publisher.submitEpochProof).not.toHaveBeenCalled(); }); + it('waits for in-flight checkpoint processing to settle after a block processing failure', async () => { + const forkDbs = times(NUM_BLOCKS, () => mockFork()); + let nextFork = 0; + worldState.fork.mockImplementation(() => Promise.resolve(forkDbs[nextFork++])); + prover.startNewBlock.mockResolvedValue(undefined); + + let processCalls = 0; + let resolveSecondProcessStarted!: () => void; + const secondProcessStarted = new Promise(resolve => { + resolveSecondProcessStarted = resolve; + }); + let releaseSecondProcess!: () => void; + const secondProcessMayFinish = new Promise(resolve => { + releaseSecondProcess = resolve; + }); + + publicProcessorFactory.create.mockImplementation(() => { + const processor = mock(); + processor.process.mockImplementation(async txs => { + const txsArray = await toArray(txs); + processCalls++; + + if (processCalls === 1) { + await secondProcessStarted; + throw new Error('Failed to process tx'); + } + + if (processCalls === 2) { + resolveSecondProcessStarted(); + await secondProcessMayFinish; + } + + const processedTxs = await Promise.all(txsArray.map(tx => mock({ hash: tx.getTxHash() }))); + return [processedTxs, [], txsArray, [], []]; + }); + return processor; + }); + + const job = createJob({ parallelBlockLimit: 2 }); + const runPromise = job.run(); + + await secondProcessStarted; + const runResolvedBeforeSecondProcessFinished = await Promise.race([ + runPromise.then(() => true), + sleep(50).then(() => false), + ]); + + releaseSecondProcess(); + await runPromise; + + expect(runResolvedBeforeSecondProcessFinished).toBe(false); + expect(job.getState()).toEqual('failed'); + expect(forkDbs[1].close).toHaveBeenCalled(); + expect(publisher.submitEpochProof).not.toHaveBeenCalled(); + }); + it('times out if deadline is hit', async () => { prover.startNewBlock.mockImplementation(() => sleep(200)); const deadline = new Date(Date.now() + 100); @@ -219,6 +281,42 @@ describe('epoch-proving-job', () => { expect(publisher.submitEpochProof).not.toHaveBeenCalled(); }); + it('aborts public processing when stopped externally', async () => { + prover.startNewBlock.mockResolvedValue(undefined); + + let processStarted!: () => void; + const processStartedPromise = new Promise(resolve => { + processStarted = resolve; + }); + let abortSignal: AbortSignal | undefined; + + publicProcessor.process.mockImplementation(async (txs, opts) => { + const signal = opts?.signal; + if (!signal) { + throw new Error('Expected public processor abort signal'); + } + abortSignal = signal; + processStarted(); + await new Promise(resolve => signal.addEventListener('abort', () => resolve(), { once: true })); + + const txsArray = await toArray(txs); + const processedTxs = await Promise.all(txsArray.map(tx => mock({ hash: tx.getTxHash() }))); + return [processedTxs, [], txsArray, [], []]; + }); + + const job = createJob({ parallelBlockLimit: 1 }); + const runPromise = job.run(); + + await processStartedPromise; + await job.stop(); + await runPromise; + + expect(abortSignal?.aborted).toBe(true); + expect(job.getState()).toEqual('stopped'); + expect(prover.addTxs).not.toHaveBeenCalled(); + expect(publisher.submitEpochProof).not.toHaveBeenCalled(); + }); + it('halts if a new block for the epoch is found', async () => { const newHeaders = times(NUM_BLOCKS + 1, i => BlockHeader.random({ blockNumber: BlockNumber(i + 1) })); l2BlockSource.getBlocksData.mockResolvedValue(newHeaders.map(h => ({ header: h }) as any)); diff --git a/yarn-project/prover-node/src/job/epoch-proving-job.ts b/yarn-project/prover-node/src/job/epoch-proving-job.ts index 73cb5dfb5d12..88b8fad06dda 100644 --- a/yarn-project/prover-node/src/job/epoch-proving-job.ts +++ b/yarn-project/prover-node/src/job/epoch-proving-job.ts @@ -46,6 +46,7 @@ export class EpochProvingJob implements Traceable { private uuid: string; private runPromise: Promise | undefined; + private abortController = new AbortController(); private epochCheckPromise: RunningPromise | undefined; private deadlineTimeoutHandler: NodeJS.Timeout | undefined; @@ -170,7 +171,7 @@ export class EpochProvingJob implements Traceable { ? AVM_MAX_CONCURRENT_SIMULATIONS : this.checkpoints.length; - await asyncPool(parallelism, this.checkpoints, async checkpoint => { + await this.processCheckpoints(parallelism, async checkpoint => { this.checkState(); const checkpointTimer = new Timer(); @@ -228,22 +229,26 @@ export class EpochProvingJob implements Traceable { // Process public fns. L1 to L2 messages are only inserted for the first block of a checkpoint, // as the fork for subsequent blocks already includes them from the previous block's synced state. - const db = await this.createFork( - BlockNumber(block.number - 1), - blockIndex === 0 ? l1ToL2Messages : undefined, - ); - const config = PublicSimulatorConfig.from({ - proverId: this.prover.getProverId().toField(), - skipFeeEnforcement: false, - collectDebugLogs: false, - collectHints: true, - collectPublicInputs: true, - collectStatistics: false, - }); - const publicProcessor = this.publicProcessorFactory.create(db, globalVariables, config); - const processed = await this.processTxs(publicProcessor, txs); - await this.prover.addTxs(processed); - await db.close(); + { + await using db = await this.createFork( + BlockNumber(block.number - 1), + blockIndex === 0 ? l1ToL2Messages : undefined, + ); + this.checkState(); + const config = PublicSimulatorConfig.from({ + proverId: this.prover.getProverId().toField(), + skipFeeEnforcement: false, + collectDebugLogs: false, + collectHints: true, + collectPublicInputs: true, + collectStatistics: false, + }); + const publicProcessor = this.publicProcessorFactory.create(db, globalVariables, config); + const processed = await this.processTxs(publicProcessor, txs); + this.checkState(); + await this.prover.addTxs(processed); + } + this.checkState(); this.log.verbose(`Processed all ${txs.length} txs for block ${block.number}`, { blockNumber: block.number, blockHash: (await block.hash()).toString(), @@ -337,7 +342,9 @@ export class EpochProvingJob implements Traceable { */ private async createFork(blockNumber: BlockNumber, l1ToL2Messages: Fr[] | undefined) { this.log.verbose(`Creating fork at ${blockNumber}`, { blockNumber }); - const db = await this.dbProvider.fork(blockNumber); + // temporary stack to control fork lifetime + await using cleanup = new AsyncDisposableStack(); + const db = cleanup.use(await this.dbProvider.fork(blockNumber)); if (l1ToL2Messages !== undefined) { this.log.verbose(`Inserting ${l1ToL2Messages.length} L1 to L2 messages in fork`, { @@ -347,9 +354,44 @@ export class EpochProvingJob implements Traceable { await appendL1ToL2MessagesToTree(db, l1ToL2Messages); } + // everything run succesfully so we can release this stack and give control of the fork's lifetime to the caller + cleanup.move(); return db; } + private async processCheckpoints( + parallelism: number, + processCheckpoint: (checkpoint: Checkpoint) => Promise, + ): Promise { + let hasError = false; + let firstError: unknown; + + await asyncPool(Math.max(parallelism, 1), this.checkpoints, async checkpoint => { + if (hasError || this.abortController.signal.aborted) { + return; + } + + try { + this.checkState(); + await processCheckpoint(checkpoint); + } catch (err) { + if (!hasError) { + hasError = true; + firstError = err; + this.failProcessing(); + } + } + }); + + if (hasError) { + throw firstError; + } + + if (this.abortController.signal.aborted) { + this.checkState(); + } + } + private progressState(state: EpochProvingJobState) { this.checkState(); this.state = state; @@ -363,12 +405,24 @@ export class EpochProvingJob implements Traceable { public async stop(state: EpochProvingJobTerminalState = 'stopped') { this.state = state; - this.prover.cancel(); + this.interruptProcessing(); if (this.runPromise) { await this.runPromise; } } + private failProcessing() { + if (!EpochProvingJobTerminalState.includes(this.state)) { + this.state = 'failed'; + } + this.interruptProcessing(); + } + + private interruptProcessing() { + this.abortController.abort(); + this.prover.cancel(); + } + private scheduleDeadlineStop() { const deadline = this.deadline; if (deadline) { @@ -444,7 +498,11 @@ export class EpochProvingJob implements Traceable { private async processTxs(publicProcessor: PublicProcessor, txs: Tx[]): Promise { const { deadline } = this; - const [processedTxs, failedTxs] = await publicProcessor.process(txs, { deadline }); + const [processedTxs, failedTxs] = await publicProcessor.process(txs, { + deadline, + signal: this.abortController.signal, + }); + this.checkState(); if (failedTxs.length) { const failedTxHashes = await Promise.all(failedTxs.map(({ tx }) => tx.getTxHash())); diff --git a/yarn-project/prover-node/src/prover-node-publisher.test.ts b/yarn-project/prover-node/src/prover-node-publisher.test.ts index f7a22a777829..31d035b37d9e 100644 --- a/yarn-project/prover-node/src/prover-node-publisher.test.ts +++ b/yarn-project/prover-node/src/prover-node-publisher.test.ts @@ -188,6 +188,82 @@ describe('prover-node-publisher', () => { }, ); + it('waits until the proven checkpoint reaches the checkpoint before the proof start', async () => { + const checkpoints = Array.from({ length: 100 }, () => RootRollupPublicInputs.random()); + const fromCheckpoint = CheckpointNumber(33); + const toCheckpoint = CheckpointNumber(64); + + rollup.getTips + .mockResolvedValueOnce({ + pending: CheckpointNumber(65), + proven: CheckpointNumber(31), + }) + .mockResolvedValueOnce({ + pending: CheckpointNumber(65), + proven: CheckpointNumber(32), + }) + .mockResolvedValue({ + pending: CheckpointNumber(65), + proven: CheckpointNumber(32), + }); + rollup.getRollupConstants.mockResolvedValue({ + l1StartBlock: 0n, + l1GenesisTime: BigInt(Math.floor(Date.now() / 1000)), + slotDuration: 1, + epochDuration: 1, + proofSubmissionEpochs: 100, + targetCommitteeSize: 48, + rollupManaLimit: Number.MAX_SAFE_INTEGER, + }); + + rollup.getCheckpoint.mockImplementation((checkpointNumber: CheckpointNumber) => + Promise.resolve({ + archive: checkpoints[checkpointNumber - 1].endArchiveRoot, + attestationsHash: Buffer32.ZERO, + payloadDigest: Buffer32.ZERO, + headerHash: Buffer32.ZERO, + blobCommitmentsHash: Buffer32.ZERO, + outHash: '0x', + slotNumber: SlotNumber(0), + feeHeader: { + excessMana: 0n, + manaUsed: 0n, + ethPerFeeAsset: 0n, + congestionCost: 0n, + proverCost: 0n, + }, + }), + ); + + const ourPublicInputs = RootRollupPublicInputs.random(); + ourPublicInputs.previousArchiveRoot = checkpoints[fromCheckpoint - 2].endArchiveRoot; + ourPublicInputs.endArchiveRoot = checkpoints[toCheckpoint - 1].endArchiveRoot; + + const ourBatchedBlob = new BatchedBlob( + ourPublicInputs.blobPublicInputs.blobCommitmentsHash, + ourPublicInputs.blobPublicInputs.z, + ourPublicInputs.blobPublicInputs.y, + ourPublicInputs.blobPublicInputs.c, + ourPublicInputs.blobPublicInputs.c.negate(), + ); + + rollup.getEpochProofPublicInputs.mockResolvedValue(ourPublicInputs.toFields()); + + await publisher.submitEpochProof({ + epochNumber: EpochNumber(2), + fromCheckpoint, + toCheckpoint, + publicInputs: ourPublicInputs, + proof: Proof.empty(), + batchedBlobInputs: ourBatchedBlob, + attestations: [], + }); + + expect(rollup.getRollupConstants).toHaveBeenCalled(); + expect(rollup.getTips).toHaveBeenCalledTimes(3); + expect(l1Utils.sendAndMonitorTransaction).toHaveBeenCalled(); + }); + it('analyzeEpochProofSubmission validates, estimates, and does not send tx', async () => { const fromCheckpoint = 33; const toCheckpoint = 64; diff --git a/yarn-project/prover-node/src/prover-node-publisher.ts b/yarn-project/prover-node/src/prover-node-publisher.ts index b1ec554523cb..5c7bfeab2460 100644 --- a/yarn-project/prover-node/src/prover-node-publisher.ts +++ b/yarn-project/prover-node/src/prover-node-publisher.ts @@ -8,11 +8,13 @@ import { areArraysEqual } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log'; +import { retryUntil } from '@aztec/foundation/retry'; import type { Tuple } from '@aztec/foundation/serialize'; import { Timer } from '@aztec/foundation/timer'; import { RollupAbi } from '@aztec/l1-artifacts'; import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client'; import { CommitteeAttestation, CommitteeAttestationsAndSigners } from '@aztec/stdlib/block'; +import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers'; import type { Proof } from '@aztec/stdlib/proofs'; import type { FeeRecipient, RootRollupPublicInputs } from '@aztec/stdlib/rollup'; import type { L1PublishProofStats } from '@aztec/stdlib/stats'; @@ -101,6 +103,11 @@ export class ProverNodePublisher { const ctx = { epochNumber, fromCheckpoint, toCheckpoint }; if (!this.interrupted) { + if (!(await this.waitUntilStartBuildsOnProven(args))) { + this.log.verbose('Checkpoint data syncing interrupted', ctx); + return false; + } + const timer = new Timer(); // Validate epoch proof range and hashes are correct before submitting await this.validateEpochProofSubmission(args); @@ -147,6 +154,53 @@ export class ProverNodePublisher { return false; } + private async waitUntilStartBuildsOnProven(args: { epochNumber: EpochNumber; fromCheckpoint: CheckpointNumber }) { + const { epochNumber, fromCheckpoint } = args; + const provenCheckpoint = await this.getProvenCheckpoint(); + if (this.isStartBuildingOnProven(fromCheckpoint, provenCheckpoint)) { + return true; + } + + const timeout = await this.getSecondsUntilProofSubmissionWindowEnd(epochNumber); + this.log.info(`Waiting for proven checkpoint to reach proof start`, { + epochNumber, + fromCheckpoint, + provenCheckpoint, + timeout, + }); + + await retryUntil( + async () => { + if (this.interrupted) { + return true; + } + + const proven = await this.getProvenCheckpoint(); + this.log.verbose(`Proven checkpoint is at ${proven} (waiting for ${fromCheckpoint - 1})`, { epochNumber }); + return this.isStartBuildingOnProven(fromCheckpoint, proven) ? true : undefined; + }, + `proven checkpoint to reach ${fromCheckpoint - 1}`, + timeout, + 4, + ); + + return !this.interrupted; + } + + private async getProvenCheckpoint() { + return (await this.rollupContract.getTips()).proven; + } + + private isStartBuildingOnProven(fromCheckpoint: CheckpointNumber, provenCheckpoint: CheckpointNumber) { + return fromCheckpoint - 1 <= provenCheckpoint; + } + + private async getSecondsUntilProofSubmissionWindowEnd(epochNumber: EpochNumber) { + const deadline = getProofSubmissionDeadlineTimestamp(epochNumber, await this.rollupContract.getRollupConstants()); + const now = BigInt(Math.floor(Date.now() / 1000)); + return Math.max(Number(deadline - now), 0.001); + } + private async validateEpochProofSubmission(args: { fromCheckpoint: CheckpointNumber; toCheckpoint: CheckpointNumber; diff --git a/yarn-project/prover-node/src/prover-node.ts b/yarn-project/prover-node/src/prover-node.ts index 92db38ae492b..dbcf9b906e63 100644 --- a/yarn-project/prover-node/src/prover-node.ts +++ b/yarn-project/prover-node/src/prover-node.ts @@ -166,10 +166,10 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable async stop() { this.log.info('Stopping ProverNode'); await this.epochsMonitor.stop(); - await this.prover.stop(); - await tryStop(this.publisherFactory); this.publisher?.interrupt(); await Promise.all(Array.from(this.jobs.values()).map(job => job.stop())); + await this.prover.stop(); + await tryStop(this.publisherFactory); this.rewardsMetrics.stop(); this.l1Metrics.stop(); await this.telemetryClient.stop(); diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts index 0a3fffe870bf..4bd1b749fd88 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/oracle.ts @@ -225,6 +225,7 @@ export class Oracle { instance.deployer, instance.currentContractClassId, instance.initializationHash, + instance.immutablesHash, ...instance.publicKeys.toFields(), ].map(toACVMField); } @@ -314,10 +315,26 @@ export class Oracle { // with two fields: `some` (a boolean) and `value` (a field array in this case). if (result === undefined) { // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size. - return [toACVMField(0), Array(13).fill(toACVMField(0))]; + // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, partial_address] = 6 fields. + return [toACVMField(0), Array(6).fill(toACVMField(0))]; } else { // Data was found so we set `some` to 1 and return it along with `value`. - return [toACVMField(1), [...result.publicKeys.toFields(), result.partialAddress].map(toACVMField)]; + // The Noir side hand-decodes a `[Field; 6]` here (see aztec-nr/aztec/src/oracle/keys.nr), so we + // emit the 5-field PublicKeys shape + partial_address explicitly + // rather than going through `publicKeys.toFields()` (which is the struct-flattened 6-field + // wire for oracle returns that decode via struct shape). + const { publicKeys, partialAddress } = result; + return [ + toACVMField(1), + [ + publicKeys.npkMHash, + publicKeys.ivpkM.x, + publicKeys.ivpkM.y, + publicKeys.ovpkMHash, + publicKeys.tpkMHash, + partialAddress, + ].map(toACVMField), + ]; } } diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts index f37e686891ef..2288551091e8 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts @@ -337,40 +337,40 @@ describe('Private Execution test suite', () => { keyStore.getAccounts.mockResolvedValue([owner, recipient, senderForTags]); - keyStore.accountHasKey.mockImplementation(async (account: AztecAddress, pkMHash: Fr) => { + keyStore.accountHasKey.mockImplementation((account: AztecAddress, pkMHash: Fr) => { if (account.equals(owner)) { - return pkMHash.equals(await ownerCompleteAddress.publicKeys.masterNullifierPublicKey.hash()); + return Promise.resolve(pkMHash.equals(ownerCompleteAddress.publicKeys.npkMHash)); } if (account.equals(recipient)) { - return pkMHash.equals(await recipientCompleteAddress.publicKeys.masterNullifierPublicKey.hash()); + return Promise.resolve(pkMHash.equals(recipientCompleteAddress.publicKeys.npkMHash)); } if (account.equals(senderForTags)) { - return pkMHash.equals(await senderForTagsCompleteAddress.publicKeys.masterNullifierPublicKey.hash()); + return Promise.resolve(pkMHash.equals(senderForTagsCompleteAddress.publicKeys.npkMHash)); } - return false; + return Promise.resolve(false); }); keyStore.getKeyValidationRequest.mockImplementation(async (pkMHash: Fr, contractAddress: AztecAddress) => { - if (pkMHash.equals(await ownerCompleteAddress.publicKeys.masterNullifierPublicKey.hash())) { + if (pkMHash.equals(ownerCompleteAddress.publicKeys.npkMHash)) { return Promise.resolve( new KeyValidationRequest( - ownerCompleteAddress.publicKeys.masterNullifierPublicKey, + ownerCompleteAddress.publicKeys.npkMHash, await computeAppNullifierHidingKey(ownerNhkM, contractAddress), ), ); } - if (pkMHash.equals(await recipientCompleteAddress.publicKeys.masterNullifierPublicKey.hash())) { + if (pkMHash.equals(recipientCompleteAddress.publicKeys.npkMHash)) { return Promise.resolve( new KeyValidationRequest( - recipientCompleteAddress.publicKeys.masterNullifierPublicKey, + recipientCompleteAddress.publicKeys.npkMHash, await computeAppNullifierHidingKey(recipientNhkM, contractAddress), ), ); } - if (pkMHash.equals(await senderForTagsCompleteAddress.publicKeys.masterNullifierPublicKey.hash())) { + if (pkMHash.equals(senderForTagsCompleteAddress.publicKeys.npkMHash)) { return Promise.resolve( new KeyValidationRequest( - senderForTagsCompleteAddress.publicKeys.masterNullifierPublicKey, + senderForTagsCompleteAddress.publicKeys.npkMHash, await computeAppNullifierHidingKey(senderForTagsNhkM, contractAddress), ), ); @@ -1265,7 +1265,7 @@ describe('Private Execution test suite', () => { // Generate a partial address, pubkey, and resulting address const completeAddress = await CompleteAddress.random(); const args = [completeAddress.address]; - const pubKey = completeAddress.publicKeys.masterIncomingViewingPublicKey; + const pubKey = completeAddress.publicKeys.ivpkM; addressStore.getCompleteAddress.mockResolvedValue(completeAddress); const { entrypoint: result } = await runSimulator({ diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution.test.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution.test.ts index 47d684aa7850..b9cd370c147a 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution.test.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution.test.ts @@ -1,7 +1,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; import { Grumpkin } from '@aztec/foundation/crypto/grumpkin'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin'; +import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin'; import type { KeyStore } from '@aztec/key-store'; import { StatefulTestContractArtifact } from '@aztec/noir-test-contracts.js/StatefulTest'; import { WASMSimulator } from '@aztec/simulator/client'; @@ -14,7 +14,7 @@ import { computeContractAddressFromInstance, } from '@aztec/stdlib/contract'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { PublicKeys, deriveKeys } from '@aztec/stdlib/keys'; +import { PublicKeys, deriveKeys, hashPublicKey } from '@aztec/stdlib/keys'; import { MessageContext } from '@aztec/stdlib/logs'; import { Note, NoteDao } from '@aztec/stdlib/note'; import { makeL2Tips } from '@aztec/stdlib/testing'; @@ -150,12 +150,13 @@ describe('Utility Execution test suite', () => { // The initializer nullifier check requires the instance to be a valid preimage of the contract address, so we // can't use a random contract address here. const instanceFields = { - version: 1 as const, + version: 2 as const, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: new Fr(42), originalContractClassId: new Fr(42), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), }; const contractAddress = await computeContractAddressFromInstance(instanceFields); @@ -242,12 +243,13 @@ describe('Utility Execution test suite', () => { const expectedSum = new Fr(9); const instanceFields = { - version: 1 as const, + version: 2 as const, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: new Fr(42), originalContractClassId: new Fr(42), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), }; const contractAddress = await computeContractAddressFromInstance(instanceFields); @@ -489,11 +491,12 @@ describe('Utility Execution test suite', () => { // Derive keys so we can mock getMasterSecretKey (used by getSharedSecrets) const { masterIncomingViewingSecretKey: ownerIvskM } = await deriveKeys(ownerSecretKey); - keyStore.getMasterSecretKey.mockImplementation((publicKey: Point) => { - if (publicKey.equals(ownerCompleteAddress.publicKeys.masterIncomingViewingPublicKey)) { + const ownerIvpkMHash = await hashPublicKey(ownerCompleteAddress.publicKeys.ivpkM); + keyStore.getMasterSecretKey.mockImplementation((pkMHash: Fr) => { + if (pkMHash.equals(ownerIvpkMHash)) { return Promise.resolve(ownerIvskM); } - throw new Error(`Unknown public key ${publicKey}`); + throw new Error(`Unknown pk_m_hash ${pkMHash}`); }); const contractAddressA = await AztecAddress.random(); diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts index e03a4ee93c19..3e252d028380 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts @@ -3,7 +3,6 @@ import type { BlockNumber } from '@aztec/foundation/branded-types'; import { uniqueBy } from '@aztec/foundation/collection'; import { Aes128 } from '@aztec/foundation/crypto/aes128'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import { LogLevels, type Logger, createLogger } from '@aztec/foundation/log'; import type { MembershipWitness } from '@aztec/foundation/trees'; import type { KeyStore } from '@aztec/key-store'; @@ -23,7 +22,7 @@ import type { CompleteAddress, ContractInstance, PartialAddress } from '@aztec/s import { siloNullifier } from '@aztec/stdlib/hash'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; import type { KeyValidationRequest } from '@aztec/stdlib/kernel'; -import { type PublicKeys, computeAddressSecret } from '@aztec/stdlib/keys'; +import { PublicKey, type PublicKeys, computeAddressSecret, hashPublicKey } from '@aztec/stdlib/keys'; import { MessageContext, deriveAppSiloedSharedSecret } from '@aztec/stdlib/logs'; import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging'; import type { NoteStatus } from '@aztec/stdlib/note'; @@ -720,15 +719,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra ); } const recipientCompleteAddress = await this.getCompleteAddressOrFail(address); - const ivskM = await this.keyStore.getMasterSecretKey( - recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey, - ); + const ivpkMHash = await hashPublicKey(recipientCompleteAddress.publicKeys.ivpkM); + const ivskM = await this.keyStore.getMasterSecretKey(ivpkMHash); const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM); const ephPkFields = this.ephemeralArrayService.readArrayAt(ephPksSlot); const secrets = await Promise.all( ephPkFields.map(fields => - deriveAppSiloedSharedSecret(addressSecret, Point.fromFields(fields), this.contractAddress), + deriveAppSiloedSharedSecret(addressSecret, PublicKey.fromFields(fields), this.contractAddress), ), ); diff --git a/yarn-project/pxe/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts b/yarn-project/pxe/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts index 9b4c5542d145..149dea355274 100644 --- a/yarn-project/pxe/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +++ b/yarn-project/pxe/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts @@ -68,7 +68,7 @@ async function getMasterSecretKeysAndKeyTypeDomainSeparators( const numRequestsToProcess = Math.min(keyValidationRequests.claimedLength, numRequestsToVerify); const keysHints = await Promise.all( keyValidationRequests.array.slice(0, numRequestsToProcess).map(async ({ request }) => { - const secretKeys = await oracle.getMasterSecretKey(request.request.pkM); + const secretKeys = await oracle.getMasterSecretKey(request.request.pkMHash); return new KeyValidationHint(secretKeys); }), ); diff --git a/yarn-project/pxe/src/private_kernel/hints/test_utils.ts b/yarn-project/pxe/src/private_kernel/hints/test_utils.ts index be5bf7a66f7c..9a1fba6009ed 100644 --- a/yarn-project/pxe/src/private_kernel/hints/test_utils.ts +++ b/yarn-project/pxe/src/private_kernel/hints/test_utils.ts @@ -14,7 +14,6 @@ import { } from '@aztec/constants'; import { makeTuple } from '@aztec/foundation/array'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import type { Serializable } from '@aztec/foundation/serialize'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { @@ -130,10 +129,7 @@ export class PrivateKernelCircuitPublicInputsBuilder { const addr = opts?.contractAddress ?? this.contractAddress; this.keyValidationRequests.push( new ScopedKeyValidationRequestAndSeparator( - new KeyValidationRequestAndSeparator( - new KeyValidationRequest(new Point(Fr.random(), Fr.random(), false), Fr.random()), - Fr.random(), - ), + new KeyValidationRequestAndSeparator(new KeyValidationRequest(Fr.random(), Fr.random()), Fr.random()), addr, ), ); @@ -253,10 +249,7 @@ export class PrivateCircuitPublicInputsBuilder { /** Adds a key validation request. */ addKeyValidationRequest(): this { this.keyValidationRequests.push( - new KeyValidationRequestAndSeparator( - new KeyValidationRequest(new Point(Fr.random(), Fr.random(), false), Fr.random()), - Fr.random(), - ), + new KeyValidationRequestAndSeparator(new KeyValidationRequest(Fr.random(), Fr.random()), Fr.random()), ); return this; } diff --git a/yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts b/yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts index e16dab33ec23..a44bab2ad2fc 100644 --- a/yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts +++ b/yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts @@ -130,12 +130,13 @@ describe('Private Kernel Sequencer', () => { oracle.getMasterSecretKey.mockResolvedValue(Fr.random() as any); oracle.getContractAddressPreimage.mockResolvedValue({ - version: 1 as const, + version: 2 as const, salt: Fr.random(), deployer: await AztecAddress.random(), currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), address: await AztecAddress.random(), saltedInitializationHash: Fr.random(), diff --git a/yarn-project/pxe/src/private_kernel/private_kernel_oracle.ts b/yarn-project/pxe/src/private_kernel/private_kernel_oracle.ts index e04720182409..cce48341341e 100644 --- a/yarn-project/pxe/src/private_kernel/private_kernel_oracle.ts +++ b/yarn-project/pxe/src/private_kernel/private_kernel_oracle.ts @@ -6,7 +6,7 @@ import { VK_TREE_HEIGHT, } from '@aztec/constants'; import type { Fr } from '@aztec/foundation/curves/bn254'; -import type { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin'; +import type { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin'; import { MembershipWitness } from '@aztec/foundation/trees'; import type { KeyStore } from '@aztec/key-store'; import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/vk-tree'; @@ -103,14 +103,14 @@ export class PrivateKernelOracle { } /** - * Retrieves the sk_m corresponding to the pk_m. - * @throws If the provided public key is not associated with any of the registered accounts. - * @param masterPublicKey - The master public key to get secret key for. + * Retrieves the sk_m corresponding to the pk_m hash. + * @throws If the provided hash is not associated with any of the registered accounts. + * @param masterPublicKeyHash - The master public key hash to get secret key for. * @returns A Promise that resolves to sk_m. * @dev Used when feeding the sk_m to the kernel circuit for keys verification. */ - public getMasterSecretKey(masterPublicKey: Point): Promise { - return this.keyStore.getMasterSecretKey(masterPublicKey); + public getMasterSecretKey(masterPublicKeyHash: Fr): Promise { + return this.keyStore.getMasterSecretKey(masterPublicKeyHash); } /** Use debug data to get the function name corresponding to a selector. */ diff --git a/yarn-project/pxe/src/storage/address_store/address_store.test.ts b/yarn-project/pxe/src/storage/address_store/address_store.test.ts index 40cea7d0f9f3..51e52319a6c2 100644 --- a/yarn-project/pxe/src/storage/address_store/address_store.test.ts +++ b/yarn-project/pxe/src/storage/address_store/address_store.test.ts @@ -1,4 +1,5 @@ import { timesParallel } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/curves/bn254'; import { Point } from '@aztec/foundation/curves/grumpkin'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import { CompleteAddress } from '@aztec/stdlib/contract'; @@ -30,7 +31,7 @@ describe('addresses', () => { const address = await CompleteAddress.random(); const otherAddress = await CompleteAddress.create( address.address, - new PublicKeys(await Point.random(), await Point.random(), await Point.random(), await Point.random()), + new PublicKeys(Fr.random(), await Point.random(), Fr.random(), Fr.random()), address.partialAddress, ); diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json index f2e80f8f02f2..ead6b82ef58e 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json @@ -2,21 +2,21 @@ "complete_addresses": [ { "index": 0, - "value": "0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a214c7a24ddf501afc8734c7379ee502296289eb24cd8cd03cd435e128c06be0000987721e0963b4a5bd81ee862e2740d8849fd90537569064d3d3a4640e858d219e95c05f09cb86d1a6257572f9082ca15d4a02373c4d8c9cee23dc61a4c2a882f9017d51bca6616102d8a1d4dba89e4ce12881a2414576f01d2fec9492814a22c19ff0b089b07da436e6f7be6b26cdc17b9cee504a528c071ef6a416299683d0b369479d6e50504702d0b56bb56e4e8e0e77171429896651d0c11621e82ebc32fcdd0d194adafd753dc0ed279f5cfb54ddcce1dd581d4631cf343ba9ee6c1ab2858abca6c00da3def156b1f12a6464384e326d5fa724c2fc2ff2b7f3fc8ad5f0000000000000000000000000000000000000000000000000000000000000003" + "value": "179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db13ad6965d11a533a663d07507319f74ac3305325f6f72423c0b24aa1193268bb19e95c05f09cb86d1a6257572f9082ca15d4a02373c4d8c9cee23dc61a4c2a882f9017d51bca6616102d8a1d4dba89e4ce12881a2414576f01d2fec9492814a22a1b054e998835d166711839b515d434b1fbc207ad4fdb5b2b43d6ac6b400871019f5bb255e87523d43da83ebc9fa95169b653d4abef902e011e9eac620fc45b0000000000000000000000000000000000000000000000000000000000000003" }, { "index": 1, - "value": "2bc83a7fe553d4b649228410040c130a782f86f9b54813f4d847d0c3eeba065a156832f7840991767f448681237ef8bce6895fc79e5d9d0dedd89dccfd9d59ce215403719ea86d38909507bba0ba2d191f72dc1991a5dfc17da8bf7e8c1f1f4f267e526a2e6e9adf6a026989be005bd50d1aea76d20816b9843bc95557696f9f16c3eb259ba3e3eb27b7fe3abc36e87923990bf5c265cb0d57790eda2a4432f1237296442bbb36cc3632af0578ad4b7d5d69d52e05937a1d3e2fe295ac9af98628737df05bb727d77dd52691d42566eb22e529f9f404a2f9bc2e1982956ba09c1df52a95111bd76680a4356951e68a20c3e51cbddb7d1536c572b416bd342e3204aa15eaf393bb18695ddee077d52be6489ed510f357a90003099ce337e6232c0000000000000000000000000000000000000000000000000000000000000007" + "value": "0bc042bac587b8ff4785ff5b6def422de3ad558e37ec89b6494ff8c5dae0aa5d17c2df1b7355bb4c4494aa4ec85d15ff8881cea1b34691f0cc558e8aef3f3f4c267e526a2e6e9adf6a026989be005bd50d1aea76d20816b9843bc95557696f9f16c3eb259ba3e3eb27b7fe3abc36e87923990bf5c265cb0d57790eda2a4432f105a5449624125d37f10cd4c68ffd57b0dc0cdaa916cb37840be1db9bf88e3c5f0e81754454e3b12035b13448a9fe3b980bf31a9808cb93e146628fb06fa1b46f0000000000000000000000000000000000000000000000000000000000000007" } ], "complete_address_index": [ { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a", - "value": "num:0" + "key": "utf8:0x0bc042bac587b8ff4785ff5b6def422de3ad558e37ec89b6494ff8c5dae0aa5d", + "value": "num:1" }, { - "key": "utf8:0x2bc83a7fe553d4b649228410040c130a782f86f9b54813f4d847d0c3eeba065a", - "value": "num:1" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db", + "value": "num:0" } ] } diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json index 6de71bb8c2e4..e52777ac981c 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json @@ -22,7 +22,7 @@ "contracts_instances": [ { "key": "utf8:0x0000000000000000000000000000000000000000000000000000000000000065", - "value": "010000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000430000000000000000000000000000000000000000000000000000000000000047" + "value": "020000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000670000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000043" } ] } diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json index 7164be86011a..24f383496aa2 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json @@ -1,51 +1,51 @@ { "key_store": [ { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ivpk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ivpk_m", "value": "19e95c05f09cb86d1a6257572f9082ca15d4a02373c4d8c9cee23dc61a4c2a882f9017d51bca6616102d8a1d4dba89e4ce12881a2414576f01d2fec9492814a2" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ivpk_m_hash", - "value": "2c8a04047c06c447dcf1011ddd80c1d03dc9f70a5fa4645722d086fe82504d76" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ivpk_m_hash", + "value": "1fd17152d394f6a43b527c531590888d610d1bcb9aa71a02498ce820bbf4dc62" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ivsk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ivsk_m", "value": "1fb01c42d1aaa2662041b899c77cb19e08192193acc5a94405f1b43c974eba7a" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-nhk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-nhk_m", "value": "2dd30220767969b10044b1322585bb4c4df4e0c5d9b4d7b3045a879a8e3e91d2" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-npk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-npk_m", "value": "214c7a24ddf501afc8734c7379ee502296289eb24cd8cd03cd435e128c06be0000987721e0963b4a5bd81ee862e2740d8849fd90537569064d3d3a4640e858d2" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-npk_m_hash", - "value": "0df588690e44b50e4ca694d25b494039b60f09451eaea7aaba97bd4cf8001710" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-npk_m_hash", + "value": "13ad6965d11a533a663d07507319f74ac3305325f6f72423c0b24aa1193268bb" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ovpk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ovpk_m", "value": "2c19ff0b089b07da436e6f7be6b26cdc17b9cee504a528c071ef6a416299683d0b369479d6e50504702d0b56bb56e4e8e0e77171429896651d0c11621e82ebc3" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ovpk_m_hash", - "value": "2cbd8a987ad7dc81814feabc55abdf40b810161611ad89b705db92f32cf94603" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ovpk_m_hash", + "value": "2a1b054e998835d166711839b515d434b1fbc207ad4fdb5b2b43d6ac6b400871" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-ovsk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-ovsk_m", "value": "279fe6ef7dd2477b919327b1ebab7497c41b9a7ccfa9d5d52e32698e3b85293b" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-tpk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-tpk_m", "value": "2fcdd0d194adafd753dc0ed279f5cfb54ddcce1dd581d4631cf343ba9ee6c1ab2858abca6c00da3def156b1f12a6464384e326d5fa724c2fc2ff2b7f3fc8ad5f" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-tpk_m_hash", - "value": "2a0b3526801cd5edcaf6b4ba6e1f0a378b6d78d42a62410e86202fb66b44dd53" + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-tpk_m_hash", + "value": "019f5bb255e87523d43da83ebc9fa95169b653d4abef902e011e9eac620fc45b" }, { - "key": "utf8:0x0e097c323e48522fcbd592590a72a0d4e50f22b3fb1913d19c936439ab74851a-tsk_m", + "key": "utf8:0x179b170f4084ee97fc27c1c5b41a9934e052077de1d275fee11428265154b6db-tsk_m", "value": "183cb61099458d1564aa57c90c7091ac623a14092ab314150c9cfbb416810320" } ] diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json index 2ee17beb3c62..8a55a9c4c66f 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json @@ -1,5 +1,5 @@ { - "schemaVersion": 5, + "schemaVersion": 6, "stores": [ { "name": "address_book", diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts b/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts index 91b2c2d90ef1..d54678092928 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts @@ -2,7 +2,6 @@ import { CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants'; import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import { EthAddress } from '@aztec/foundation/eth-address'; import type { Tuple } from '@aztec/foundation/serialize'; import { KeyStore } from '@aztec/key-store'; @@ -15,7 +14,7 @@ import { BlockHash, Body, GENESIS_BLOCK_HEADER_HASH, L2Block } from '@aztec/stdl import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; import { CompleteAddress, SerializableContractInstance } from '@aztec/stdlib/contract'; import { GasFees } from '@aztec/stdlib/gas'; -import { PublicKeys } from '@aztec/stdlib/keys'; +import { PublicKey, PublicKeys } from '@aztec/stdlib/keys'; import { ContractClassLog, ContractClassLogFields, @@ -187,18 +186,17 @@ export const SCHEMA_TESTS: readonly SchemaTest[] = [ await contractStore.addContractInstance( new SerializableContractInstance({ - version: 1, + version: 2, salt: new Fr(73n), deployer: AztecAddress.fromBigInt(79n), currentContractClassId: new Fr(83n), originalContractClassId: new Fr(89n), initializationHash: new Fr(97n), - publicKeys: new PublicKeys( - new Point(new Fr(41n), new Fr(43n), false), - new Point(new Fr(47n), new Fr(53n), false), - new Point(new Fr(59n), new Fr(61n), false), - new Point(new Fr(67n), new Fr(71n), false), - ), + immutablesHash: new Fr(103n), + // Only `ivpk_m` is exposed as a curve point; the other three master keys + // are exposed as `hash_public_key` digests. Constructor signature is now + // `(npkMHash, ivpkM, ovpkMHash, tpkMHash)`. + publicKeys: new PublicKeys(new Fr(41n), new PublicKey(new Fr(47n), new Fr(53n)), new Fr(59n), new Fr(67n)), }).withAddress(AztecAddress.fromBigInt(101n)), ); }, diff --git a/yarn-project/pxe/src/storage/metadata.ts b/yarn-project/pxe/src/storage/metadata.ts index aa63404894b5..b828fac62539 100644 --- a/yarn-project/pxe/src/storage/metadata.ts +++ b/yarn-project/pxe/src/storage/metadata.ts @@ -1 +1 @@ -export const PXE_DATA_SCHEMA_VERSION = 5; +export const PXE_DATA_SCHEMA_VERSION = 6; diff --git a/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts b/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts index b2800582f02d..6c9e4a430d33 100644 --- a/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts +++ b/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts @@ -494,7 +494,7 @@ describe('SenderTaggingStore', () => { describe('finalizePendingIndexesOfAPartiallyRevertedTx', () => { function makeTxEffect(txHash: TxHash, siloedTags: SiloedTag[]): TxEffect { return new TxEffect( - RevertCode.APP_LOGIC_REVERTED, + RevertCode.REVERTED, txHash, Fr.ZERO, [Fr.random()], // noteHashes (at least 1 nullifier required below, not here) diff --git a/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts b/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts index d2020a61218b..db241763b58e 100644 --- a/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts +++ b/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts @@ -467,12 +467,12 @@ describe('syncSenderTaggingIndexes', () => { ); }); - // Mock getTxReceipt to return FINALIZED with APP_LOGIC_REVERTED + // Mock getTxReceipt to return FINALIZED with REVERTED aztecNode.getTxReceipt.mockResolvedValue( new TxReceipt( revertedTxHash, TxStatus.FINALIZED, - TxExecutionResult.APP_LOGIC_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, @@ -482,7 +482,7 @@ describe('syncSenderTaggingIndexes', () => { // Mock getTxEffect to return a TxEffect where only the tag at index 4 survived (non-revertible phase) const txEffect = new TxEffect( - RevertCode.APP_LOGIC_REVERTED, + RevertCode.REVERTED, revertedTxHash, Fr.ZERO, [Fr.random()], // noteHashes diff --git a/yarn-project/pxe/src/tagging/sender_sync/utils/get_status_change_of_pending.test.ts b/yarn-project/pxe/src/tagging/sender_sync/utils/get_status_change_of_pending.test.ts index 676b491d8910..2842a8554eb7 100644 --- a/yarn-project/pxe/src/tagging/sender_sync/utils/get_status_change_of_pending.test.ts +++ b/yarn-project/pxe/src/tagging/sender_sync/utils/get_status_change_of_pending.test.ts @@ -55,7 +55,7 @@ describe('getStatusChangeOfPending', () => { new TxReceipt( hash, TxStatus.FINALIZED, - TxExecutionResult.APP_LOGIC_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, @@ -67,7 +67,7 @@ describe('getStatusChangeOfPending', () => { new TxReceipt( hash, TxStatus.FINALIZED, - TxExecutionResult.TEARDOWN_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, @@ -79,7 +79,7 @@ describe('getStatusChangeOfPending', () => { new TxReceipt( hash, TxStatus.FINALIZED, - TxExecutionResult.BOTH_REVERTED, + TxExecutionResult.REVERTED, undefined, undefined, undefined, diff --git a/yarn-project/sequencer-client/README.md b/yarn-project/sequencer-client/README.md index dcd133ab02e5..6738e8cb168d 100644 --- a/yarn-project/sequencer-client/README.md +++ b/yarn-project/sequencer-client/README.md @@ -4,13 +4,13 @@ The sequencer client is the proposer-side counterpart to the [validator client]( A single instance owns the entire proposer flow for one slot: deciding whether to propose, building several L2 blocks one after another, signing them, gossiping them, collecting attestations from the committee, and submitting the final checkpoint to L1 in one Multicall3 transaction together with governance and slashing votes. -The sequencer does **not** decide what is in the next block on its own. It composes the work of several other subsystems: the [tx pool](../p2p/README.md) supplies transactions, the [validator client](../validator-client/README.md) owns the operator keys and signs proposals, the `CheckpointBuilder` (defined in `@aztec/validator-client`, but constructed and held by the sequencer's `CheckpointProposalJob`) executes the txs, the [archiver](../archiver/README.md) provides the L2 chain state needed to anchor each block, the [epoch cache](../epoch-cache/README.md) answers proposer/committee lookups, and the [slasher](../slasher/README.md) supplies offenses to vote on. +The sequencer does **not** decide what is in the next block on its own. It composes the work of several other subsystems: the [tx pool](../p2p/README.md) supplies transactions, the [validator client](../validator-client/README.md) owns operator keys and contains the `CheckpointBuilder` that actually executes them, the [archiver](../archiver/README.md) provides the L2 chain state needed to anchor each block, the [epoch cache](../epoch-cache/README.md) answers proposer/committee lookups, and the [slasher](../slasher/README.md) supplies offenses to vote on. ## Key Concepts ### Slots, Blocks, and Checkpoints -The Aztec design splits each Aztec slot into multiple L2 blocks: +The Aztec consensus design splits each Aztec slot into multiple L2 blocks. This is the design originally called [building in chunks](https://github.com/AztecProtocol/engineering-designs/blob/main/docs/building-in-chunks/index.md). - **Slot** — a fixed time window (e.g. 72 s) during which one proposer is allowed to build. - **Block** — a single batch of transactions, executed and validated as a unit, with its own header. @@ -26,13 +26,11 @@ There are two tips the sequencer cares about: - The **proposed chain** is the set of blocks that have been broadcast over p2p but not yet committed to L1. Both the sequencer and validators push these blocks into the archiver so the rest of the node can serve them. - The **checkpointed chain** is the set of checkpoints that have landed on L1, recovered from `CheckpointProposed` events. -Within a slot, the proposer adds blocks to the proposed chain as it goes. At the end of its slot, it sends a `CheckpointProposal` that committee members attest to; intermediate blocks are accepted onto the proposed chain by virtue of the proposer's signature alone, and every node that wants to follow the proposed chain re-executes them. See the [validator client README](../validator-client/README.md) for the consumer side. +Within a slot, the proposer adds blocks to the proposed chain as it goes. Only the last block within the slot is bundled with a `CheckpointProposal` that committee members attest to; intermediate blocks are accepted onto the proposed chain by virtue of the proposer's signature alone, and every node that wants to follow the proposed chain re-executes them. See the [validator client README](../validator-client/README.md) for the consumer side. ### Proposer Pipelining -The legacy non-pipelined flow had the proposer for slot `N` build, attest, and publish inside slot `N`; so the proposer spent most of `N` collecting attestations and waiting for the L1 transaction to be mined, leaving a long idle window. - -Pipelining removes that idle window: the proposer for slot `N` builds blocks during slot `N - 1`, finishes attestation collection before the slot boundary, and submits the L1 transaction at the start of slot `N`. +The legacy ("non-pipelined") flow has the proposer for slot `N` build, attest, and publish inside slot `N`. The proposer spends most of `N` collecting attestations and waiting for the L1 transaction to be mined, leaving a long idle window. Pipelining, [proposed in this discussion](https://github.com/AztecProtocol/governance/discussions/8), removes that idle window: the proposer for slot `N` builds blocks during slot `N - 1`, finishes attestation collection before the slot boundary, and submits the L1 transaction at the start of slot `N`. Pipelining shifts the work like this: @@ -45,35 +43,44 @@ Pipelining shifts the work like this: \* The pipelined timing model reserves enough end-of-slot budget for attestations to be in hand by the slot boundary, but the enforced deadline (`checkpointAttestationDeadline`) actually extends to `2 * aztecSlotDuration - l1PublishingTime`, so a late attestation can still spill into the target slot. -The non-pipelined mode is being removed; this README treats pipelining as the default. The toggle still exists for lingering tests. +In practice, "non-pipelined mode" is being removed; this README treats pipelining as the default. The toggle still exists (`enableProposerPipelining`) because `EpochCache` consults it when looking up the proposer for the next L1 slot — when pipelining is enabled, the sequencer asks the cache for the proposer of `slot + 1` rather than `slot`. + +The pipelining flow introduces two failure modes that block building has to handle: -Note that, under pipelining, if the parent checkpoint we built on top of fails to land cleanly on L1, the next proposer's work is discarded (`pipelined-checkpoint-discarded` event). +- **Pipeline depth** is bounded to 2 (`checkpointNumber ≤ confirmedCheckpoint + 2`). Building further ahead would require trusting more in-flight parent proposals than the design allows. +- **Pipelined parent invalidation**: if the parent checkpoint we built on top of fails to land cleanly on L1, the next proposer's work is discarded (`pipelined-checkpoint-discarded` event) and an `invalidate` request is enqueued for the parent. ## Architecture -```mermaid -flowchart TD - Seq["Sequencer
state machine, one slot at a time
work() → prepareCheckpointProposal() → CheckpointProposalJob"] - - VC["ValidatorClient
operator keys, HA signer
signs block + checkpoint proposals"] - EC["EpochCache
proposer + committee lookup"] - CB["CheckpointBuilder
forked world state
per-block execution via PublicProcessor"] - Pub["SequencerPublisher
Multicall3 L1 tx
with preChecks"] - - P2P["p2pClient"] - TP["TxProvider
(tx pool)"] - Arc["Archiver
L2 tips, addBlock"] - L1["L1 Rollup Contract"] - - Seq -->|signs proposals| VC - Seq -->|proposer / committee| EC - Seq -->|builds blocks| CB - Seq -->|enqueues actions| Pub - - Seq -->|broadcast block + checkpoint proposals| P2P - Seq -->|push to proposed chain| Arc - CB -->|pull txs| TP - Pub -->|submit Multicall3| L1 +``` + ┌──────────────────────────────────────────────────────────────┐ + │ Sequencer │ + │ (state machine, one slot at a time) │ + │ │ + │ work() ──► prepareCheckpointProposal() ──► proposal job │ + └─────┬────────────────┬──────────────────┬──────────────────┬─┘ + │ │ │ │ + ▼ ▼ ▼ ▼ + ┌──────────────────┐ ┌──────────┐ ┌──────────────────┐ ┌────────────────┐ + │ ValidatorClient │ │ Epoch │ │ CheckpointBuilder│ │ Sequencer │ + │ (owns keys, │ │ Cache │ │ (forked world │ │ Publisher │ + │ HA signer, │ │ (proposer│ │ state, per-block│ │ (Multicall3 │ + │ signs the │ │ + │ │ execution via │ │ L1 tx, with │ + │ proposals) │ │ comm.) │ │ PublicProcessor)│ │ pre-checks) │ + └──────────────────┘ └──────────┘ └──────────────────┘ └────────────────┘ + │ │ │ + │ block + checkpoint │ pull txs │ + │ proposals over p2p ▼ ▼ + │ ┌──────────┐ ┌────────────┐ + ├────────────────────────► │ Tx │ │ L1 Rollup │ + │ │ Provider │ │ Contract │ + │ push blocks to └──────────┘ └────────────┘ + ▼ proposed chain + ┌──────────────────┐ + │ Archiver │ + │ (l2 tips, │ + │ addBlock) │ + └──────────────────┘ ``` `SequencerClient.new(config, deps)` is the entrypoint and is constructed by the full node. It reads L1 constants (`l1GenesisTime`, `slotDuration`, `rollupManaLimit`) from the rollup contract, builds the publisher factory, validator client wiring, and timetable, then instantiates the `Sequencer`. See `src/client/sequencer-client.ts`. @@ -108,20 +115,18 @@ The sequencer is a `TypedEventEmitter`. The most useful events | `pipelined-checkpoint-discarded` | Pipelined parent failed to land; this slot's work is thrown away. | | `checkpoint-error` | Catch-all: an exception escaped `work()`. | -State enum (`src/sequencer/utils.ts`). The happy-path slot cycle is: +State enum (`src/sequencer/utils.ts`): ``` -IDLE → SYNCHRONIZING → PROPOSER_CHECK - → INITIALIZING_CHECKPOINT - → (WAITING_FOR_TXS ↔ CREATING_BLOCK ↔ WAITING_UNTIL_NEXT_BLOCK)* - → ASSEMBLING_CHECKPOINT - → COLLECTING_ATTESTATIONS - → PUBLISHING_CHECKPOINT - → IDLE +STOPPED → STOPPING → IDLE → SYNCHRONIZING → PROPOSER_CHECK + → INITIALIZING_CHECKPOINT + → (WAITING_FOR_TXS ↔ CREATING_BLOCK ↔ WAITING_UNTIL_NEXT_BLOCK)* + → ASSEMBLING_CHECKPOINT + → COLLECTING_ATTESTATIONS + → PUBLISHING_CHECKPOINT + → IDLE ``` -Lifecycle transitions sit outside the cycle: `start()` moves `STOPPED → IDLE`, and `stop()` moves the current state through `STOPPING → STOPPED`. - ### CheckpointProposalJob `CheckpointProposalJob` (`src/sequencer/checkpoint_proposal_job.ts`) is the per-slot unit of work. It owns the lifecycle from "we have decided to propose" through "the L1 transaction has been submitted". The contract is: @@ -214,6 +219,7 @@ Key entry points: | `GlobalVariableBuilder` | `src/global_variable_builder/` | Computes `CheckpointGlobalVariables` and predicts the per-slot fee asset price modifier. See its [README](src/global_variable_builder/README.md). | | `L1TxFailedStore` | `src/publisher/l1_tx_failed_store/` | Persists actions that returned a revert reason so they aren't retried in the same form on the next slot. | | `ChainStateOverrides` | `src/sequencer/chain_state_overrides.ts` | Builds the L1 `eth_call` overrides used during the pipelined parent + invalidation simulations. | +| `AutomineSequencer` | `src/sequencer/automine/` | Minimal queue-driven sequencer for single-sequencer e2e tests. Bypasses consensus, pipelining, and timetable enforcement. See [`src/sequencer/automine/README.md`](src/sequencer/automine/README.md). | ## Configuration @@ -227,11 +233,11 @@ The configuration object is `SequencerConfig` (`src/sequencer/config.ts` + `src/ | `minValidTxsPerBlock` | falls back to `minTxsPerBlock` | After execution, discard the block if fewer txs validated. | | `maxTxsPerBlock` / `SEQ_MAX_TX_PER_BLOCK` | unset | Hard per-block tx cap (capped at `maxTxsPerCheckpoint` at startup). | | `maxTxsPerCheckpoint` / `SEQ_MAX_TX_PER_CHECKPOINT` | unset | Total tx cap across the checkpoint. Enables redistribution when set. | -| `maxBlocksPerCheckpoint` / `MAX_BLOCKS_PER_CHECKPOINT` | 24 | Absolute ceiling on blocks per checkpoint, applied on top of the timetable's `maxNumberOfBlocks`. Also caps the `indexWithinCheckpoint` accepted on inbound block proposals. | +| `maxBlocksPerCheckpoint` / `MAX_BLOCKS_PER_CHECKPOINT` | 24 | Hard ceiling beyond what the timetable allows. Also caps the `indexWithinCheckpoint` accepted on inbound block proposals. | | `maxL2BlockGas` / `SEQ_MAX_L2_BLOCK_GAS` | unset | Per-block mana cap, capped at `rollupManaLimit`. | | `maxDABlockGas` / `SEQ_MAX_DA_BLOCK_GAS` | unset | Per-block DA gas cap, capped at `MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT`. | | `perBlockAllocationMultiplier` / `SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER` | 1.2 | Multiplier passed to the checkpoint builder so early blocks can use slightly more than their even share. | -| `redistributeCheckpointBudget` / `SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET` | true | Legacy flag, kept for back-compat. Has no effect on proposal building — redistribution is always on. | +| `redistributeCheckpointBudget` / `SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET` | true | Legacy flag. Redistribution is always on during proposal building. | ### Timing @@ -242,7 +248,7 @@ The configuration object is `SequencerConfig` (`src/sequencer/config.ts` + `src/ | `attestationPropagationTime` / `SEQ_ATTESTATION_PROPAGATION_TIME` | 2 s | One-way p2p estimate fed to the timetable. | | `l1PublishingTime` / `SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT` | full L1 slot | Time reserved for the L1 tx to land. | | `sequencerPollingIntervalMS` / `SEQ_POLLING_INTERVAL_MS` | 500 | Work-loop tick rate. | -| `enableProposerPipelining` / `SEQ_ENABLE_PROPOSER_PIPELINING` | false | When true, the sequencer builds for `slot + 1`. The flag lives in shared `PipelineConfig`; both the sequencer's timetable and `EpochCache`'s proposer-of-next-slot lookup read it. | +| `enableProposerPipelining` / `SEQ_ENABLE_PROPOSER_PIPELINING` | false | When true, the sequencer builds for `slot + 1`. The flag lives in shared `PipelineConfig` and is read by `EpochCache`, not by the sequencer directly. | ### Behavior @@ -254,8 +260,8 @@ The configuration object is `SequencerConfig` (`src/sequencer/config.ts` + `src/ | `coinbase` / `COINBASE` | proposer addr | Recipient of block rewards. | | `feeRecipient` / `FEE_RECIPIENT` | proposer addr | Recipient of tx fees. | | `governanceProposerPayload` / `GOVERNANCE_PROPOSER_PAYLOAD_ADDRESS` | unset | Payload signaled in the governance vote each slot. | -| `secondsBeforeInvalidatingBlockAsCommitteeMember` / `SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_COMMITTEE_MEMBER` | 144 | When *not* the proposer, committee members may invalidate a stuck checkpoint after this many seconds into the slot. | -| `secondsBeforeInvalidatingBlockAsNonCommitteeMember` / `SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_NON_COMMITTEE_MEMBER` | 432 | Same for any node — last resort. | +| `secondsBeforeInvalidatingBlockAsCommitteeMember` | 144 | When *not* the proposer, committee members may invalidate a stuck checkpoint after this many seconds into the slot. | +| `secondsBeforeInvalidatingBlockAsNonCommitteeMember` | 432 | Same for any node — last resort. | The full list (including test/fault-injection hooks like `pauseProposingForSlots` and `skipPublishingCheckpointsPercent`) lives in `src/config.ts`. diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index 34c14f2a509f..16f703bccc9c 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -53,6 +53,7 @@ export const DefaultSequencerConfig = { skipCollectingAttestations: false, skipInvalidateBlockAsProposer: false, broadcastInvalidBlockProposal: false, + broadcastInvalidCheckpointProposalOnly: false, injectFakeAttestation: false, injectHighSValueAttestation: false, injectUnrecoverableSignatureAttestation: false, @@ -191,6 +192,15 @@ export const sequencerConfigMappings: ConfigMappingsType = { description: 'Broadcast invalid block proposals with corrupted state (for testing only)', ...booleanConfigHelper(DefaultSequencerConfig.broadcastInvalidBlockProposal), }, + invalidBlockProposalIndexWithinCheckpoint: { + description: 'Broadcast an invalid block proposal only at this indexWithinCheckpoint (for testing only)', + ...optionalNumberConfigHelper(), + }, + broadcastInvalidCheckpointProposalOnly: { + description: + 'Broadcast invalid checkpoint proposals while keeping the underlying block proposals valid (for testing only). When unset, the checkpoint follows broadcastInvalidBlockProposal.', + ...booleanConfigHelper(DefaultSequencerConfig.broadcastInvalidCheckpointProposalOnly), + }, injectFakeAttestation: { description: 'Inject a fake attestation (for testing only)', ...booleanConfigHelper(DefaultSequencerConfig.injectFakeAttestation), diff --git a/yarn-project/sequencer-client/src/index.ts b/yarn-project/sequencer-client/src/index.ts index 2375b9013a90..7b156d567f79 100644 --- a/yarn-project/sequencer-client/src/index.ts +++ b/yarn-project/sequencer-client/src/index.ts @@ -1,7 +1,16 @@ export * from './client/index.js'; export * from './config.js'; export * from './publisher/index.js'; -export { Sequencer, SequencerState, type SequencerEvents } from './sequencer/index.js'; +export { + AutomineSequencer, + type AutomineSequencerConstants, + type AutomineSequencerDeps, + createAutomineSequencer, + type CreateAutomineSequencerArgs, + Sequencer, + SequencerState, + type SequencerEvents, +} from './sequencer/index.js'; // Used by the node to simulate public parts of transactions. Should these be moved to a shared library? // ISSUE(#9832) diff --git a/yarn-project/sequencer-client/src/publisher/sequencer-bundle-simulator.ts b/yarn-project/sequencer-client/src/publisher/sequencer-bundle-simulator.ts new file mode 100644 index 000000000000..5ae7c1647117 --- /dev/null +++ b/yarn-project/sequencer-client/src/publisher/sequencer-bundle-simulator.ts @@ -0,0 +1,253 @@ +import type { EpochCache } from '@aztec/epoch-cache'; +import { Multicall3, type RollupContract, buildSimulationOverridesStateOverride } from '@aztec/ethereum/contracts'; +import { type L1TxUtils, MAX_L1_TX_LIMIT } from '@aztec/ethereum/l1-tx-utils'; +import { formatViemError } from '@aztec/ethereum/utils'; +import type { SlotNumber } from '@aztec/foundation/branded-types'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; + +import type { Hex, StateOverride } from 'viem'; + +import type { RequestWithExpiry } from './sequencer-publisher.js'; + +/** A request that was dropped by bundle simulation, with the decoded revert reason. */ +export type DroppedRequest = { + request: RequestWithExpiry; + revertReason: string | undefined; + returnData: Hex | undefined; +}; + +/** + * Result of {@link SequencerBundleSimulator.simulate}. + * + * - `success`: simulation succeeded. `requests` is the filtered survivor list, `gasLimit` is + * the bumped gas limit derived from `gasUsed` (plus blob evaluation gas). `droppedRequests` + * lists the entries that were observed to revert in simulation. + * - `fallback`: the node does not support eth_simulateV1 (or the simulate call threw). The + * caller should send `requests` as-is with a safe gas limit (e.g. {@link MAX_L1_TX_LIMIT}). + * `droppedRequests` carries any entries that the first pass already proved reverted, so the + * caller does not re-include them when the second pass falls back. + * - `aborted`: the bundle cannot be sent. `droppedRequests` contains only entries that were + * actually observed to revert (so they can be reported as simulation failures); it is empty + * when the abort was caused by an empty input bundle. + */ +export type BundleSimulateResult = + | { kind: 'success'; requests: RequestWithExpiry[]; gasLimit: bigint; droppedRequests: DroppedRequest[] } + | { kind: 'fallback'; requests: RequestWithExpiry[]; droppedRequests: DroppedRequest[] } + | { kind: 'aborted'; reason: AbortReason; droppedRequests: DroppedRequest[] }; + +export type AbortReason = 'empty-bundle' | 'all-reverted' | 'second-pass-reverts'; + +type SimulatePassResult = + | { kind: 'decoded'; survivors: RequestWithExpiry[]; droppedRequests: DroppedRequest[]; gasUsed: bigint } + | { kind: 'fallback' }; + +/** + * Bundle-level simulator for the aggregate3 payload that `SequencerPublisher` is about to send. + * + * Runs `eth_simulateV1` against `Multicall3.aggregate3`, drops entries that revert, and returns + * a gasLimit for the survivors. When `eth_simulateV1` is unavailable, signals fallback to the + * caller so it can send the bundle as-is with a conservative gas limit. + */ +export class SequencerBundleSimulator { + private readonly log: Logger; + + constructor( + private readonly deps: { + getL1TxUtils: () => L1TxUtils; + rollupContract: RollupContract; + epochCache: EpochCache; + log?: Logger; + }, + ) { + this.log = deps.log ?? createLogger('sequencer:publisher:bundle-simulator'); + } + + /** + * Simulates the given bundle at the target slot's start timestamp and filters out entries + * that revert. + * + * - If all entries pass on the first pass, returns `success` with the gasLimit. + * - If some entries revert, re-simulates the survivors. If the second pass is clean, returns + * `success` with the survivors and dropped entries. If the second pass surfaces any revert, + * returns `aborted` — we refuse to send a bundle whose composition still has internal + * reverts after one round of filtering. + * - If eth_simulateV1 is unavailable, returns `fallback`. The caller is expected to send the + * bundle as-is with a safe gas limit. + * + * The simulation `block.timestamp` is always the target L2 slot's start timestamp, since + * propose's `validateHeader` and EIP-712 signature checks both derive a slot from + * `block.timestamp` and compare against the slot the validator signed for. + * + * Known limitation: on networks where L1 is mining behind cadence (missed L1 slots, anvil with + * overridden timestamps), the actual `block.timestamp` at send time can land in the prior L2 + * slot. In that case `propose` would revert silently inside the multicall. The simulator does + * not detect this case because it simulates AT the target timestamp — the prior implementation + * used `min(predictedNextL1Ts, targetTimestamp)` to surface this failure mode at simulate time. + */ + public async simulate(validRequests: RequestWithExpiry[], targetSlot: SlotNumber): Promise { + if (validRequests.length === 0) { + return { kind: 'aborted', reason: 'empty-bundle', droppedRequests: [] }; + } + // Pin the publisher we'll use across the whole simulate call so that the publisher's rotation + // can't change l1TxUtils mid-flight. + const l1TxUtils = this.deps.getL1TxUtils(); + + const proposeRequest = validRequests.find(r => r.action === 'propose'); + const simulateTimestamp = getTimestampForSlot(targetSlot, this.deps.epochCache.getL1Constants()); + const firstPassOverrides = await this.buildStateOverrides(!!proposeRequest); + + const firstPass = await this.simulateAndDecode(l1TxUtils, validRequests, simulateTimestamp, firstPassOverrides); + + if (firstPass.kind === 'fallback') { + this.log.warn('Bundle simulate fallback (eth_simulateV1 unavailable); caller will send bundle as-is', { + actions: validRequests.map(r => r.action), + }); + return { kind: 'fallback', requests: validRequests, droppedRequests: [] }; + } + + if (firstPass.survivors.length === 0) { + this.log.warn('All bundle entries dropped in simulation; aborting send', { + actions: validRequests.map(r => r.action), + }); + return { kind: 'aborted', reason: 'all-reverted', droppedRequests: firstPass.droppedRequests }; + } + + if (firstPass.droppedRequests.length === 0) { + return this.buildSuccessResult(l1TxUtils, firstPass.survivors, [], firstPass.gasUsed, proposeRequest); + } + + this.log.warn('Some bundle entries reverted; re-simulating reduced bundle', { + droppedActions: firstPass.droppedRequests.map(d => d.request.action), + remainingActions: firstPass.survivors.map(r => r.action), + }); + + // Rebuild overrides for the reduced bundle: if propose was dropped, we no longer need the blob-check override + const proposeSurvived = proposeRequest !== undefined && firstPass.survivors.includes(proposeRequest); + const secondPassOverrides = proposeSurvived ? firstPassOverrides : await this.buildStateOverrides(false); + const secondPass = await this.simulateAndDecode( + l1TxUtils, + firstPass.survivors, + simulateTimestamp, + secondPassOverrides, + ); + + if (secondPass.kind === 'fallback') { + this.log.warn( + 'Bundle simulate errored on second pass (eth_simulateV1 unavailable); sending first-pass survivors as-is', + { + actions: firstPass.survivors.map(r => r.action), + droppedActions: firstPass.droppedRequests.map(d => d.request.action), + }, + ); + return { kind: 'fallback', requests: firstPass.survivors, droppedRequests: firstPass.droppedRequests }; + } + + // We refuse to chase reverts through repeated trimming: anything other than a clean second pass aborts the whole send + if (secondPass.droppedRequests.length > 0) { + this.log.error('Re-simulate surfaced reverts; aborting send', { + secondPassDroppedActions: secondPass.droppedRequests.map(d => d.request.action), + }); + return { + kind: 'aborted', + reason: 'second-pass-reverts', + droppedRequests: [...firstPass.droppedRequests, ...secondPass.droppedRequests], + }; + } + + return this.buildSuccessResult( + l1TxUtils, + secondPass.survivors, + firstPass.droppedRequests, + secondPass.gasUsed, + proposeRequest, + ); + } + + private buildSuccessResult( + l1TxUtils: L1TxUtils, + survivors: RequestWithExpiry[], + droppedRequests: DroppedRequest[], + bundleGasUsed: bigint, + proposeRequest: RequestWithExpiry | undefined, + ): BundleSimulateResult { + const proposeSurvived = proposeRequest !== undefined && survivors.includes(proposeRequest); + const blobEvaluationGas = proposeSurvived ? (proposeRequest?.blobEvaluationGas ?? 0n) : 0n; + const gasLimit = this.computeGasLimit(l1TxUtils, bundleGasUsed, blobEvaluationGas); + this.log.debug('Bundle simulate complete', { + survivingRequests: survivors.length, + bundleGasUsed, + gasLimit, + actions: survivors.map(r => r.action), + }); + return { kind: 'success', requests: survivors, gasLimit, droppedRequests }; + } + + /** + * `gasLimit = bumpGasLimit(ceil(gasUsed * 64 / 63))`, plus blob evaluation gas if a propose + * survived, capped at the L1 block gas limit. + */ + private computeGasLimit(l1TxUtils: L1TxUtils, bundleGasUsed: bigint, blobEvaluationGas: bigint): bigint { + const gasUsedWithEip150 = (bundleGasUsed * 64n + 62n) / 63n; + const gasLimit = l1TxUtils.bumpGasLimit(gasUsedWithEip150) + blobEvaluationGas; + return gasLimit > MAX_L1_TX_LIMIT ? MAX_L1_TX_LIMIT : gasLimit; + } + + /** + * eth_simulateV1 cannot carry blob sidecar data, so disable the rollup's on-chain blob check + * when a propose is in the bundle. + */ + private buildStateOverrides(hasProposeAction: boolean): Promise { + return buildSimulationOverridesStateOverride( + this.deps.rollupContract, + hasProposeAction ? { disableBlobCheck: true } : undefined, + ); + } + + private async simulateAndDecode( + l1TxUtils: L1TxUtils, + requests: RequestWithExpiry[], + simulateTimestamp: bigint, + stateOverrides: StateOverride, + ): Promise { + let simResult: Awaited>; + try { + simResult = await Multicall3.simulateAggregate3( + requests.map(r => ({ to: r.request.to! as Hex, data: r.request.data! as Hex, abi: r.request.abi })), + l1TxUtils, + { + blockOverrides: { time: simulateTimestamp, gasLimit: MAX_L1_TX_LIMIT * 2n }, + stateOverrides, + gas: MAX_L1_TX_LIMIT, + fallbackGasEstimate: MAX_L1_TX_LIMIT, + }, + ); + } catch (err) { + this.log.warn('Bundle simulate threw; treating as fallback', { + err: formatViemError(err), + actions: requests.map(r => r.action), + }); + return { kind: 'fallback' }; + } + + if (simResult.kind === 'fallback') { + return { kind: 'fallback' }; + } + + const survivors: RequestWithExpiry[] = []; + const droppedRequests: DroppedRequest[] = []; + for (let i = 0; i < requests.length; i++) { + const entry = simResult.entries[i]; + if (entry.success) { + survivors.push(requests[i]); + continue; + } + droppedRequests.push({ + request: requests[i], + revertReason: entry.revertReason, + returnData: entry.returnData, + }); + } + return { kind: 'decoded', survivors, droppedRequests, gasUsed: simResult.gasUsed }; + } +} diff --git a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts index ce8479609636..2a9bac671e44 100644 --- a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts +++ b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts @@ -5,19 +5,17 @@ import type { L1ContractsConfig } from '@aztec/ethereum/config'; import { type GovernanceProposerContract, Multicall3, + MulticallForwarderRevertedError, type RollupContract, - type SimulationOverridesPlan, type SlashingProposerContract, } from '@aztec/ethereum/contracts'; import { - type GasPrice, type L1TxUtils, type L1TxUtilsConfig, + MAX_L1_TX_LIMIT, defaultL1TxUtilsConfig, } from '@aztec/ethereum/l1-tx-utils'; -import { FormattedViemError } from '@aztec/ethereum/utils'; -import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; -import { Fr } from '@aztec/foundation/curves/bn254'; +import { BlockNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { TimeoutError } from '@aztec/foundation/error'; import { EthAddress } from '@aztec/foundation/eth-address'; import { sleep } from '@aztec/foundation/sleep'; @@ -33,9 +31,12 @@ import { type MockProxy, mock } from 'jest-mock-extended'; import { type GetCodeReturnType, type GetTransactionReceiptReturnType, + type Hex, type PrivateKeyAccount, type TransactionReceipt, encodeFunctionData, + encodeFunctionResult, + multicall3Abi, toHex, } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; @@ -168,10 +169,13 @@ describe('SequencerPublisher', () => { (l1TxUtils as any).estimateGas.mockResolvedValue(GAS_GUESS); (l1TxUtils as any).simulate.mockResolvedValue({ gasUsed: 1_000_000n, result: '0x' }); (l1TxUtils as any).bumpGasLimit.mockImplementation((val: bigint) => val + (val * 20n) / 100n); + l1TxUtils.getSenderBalance.mockResolvedValue(10_000_000_000_000_000_000n); // 10 ETH, sufficient for all tests (l1TxUtils as any).client = { account: { address: '0x1234567890123456789012345678901234567890', }, + getGasPrice: () => Promise.resolve(1n), + getBlock: () => Promise.resolve({ timestamp: 0n }), }; const currentL2Slot = publisher.getCurrentL2Slot(); @@ -230,7 +234,8 @@ describe('SequencerPublisher', () => { forwardSpy.mockResolvedValue({ receipt: proposeTxReceipt, - errorMsg: undefined, + stats: undefined, + multicallData: '0x', }); await publisher.sendRequests(); @@ -274,8 +279,7 @@ describe('SequencerPublisher', () => { expect.objectContaining({ blobs: expect.any(Array), }), - mockRollupAddress, - expect.anything(), // the logger + { gasLimitRequired: true }, ); expect(forwardSpy.mock.calls[0][2]?.gasLimit).toBeGreaterThan(2_000_000n); @@ -291,7 +295,8 @@ describe('SequencerPublisher', () => { it('errors if forwarder tx fails', async () => { forwardSpy.mockRejectedValueOnce(new Error()).mockResolvedValueOnce({ receipt: proposeTxReceipt, - errorMsg: undefined, + stats: undefined, + multicallData: '0x', }); await publisher.enqueueProposeCheckpoint( @@ -312,7 +317,14 @@ describe('SequencerPublisher', () => { secondL1TxUtils = mock(); secondL1TxUtils.getBlockNumber.mockResolvedValue(1n); secondL1TxUtils.getSenderAddress.mockReturnValue(EthAddress.random()); - secondL1TxUtils.getSenderBalance.mockResolvedValue(1000n); + secondL1TxUtils.getSenderBalance.mockResolvedValue(10_000_000_000_000_000_000n); // 10 ETH + (secondL1TxUtils as any).client = { + account: { address: EthAddress.random().toString() }, + getGasPrice: () => Promise.resolve(1n), + }; + (secondL1TxUtils as any).bumpGasLimit = (val: bigint) => val + (val * 20n) / 100n; + (secondL1TxUtils as any).simulate = () => Promise.resolve({ gasUsed: 1_000_000n, result: '0x' }); + (secondL1TxUtils as any).getBlockNumber = () => Promise.resolve(1n); getNextPublisher = jest.fn(); @@ -352,7 +364,7 @@ describe('SequencerPublisher', () => { it('rotates to next publisher when forward throws and retries successfully', async () => { forwardSpy .mockRejectedValueOnce(new Error('RPC error')) - .mockResolvedValueOnce({ receipt: proposeTxReceipt, errorMsg: undefined }); + .mockResolvedValueOnce({ receipt: proposeTxReceipt, stats: undefined, multicallData: '0x' }); getNextPublisher.mockResolvedValueOnce(secondL1TxUtils); await rotatingPublisher.enqueueProposeCheckpoint( @@ -371,7 +383,6 @@ describe('SequencerPublisher', () => { expect.anything(), expect.anything(), expect.anything(), - expect.anything(), ); expect(forwardSpy).toHaveBeenNthCalledWith( 2, @@ -380,7 +391,6 @@ describe('SequencerPublisher', () => { expect.anything(), expect.anything(), expect.anything(), - expect.anything(), ); expect(getNextPublisher).toHaveBeenCalledWith([l1TxUtils.getSenderAddress()]); // Result is defined (rotation succeeded and tx was sent) @@ -424,152 +434,232 @@ describe('SequencerPublisher', () => { expect(result).toBeUndefined(); }); - it('does not rotate when forward returns a revert (on-chain failure)', async () => { - forwardSpy.mockResolvedValue({ receipt: { ...proposeTxReceipt, status: 'reverted' }, errorMsg: 'revert reason' }); - + it('does not enter the rotation loop when txTimeoutAt is already in the past', async () => { + const pastTimeout = new Date(Date.now() - 1000); await rotatingPublisher.enqueueProposeCheckpoint( new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + { txTimeoutAt: pastTimeout }, ); const result = await rotatingPublisher.sendRequests(); - expect(forwardSpy).toHaveBeenCalledTimes(1); + expect(result).toBeUndefined(); + expect(forwardSpy).not.toHaveBeenCalled(); expect(getNextPublisher).not.toHaveBeenCalled(); - // Result contains the reverted receipt (no rotation) - expect(result?.result).toMatchObject({ receipt: { status: 'reverted' } }); }); - }); - it('does not send propose tx if rollup validation fails', async () => { - l1TxUtils.simulate.mockRejectedValueOnce(new Error('Test error')); + it('stops rotating once txTimeoutAt elapses mid-rotation', async () => { + // First forward throws; getNextPublisher rotates to a new publisher; but by then the + // deadline has elapsed and the rotation loop should bail before the second forward call. + // Use jest fake timers to control `Date.now()` deterministically — the rotation loop + // checks the deadline via `new Date() > txConfig.txTimeoutAt`, so faking the system clock + // is the cleanest way to model "deadline elapses mid-rotation" without racing wall-clock + // setTimeout against CI host speed. + jest.useFakeTimers({ doNotFake: ['nextTick', 'queueMicrotask', 'setImmediate'] }); + try { + jest.setSystemTime(new Date('2026-01-01T00:00:00Z')); + const futureTimeout = new Date(Date.now() + 1000); + forwardSpy.mockImplementationOnce(() => { + // Simulate enough wall-clock advance during the forward to push past the deadline, + // so the loop's next deadline check bails before the second attempt. + jest.setSystemTime(Date.now() + 5000); + return Promise.reject(new Error('RPC error on first')); + }); + getNextPublisher.mockResolvedValueOnce(secondL1TxUtils); + + await rotatingPublisher.enqueueProposeCheckpoint( + new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), + CommitteeAttestationsAndSigners.empty(testSignatureContext), + Signature.empty(), + { txTimeoutAt: futureTimeout }, + ); + const result = await rotatingPublisher.sendRequests(); + + expect(result).toBeUndefined(); + // forward was attempted exactly once (the first publisher); rotation was aborted before + // the second attempt because the deadline had passed. + expect(forwardSpy).toHaveBeenCalledTimes(1); + } finally { + jest.useRealTimers(); + } + }); + + it('does not rotate when forward throws MulticallForwarderRevertedError (on-chain failure)', async () => { + forwardSpy.mockRejectedValueOnce( + new MulticallForwarderRevertedError({ ...proposeTxReceipt, status: 'reverted' }), + ); - await expect( - publisher.enqueueProposeCheckpoint( + await rotatingPublisher.enqueueProposeCheckpoint( new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), - ), - ).rejects.toThrow(); - - expect(l1TxUtils.simulate).toHaveBeenCalledTimes(1); + ); + const result = await rotatingPublisher.sendRequests(); - const result = await publisher.sendRequests(); - expect(result).toEqual(undefined); - expect(forwardSpy).not.toHaveBeenCalled(); + expect(forwardSpy).toHaveBeenCalledTimes(1); + expect(getNextPublisher).not.toHaveBeenCalled(); + expect(result).toBeUndefined(); + }); }); - it('preCheck closure uses preCheckSimulationOverridesPlan, not the enqueue-time plan', async () => { - (publisher.epochCache.isProposerPipeliningEnabled as jest.Mock).mockReturnValue(true); - - const validateSpy = jest.spyOn(publisher, 'validateCheckpointForSubmission').mockResolvedValue(undefined); - - const enqueuePlan: SimulationOverridesPlan = { - chainTipsOverride: { pending: CheckpointNumber(7) }, - pendingCheckpointState: { archive: Fr.random() }, - }; - const preCheckPlan: SimulationOverridesPlan = { - chainTipsOverride: { pending: CheckpointNumber(8) }, - }; - + it('does not send propose tx if rollup validation fails', async () => { await publisher.enqueueProposeCheckpoint( new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), - { simulationOverridesPlan: enqueuePlan, preCheckSimulationOverridesPlan: preCheckPlan }, ); - // Enqueue-time validation called with the enqueue plan (plus withoutBlobCheck applied). - expect(validateSpy).toHaveBeenCalledTimes(1); - expect(validateSpy.mock.calls[0][3]).toMatchObject({ - chainTipsOverride: { pending: CheckpointNumber(7) }, - disableBlobCheck: true, + // Simulate the bundle-level validate returning a failed entry for the propose call. + // When all entries fail, bundleSimulate returns undefined and sendRequests returns undefined. + const failedResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [{ success: false, returnData: '0x' }], }); + (l1TxUtils as any).simulate.mockResolvedValueOnce({ gasUsed: 0n, result: failedResult }); - // The pending preCheck request should now run the preCheck closure with the preCheck plan. - const requests: { preCheck?: () => Promise }[] = (publisher as any).requests; - expect(requests).toHaveLength(1); - const preCheck = requests[0].preCheck; - expect(preCheck).toBeDefined(); - - validateSpy.mockClear(); - await preCheck!(); - - expect(validateSpy).toHaveBeenCalledTimes(1); - expect(validateSpy.mock.calls[0][3]).toMatchObject({ - chainTipsOverride: { pending: CheckpointNumber(8) }, - disableBlobCheck: true, - }); - // And not the enqueue plan's archive override. - expect(validateSpy.mock.calls[0][3]?.pendingCheckpointState).toBeUndefined(); + const result = await publisher.sendRequests(); + expect(result).toEqual(undefined); + expect(forwardSpy).not.toHaveBeenCalled(); + expect(l1TxUtils.simulate).toHaveBeenCalledTimes(1); }); - it('preCheck does not fall back to the enqueue plan when preCheckSimulationOverridesPlan is omitted', async () => { - (publisher.epochCache.isProposerPipeliningEnabled as jest.Mock).mockReturnValue(true); + describe('bundleSimulate second-pass re-decode', () => { + const addTwoRequests = () => { + const currentL2Slot = publisher.getCurrentL2Slot(); + publisher.addRequest({ + action: 'invalidate-by-invalid-attestation', + request: { to: mockRollupAddress, data: '0xdeadbeef' }, + lastValidL2Slot: SlotNumber(Number(currentL2Slot) + 2), + checkSuccess: () => true, + }); + publisher.addRequest({ + action: 'propose', + request: { + to: mockRollupAddress, + data: encodeFunctionData({ + abi: EmpireBaseAbi, + functionName: 'signal', + args: [EthAddress.random().toString()], + }), + }, + lastValidL2Slot: SlotNumber(Number(currentL2Slot) + 2), + checkSuccess: () => true, + }); + }; - const validateSpy = jest.spyOn(publisher, 'validateCheckpointForSubmission').mockResolvedValue(undefined); + it('drops an entry that still reverts in the second-pass re-simulate', async () => { + addTwoRequests(); + + // First simulate: invalidate succeeds, propose fails. + const firstResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [ + { success: true, returnData: '0x' }, + { success: false, returnData: '0x' }, + ], + }); + // Second simulate (reduced bundle with only invalidate): that entry also fails. + const secondResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [{ success: false, returnData: '0x' }], + }); - const enqueuePlan: SimulationOverridesPlan = { - chainTipsOverride: { pending: CheckpointNumber(7) }, - pendingCheckpointState: { archive: Fr.random() }, - }; + (l1TxUtils as any).simulate + .mockResolvedValueOnce({ gasUsed: 500_000n, result: firstResult }) + .mockResolvedValueOnce({ gasUsed: 0n, result: secondResult }); - await publisher.enqueueProposeCheckpoint( - new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), - CommitteeAttestationsAndSigners.empty(testSignatureContext), - Signature.empty(), - { simulationOverridesPlan: enqueuePlan }, - ); + const result = await publisher.sendRequests(); - expect(validateSpy).toHaveBeenCalledTimes(1); - expect(validateSpy.mock.calls[0][3]).toMatchObject({ - chainTipsOverride: { pending: CheckpointNumber(7) }, - disableBlobCheck: true, + // Both passes dropped everything — should abort. + expect(result).toBeUndefined(); + expect(forwardSpy).not.toHaveBeenCalled(); + expect(l1TxUtils.simulate).toHaveBeenCalledTimes(2); }); - const requests: { preCheck?: () => Promise }[] = (publisher as any).requests; - expect(requests).toHaveLength(1); - const preCheck = requests[0].preCheck; - expect(preCheck).toBeDefined(); + it('sends only survivors after second-pass re-simulate filters additional failures', async () => { + addTwoRequests(); + + // First simulate: both succeed initially. + // (Simulate a case where second-pass further trims — to test the path where + // first pass survivors differ from second pass survivors.) + const firstResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [ + { success: true, returnData: '0x' }, + { success: false, returnData: '0x' }, + ], + }); + // Second simulate (reduced bundle with only invalidate): that one succeeds. + const secondResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [{ success: true, returnData: '0x' }], + }); - validateSpy.mockClear(); - await preCheck!(); + (l1TxUtils as any).simulate + .mockResolvedValueOnce({ gasUsed: 500_000n, result: firstResult }) + .mockResolvedValueOnce({ gasUsed: 300_000n, result: secondResult }); - expect(validateSpy).toHaveBeenCalledTimes(1); - const preCheckArg = validateSpy.mock.calls[0][3]; - expect(preCheckArg?.disableBlobCheck).toBe(true); - expect(preCheckArg?.chainTipsOverride).toBeUndefined(); - expect(preCheckArg?.pendingCheckpointState).toBeUndefined(); - }); + forwardSpy.mockResolvedValue({ receipt: proposeTxReceipt, stats: undefined, multicallData: '0x' }); - it('returns errorMsg if forwarder tx reverts', async () => { - forwardSpy.mockResolvedValue({ - receipt: { ...proposeTxReceipt, status: 'reverted' }, - errorMsg: 'Test error', + const result = await publisher.sendRequests(); + + expect(result).toBeDefined(); + // Only the invalidate survivor was sent. + expect(result?.sentActions).toEqual(['invalidate-by-invalid-attestation']); + expect(forwardSpy).toHaveBeenCalledTimes(1); + expect(l1TxUtils.simulate).toHaveBeenCalledTimes(2); }); - await publisher.enqueueProposeCheckpoint( - new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), - CommitteeAttestationsAndSigners.empty(testSignatureContext), - Signature.empty(), - ); - const result = await publisher.sendRequests(); + it('preserves first-pass survivors when second-pass simulate returns fallback', async () => { + addTwoRequests(); + + // First simulate: propose fails, invalidate survives. + const firstResult = encodeFunctionResult({ + abi: multicall3Abi, + functionName: 'aggregate3', + result: [ + { success: true, returnData: '0x' }, + { success: false, returnData: '0x' }, + ], + }); + // Second simulate: fallback (eth_simulateV1 not supported on the reduced bundle). + (l1TxUtils as any).simulate + .mockResolvedValueOnce({ gasUsed: 500_000n, result: firstResult }) + .mockResolvedValueOnce({ gasUsed: 1_000_000n, result: '0x' }); + + forwardSpy.mockResolvedValue({ receipt: proposeTxReceipt, stats: undefined, multicallData: '0x' }); + + const result = await publisher.sendRequests(); - expect(result).not.toBeInstanceOf(FormattedViemError); - if (result instanceof FormattedViemError) { - fail('Not Expected result to be a FormattedViemError'); - } else { - expect((result as any).result.errorMsg).toEqual('Test error'); - } + // Second-pass fallback must NOT re-include the propose entry that first-pass dropped. + expect(result).toBeDefined(); + expect(result?.sentActions).toEqual(['invalidate-by-invalid-attestation']); + expect(result?.failedActions).toEqual(['propose']); + expect(forwardSpy).toHaveBeenCalledTimes(1); + expect(forwardSpy.mock.calls[0][2]?.gasLimit).toEqual(MAX_L1_TX_LIMIT); + // The forwarded bundle should only contain the survivor. + expect(forwardSpy.mock.calls[0][0]).toHaveLength(1); + expect(l1TxUtils.simulate).toHaveBeenCalledTimes(2); + }); }); it('does not send requests if interrupted', async () => { forwardSpy.mockImplementationOnce( () => - sleep(10, { receipt: proposeTxReceipt, gasPrice: { maxFeePerGas: 1n, maxPriorityFeePerGas: 1n } }) as Promise<{ + sleep(10, { + receipt: proposeTxReceipt, + stats: undefined, + multicallData: '0x', + }) as Promise<{ receipt: TransactionReceipt; - gasPrice: GasPrice; - errorMsg: undefined; + stats: undefined; + multicallData: Hex; }>, ); await publisher.enqueueProposeCheckpoint( @@ -586,64 +676,6 @@ describe('SequencerPublisher', () => { expect((publisher as any).requests.length).toEqual(0); }); - it('discards only the request whose preCheck fails before sending', async () => { - const currentL2Slot = publisher.getCurrentL2Slot(); - const keptRequest = { - to: mockGovernanceProposerAddress, - data: encodeFunctionData({ - abi: EmpireBaseAbi, - functionName: 'signal', - args: [EthAddress.random().toString()], - }), - }; - const failedRequest = { - to: mockRollupAddress, - data: encodeFunctionData({ - abi: EmpireBaseAbi, - functionName: 'signal', - args: [EthAddress.random().toString()], - }), - }; - - const keptPreCheck = jest.fn(() => Promise.resolve()); - const failedPreCheck = jest.fn(() => Promise.reject(new Error('preCheck failed'))); - - publisher.addRequest({ - action: 'vote-offenses', - request: keptRequest, - lastValidL2Slot: currentL2Slot, - preCheck: keptPreCheck, - checkSuccess: () => true, - }); - publisher.addRequest({ - action: 'governance-signal', - request: failedRequest, - lastValidL2Slot: currentL2Slot, - preCheck: failedPreCheck, - checkSuccess: () => true, - }); - - forwardSpy.mockResolvedValue({ - receipt: proposeTxReceipt, - errorMsg: undefined, - }); - - const result = await publisher.sendRequestsAt(new Date((publisher as any).dateProvider.now())); - - expect(keptPreCheck).toHaveBeenCalledTimes(1); - expect(failedPreCheck).toHaveBeenCalledTimes(1); - expect(result?.sentActions).toEqual(['vote-offenses']); - expect(forwardSpy).toHaveBeenCalledTimes(1); - expect(forwardSpy).toHaveBeenCalledWith( - [keptRequest], - l1TxUtils, - { gasLimit: undefined, txTimeoutAt: undefined }, - undefined, - mockRollupAddress, - expect.anything(), - ); - }); - it('does not send requests if no valid requests are found', async () => { publisher.addRequest({ action: 'propose', @@ -704,15 +736,18 @@ describe('SequencerPublisher', () => { forwardSpy.mockResolvedValue({ receipt: proposeTxReceipt, - errorMsg: undefined, + stats: undefined, + multicallData: '0x', }); await publisher.sendRequests(); expect(forwardSpy).toHaveBeenCalledTimes(1); - // The gas config should only include the valid request's gas (100_000), not the expired one (500_000) + // The expired request (500_000) is filtered before bundle simulate. + // Bundle simulate returns '0x' (fallback), so gasLimit comes from MAX_L1_TX_LIMIT, + // not from per-request gasConfig — the expired request's gasLimit has no effect. const txConfig = forwardSpy.mock.calls[0][2]; - expect(txConfig?.gasLimit).toEqual(100_000n); + expect(txConfig?.gasLimit).toEqual(MAX_L1_TX_LIMIT); }); it('does not signal for payload when quorum is reached', async () => { @@ -737,8 +772,8 @@ describe('SequencerPublisher', () => { it('does not signal for payload with empty code', async () => { const { govPayload } = mockGovernancePayload(); - l1TxUtils.getCode.mockReturnValue(Promise.resolve(undefined)); - ``; + // isPayloadEmpty now lives on GovernanceProposerContract, not L1TxUtils. + governanceProposerContract.isPayloadEmpty.mockResolvedValue(true); expect( await publisher.enqueueGovernanceCastSignal( diff --git a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts index 47819bcb1221..cf4146867c7e 100644 --- a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts @@ -7,12 +7,10 @@ import { type GovernanceProposerContract, MULTI_CALL_3_ADDRESS, Multicall3, - RollupContract, - SimulationOverridesBuilder, + MulticallForwarderRevertedError, + type RollupContract, type SimulationOverridesPlan, type SlashingProposerContract, - type ViemCommitteeAttestations, - type ViemHeader, buildSimulationOverridesStateOverride, } from '@aztec/ethereum/contracts'; import { type L1FeeAnalysisResult, L1FeeAnalyzer } from '@aztec/ethereum/l1-fee-analysis'; @@ -25,46 +23,67 @@ import { type TransactionStats, WEI_CONST, } from '@aztec/ethereum/l1-tx-utils'; -import { FormattedViemError, formatViemError, mergeAbis, tryExtractEvent } from '@aztec/ethereum/utils'; -import { sumBigint } from '@aztec/foundation/bigint'; +import { + FormattedViemError, + formatViemError, + mergeAbis, + tryDecodeRevertReason, + tryExtractEvent, +} from '@aztec/ethereum/utils'; import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { trimmedBytesLength } from '@aztec/foundation/buffer'; import { pick } from '@aztec/foundation/collection'; import type { Fr } from '@aztec/foundation/curves/bn254'; import { TimeoutError } from '@aztec/foundation/error'; import { EthAddress } from '@aztec/foundation/eth-address'; -import { Signature, type ViemSignature } from '@aztec/foundation/eth-signature'; +import { Signature } from '@aztec/foundation/eth-signature'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { InterruptibleSleep } from '@aztec/foundation/sleep'; import { bufferToHex } from '@aztec/foundation/string'; import { type DateProvider, Timer } from '@aztec/foundation/timer'; -import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts'; +import { EmpireBaseAbi, ErrorsAbi, RollupAbi, SlashingProposerAbi } from '@aztec/l1-artifacts'; import { type ProposerSlashAction, encodeSlashConsensusVotes } from '@aztec/slasher'; import { CommitteeAttestationsAndSigners, type ValidateCheckpointResult } from '@aztec/stdlib/block'; import type { Checkpoint } from '@aztec/stdlib/checkpoint'; -import { getLastL1SlotTimestampForL2Slot, getNextL1SlotTimestamp } from '@aztec/stdlib/epoch-helpers'; +import { getNextL1SlotTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import type { CheckpointHeader } from '@aztec/stdlib/rollup'; import type { L1PublishCheckpointStats } from '@aztec/stdlib/stats'; import { type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client'; import { + type Abi, type Hex, type TransactionReceipt, type TypedDataDefinition, encodeFunctionData, keccak256, - multicall3Abi, toHex, } from 'viem'; import type { SequencerPublisherConfig } from './config.js'; import { type FailedL1Tx, type L1TxFailedStore, createL1TxFailedStore } from './l1_tx_failed_store/index.js'; +import { type DroppedRequest, SequencerBundleSimulator } from './sequencer-bundle-simulator.js'; import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js'; +/** + * Returns true if the receipt indicates a successful send AND the expected event was emitted + * by the target contract. Both pieces are required: an aggregate3 entry that reverted will + * have receipt.status === 'success' but no event log. + */ +function extractEventSuccess( + receipt: TransactionReceipt | undefined, + opts: { address: string; abi: Abi; eventName: string }, +): boolean { + if (!receipt || receipt.status !== 'success') { + return false; + } + return !!tryExtractEvent(receipt.logs, opts.address.toString() as Hex, opts.abi, opts.eventName); +} + /** Result of a sendRequests call, returned by both sendRequests() and sendRequestsAt(). */ export type SendRequestsResult = { - /** The L1 transaction receipt or error from the bundled multicall. */ - result: { receipt: TransactionReceipt; errorMsg?: string } | FormattedViemError; + /** The L1 transaction receipt from the bundled multicall. */ + result: { receipt: TransactionReceipt }; /** Actions that expired (past their deadline) before the request was sent. */ expiredActions: Action[]; /** Actions that were included in the sent L1 transaction. */ @@ -119,24 +138,16 @@ export type InvalidateCheckpointRequest = { type EnqueueProposeCheckpointOpts = { txTimeoutAt?: Date; - simulationOverridesPlan?: SimulationOverridesPlan; - /** - * Overrides to apply to the preCheck simulation right before L1 submission. - * Intentionally separate from `simulationOverridesPlan`: enqueue-time validation - * may need pipelined-parent / pretend-proof-landed overrides, but preCheck must - * reflect real L1 state to catch state drift between build and submission. - */ - preCheckSimulationOverridesPlan?: SimulationOverridesPlan; }; -interface RequestWithExpiry { +export interface RequestWithExpiry { action: Action; request: L1TxRequest; lastValidL2Slot: SlotNumber; gasConfig?: Pick; blobConfig?: L1BlobInputs; - /** Optional pre-send validation. If it rejects, the request is discarded. */ - preCheck?: () => Promise; + /** Gas consumed by validateBlobs; stashed for the bundle simulate at send time. */ + blobEvaluationGas?: bigint; checkSuccess: ( request: L1TxRequest, result?: { receipt: TransactionReceipt; stats?: TransactionStats; errorMsg?: string }, @@ -146,16 +157,19 @@ interface RequestWithExpiry { export class SequencerPublisher { private interrupted = false; private metrics: SequencerPublisherMetrics; + private bundleSimulator: SequencerBundleSimulator; public epochCache: EpochCache; private failedTxStore?: Promise; - protected governanceLog = createLogger('sequencer:publisher:governance'); - protected slashingLog = createLogger('sequencer:publisher:slashing'); + /** + * ABI used to decode raw revert payloads from dropped bundle entries when the original + * request did not carry an abi (e.g. the propose request). Merges every contract the + * publisher can route to so any of their custom errors decode against it. + */ + private readonly revertDecoderAbi: Abi = mergeAbis([RollupAbi, SlashingProposerAbi, EmpireBaseAbi, ErrorsAbi]); protected lastActions: Partial> = {}; - private isPayloadEmptyCache: Map = new Map(); - protected log: Logger; protected ethereumSlotDuration: bigint; protected aztecSlotDuration: bigint; @@ -165,9 +179,6 @@ export class SequencerPublisher { private blobClient: BlobClientInterface; - /** Address to use for simulations in fisherman mode (actual proposer's address) */ - private proposerAddressForSimulation?: EthAddress; - /** Optional callback to obtain a replacement publisher when the current one fails to send. */ private getNextPublisher?: (excludeAddresses: EthAddress[]) => Promise; @@ -180,12 +191,6 @@ export class SequencerPublisher { /** Interruptible sleep used by sendRequestsAt to wait until a target timestamp. */ private readonly interruptibleSleep = new InterruptibleSleep(); - // A CALL to a cold address is 2700 gas - public static MULTICALL_OVERHEAD_GAS_GUESS = 5000n; - - // Gas report for VotingWithSigTest shows a max gas of 100k, but we've seen it cost 700k+ in testnet - public static VOTE_GAS_GUESS: bigint = 800_000n; - public l1TxUtils: L1TxUtils; public rollupContract: RollupContract; public govProposerContract: GovernanceProposerContract; @@ -244,7 +249,7 @@ export class SequencerPublisher { this.l1FeeAnalyzer = new L1FeeAnalyzer( this.l1TxUtils.client, deps.dateProvider, - createLogger('sequencer:publisher:fee-analyzer'), + this.log.createChild('fee-analyzer'), ); } @@ -252,11 +257,18 @@ export class SequencerPublisher { this.feeAssetPriceOracle = new FeeAssetPriceOracle( this.l1TxUtils.client, this.rollupContract, - createLogger('sequencer:publisher:price-oracle'), + this.log.createChild('price-oracle'), ); // Initialize failed L1 tx store (optional, for test networks) this.failedTxStore = createL1TxFailedStore(config.l1TxFailedStore, this.log); + + this.bundleSimulator = new SequencerBundleSimulator({ + getL1TxUtils: () => this.l1TxUtils, + rollupContract: this.rollupContract, + epochCache: this.epochCache, + log: this.log.createChild('bundle-simulator'), + }); } /** @@ -308,14 +320,6 @@ export class SequencerPublisher { return this.l1FeeAnalyzer; } - /** - * Sets the proposer address to use for simulations in fisherman mode. - * @param proposerAddress - The actual proposer's address to use for balance lookups in simulations - */ - public setProposerAddressForSimulation(proposerAddress: EthAddress | undefined) { - this.proposerAddressForSimulation = proposerAddress; - } - public addRequest(request: RequestWithExpiry) { this.requests.push(request); } @@ -393,23 +397,26 @@ export class SequencerPublisher { /** * Sends all requests that are still valid. + * @param targetSlot - The target L2 slot for this send. When provided (pipelined path via + * sendRequestsAt), it is threaded into bundleSimulate so the block.timestamp override + * matches the slot the propose is built for. When omitted, falls back to + * getCurrentL2Slot() for the non-pipelined callers in Sequencer.doWork. * @returns one of: * - A receipt and stats if the tx succeeded * - a receipt and errorMsg if it failed on L1 * - undefined if no valid requests are found OR the tx failed to send. */ @trackSpan('SequencerPublisher.sendRequests') - public async sendRequests(): Promise { + public async sendRequests(targetSlot?: SlotNumber): Promise { const requestsToProcess = [...this.requests]; this.requests = []; if (this.interrupted || requestsToProcess.length === 0) { return undefined; } - const currentL2Slot = this.getCurrentL2Slot(); + const currentL2Slot = targetSlot ?? this.getCurrentL2Slot(); this.log.debug(`Sending requests on L2 slot ${currentL2Slot}`); const validRequests = requestsToProcess.filter(request => request.lastValidL2Slot >= currentL2Slot); - const validActions = validRequests.map(x => x.action); const expiredActions = requestsToProcess .filter(request => request.lastValidL2Slot < currentL2Slot) .map(x => x.action); @@ -432,70 +439,58 @@ export class SequencerPublisher { return undefined; } - // @note - we can only have one blob config per bundle - // find requests with gas and blob configs - // See https://github.com/AztecProtocol/aztec-packages/issues/11513 + // Collect earliest txTimeoutAt across all requests. const gasConfigs = validRequests.filter(request => request.gasConfig).map(request => request.gasConfig); - const blobConfigs = validRequests.filter(request => request.blobConfig).map(request => request.blobConfig); - - if (blobConfigs.length > 1) { - throw new Error('Multiple blob configs found'); - } - - const blobConfig = blobConfigs[0]; - - // Merge gasConfigs. Yields the sum of gasLimits, and the earliest txTimeoutAt, or undefined if no gasConfig sets them. - const gasLimits = gasConfigs.map(g => g?.gasLimit).filter((g): g is bigint => g !== undefined); - let gasLimit = gasLimits.length > 0 ? sumBigint(gasLimits) : undefined; // sum - // Cap at L1 block gas limit so the node accepts the tx ("gas limit too high" otherwise). - const maxGas = MAX_L1_TX_LIMIT; - if (gasLimit !== undefined && gasLimit > maxGas) { - this.log.debug('Capping bundled tx gas limit to L1 max', { - requested: gasLimit, - capped: maxGas, - }); - gasLimit = maxGas; - } const txTimeoutAts = gasConfigs.map(g => g?.txTimeoutAt).filter((g): g is Date => g !== undefined); - const txTimeoutAt = txTimeoutAts.length > 0 ? new Date(Math.min(...txTimeoutAts.map(g => g.getTime()))) : undefined; // earliest - const txConfig: RequestWithExpiry['gasConfig'] = { gasLimit, txTimeoutAt }; + const txTimeoutAt = txTimeoutAts.length > 0 ? new Date(Math.min(...txTimeoutAts.map(g => g.getTime()))) : undefined; // Sort the requests so that proposals always go first // This ensures the committee gets precomputed correctly validRequests.sort((a, b) => compareActions(a.action, b.action)); try { - // Capture context for failed tx backup before sending - const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); - const multicallData = encodeFunctionData({ - abi: multicall3Abi, - functionName: 'aggregate3', - args: [ - validRequests.map(r => ({ - target: r.request.to!, - callData: r.request.data!, - allowFailure: true, - })), - ], - }); - const blobDataHex = blobConfig?.blobs?.map(b => toHex(b)) as Hex[] | undefined; + // Bundle-level eth_simulateV1: filters out entries that revert and derives the gasLimit. + const bundleResult = await this.bundleSimulator.simulate(validRequests, currentL2Slot); - const txContext = { multicallData, blobData: blobDataHex, l1BlockNumber }; + if (bundleResult.kind === 'aborted') { + this.logDroppedInSim(bundleResult.droppedRequests); + void this.backupDroppedInSim(bundleResult.droppedRequests); + return undefined; + } + + const { requests, droppedRequests, gasLimit } = + bundleResult.kind === 'fallback' + ? { + requests: bundleResult.requests, + droppedRequests: bundleResult.droppedRequests, + gasLimit: MAX_L1_TX_LIMIT, + } + : bundleResult; + + this.logDroppedInSim(droppedRequests); + + // Compute blobConfig from survivors (not original validRequests) so that if the propose + // entry was dropped by bundleSimulate we don't attach a blob-typed config to a non-blob tx. + const [blobConfig] = requests.filter(r => r.blobConfig).map(r => r.blobConfig); + const txConfig: RequestWithExpiry['gasConfig'] = { gasLimit, txTimeoutAt }; this.log.debug('Forwarding transactions', { - validRequests: validRequests.map(request => request.action), + requests: requests.map(request => request.action), txConfig, }); - const result = await this.forwardWithPublisherRotation(validRequests, txConfig, blobConfig); + const result = await this.forwardWithPublisherRotation(requests, txConfig, blobConfig); if (result === undefined) { return undefined; } - const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions( - validRequests, + const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions(requests, result); + const allFailedActions = [...failedActions, ...droppedRequests.map(d => d.request.action)]; + return { result, - txContext, - ); - return { result, expiredActions, sentActions: validActions, successfulActions, failedActions }; + expiredActions, + sentActions: requests.map(x => x.action), + successfulActions, + failedActions: allFailedActions, + }; } catch (err) { const viemError = formatViemError(err); this.log.error(`Failed to publish bundled transactions`, viemError); @@ -512,6 +507,40 @@ export class SequencerPublisher { } } + /** Logs entries dropped by bundle simulation as warnings on the publisher's logger. */ + private logDroppedInSim(dropped: DroppedRequest[]): void { + for (const drop of dropped) { + const revertReasonDecoded = drop.revertReason ?? tryDecodeRevertReason(drop.returnData, this.revertDecoderAbi); + this.log.warn('Bundle entry dropped: action reverted in sim', { + action: drop.request.action, + revertReason: revertReasonDecoded ?? drop.returnData, + revertReasonDecoded, + returnData: drop.returnData, + }); + } + } + + /** Backs up entries dropped by bundle simulation, one record per dropped action. */ + private async backupDroppedInSim(dropped: DroppedRequest[]): Promise { + if (dropped.length === 0) { + return; + } + const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); + for (const { request: req } of dropped) { + this.backupFailedTx({ + id: keccak256(req.request.data!), + failureType: 'simulation', + request: { to: req.request.to! as Hex, data: req.request.data! }, + l1BlockNumber: l1BlockNumber.toString(), + error: { message: 'Bundle entry dropped: action reverted in sim' }, + context: { + actions: [req.action], + sender: this.getSenderAddress().toString(), + }, + }); + } + } + /** * Forwards transactions via Multicall3, rotating to the next available publisher if a send * failure occurs (i.e. the tx never reached the chain). @@ -522,19 +551,30 @@ export class SequencerPublisher { txConfig: RequestWithExpiry['gasConfig'], blobConfig: L1BlobInputs | undefined, ) { + if (!txConfig?.gasLimit) { + throw new Error('gasLimit is required for bundled transactions'); + } + const txConfigWithGasLimit = txConfig as L1TxConfig & { gasLimit: bigint }; + const triedAddresses: EthAddress[] = []; let currentPublisher = this.l1TxUtils; while (true) { + if (txConfig.txTimeoutAt && new Date() > txConfig.txTimeoutAt) { + this.log.warn(`Tx timeout (${txConfig.txTimeoutAt.toISOString()}) elapsed; stopping publisher rotation`, { + triedAddresses: triedAddresses.map(a => a.toString()), + }); + return undefined; + } triedAddresses.push(currentPublisher.getSenderAddress()); + try { const result = await Multicall3.forward( validRequests.map(r => r.request), currentPublisher, - txConfig, + txConfigWithGasLimit, blobConfig, - this.rollupContract.address, - this.log, + { gasLimitRequired: true }, ); this.l1TxUtils = currentPublisher; return result; @@ -542,6 +582,12 @@ export class SequencerPublisher { if (err instanceof TimeoutError) { throw err; } + if (err instanceof MulticallForwarderRevertedError) { + this.log.error('Forwarder transaction reverted on-chain; not rotating publisher', err, { + transactionHash: err.receipt.transactionHash, + }); + return undefined; + } const viemError = formatViemError(err); if (!this.getNextPublisher) { this.log.error('Failed to publish bundled transactions', viemError); @@ -553,7 +599,11 @@ export class SequencerPublisher { ); const nextPublisher = await this.getNextPublisher([...triedAddresses]); if (!nextPublisher) { - this.log.error('All available publishers exhausted, failed to publish bundled transactions'); + this.log.error( + `All available publishers exhausted (tried ${triedAddresses.length}), failed to publish bundled transactions`, + viemError, + { triedAddresses: triedAddresses.map(a => a.toString()) }, + ); return undefined; } currentPublisher = nextPublisher; @@ -562,112 +612,59 @@ export class SequencerPublisher { } /* - * Schedules sending all enqueued requests at (or after) the given timestamp. + * Schedules sending all enqueued requests at (or after) the start of the given L2 slot. + * Sleeps until one L1 slot before the L2 slot boundary so the tx has a chance of being + * picked up by the first L1 block of the L2 slot. + * NB: there is a known correctness risk — being included in the L1 block right before the + * L2 slot starts would revert propose with HeaderLib__InvalidSlotNumber. * Uses InterruptibleSleep so it can be cancelled via interrupt(). - * Returns the promise for the L1 response (caller should NOT await this in the work loop). */ - public async sendRequestsAt(submitAfter: Date): Promise { - const ms = submitAfter.getTime() - this.dateProvider.now(); - if (ms > 0) { - this.log.debug(`Sleeping ${ms}ms before sending requests`, { submitAfter }); - await this.interruptibleSleep.sleep(ms); + public async sendRequestsAt(targetSlot: SlotNumber): Promise { + const l1Constants = this.epochCache.getL1Constants(); + // Start of the target L2 slot, in ms (getTimestampForSlot returns seconds). + const startOfTargetSlotMs = Number(getTimestampForSlot(targetSlot, l1Constants)) * 1000; + // Aim to be in the mempool one L1 slot before the L2 slot starts, so we have a chance of + // being picked up by the first L1 block of the L2 slot. + const submitAfterMs = startOfTargetSlotMs - Number(this.ethereumSlotDuration) * 1000; + const sleepMs = submitAfterMs - this.dateProvider.now(); + if (sleepMs > 0) { + this.log.debug(`Sleeping ${sleepMs}ms before sending requests`, { + targetSlot, + submitAfterMs, + }); + await this.interruptibleSleep.sleep(sleepMs); } if (this.interrupted) { return undefined; } - - // Re-validate enqueued requests after the sleep (state may have changed, e.g. prune or L1 reorg) - const validRequests: RequestWithExpiry[] = []; - for (const request of this.requests) { - if (!request.preCheck) { - validRequests.push(request); - continue; - } - - try { - await request.preCheck(); - validRequests.push(request); - } catch (err) { - this.log.warn(`Pre-send validation failed for ${request.action}, discarding request`, err); - } - } - - this.requests = validRequests; - if (this.requests.length === 0) { - return undefined; - } - - return this.sendRequests(); + return this.sendRequests(targetSlot); } private callbackBundledTransactions( requests: RequestWithExpiry[], - result: { receipt: TransactionReceipt; errorMsg?: string } | FormattedViemError | undefined, - txContext: { multicallData: Hex; blobData?: Hex[]; l1BlockNumber: bigint }, + result: { receipt: TransactionReceipt; multicallData: Hex }, ) { const actionsListStr = requests.map(r => r.action).join(', '); - if (result instanceof FormattedViemError) { - this.log.error(`Failed to publish bundled transactions (${actionsListStr})`, result); - this.backupFailedTx({ - id: keccak256(txContext.multicallData), - failureType: 'send-error', - request: { to: MULTI_CALL_3_ADDRESS, data: txContext.multicallData }, - blobData: txContext.blobData, - l1BlockNumber: txContext.l1BlockNumber.toString(), - error: { message: result.message, name: result.name }, - context: { - actions: requests.map(r => r.action), - requests: requests.map(r => ({ action: r.action, to: r.request.to! as Hex, data: r.request.data! })), - sender: this.getSenderAddress().toString(), - }, - }); - return { failedActions: requests.map(r => r.action) }; - } else { - this.log.verbose(`Published bundled transactions (${actionsListStr})`, { - result, - requests: requests.map(r => ({ - ...r, - // Avoid logging large blob data - blobConfig: r.blobConfig - ? { ...r.blobConfig, blobs: r.blobConfig.blobs.map(b => ({ size: trimmedBytesLength(b) })) } - : undefined, - })), - }); - const successfulActions: Action[] = []; - const failedActions: Action[] = []; - for (const request of requests) { - if (request.checkSuccess(request.request, result)) { - successfulActions.push(request.action); - } else { - failedActions.push(request.action); - } - } - // Single backup for the whole reverted tx - if (failedActions.length > 0 && result?.receipt?.status === 'reverted') { - this.backupFailedTx({ - id: result.receipt.transactionHash, - failureType: 'revert', - request: { to: MULTI_CALL_3_ADDRESS, data: txContext.multicallData }, - blobData: txContext.blobData, - l1BlockNumber: result.receipt.blockNumber.toString(), - receipt: { - transactionHash: result.receipt.transactionHash, - blockNumber: result.receipt.blockNumber.toString(), - gasUsed: (result.receipt.gasUsed ?? 0n).toString(), - status: 'reverted', - }, - error: { message: result.errorMsg ?? 'Transaction reverted' }, - context: { - actions: failedActions, - requests: requests - .filter(r => failedActions.includes(r.action)) - .map(r => ({ action: r.action, to: r.request.to! as Hex, data: r.request.data! })), - sender: this.getSenderAddress().toString(), - }, - }); + this.log.verbose(`Published bundled transactions (${actionsListStr})`, { + result, + requests: requests.map(r => ({ + ...r, + // Avoid logging large blob data + blobConfig: r.blobConfig + ? { ...r.blobConfig, blobs: r.blobConfig.blobs.map(b => ({ size: trimmedBytesLength(b) })) } + : undefined, + })), + }); + const successfulActions: Action[] = []; + const failedActions: Action[] = []; + for (const request of requests) { + if (request.checkSuccess(request.request, result)) { + successfulActions.push(request.action); + } else { + failedActions.push(request.action); } - return { successfulActions, failedActions }; } + return { successfulActions, failedActions }; } /** @@ -677,7 +674,11 @@ export class SequencerPublisher { */ public async canProposeAt(tipArchive: Fr, msgSender: EthAddress, simulationOverridesPlan?: SimulationOverridesPlan) { // TODO: #14291 - should loop through multiple keys to check if any of them can propose - const ignoredErrors = ['SlotAlreadyInChain', 'InvalidProposer', 'InvalidArchive']; + // These errors are expected when we cannot actually propose right now — usually because our + // local view of the chain is ahead of L1 (proposed parent hasn't landed yet, or someone + // else has just landed the slot, or the archive override doesn't match). We log a warn and + // skip the proposal; we do NOT treat these as bugs. + const expectedErrors = ['SlotAlreadyInChain', 'InvalidProposer', 'InvalidArchive']; const pipelined = this.epochCache.isProposerPipeliningEnabled(); const slotOffset = pipelined ? this.aztecSlotDuration : 0n; @@ -691,8 +692,8 @@ export class SequencerPublisher { await buildSimulationOverridesStateOverride(this.rollupContract, simulationOverridesPlan), ) .catch(err => { - if (err instanceof FormattedViemError && ignoredErrors.find(e => err.message.includes(e))) { - this.log.warn(`Failed canProposeAtTime check with ${ignoredErrors.find(e => err.message.includes(e))}`, { + if (err instanceof FormattedViemError && expectedErrors.find(e => err.message.includes(e))) { + this.log.warn(`Failed canProposeAtTime check with ${expectedErrors.find(e => err.message.includes(e))}`, { error: err.message, }); } else { @@ -725,7 +726,8 @@ export class SequencerPublisher { flags, ] as const; - const ts = this.getSimulationTimestamp(header.slotNumber); + const l1Constants = this.epochCache.getL1Constants(); + const ts = getTimestampForSlot(header.slotNumber, l1Constants); const stateOverrides = await buildSimulationOverridesStateOverride(this.rollupContract, simulationOverridesPlan); let balance = 0n; if (this.config.fishermanMode) { @@ -879,35 +881,6 @@ export class SequencerPublisher { } } - /** Simulates `propose` to make sure that the checkpoint is valid for submission */ - @trackSpan('SequencerPublisher.validateCheckpointForSubmission') - public async validateCheckpointForSubmission( - checkpoint: Checkpoint, - attestationsAndSigners: CommitteeAttestationsAndSigners, - attestationsAndSignersSignature: Signature, - simulationOverridesPlan?: SimulationOverridesPlan, - ): Promise { - const blobFields = checkpoint.toBlobFields(); - const blobs = await getBlobsPerL1Block(blobFields); - const blobInput = getPrefixedEthBlobCommitments(blobs); - - const args = [ - { - header: checkpoint.header.toViem(), - archive: toHex(checkpoint.archive.root.toBuffer()), - oracleInput: { - feeAssetPriceModifier: checkpoint.feeAssetPriceModifier, - }, - }, - attestationsAndSigners.getPackedAttestations(), - attestationsAndSigners.getSigners().map(signer => signer.toString()), - attestationsAndSignersSignature.toViemSignature(), - blobInput, - ] as const; - - await this.simulateProposeTx(args, simulationOverridesPlan); - } - private async enqueueCastSignalHelper( slotNumber: SlotNumber, signalType: GovernanceSignalAction, @@ -938,7 +911,7 @@ export class SequencerPublisher { return false; } - if (await this.isPayloadEmpty(payload)) { + if (await base.isPayloadEmpty(payload)) { this.log.warn(`Skipping vote cast for payload with empty code`); return false; } @@ -981,45 +954,19 @@ export class SequencerPublisher { lastValidL2Slot: slotNumber, }); - const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); - const timestamp = this.getSimulationTimestamp(slotNumber); - - try { - await this.l1TxUtils.simulate(request, { time: timestamp }, [], mergeAbis([request.abi ?? [], ErrorsAbi])); - this.log.debug(`Simulation for ${action} at slot ${slotNumber} succeeded`, { request }); - } catch (err) { - const viemError = formatViemError(err); - this.log.error(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, viemError, { - simulationTimestamp: timestamp, - l1BlockNumber, - }); - this.backupFailedTx({ - id: keccak256(request.data!), - failureType: 'simulation', - request: { to: request.to!, data: request.data!, value: request.value?.toString() }, - l1BlockNumber: l1BlockNumber.toString(), - error: { message: viemError.message, name: viemError.name }, - context: { - actions: [action], - slot: slotNumber, - sender: this.getSenderAddress().toString(), - }, - }); - // Yes, we enqueue the request anyway, in case there was a bug with the simulation itself - } - // TODO(palla/slash): All votes (governance and slashing) should txTimeoutAt at the end of the slot. this.addRequest({ - gasConfig: { gasLimit: SequencerPublisher.VOTE_GAS_GUESS }, action, request, lastValidL2Slot: slotNumber, checkSuccess: (_request, result) => { const success = result && - result.receipt && - result.receipt.status === 'success' && - tryExtractEvent(result.receipt.logs, base.address.toString(), EmpireBaseAbi, 'SignalCast'); + extractEventSuccess(result.receipt, { + address: base.address.toString(), + abi: EmpireBaseAbi, + eventName: 'SignalCast', + }); const logData = { ...result, slotNumber, round, payload: payload.toString() }; if (!success) { @@ -1041,17 +988,6 @@ export class SequencerPublisher { return true; } - private async isPayloadEmpty(payload: EthAddress): Promise { - const key = payload.toString(); - const cached = this.isPayloadEmptyCache.get(key); - if (cached) { - return cached; - } - const isEmpty = !(await this.l1TxUtils.getCode(payload)); - this.isPayloadEmptyCache.set(key, isEmpty); - return isEmpty; - } - /** * Enqueues a governance castSignal transaction to cast a signal for a given slot number. * @param slotNumber - The slot number to cast a signal for. @@ -1100,10 +1036,14 @@ export class SequencerPublisher { } const votes = bufferToHex(encodeSlashConsensusVotes(action.votes)); const request = await this.slashingProposerContract.buildVoteRequestFromSigner(votes, slotNumber, signer); - await this.simulateAndEnqueueRequest( + this.enqueueRequest( 'vote-offenses', request, - (receipt: TransactionReceipt) => !!this.slashingProposerContract!.tryExtractVoteCastEvent(receipt.logs), + { + address: this.slashingProposerContract.address.toString(), + abi: SlashingProposerAbi, + eventName: 'VoteCast', + }, slotNumber, ); break; @@ -1123,11 +1063,14 @@ export class SequencerPublisher { action.round, action.committees, ); - await this.simulateAndEnqueueRequest( + this.enqueueRequest( 'execute-slash', executeRequest, - (receipt: TransactionReceipt) => - !!this.slashingProposerContract!.tryExtractRoundExecutedEvent(receipt.logs), + { + address: this.slashingProposerContract.address.toString(), + abi: SlashingProposerAbi, + eventName: 'RoundExecuted', + }, slotNumber, ); break; @@ -1143,7 +1086,7 @@ export class SequencerPublisher { return true; } - /** Simulates and enqueues a proposal for a checkpoint on L1 */ + /** Enqueues a proposal for a checkpoint on L1 */ public async enqueueProposeCheckpoint( checkpoint: Checkpoint, attestationsAndSigners: CommitteeAttestationsAndSigners, @@ -1164,61 +1107,11 @@ export class SequencerPublisher { feeAssetPriceModifier: checkpoint.feeAssetPriceModifier, }; - const simulationOverridesPlan = SimulationOverridesBuilder.from(opts.simulationOverridesPlan) - .withoutBlobCheck() - .build(); - - const preCheckSimulationOverridesPlan = SimulationOverridesBuilder.from(opts.preCheckSimulationOverridesPlan) - .withoutBlobCheck() - .build(); - - try { - // @note This will make sure that we are passing the checks for our header ASSUMING that the data is also made available - // This means that we can avoid the simulation issues in later checks. - // By simulation issue, I mean the fact that the block.timestamp is equal to the last block, not the next, which - // make time consistency checks break. - // TODO(palla): Check whether we're validating twice, once here and once within addProposeTx, since we call simulateProposeTx in both places. - await this.validateCheckpointForSubmission( - checkpoint, - attestationsAndSigners, - attestationsAndSignersSignature, - simulationOverridesPlan, - ); - } catch (err: any) { - this.log.error(`Checkpoint validation failed. ${err instanceof Error ? err.message : 'No error message'}`, err, { - ...checkpoint.getStats(), - slotNumber: checkpoint.header.slotNumber, - simulationOverridesPlan, - }); - throw err; - } - - // Build a pre-check callback that re-validates the checkpoint before L1 submission. - // During pipelining this catches stale proposals due to prunes or L1 reorgs that occur during the pipeline sleep. - let preCheck = undefined; - if (this.epochCache.isProposerPipeliningEnabled()) { - preCheck = async () => { - this.log.debug(`Re-validating checkpoint ${checkpoint.number} before L1 submission`); - await this.validateCheckpointForSubmission( - checkpoint, - attestationsAndSigners, - attestationsAndSignersSignature, - preCheckSimulationOverridesPlan, - ); - }; - } - this.log.verbose(`Enqueuing checkpoint propose transaction`, { ...checkpoint.toCheckpointInfo(), txTimeoutAt: opts.txTimeoutAt, - simulationOverridesPlan, }); - await this.addProposeTx( - checkpoint, - proposeTxArgs, - { txTimeoutAt: opts.txTimeoutAt, simulationOverridesPlan }, - preCheck, - ); + await this.addProposeTx(checkpoint, proposeTxArgs, { txTimeoutAt: opts.txTimeoutAt }); } public enqueueInvalidateCheckpoint( @@ -1229,23 +1122,22 @@ export class SequencerPublisher { return; } - // We issued the simulation against the rollup contract, so we need to account for the overhead of the multicall3 - const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil((Number(request.gasUsed) * 64) / 63))); - const { gasUsed, checkpointNumber } = request; - const logData = { gasUsed, checkpointNumber, gasLimit, opts }; + const logData = { gasUsed, checkpointNumber, opts }; this.log.verbose(`Enqueuing invalidate checkpoint request`, logData); this.addRequest({ action: `invalidate-by-${request.reason}`, request: request.request, - gasConfig: { gasLimit, txTimeoutAt: opts.txTimeoutAt }, + gasConfig: opts.txTimeoutAt ? { txTimeoutAt: opts.txTimeoutAt } : undefined, lastValidL2Slot: SlotNumber(this.getCurrentL2Slot() + 2), checkSuccess: (_req, result) => { const success = result && - result.receipt && - result.receipt.status === 'success' && - tryExtractEvent(result.receipt.logs, this.rollupContract.address, RollupAbi, 'CheckpointInvalidated'); + extractEventSuccess(result.receipt, { + address: this.rollupContract.address, + abi: RollupAbi, + eventName: 'CheckpointInvalidated', + }); if (!success) { this.log.warn(`Invalidate checkpoint ${request.checkpointNumber} failed`, { ...result, ...logData }); } else { @@ -1256,73 +1148,36 @@ export class SequencerPublisher { }); } - private async simulateAndEnqueueRequest( + /** + * Dedup-checked enqueue helper for actions that are simulated at bundle-send time rather + * than at enqueue time. Validates the (action, slot) dedup key, sets `lastActions`, and + * enqueues without a gasLimit so the bundle simulate sets the only gasLimit that matters. + */ + private enqueueRequest( action: Action, request: L1TxRequest, - checkSuccess: (receipt: TransactionReceipt) => boolean | undefined, + eventOpts: { address: string; abi: Abi; eventName: string }, slotNumber: SlotNumber, - ) { - const timestamp = this.getSimulationTimestamp(slotNumber); - const logData = { slotNumber, timestamp, gasLimit: undefined as bigint | undefined }; + ): boolean { if (this.lastActions[action] && this.lastActions[action] === slotNumber) { this.log.debug(`Skipping duplicate action ${action} for slot ${slotNumber}`); return false; } - const cachedLastActionSlot = this.lastActions[action]; this.lastActions[action] = slotNumber; - this.log.debug(`Simulating ${action} for slot ${slotNumber}`, logData); - - const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); - - let gasUsed: bigint; - const simulateAbi = mergeAbis([request.abi ?? [], ErrorsAbi]); - - try { - ({ gasUsed } = await this.l1TxUtils.simulate(request, { time: timestamp }, [], simulateAbi)); - this.log.verbose(`Simulation for ${action} succeeded`, { ...logData, request, gasUsed }); - } catch (err) { - const viemError = formatViemError(err, simulateAbi); - this.log.error(`Simulation for ${action} at ${slotNumber} failed`, viemError, logData); - - this.backupFailedTx({ - id: keccak256(request.data!), - failureType: 'simulation', - request: { to: request.to!, data: request.data!, value: request.value?.toString() }, - l1BlockNumber: l1BlockNumber.toString(), - error: { message: viemError.message, name: viemError.name }, - context: { - actions: [action], - slot: slotNumber, - sender: this.getSenderAddress().toString(), - }, - }); - - return false; - } - - // We issued the simulation against the rollup contract, so we need to account for the overhead of the multicall3 - const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil((Number(gasUsed) * 64) / 63))); - logData.gasLimit = gasLimit; - - // Store the ABI used for simulation on the request so Multicall3.forward can decode errors - // when the tx is sent and a revert is diagnosed via simulation. - const requestWithAbi = { ...request, abi: simulateAbi }; - - this.log.debug(`Enqueuing ${action}`, logData); + this.log.debug(`Enqueuing ${action}`, { slotNumber }); this.addRequest({ action, - request: requestWithAbi, - gasConfig: { gasLimit }, + request, lastValidL2Slot: slotNumber, - checkSuccess: (_req, result) => { - const success = result && result.receipt && result.receipt.status === 'success' && checkSuccess(result.receipt); + checkSuccess: (_request, result) => { + const success = result && extractEventSuccess(result.receipt, eventOpts); if (!success) { - this.log.warn(`Action ${action} at ${slotNumber} failed`, { ...result, ...logData }); + this.log.warn(`Action ${action} at ${slotNumber} failed`, { ...result, slotNumber }); this.lastActions[action] = cachedLastActionSlot; } else { - this.log.info(`Action ${action} at ${slotNumber} succeeded`, { ...result, ...logData }); + this.log.info(`Action ${action} at ${slotNumber} succeeded`, { ...result, slotNumber }); } return !!success; }, @@ -1348,7 +1203,7 @@ export class SequencerPublisher { this.l1TxUtils.restart(); } - private async prepareProposeTx(encodedData: L1ProcessArgs, simulationOverridesPlan?: SimulationOverridesPlan) { + private async prepareProposeTx(encodedData: L1ProcessArgs) { const kzg = Blob.getViemKzgInstance(); const blobInput = getPrefixedEthBlobCommitments(encodedData.blobs); this.log.debug('Validating blob input', { blobInput }); @@ -1361,7 +1216,11 @@ export class SequencerPublisher { blobEvaluationGas = BigInt(encodedData.blobs.length) * 21_000n; this.log.debug(`Using fixed blob evaluation gas estimate in fisherman mode: ${blobEvaluationGas}`); } else { - // Normal mode - use estimateGas with blob inputs + // We call validateBlobs via estimateGas with real blob+kzg sidecars as a consistency check + // that our locally-built blob commitments match the blob data. The bundle simulate at send + // time uses eth_simulateV1, which cannot carry blob inputs, so the rollup's on-chain blob + // check is forced off there — making this the only pre-flight detector of a commitment/data + // mismatch. The returned gas estimate is stashed on the request for the bundle path to read. blobEvaluationGas = await this.l1TxUtils .estimateGas( this.getSenderAddress().toString(), @@ -1419,119 +1278,21 @@ export class SequencerPublisher { blobInput, ] as const; - const { rollupData, simulationResult } = await this.simulateProposeTx(args, simulationOverridesPlan); - - return { args, blobEvaluationGas, rollupData, simulationResult }; - } - - /** - * Simulates the propose tx with eth_simulateV1 - * @param args - The propose tx args - * @returns The simulation result - */ - private async simulateProposeTx( - args: readonly [ - { - readonly header: ViemHeader; - readonly archive: `0x${string}`; - readonly oracleInput: { - readonly feeAssetPriceModifier: bigint; - }; - }, - ViemCommitteeAttestations, - `0x${string}`[], // Signers - ViemSignature, - `0x${string}`, - ], - simulationOverridesPlan?: SimulationOverridesPlan, - ) { - const rollupData = encodeFunctionData({ - abi: RollupAbi, - functionName: 'propose', - args, - }); - - const stateOverrides = await buildSimulationOverridesStateOverride(this.rollupContract, simulationOverridesPlan); - // In fisherman mode, simulate as the proposer but with sufficient balance - if (this.proposerAddressForSimulation) { - stateOverrides.push({ - address: this.proposerAddressForSimulation.toString(), - balance: 10n * WEI_CONST * WEI_CONST, // 10 ETH - }); - } + const rollupData = encodeFunctionData({ abi: RollupAbi, functionName: 'propose', args }); - const l1BlockNumber = await this.l1TxUtils.getBlockNumber(); - const simTs = this.getSimulationTimestamp(SlotNumber.fromBigInt(args[0].header.slotNumber)); - - const simulationResult = await this.l1TxUtils - .simulate( - { - to: this.rollupContract.address, - data: rollupData, - gas: MAX_L1_TX_LIMIT, - ...(this.proposerAddressForSimulation && { from: this.proposerAddressForSimulation.toString() }), - }, - { - time: simTs, - // @note reth should have a 30m gas limit per block but throws errors that this tx is beyond limit so we increase here - gasLimit: MAX_L1_TX_LIMIT * 2n, - }, - stateOverrides, - RollupAbi, - { - // @note fallback gas estimate to use if the node doesn't support simulation API - fallbackGasEstimate: MAX_L1_TX_LIMIT, - }, - ) - .catch(err => { - // In fisherman mode, we expect ValidatorSelection__MissingProposerSignature since fisherman doesn't have proposer signature - const viemError = formatViemError(err); - if (this.config.fishermanMode && viemError.message?.includes('ValidatorSelection__MissingProposerSignature')) { - this.log.debug(`Ignoring expected ValidatorSelection__MissingProposerSignature error in fisherman mode`); - // Return a minimal simulation result with the fallback gas estimate - return { - gasUsed: MAX_L1_TX_LIMIT, - logs: [], - }; - } - this.log.error(`Failed to simulate propose tx`, viemError, { simulationTimestamp: simTs }); - this.backupFailedTx({ - id: keccak256(rollupData), - failureType: 'simulation', - request: { to: this.rollupContract.address, data: rollupData }, - l1BlockNumber: l1BlockNumber.toString(), - error: { message: viemError.message, name: viemError.name }, - context: { - actions: ['propose'], - slot: Number(args[0].header.slotNumber), - sender: this.getSenderAddress().toString(), - }, - }); - throw err; - }); - - return { rollupData, simulationResult }; + return { args, blobEvaluationGas, rollupData }; } private async addProposeTx( checkpoint: Checkpoint, encodedData: L1ProcessArgs, opts: EnqueueProposeCheckpointOpts = {}, - preCheck?: () => Promise, ): Promise { const slot = checkpoint.header.slotNumber; const timer = new Timer(); const kzg = Blob.getViemKzgInstance(); - const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx( - encodedData, - opts.simulationOverridesPlan, - ); + const { rollupData, blobEvaluationGas } = await this.prepareProposeTx(encodedData); const startBlock = await this.l1TxUtils.getBlockNumber(); - const gasLimit = this.l1TxUtils.bumpGasLimit( - BigInt(Math.ceil((Number(simulationResult.gasUsed) * 64) / 63)) + - blobEvaluationGas + - SequencerPublisher.MULTICALL_OVERHEAD_GAS_GUESS, // We issue the simulation against the rollup contract, so we need to account for the overhead of the multicall3 - ); // Send the blobs to the blob client preemptively. This helps in tests where the sequencer mistakingly thinks that the propose // tx fails but it does get mined. We make sure that the blobs are sent to the blob client regardless of the tx outcome. @@ -1548,8 +1309,8 @@ export class SequencerPublisher { data: rollupData, }, lastValidL2Slot: checkpoint.header.slotNumber, - gasConfig: { txTimeoutAt: opts.txTimeoutAt, gasLimit }, - preCheck, + gasConfig: { txTimeoutAt: opts.txTimeoutAt, gasLimit: undefined }, + blobEvaluationGas, blobConfig: { blobs: encodedData.blobs.map(b => b.data), kzg, @@ -1559,10 +1320,11 @@ export class SequencerPublisher { return false; } const { receipt, stats, errorMsg } = result; - const success = - receipt && - receipt.status === 'success' && - tryExtractEvent(receipt.logs, this.rollupContract.address, RollupAbi, 'CheckpointProposed'); + const success = extractEventSuccess(receipt, { + address: this.rollupContract.address, + abi: RollupAbi, + eventName: 'CheckpointProposed', + }); if (success) { const endBlock = receipt.blockNumber; @@ -1603,13 +1365,6 @@ export class SequencerPublisher { }); } - /** Returns the timestamp of the last L1 slot within a given L2 slot. Used as the simulation timestamp - * for eth_simulateV1 calls, since it's guaranteed to be greater than any L1 block produced during the slot. */ - private getSimulationTimestamp(slot: SlotNumber): bigint { - const l1Constants = this.epochCache.getL1Constants(); - return getLastL1SlotTimestampForL2Slot(slot, l1Constants); - } - /** Returns the timestamp of the next L1 slot boundary after now. */ private getNextL1SlotTimestamp(): bigint { const l1Constants = this.epochCache.getL1Constants(); diff --git a/yarn-project/sequencer-client/src/sequencer/README.md b/yarn-project/sequencer-client/src/sequencer/README.md index e2d94a1878c9..fc3692c33ce1 100644 --- a/yarn-project/sequencer-client/src/sequencer/README.md +++ b/yarn-project/sequencer-client/src/sequencer/README.md @@ -2,11 +2,11 @@ This document covers how the sequencer schedules its work within a slot. See the [package README](../../README.md) for the high-level architecture; this one focuses on the timing math and the state-machine deadlines. -The model described here is for **proposer pipelining**, the standard mode in production. Non-pipelined scheduling existed historically. +The model described here is for **proposer pipelining**, the standard mode in production. Non-pipelined scheduling existed historically and is in the process of being removed. ## Overview -Block production runs on a cadence of fixed-length **slots** (e.g. 72 s). Each slot has a single elected proposer who is allowed to build during that slot. The proposer can build several blocks within the slot, but all those blocks are part of the same **checkpoint** and commit to the same L2 slot: +Block production runs on three nested clocks: - A **slot** is a fixed window (e.g. 72 s) during which one elected proposer is allowed to build. - A slot contains several equal-length **sub-slots** (e.g. 8 s). Each sub-slot owns the budget for one L2 block and has a deadline fixed relative to the slot start. @@ -192,7 +192,7 @@ Block 1 has 7 s of build time instead of 8 s. Still well above `minExecutionTime ### Very slow initialization (8 s) -Sub-slot 1's deadline (9 s) is less than `minExecutionTime` (2 s) away, so it is skipped entirely. The first attempted block runs in sub-slot 2 with the usual budget. The checkpoint will have one fewer block. +Sub-slot 1's deadline (9 s) is closer than `minExecutionTime` (2 s), so it is skipped entirely. The first attempted block runs in sub-slot 2 with the usual budget. The checkpoint will have one fewer block. ### Block takes longer than its budget @@ -208,7 +208,7 @@ The current sub-slot is dropped without committing anything. The loop retries on ### Build slot ends before attestations arrive -`waitForAttestations` enforces `checkpointAttestationDeadline` (`2 * aztecSlotDuration - l1PublishingTime`) and returns `undefined` if the quorum is not in by then. The proposal stays on the proposed chain but no `propose` call is enqueued for L1; governance and slashing votes still go out via `sendRequestsAt`. The publishing-state deadline allows spillover into the target slot precisely to absorb a small overrun while the quorum is still arriving. +`assertTimeLeft` will reject `PUBLISHING_CHECKPOINT` if the attestation deadline has passed; the slot is abandoned, and `checkpoint-publish-failed` is emitted. The `PUBLISHING_CHECKPOINT` deadline allows spillover into the target slot (`2 * aztecSlotDuration - l1PublishingTime`) precisely to absorb a small overrun. ### Pipelined parent fails on L1 @@ -228,6 +228,6 @@ aztecSlotDuration ≥ checkpointInitializationTime + blockDuration // last-block re-execution window ``` -If `blockDuration` is set below `minExecutionTime`, the timing model normalizes `minExecutionTime` down to `blockDuration` rather than rejecting the config (see `normalizeCheckpointTimingConfig` in `stdlib/src/timetable/index.ts`). `p2pPropagationTime` should be measured against the deployment's actual p2p latency: it directly determines how much of each slot is spent on the cooldown. +Block duration should be ≥ `minExecutionTime` (otherwise no sub-slot ever has enough headroom). `p2pPropagationTime` should be measured against the deployment's actual p2p latency: it directly determines how much of each slot is spent on the cooldown. `l1PublishingTime` should fit inside the Ethereum slot the target slot maps to. The default of 12 s lines up with one Ethereum slot; congested deployments may need to increase it (which only affects the `PUBLISHING_CHECKPOINT` deadline, not the number of blocks built). diff --git a/yarn-project/sequencer-client/src/sequencer/automine/README.md b/yarn-project/sequencer-client/src/sequencer/automine/README.md new file mode 100644 index 000000000000..baabfd7aaf53 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/automine/README.md @@ -0,0 +1,46 @@ +# AutomineSequencer + +A minimal, deterministic, queue-driven sequencer for e2e tests that do not exercise block-building or consensus mechanics (e.g. `e2e_token`, `e2e_amm`, `e2e_authwit`). + +## When to use it + +Use `AutomineSequencer` (via `AUTOMINE_E2E_OPTS`) for single-sequencer tests that care about contract logic, not about proposer selection, attestations, pipelining, or multi-validator coordination. It bypasses all of that machinery. + +Use the production `Sequencer` (via `PIPELINING_SETUP_OPTS` or the default) for tests that explicitly exercise consensus, validator rotation, P2P gossip, slashing, or multi-node behavior. + +**Requirement**: the deployed rollup must have `aztecTargetCommitteeSize == 0`. This causes `Rollup.verifyProposer` / `verifyAttestations` on L1 to short-circuit and accept an empty `CommitteeAttestationsAndSigners`, which is what `AutomineSequencer` always sends. + +## What it omits + +Compared to the production `Sequencer`: + +- No proposer-turn check (single sequencer, always proposes). +- No sync check, no pipelining, no timetable enforcement. +- No validator orchestration, attestation collection, or P2P proposal gossip. +- No slashing, no governance votes, no `SequencerEvents`. + +Consumers (archiver, world-state, `EpochTestSettler`) observe L1 and the archiver tip directly rather than listening for sequencer events. + +## Serial-queue invariant + +Every operation — mempool-driven block builds, explicit empty-block builds, time warps, and reorgs — is serialized through a single `SerialQueue`. They never interleave. + +Public entry points: + +| Method | Description | +| --- | --- | +| `buildIfPending()` | Enqueues a mempool-driven build. Coalesces bursts into one job. | +| `buildEmptyBlock()` | Enqueues a forced empty-block build. | +| `warpTo(ts)` / `warpBy(delta)` | Advances L1 time to a slot boundary. | +| `revertToCheckpoint(n)` | Rolls L1 back to the block that published checkpoint `n`, then resets archiver, world-state, and P2P pool. | +| `syncPoint()` | Awaits the queue reaching idle. | + +## Entry points + +**Factory** — `createAutomineSequencer` in `automine_factory.ts` wires up all dependencies (publisher manager, keystore, cheat codes, etc.), starts the `PublisherManager`, and returns an unstarted `AutomineSequencer`. The caller (`AztecNodeService.createAndSync` in `aztec-node/src/aztec-node/server.ts`) invokes `AutomineSequencer.start()` separately. It is called by the full node when `aztecTargetCommitteeSize == 0`. + +**Test fixture** — `AUTOMINE_E2E_OPTS` in `end-to-end/src/fixtures/fixtures.ts` is the test-side entry point. Pass it to `setup()` to get a node + `AutomineSequencer` instead of the production sequencer stack. + +## Epoch proving caveat + +Epoch proving remains manual under `AUTOMINE_E2E_OPTS`. The e2e `setup()` fixture does NOT wire an `EpochTestSettler` — that observer is only attached in `local-network.ts`. Tests that cross epoch boundaries must therefore advance the proven anchor explicitly via `cheatCodes.rollup.markAsProven(...)`. See `e2e_lending_contract.test.ts` (which calls `progressSlots` in `simulators/lending_simulator.ts`) and `e2e_pruned_blocks.test.ts` for real examples. diff --git a/yarn-project/sequencer-client/src/sequencer/automine/automine_factory.ts b/yarn-project/sequencer-client/src/sequencer/automine/automine_factory.ts new file mode 100644 index 000000000000..a67a8ff85102 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/automine/automine_factory.ts @@ -0,0 +1,145 @@ +import type { Archiver } from '@aztec/archiver'; +import type { BlobClientInterface } from '@aztec/blob-client/client'; +import type { EpochCache } from '@aztec/epoch-cache'; +import { GovernanceProposerContract, type RollupContract } from '@aztec/ethereum/contracts'; +import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils'; +import { PublisherManager } from '@aztec/ethereum/publisher-manager'; +import { EthCheatCodes } from '@aztec/ethereum/test'; +import type { ViemPublicClient } from '@aztec/ethereum/types'; +import type { Logger } from '@aztec/foundation/log'; +import type { DateProvider } from '@aztec/foundation/timer'; +import type { KeystoreManager } from '@aztec/node-keystore'; +import type { P2PClient as ConcreteP2PClient, P2P } from '@aztec/p2p'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import type { ChainConfig } from '@aztec/stdlib/config'; +import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; +import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { TelemetryClient } from '@aztec/telemetry-client'; +import { type FullNodeCheckpointsBuilder, NodeKeystoreAdapter, type ValidatorClient } from '@aztec/validator-client'; + +import { type SequencerClientConfig, getPublisherConfigFromSequencerConfig } from '../../config.js'; +import type { GlobalVariableBuilder } from '../../global_variable_builder/global_builder.js'; +import { SequencerPublisherFactory } from '../../publisher/sequencer-publisher-factory.js'; +import { AutomineSequencer } from './automine_sequencer.js'; + +/** Arguments for {@link createAutomineSequencer}. */ +export type CreateAutomineSequencerArgs = { + config: SequencerClientConfig & Pick; + l1TxUtils: L1TxUtils[]; + funderL1TxUtils: L1TxUtils | undefined; + publicClient: ViemPublicClient; + rollupContract: RollupContract; + epochCache: EpochCache; + blobClient: BlobClientInterface | undefined; + telemetry: TelemetryClient; + dateProvider: DateProvider; + keyStoreManager: KeystoreManager; + validatorClient: ValidatorClient; + checkpointsBuilder: FullNodeCheckpointsBuilder; + globalVariableBuilder: GlobalVariableBuilder; + worldStateSynchronizer: WorldStateSynchronizer; + archiver: L2BlockSource & + L1ToL2MessageSource & + Pick; + p2pClient: P2P & Pick; + l1Constants: { l1GenesisTime: bigint; slotDuration: number; ethereumSlotDuration: number; rollupManaLimit: number }; + log: Logger; +}; + +/** + * Builds an {@link AutomineSequencer} for use in single-sequencer e2e tests. + * + * Constructs the PublisherManager, GovernanceProposerContract, SequencerPublisherFactory, + * looks up the attestor/coinbase/feeRecipient from the keystore, wires EthCheatCodes, + * and starts the publisher manager before returning. + */ +export async function createAutomineSequencer({ + config, + l1TxUtils, + funderL1TxUtils, + publicClient, + rollupContract, + epochCache, + blobClient, + telemetry, + dateProvider, + keyStoreManager, + validatorClient, + checkpointsBuilder, + globalVariableBuilder, + worldStateSynchronizer, + archiver, + p2pClient, + l1Constants, + log, +}: CreateAutomineSequencerArgs): Promise { + const publisherManager = new PublisherManager(l1TxUtils, getPublisherConfigFromSequencerConfig(config), { + bindings: log.getBindings(), + funder: funderL1TxUtils, + }); + const governanceProposerContract = new GovernanceProposerContract( + publicClient, + config.governanceProposerAddress.toString(), + ); + const publisherFactory = new SequencerPublisherFactory(config, { + telemetry, + blobClient: blobClient!, + epochCache, + governanceProposerContract, + rollupContract, + dateProvider, + publisherManager, + nodeKeyStore: NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager), + logger: log, + }); + const attestorAddresses = NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager).getAttesterAddresses(); + const attestor = attestorAddresses[0]; + if (!attestor) { + throw new Error('AutomineSequencer requires at least one attestor address in the keystore'); + } + const coinbase = validatorClient.getCoinbaseForAttestor(attestor); + const feeRecipient = validatorClient.getFeeRecipientForAttestor(attestor); + const ethCheatCodes = new EthCheatCodes(config.l1RpcUrls, dateProvider, log.createChild('eth-cheat-codes')); + + // Include the funder's L1TxUtils in the reorg reset list so funding-tx nonces don't + // go stale after L1 rollbacks. Dedupe by sender address in case the funder reuses a + // publisher's signer. + const reorgResetL1TxUtils = (() => { + if (!funderL1TxUtils) { + return l1TxUtils; + } + const funderAddress = funderL1TxUtils.getSenderAddress().toString(); + const alreadyIncluded = l1TxUtils.some(utils => utils.getSenderAddress().toString() === funderAddress); + return alreadyIncluded ? l1TxUtils : [...l1TxUtils, funderL1TxUtils]; + })(); + + const automineSequencer = new AutomineSequencer({ + publisherFactory, + checkpointsBuilder, + globalsBuilder: globalVariableBuilder, + worldState: worldStateSynchronizer, + l2BlockSource: archiver, + l1ToL2MessageSource: archiver, + p2pClient, + ethCheatCodes, + dateProvider: dateProvider as any, // TestDateProvider; verified at construction in fixture + l1Constants: { + l1GenesisTime: l1Constants.l1GenesisTime, + slotDuration: l1Constants.slotDuration, + ethereumSlotDuration: l1Constants.ethereumSlotDuration, + rollupManaLimit: l1Constants.rollupManaLimit, + epochDuration: config.aztecEpochDuration, + }, + coinbase, + feeRecipient, + signatureContext: { chainId: config.l1ChainId, rollupAddress: config.rollupAddress }, + config, + archiver, + l1TxUtils: reorgResetL1TxUtils, + stopExtras: () => publisherManager.stop(), + log: log.createChild('automine-sequencer'), + }); + + await publisherManager.start(); + return automineSequencer; +} diff --git a/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts b/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts new file mode 100644 index 000000000000..805b507adff4 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts @@ -0,0 +1,592 @@ +import type { Archiver } from '@aztec/archiver'; +import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils'; +import type { EthCheatCodes } from '@aztec/ethereum/test'; +import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import type { EthAddress } from '@aztec/foundation/eth-address'; +import { Signature } from '@aztec/foundation/eth-signature'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { SerialQueue } from '@aztec/foundation/queue'; +import { RunningPromise } from '@aztec/foundation/running-promise'; +import type { TestDateProvider } from '@aztec/foundation/timer'; +import { isErrorClass } from '@aztec/foundation/types'; +import type { P2PClient as ConcreteP2PClient, P2P } from '@aztec/p2p'; +import type { AztecAddress } from '@aztec/stdlib/aztec-address'; +import { CommitteeAttestationsAndSigners, type L2Block, type L2BlockSource } from '@aztec/stdlib/block'; +import { getPreviousCheckpointOutHashes } from '@aztec/stdlib/checkpoint'; +import type { ChainConfig } from '@aztec/stdlib/config'; +import { + type L1RollupConstants, + getEpochAtSlot, + getSlotAtTimestamp, + getTimestampForSlot, +} from '@aztec/stdlib/epoch-helpers'; +import { InsufficientValidTxsError, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; +import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import type { FailedTx, Tx } from '@aztec/stdlib/tx'; +import type { + BuildBlockInCheckpointResult, + CheckpointBuilder, + FullNodeCheckpointsBuilder, +} from '@aztec/validator-client'; + +import type { GlobalVariableBuilder } from '../../global_variable_builder/global_builder.js'; +import type { SequencerPublisherFactory } from '../../publisher/sequencer-publisher-factory.js'; +import type { SequencerPublisher } from '../../publisher/sequencer-publisher.js'; +import type { SequencerConfig } from '../config.js'; + +/** + * L1 rollup constants needed by the AutomineSequencer. Same as SequencerRollupConstants + * plus `epochDuration` for the epoch-based checkpoint out-hash lookup. + */ +export type AutomineSequencerConstants = Pick< + L1RollupConstants, + 'ethereumSlotDuration' | 'l1GenesisTime' | 'slotDuration' | 'rollupManaLimit' | 'epochDuration' +>; + +/** Dependencies for the AutomineSequencer. */ +export type AutomineSequencerDeps = { + publisherFactory: SequencerPublisherFactory; + checkpointsBuilder: FullNodeCheckpointsBuilder; + globalsBuilder: GlobalVariableBuilder; + worldState: WorldStateSynchronizer; + l2BlockSource: L2BlockSource; + l1ToL2MessageSource: L1ToL2MessageSource; + /** P2P client; must also expose `sync()` for post-rollback pool recovery. */ + p2pClient: P2P & Pick; + ethCheatCodes: EthCheatCodes; + dateProvider: TestDateProvider; + l1Constants: AutomineSequencerConstants; + coinbase: EthAddress; + feeRecipient: AztecAddress; + signatureContext: CoordinationSignatureContext; + config: SequencerConfig & Pick; + /** + * Archiver used to push locally-built blocks and proposed checkpoints into the in-memory + * store, force an immediate L1 sync after publishing, and roll back state during reorgs. + */ + archiver: Pick; + /** L1 tx utils whose cached nonces must be reset after an L1 reorg. */ + l1TxUtils: Pick[]; + /** + * Optional extra cleanup hook awaited inside {@link AutomineSequencer.stop}. Used by the + * factory to shut down the PublisherManager funding loop after the queue and poller drain. + */ + stopExtras?: () => Promise; + /** How often to poll the mempool for new txs while running. Defaults to 50ms. */ + pollIntervalMs?: number; + log?: Logger; +}; + +/** + * Minimal, deterministic, queue-driven sequencer for e2e tests that don't exercise + * block-building or consensus (e.g. e2e_token, e2e_amm, e2e_authwit). + * + * Differences from the production `Sequencer`: + * - No proposer-turn check (single sequencer). + * - No sync check, no pipelining, no validator orchestration, no attestations, + * no slashing, no votes, no P2P proposal gossip, no timetable enforcement. + * - No event emission — consumers (archiver, world-state, `EpochTestSettler`) observe + * L1 and the archiver tip rather than sequencer events. + * - All test-driven time control (warp / mine empty block) goes through a single + * serial queue alongside mempool-driven builds; the three never interleave. + * + * Requires `aztecTargetCommitteeSize == 0` on the deployed rollup so that the + * L1 `verifyProposer` / `verifyAttestations` short-circuits accept an empty + * `CommitteeAttestationsAndSigners` (see + * `l1-contracts/src/core/libraries/rollup/ValidatorSelectionLib.sol:244`). + */ +export class AutomineSequencer { + private readonly log: Logger; + private readonly queue: SerialQueue; + private readonly pollIntervalMs: number; + private readonly deps: AutomineSequencerDeps; + + private running = false; + private stopped = false; + private paused = false; + private mempoolPoller?: RunningPromise; + private publisher?: SequencerPublisher; + private attestorAddress?: EthAddress; + + /** Set while a mempool-driven build is queued but not yet run; used to coalesce. */ + private buildQueued: Promise | undefined = undefined; + + /** Last L2 slot we published a checkpoint for (-1 means none yet). */ + private lastBuiltSlot: number = -1; + + constructor(deps: AutomineSequencerDeps) { + this.deps = deps; + this.log = deps.log ?? createLogger('sequencer:automine'); + this.queue = new SerialQueue(); + this.pollIntervalMs = deps.pollIntervalMs ?? 50; + } + + /** + * Starts the sequencer. Switches anvil into automine mode (no interval mining), + * acquires a publisher, and begins polling the mempool for pending txs. + */ + public async start(): Promise { + if (this.running) { + return; + } + this.running = true; + + await this.deps.ethCheatCodes.setIntervalMining(0, { silent: true }); + await this.deps.ethCheatCodes.setAutomine(true, { silent: true }); + + const { publisher, attestorAddress } = await this.deps.publisherFactory.create(); + this.publisher = publisher; + this.attestorAddress = attestorAddress; + this.log.info(`AutomineSequencer started`, { + publisher: this.publisher.getSenderAddress().toString(), + attestor: this.attestorAddress.toString(), + }); + + this.queue.start(); + + // Fallback poller that triggers a build if we discover pending txs without an explicit + // notification. Tests can also call `buildIfPending()` directly to skip the poll wait. + this.mempoolPoller = new RunningPromise(() => this.maybeEnqueueBuild(), this.log, this.pollIntervalMs); + this.mempoolPoller.start(); + } + + /** + * Stops the sequencer. Drains the queue, unsubscribes the mempool poller, and runs any + * registered {@link AutomineSequencerDeps.stopExtras} hook (e.g. the PublisherManager's + * funding loop). Idempotent: subsequent calls return without re-running cleanup. + */ + public async stop(): Promise { + if (this.stopped) { + return; + } + this.stopped = true; + this.running = false; + await this.mempoolPoller?.stop(); + await this.queue.end(); + await this.deps.stopExtras?.(); + this.log.info('AutomineSequencer stopped'); + } + + /** + * Enqueues a mempool-driven build. Coalesces consecutive calls so a burst of new txs + * collapses into one build job. Returns the built block (or undefined if nothing was built + * or the sequencer is paused). + */ + public buildIfPending(): Promise { + if (!this.running || this.paused) { + return Promise.resolve(undefined); + } + if (this.buildQueued) { + // A build is already queued; coalesce. The pending build will pick up the new txs. + return this.buildQueued; + } + this.buildQueued = this.queue.put(async () => { + try { + return await this.runBuild({ allowEmpty: false }); + } finally { + this.buildQueued = undefined; + } + }); + return this.buildQueued; + } + + /** + * Pauses mempool-driven block production. Pending txs accumulate in the pool without being + * mined. Explicit test-harness operations (`buildEmptyBlock`, `warpTo`, `revertToCheckpoint`) + * continue to work; this only gates the mempool poller and `buildIfPending`. + */ + public pause(): void { + if (this.paused) { + return; + } + this.paused = true; + this.log.info('AutomineSequencer paused'); + } + + /** Resumes mempool-driven block production after a previous {@link pause}. */ + public resume(): void { + if (!this.paused) { + return; + } + this.paused = false; + this.log.info('AutomineSequencer resumed'); + } + + /** + * Updates the in-memory sequencer config. Mirrors {@link SequencerClient.updateConfig} so that + * `AztecNode.setConfig` (e.g. tests bumping `minTxsPerBlock` to bundle multiple txs into one + * block) propagates to the AutomineSequencer's gating logic in {@link runBuild}. + */ + public updateConfig(config: Partial): void { + Object.assign(this.deps.config, config); + } + + /** Returns a snapshot of the current sequencer config (used by pause/resume bookkeeping). */ + public getConfig(): SequencerConfig { + return this.deps.config; + } + + /** Enqueues an empty-block build. Resolves to the built block. */ + public buildEmptyBlock(): Promise { + return this.queue.put(async () => { + const block = await this.runBuild({ allowEmpty: true }); + if (!block) { + throw new Error('buildEmptyBlock: runBuild returned undefined'); + } + return block; + }); + } + + /** + * Warps L1 timestamp to `targetTimestampSec`. Rounded up to the next aztec-slot + * boundary so the next build lands on a fresh slot. Atomic with respect to builds — + * the queue ensures no build is in flight while the warp executes. + */ + public warpTo(targetTimestampSec: number): Promise { + return this.queue.put(() => this.runWarp(targetTimestampSec)); + } + + /** Warps L1 timestamp forward by `deltaSec` seconds from the current L1 time. */ + public warpBy(deltaSec: number): Promise { + return this.queue.put(async () => { + const current = await this.deps.ethCheatCodes.lastBlockTimestamp(); + await this.runWarp(current + deltaSec); + }); + } + + /** + * Reorgs L1 so that every L1 block strictly after the one that published + * `targetCheckpoint` is removed. The archiver, world-state, and date provider + * are all brought back in sync before the promise resolves. + * + * Runs inside the serial queue so it never interleaves with a build or warp. + */ + public revertToCheckpoint(targetCheckpoint: number): Promise { + return this.queue.put(() => this.runRevert(targetCheckpoint)); + } + + /** Awaits the queue draining to a fully idle state. */ + public syncPoint(): Promise { + return this.queue.syncPoint(); + } + + /** Called from the mempool poller. Enqueues a build if there are pending txs. */ + private async maybeEnqueueBuild(): Promise { + if (!this.running || this.paused || this.buildQueued) { + return; + } + try { + const pending = await this.deps.p2pClient.getPendingTxCount(); + if (pending > 0) { + // Fire-and-forget; the build result is delivered via `buildIfPending()` callers, + // not via the poller. + void this.buildIfPending().catch(err => { + this.log.error('Mempool-driven build failed', err); + }); + } + } catch (err) { + this.log.warn('Failed to poll mempool', { err: err instanceof Error ? err.message : String(err) }); + } + } + + /** Builds one checkpoint with a single block, publishes it, syncs the date provider. */ + private async runBuild({ allowEmpty }: { allowEmpty: boolean }): Promise { + if (!this.running || !this.publisher || !this.attestorAddress) { + return undefined; + } + + const txCount = await this.deps.p2pClient.getPendingTxCount(); + // For mempool-driven builds, wait for at least `minTxsPerBlock` pending txs (or 1 if not set) + // before building. This mirrors the production sequencer's `waitForMinTxs` behavior, and is + // required for tests that bundle multiple txs into one block via `setConfig({ minTxsPerBlock })`. + // Explicit empty-block / warp paths pass `allowEmpty: true` and bypass this gate. + const minRequired = allowEmpty ? 0 : Math.max(this.deps.config.minTxsPerBlock ?? 1, 1); + if (txCount < minRequired) { + return undefined; + } + + // Decide target slot from the pending block's timestamp — picks up any prior + // `setNextBlockTimestamp` call (e.g. queued by runWarp) instead of assuming +1 over + // the last mined block. + const pendingBlockTs = await this.deps.ethCheatCodes.nextBlockTimestamp(); + let targetSlot = Number(getSlotAtTimestamp(BigInt(pendingBlockTs), this.deps.l1Constants)); + if (targetSlot <= this.lastBuiltSlot) { + // Pending block doesn't reach a new slot yet; advance to the next slot we own. + targetSlot = this.lastBuiltSlot + 1; + } + const slotBoundaryTs = Number(getTimestampForSlot(SlotNumber(targetSlot), this.deps.l1Constants)); + + // Pre-set anvil's next block timestamp only if the slot boundary is past what's already + // scheduled. setNextBlockTimestamp rejects values not strictly greater than the last block's + // timestamp, and pendingBlockTs is always > lastBlockTimestamp, so this guard is sufficient. + if (slotBoundaryTs > pendingBlockTs) { + await this.deps.ethCheatCodes.setNextBlockTimestamp(slotBoundaryTs); + } + + const tips = await this.deps.l2BlockSource.getL2Tips(); + const syncedToBlockNumber = tips.proposed.number; + + // Ensure world state has processed the archiver's tip before forking. Without this, + // world state may still be at the previous block (since it syncs asynchronously from + // the archiver), and `fork(syncedToBlockNumber)` would fail with + // "Unable to initialize from future block". + await this.deps.worldState.syncImmediate(BlockNumber(syncedToBlockNumber)); + + const nextBlockNumber = BlockNumber(syncedToBlockNumber + 1); + const checkpointNumber = CheckpointNumber(tips.proposedCheckpoint.checkpoint.number + 1); + const targetEpoch = getEpochAtSlot(SlotNumber(targetSlot), this.deps.l1Constants); + + this.log.verbose(`Building automine checkpoint`, { + checkpointNumber, + blockNumber: nextBlockNumber, + slot: targetSlot, + slotTimestamp: slotBoundaryTs, + txCount, + allowEmpty, + }); + + const checkpointGlobals = await this.deps.globalsBuilder.buildCheckpointGlobalVariables( + this.deps.coinbase, + this.deps.feeRecipient, + SlotNumber(targetSlot), + ); + + const l1ToL2Messages = await this.deps.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber); + + const previousCheckpointOutHashes = await getPreviousCheckpointOutHashes({ + blockSource: this.deps.l2BlockSource, + epoch: targetEpoch, + checkpointNumber, + l1Constants: this.deps.l1Constants, + pipeliningEnabled: false, + log: this.log, + }); + + const feeAssetPriceModifier = await this.publisher.getFeeAssetPriceModifier(); + + await using fork = await this.deps.worldState.fork(syncedToBlockNumber, { closeDelayMs: 0 }); + + const checkpointBuilder = await this.deps.checkpointsBuilder.startCheckpoint( + checkpointNumber, + checkpointGlobals, + feeAssetPriceModifier, + l1ToL2Messages, + previousCheckpointOutHashes, + fork, + this.log.getBindings(), + ); + + const pendingTxs = this.deps.p2pClient.iterateEligiblePendingTxs(); + + const buildResult = await this.tryBuildBlock( + checkpointBuilder, + pendingTxs, + nextBlockNumber, + checkpointGlobals.timestamp, + allowEmpty, + checkpointNumber, + ); + if (!buildResult) { + return undefined; + } + + const checkpoint = await checkpointBuilder.completeCheckpoint(); + + // Empty CommitteeAttestationsAndSigners is accepted on-chain when committee size is 0. + const emptyAttestations = CommitteeAttestationsAndSigners.empty(this.deps.signatureContext); + const emptyAttestationsSignature = Signature.empty(); + + // Push the block and proposed checkpoint into the archiver locally BEFORE publishing to L1. + // This avoids racing the archiver's L1 polling: if the L1 publish happened first, polling + // could surface the checkpoint and reject our subsequent local push as duplicate. Pushing + // first means the archiver already has the proposed entry when L1 polling fires; the L1 + // sync path then promotes the existing proposed checkpoint via promoteProposedToCheckpointed + // rather than re-adding it. + await this.deps.archiver.addBlock(buildResult.block); + await this.deps.archiver.addProposedCheckpoint({ + header: checkpoint.header, + checkpointNumber, + startBlock: BlockNumber(buildResult.block.number), + blockCount: 1, + totalManaUsed: checkpoint.header.totalManaUsed.toBigInt(), + feeAssetPriceModifier, + }); + + await this.publisher.enqueueProposeCheckpoint(checkpoint, emptyAttestations, emptyAttestationsSignature); + const result = await this.publisher.sendRequests(SlotNumber(targetSlot)); + + const successful = result?.successfulActions?.find(a => a === 'propose'); + if (!successful) { + this.log.error('Propose action did not succeed under automine', { + slot: targetSlot, + checkpointNumber, + successful: result?.successfulActions, + failed: result?.failedActions, + }); + throw new Error(`AutomineSequencer: propose did not succeed for slot ${targetSlot}`); + } + + // Force one full L1-sync cycle synchronously. The local addBlock/addProposedCheckpoint + // above advances the proposed tip, but tips.checkpointed and the L1->L2 inbox tree state + // only advance when the archiver observes the L1-confirmed checkpoint via its sync loop. + await this.deps.archiver.syncImmediate(); + + // Sync the date provider to the L1 block timestamp we just mined. + const newL1Ts = await this.deps.ethCheatCodes.lastBlockTimestamp(); + this.deps.dateProvider.setTime(newL1Ts * 1000); + + this.lastBuiltSlot = targetSlot; + + this.log.verbose(`Automine checkpoint published`, { + checkpointNumber, + blockNumber: nextBlockNumber, + slot: targetSlot, + l1Timestamp: newL1Ts, + txCount: buildResult.numTxs, + }); + + return buildResult.block; + } + + /** + * Warps L1 timestamp to (or past) `targetTimestampSec`, rounded up to the next aztec-slot + * boundary, by queuing an empty-checkpoint build at that slot. Mines exactly one L1 block + * (the propose tx auto-mined under anvil's automine mode), with the timestamp pre-set so + * the mined block lands on the slot boundary. + */ + private async runWarp(targetTimestampSec: number): Promise { + const currentL1Ts = await this.deps.ethCheatCodes.lastBlockTimestamp(); + if (targetTimestampSec <= currentL1Ts) { + this.log.debug(`Warp target ${targetTimestampSec} is not in the future of current L1 ts ${currentL1Ts}`); + return; + } + + // Round up to the next aztec-slot boundary so the next build naturally lands on a new slot. + const targetSlot = Number(getSlotAtTimestamp(BigInt(targetTimestampSec), this.deps.l1Constants)); + const slotBoundaryTs = Number(getTimestampForSlot(SlotNumber(targetSlot + 1), this.deps.l1Constants)); + + // Queue the next L1 block at the slot boundary timestamp, then build (and publish) an + // empty L2 checkpoint. The propose tx auto-mines a single L1 block at slotBoundaryTs, + // and `runBuild` syncs the date provider to the new L1 timestamp. + await this.deps.ethCheatCodes.setNextBlockTimestamp(slotBoundaryTs); + await this.runBuild({ allowEmpty: true }); + + this.log.verbose(`Warped L1 to slot boundary`, { slot: targetSlot + 1, timestamp: slotBoundaryTs }); + } + + /** + * Rolls L1 back to the block that published `targetCheckpoint`, drops the archiver's + * in-memory state to match, and resets internal slot bookkeeping. + */ + private async runRevert(targetCheckpoint: number): Promise { + const checkpointData = await this.deps.l2BlockSource.getCheckpointData({ + number: CheckpointNumber(targetCheckpoint), + }); + if (!checkpointData) { + throw new Error(`AutomineSequencer: checkpoint ${targetCheckpoint} not found in archiver`); + } + + const targetL1Block = Number(checkpointData.l1.blockNumber); + this.log.verbose(`Reverting to checkpoint ${targetCheckpoint}`, { + targetCheckpoint, + targetL1Block, + checkpointSlot: checkpointData.header.slotNumber, + }); + + // Roll the archiver back to the last block of targetCheckpoint before the L1 reorg, + // since the archiver needs to fetch the target checkpoint's L1 block hash during rollback. + const lastBlockInCheckpoint = BlockNumber(checkpointData.startBlock + checkpointData.blockCount - 1); + await this.deps.archiver.rollbackTo(lastBlockInCheckpoint); + + // Force the P2P block stream to run one cycle immediately so it processes the + // chain-pruned event triggered by the archiver rollback above. Without this, the + // P2P pool may not have restored rolled-back txs to pending by the time the next + // build runs. + await this.deps.p2pClient.sync(); + + // Force world-state to process the archiver's prune event immediately, so the next build + // doesn't try to insert nullifiers that were already in the pruned checkpoints. + await this.deps.worldState.syncImmediate(); + + // Remove all L1 blocks strictly after the target checkpoint's publish block so that + // the propose txs for later checkpoints are gone from L1. We use reorg(depth) directly + // to keep targetL1Block itself as the new chain tip. + const currentL1Block = await this.deps.ethCheatCodes.publicClient.getBlockNumber(); + const depth = Number(currentL1Block) - targetL1Block; + if (depth > 0) { + await this.deps.ethCheatCodes.reorg(depth); + } + + // anvil_rollback re-queues the rolled-back txs into the mempool. Clear them so they + // don't get re-mined, then reset the publisher nonce tracker so the next propose tx + // uses the correct nonce for the post-reorg chain state. + await this.deps.ethCheatCodes.rpcCall('anvil_dropAllTransactions', []); + this.deps.l1TxUtils.forEach(utils => utils.resetNonce()); + + // Reset slot bookkeeping so the next build picks up at the correct slot. + this.lastBuiltSlot = Number(checkpointData.header.slotNumber); + + this.log.verbose(`Reverted to checkpoint ${targetCheckpoint}`, { + targetCheckpoint, + targetL1Block, + }); + } + + /** + * Wraps `checkpointBuilder.buildBlock` with the failed-tx handling shared by both error + * and success paths: drops the failed txs from the P2P mempool, and returns `undefined` + * when `InsufficientValidTxsError` aborts the build (so the caller skips publishing). + */ + private async tryBuildBlock( + checkpointBuilder: CheckpointBuilder, + pendingTxs: AsyncIterableIterator, + nextBlockNumber: BlockNumber, + timestamp: bigint, + allowEmpty: boolean, + checkpointNumber: CheckpointNumber, + ): Promise { + let buildResult: BuildBlockInCheckpointResult; + try { + buildResult = await checkpointBuilder.buildBlock(pendingTxs, nextBlockNumber, timestamp, { + maxTransactions: this.deps.config.maxTxsPerBlock, + // Allow empty for explicit-empty builds; require at least 1 valid tx otherwise. + minValidTxs: allowEmpty ? 0 : 1, + isBuildingProposal: true, + maxBlocksPerCheckpoint: 1, + perBlockAllocationMultiplier: 1, + }); + } catch (err) { + // Mirrors production's checkpoint_proposal_job: if every pending tx failed execution and + // we didn't reach minValidTxs, drop the failed txs from the mempool so they don't block + // the poller forever, then abort this build with no checkpoint published. + if (isErrorClass(err, InsufficientValidTxsError)) { + await this.dropFailedTxsFromP2P(err.failedTxs); + this.log.verbose(`AutomineSequencer: insufficient valid txs, skipping build`, { + checkpointNumber, + processedCount: err.processedCount, + minRequired: err.minRequired, + failedCount: err.failedTxs.length, + }); + return undefined; + } + throw err; + } + + // Drop any txs that failed execution but didn't trigger InsufficientValidTxsError, so we + // don't re-pick them up on the next build. + await this.dropFailedTxsFromP2P(buildResult.failedTxs); + + return buildResult; + } + + /** Removes txs that failed execution from the P2P mempool so they don't get retried. */ + private async dropFailedTxsFromP2P(failedTxs: FailedTx[]): Promise { + if (failedTxs.length === 0) { + return; + } + const failedTxHashes = failedTxs.map(fail => fail.tx.getTxHash()); + this.log.verbose(`Dropping failed txs ${failedTxHashes.join(', ')}`); + await this.deps.p2pClient.handleFailedExecution(failedTxHashes); + } +} diff --git a/yarn-project/sequencer-client/src/sequencer/chain_state_overrides.ts b/yarn-project/sequencer-client/src/sequencer/chain_state_overrides.ts index 412f1562d461..60c588faa974 100644 --- a/yarn-project/sequencer-client/src/sequencer/chain_state_overrides.ts +++ b/yarn-project/sequencer-client/src/sequencer/chain_state_overrides.ts @@ -1,135 +1,162 @@ import { RollupContract, SimulationOverridesBuilder, type SimulationOverridesPlan } from '@aztec/ethereum/contracts'; import { CheckpointNumber } from '@aztec/foundation/branded-types'; -import type { Fr } from '@aztec/foundation/curves/bn254'; import type { Logger } from '@aztec/foundation/log'; -import { computeCheckpointPayloadDigest } from '@aztec/stdlib/checkpoint'; -import type { ProposedCheckpointData } from '@aztec/stdlib/checkpoint'; +import { type ProposedCheckpointData, computeCheckpointPayloadDigest } from '@aztec/stdlib/checkpoint'; import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; -type PipelinedParentSimulationOverridesPlanInput = { - checkpointNumber: CheckpointNumber; - proposedCheckpointData?: ProposedCheckpointData; +type CheckpointSimulationOverridesPlanInput = { + /** Target rollup contract. */ rollup: RollupContract; - signatureContext: CoordinationSignatureContext; + /** Checkpoint number to be proposed. */ + checkpointNumber: CheckpointNumber; + /** Logger instance. */ log: Logger; /** - * Whether proposer pipelining is enabled. Controls only the parent pending/fee-header - * portion of the plan — the proven override below is independent of pipelining because - * the boundary build needs it for globals and enqueue-time validation regardless. + * The proposed parent checkpoint when pipelining. Its `checkpointNumber` must equal + * `checkpointNumber - 1`; the helper enforces this. Mutually exclusive with + * `invalidateToPendingCheckpointNumber`. + */ + proposedCheckpointData?: ProposedCheckpointData; + /** + * The pending checkpoint number we'll end up at after invalidation lands. Mutually exclusive + * with `proposedCheckpointData`. */ - pipeliningEnabled: boolean; - /** If set, also overrides `tips.proven` so `canPruneAtTime` returns false at the simulation timestamp. */ - prunePending?: { provenOverride: CheckpointNumber }; -}; - -type SubmissionSimulationOverridesPlanInput = { - pipelinedParentPlan?: SimulationOverridesPlan; invalidateToPendingCheckpointNumber?: CheckpointNumber; - lastArchiveRoot: Fr; - pipeliningEnabled: boolean; + /** + * The real on-chain pending checkpoint number (typically `syncedTo.checkpointedCheckpointNumber`). + * Used as the snapshot we pin both `pending` and `proven` to avoid prunes in simulation. + */ + checkpointedCheckpointNumber: CheckpointNumber; + /** + * Chain-level consensus signature context. Used to recompute the parent's `payloadDigest` for the + * pipelined simulation override so it matches what `propose` will write into `tempCheckpointLogs[parent]` + * once the parent lands. + */ + signatureContext: CoordinationSignatureContext; }; /** - * Builds the simulated chain view used while constructing a checkpoint proposal. May carry: - * - A pending parent override + fee header (only when pipelining is enabled). - * - A proven override (whenever `prunePending` is set, even with pipelining off — the boundary - * build needs it for the globals builder's mana-min-fee lookup and the enqueue-time - * submission simulation regardless of pipelining). + * Builds the SimulationOverridesPlan describing the simulated L1 rollup state for a checkpoint's + * enqueue-time simulations: `canProposeAt` (in Sequencer.doWork) and the propose-related sims + * (validateBlockHeader, simulateProposeTx). The plan reflects "as if our pipelined parent + * checkpoint has landed and any required invalidation has executed" — the gap that needs to be + * bridged at enqueue time. + * + * Pipelining (`proposedCheckpointData`) and invalidation (`invalidateToPendingCheckpointNumber`) + * are mutually exclusive; passing both throws. */ -export async function buildPipelinedParentSimulationOverridesPlan( - input: PipelinedParentSimulationOverridesPlanInput, +export async function buildCheckpointSimulationOverridesPlan( + input: CheckpointSimulationOverridesPlanInput, ): Promise { - const builder = new SimulationOverridesBuilder(); - - if (input.pipeliningEnabled) { - const parentCheckpointNumber = CheckpointNumber(input.checkpointNumber - 1); - builder.withChainTips({ pending: parentCheckpointNumber }); - - if (input.proposedCheckpointData) { - const { header, archive, checkpointOutHash, feeAssetPriceModifier } = input.proposedCheckpointData; - builder.withPendingArchive(archive.root).withPendingTempCheckpointLogFields({ - headerHash: header.hash(), - outHash: checkpointOutHash, - slotNumber: header.slotNumber, - payloadDigest: computeCheckpointPayloadDigest({ - header, - archiveRoot: archive.root, - feeAssetPriceModifier, - signatureContext: input.signatureContext, - }), - }); - } - - const pendingFeeHeader = await computePipelinedParentFeeHeader(input); - if (pendingFeeHeader) { - builder.withPendingFeeHeader(pendingFeeHeader); - } + if (input.proposedCheckpointData && input.invalidateToPendingCheckpointNumber !== undefined) { + throw new Error( + 'Error in buildCheckpointSimulationOverridesPlan: proposedCheckpointData and invalidateToPendingCheckpointNumber are mutually exclusive', + ); } - if (input.prunePending) { - builder.withChainTips({ proven: input.prunePending.provenOverride }); + const builder = new SimulationOverridesBuilder(); + const pendingCheckpointNumber = derivePendingCheckpointNumber(input); + + // Override the latest checkpoint number when invalidating or pipelining, so our checkpoint + // follows from it. We also override the proven chain tip so we dont need to worry about + // prunes kicking in that would break out simulation if there's a prune pending. We always + // assume that a proof will land in time. If we don't have a pending checkpoint number to force, + // we still set both tips to the current checkpoint number to avoid the prune trigger. + const overridenChainTip = pendingCheckpointNumber ?? input.checkpointedCheckpointNumber; + builder.withChainTips({ pending: overridenChainTip, proven: overridenChainTip }); + + if (input.proposedCheckpointData) { + const { header, archive, checkpointOutHash, feeAssetPriceModifier } = input.proposedCheckpointData; + builder.withPendingArchive(archive.root); + // Override every locally-derivable `tempCheckpointLogs[parent]` field that L1 will eventually + // write. `slotNumber` is load-bearing for `STFLib.canPruneAtTime`: without it the cell reads + // slotNumber 0, the contract treats the pending tip as belonging to an expired epoch, and + // `getEffectivePendingCheckpointNumber` silently collapses pending back to proven — producing + // a spurious `Rollup__InvalidArchive` against the on-chain genesis archive. The other fields + // (headerHash, outHash, payloadDigest) are not strictly load-bearing for `canProposeAt` / + // `validateBlockHeader`, but mirroring the full cell keeps the simulation byte-faithful with + // what the actual `propose()` send will observe, which is a defense against future reads + // taking dependencies on them. + builder.withPendingTempCheckpointLogFields({ + headerHash: header.hash(), + outHash: checkpointOutHash, + slotNumber: header.slotNumber, + payloadDigest: computeCheckpointPayloadDigest({ + header, + archiveRoot: archive.root, + feeAssetPriceModifier, + signatureContext: input.signatureContext, + }), + }); + + const feeHeader = await computePipelinedParentFeeHeader({ + checkpointNumber: input.checkpointNumber, + proposedCheckpointData: input.proposedCheckpointData, + rollup: input.rollup, + log: input.log, + }); + if (feeHeader) { + builder.withPendingFeeHeader(feeHeader); + } } return builder.build(); } -/** Builds the simulated chain view used when validating and enqueueing checkpoint submission. */ -export function buildSubmissionSimulationOverridesPlan( - input: SubmissionSimulationOverridesPlanInput, -): SimulationOverridesPlan | undefined { - const pendingCheckpointNumber = - input.invalidateToPendingCheckpointNumber ?? input.pipelinedParentPlan?.chainTipsOverride?.pending; - - const builder = SimulationOverridesBuilder.from(input.pipelinedParentPlan); - if (pendingCheckpointNumber !== undefined) { - builder.withChainTips({ pending: pendingCheckpointNumber }); +function derivePendingCheckpointNumber(input: CheckpointSimulationOverridesPlanInput): CheckpointNumber | undefined { + if (input.invalidateToPendingCheckpointNumber !== undefined) { + return input.invalidateToPendingCheckpointNumber; } - - if (input.pipeliningEnabled && pendingCheckpointNumber !== undefined) { - builder.withPendingArchive(input.lastArchiveRoot); + if (!input.proposedCheckpointData) { + return undefined; } - - return builder.build(); + if (input.checkpointNumber < 1) { + throw new Error(`Cannot build simulation override for checkpoint ${input.checkpointNumber}: no parent exists`); + } + const expectedParent = CheckpointNumber(input.checkpointNumber - 1); + if (input.proposedCheckpointData.checkpointNumber !== expectedParent) { + throw new Error( + `Cannot build simulation override for checkpoint ${input.checkpointNumber}: proposedCheckpointData.checkpointNumber (${input.proposedCheckpointData.checkpointNumber}) does not match expected parent ${expectedParent}`, + ); + } + return expectedParent; } type PipelinedParentFeeHeaderInput = { checkpointNumber: CheckpointNumber; - proposedCheckpointData?: ProposedCheckpointData; + proposedCheckpointData: ProposedCheckpointData; rollup: RollupContract; log: Logger; }; -/** Derives the pending parent fee header used during pipelined proposal simulation. */ +/** + * Derives the pending parent fee header used during pipelined proposal simulation. Returns + * `undefined` only when no grandparent exists (i.e. the proposed parent is the genesis + * checkpoint); all other failure modes (missing grandparent state, missing fee header, RPC + * errors) throw so callers don't silently desync the fee-header override. + */ export async function computePipelinedParentFeeHeader(input: PipelinedParentFeeHeaderInput) { - if (!input.proposedCheckpointData || input.checkpointNumber < 2) { + if (input.checkpointNumber < 2) { return undefined; } const grandparentCheckpointNumber = CheckpointNumber(input.checkpointNumber - 2); - try { - const [grandparentCheckpoint, manaTarget] = await Promise.all([ - input.rollup.getCheckpoint(grandparentCheckpointNumber), - input.rollup.getManaTarget(), - ]); + const [grandparentCheckpoint, manaTarget] = await Promise.all([ + input.rollup.getCheckpoint(grandparentCheckpointNumber), + input.rollup.getManaTarget(), + ]); - if (!grandparentCheckpoint?.feeHeader) { - input.log.error( - `Grandparent checkpoint or feeHeader missing for checkpoint ${grandparentCheckpointNumber.toString()}`, - ); - return undefined; - } - - return RollupContract.computeChildFeeHeader( - grandparentCheckpoint.feeHeader, - input.proposedCheckpointData.totalManaUsed, - input.proposedCheckpointData.feeAssetPriceModifier, - manaTarget, - ); - } catch (err) { - input.log.error( - `Failed to derive pipelined parent fee header for checkpoint ${grandparentCheckpointNumber.toString()}: ${err}`, + if (!grandparentCheckpoint?.feeHeader) { + throw new Error( + `Grandparent checkpoint or feeHeader missing for checkpoint ${grandparentCheckpointNumber.toString()}`, ); - return undefined; } + + return RollupContract.computeChildFeeHeader( + grandparentCheckpoint.feeHeader, + input.proposedCheckpointData.totalManaUsed, + input.proposedCheckpointData.feeAssetPriceModifier, + manaTarget, + ); } diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts index 83345c8eef76..8661d7c0850b 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts @@ -69,10 +69,7 @@ import { mockTxIterator, setupTxsAndBlock, } from '../test/utils.js'; -import { - buildPipelinedParentSimulationOverridesPlan, - computePipelinedParentFeeHeader, -} from './chain_state_overrides.js'; +import { buildCheckpointSimulationOverridesPlan, computePipelinedParentFeeHeader } from './chain_state_overrides.js'; import { CheckpointProposalJob } from './checkpoint_proposal_job.js'; import type { CheckpointProposalJobMetricsRecorder } from './checkpoint_proposal_job_metrics.js'; import type { SequencerEvents } from './events.js'; @@ -188,8 +185,15 @@ describe('CheckpointProposalJob', () => { publisher.enqueueProposeCheckpoint.mockResolvedValue(undefined); publisher.enqueueGovernanceCastSignal.mockResolvedValue(true); publisher.enqueueSlashingActions.mockResolvedValue(true); + + // Default rollup contract reads used by pipelined fee-header derivation. Tests that exercise + // the failure modes override these via jest.spyOn. + jest.spyOn(publisher.rollupContract, 'getCheckpoint').mockResolvedValue({ + feeHeader: { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 1n, congestionCost: 0n, proverCost: 0n }, + } as any); + jest.spyOn(publisher.rollupContract, 'getManaTarget').mockResolvedValue(10_000n); publisher.sendRequestsAt.mockResolvedValue({ - result: { receipt: { status: 'success' } as TransactionReceipt, errorMsg: undefined }, + result: { receipt: { status: 'success' } as TransactionReceipt }, successfulActions: ['propose'], failedActions: [], sentActions: ['propose'], @@ -369,6 +373,8 @@ describe('CheckpointProposalJob', () => { checkpointBuilder.seedBlocks([block], [txs]); validatorClient.collectAttestations.mockResolvedValue(getAttestations(block)); epochCache.isProposerPipeliningEnabled.mockReturnValue(true); + // We build checkpoint 2 on top of proposed parent at checkpoint 1. + checkpointNumber = CheckpointNumber(2); const checkpoint = await createCheckpointProposalJob({ targetSlot: SlotNumber(newSlotNumber + 1), @@ -772,6 +778,7 @@ describe('CheckpointProposalJob', () => { overrides?.targetEpoch ?? epoch, checkpointNumber, lastBlockNumber, + CheckpointNumber(checkpointNumber - 1), proposer, publisher, attestorAddress, @@ -824,10 +831,10 @@ describe('CheckpointProposalJob', () => { proverCost: 10n, }; - it('returns undefined when proposedCheckpointData is not set', async () => { + it('returns undefined when checkpoint number is below 2 (genesis grandparent)', async () => { const result = await computePipelinedParentFeeHeader({ - checkpointNumber: pipelinedCheckpointNumber, - proposedCheckpointData: undefined, + checkpointNumber: CheckpointNumber(1), + proposedCheckpointData: pendingData, rollup: publisher.rollupContract, log: createLogger('test'), }); @@ -863,152 +870,155 @@ describe('CheckpointProposalJob', () => { expect(result).toEqual(expected); }); - it('returns undefined when grandparent checkpoint is not found', async () => { + it('throws when grandparent checkpoint is not found', async () => { mockRollup({ grandparentCheckpoint: undefined }); - const result = await computePipelinedParentFeeHeader({ - checkpointNumber: pipelinedCheckpointNumber, - proposedCheckpointData: pendingData, - rollup: publisher.rollupContract, - log: createLogger('test'), - }); - expect(result).toBeUndefined(); + await expect( + computePipelinedParentFeeHeader({ + checkpointNumber: pipelinedCheckpointNumber, + proposedCheckpointData: pendingData, + rollup: publisher.rollupContract, + log: createLogger('test'), + }), + ).rejects.toThrow(/Grandparent checkpoint or feeHeader missing/); }); - it('returns undefined when grandparent checkpoint has no feeHeader', async () => { + it('throws when grandparent checkpoint has no feeHeader', async () => { mockRollup({ grandparentCheckpoint: { feeHeader: undefined } }); - const result = await computePipelinedParentFeeHeader({ - checkpointNumber: pipelinedCheckpointNumber, - proposedCheckpointData: pendingData, - rollup: publisher.rollupContract, - log: createLogger('test'), - }); - expect(result).toBeUndefined(); + await expect( + computePipelinedParentFeeHeader({ + checkpointNumber: pipelinedCheckpointNumber, + proposedCheckpointData: pendingData, + rollup: publisher.rollupContract, + log: createLogger('test'), + }), + ).rejects.toThrow(/Grandparent checkpoint or feeHeader missing/); }); - it('returns undefined when rollup calls throw', async () => { + it('propagates errors from rollup calls', async () => { jest.spyOn(publisher.rollupContract, 'getCheckpoint').mockRejectedValue(new Error('rpc error')); - const result = await computePipelinedParentFeeHeader({ - checkpointNumber: pipelinedCheckpointNumber, - proposedCheckpointData: pendingData, - rollup: publisher.rollupContract, - log: createLogger('test'), - }); - expect(result).toBeUndefined(); + await expect( + computePipelinedParentFeeHeader({ + checkpointNumber: pipelinedCheckpointNumber, + proposedCheckpointData: pendingData, + rollup: publisher.rollupContract, + log: createLogger('test'), + }), + ).rejects.toThrow(/rpc error/); }); }); - describe('buildPipelinedParentSimulationOverridesPlan', () => { + describe('buildCheckpointSimulationOverridesPlan', () => { const checkpointNumberUnderTest = CheckpointNumber(2); - it('sets pending override for the parent checkpoint when pipelining is enabled', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ - checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, - rollup: publisher.rollupContract, - signatureContext, - log: createLogger('test'), - pipeliningEnabled: true, - }); - expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); - expect(plan?.chainTipsOverride?.proven).toBeUndefined(); - }); + const grandparentFeeHeader: FeeHeader = { + manaUsed: 3000n, + excessMana: 1000n, + ethPerFeeAsset: 500n, + congestionCost: 50n, + proverCost: 10n, + }; - it('returns undefined when pipelining off and no prunePending', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ - checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, - rollup: publisher.rollupContract, - signatureContext, - log: createLogger('test'), - pipeliningEnabled: false, - }); - expect(plan).toBeUndefined(); - }); + function mockGrandparentFeeHeader() { + jest + .spyOn(publisher.rollupContract, 'getCheckpoint') + .mockResolvedValue({ feeHeader: grandparentFeeHeader } as any); + jest.spyOn(publisher.rollupContract, 'getManaTarget').mockResolvedValue(10_000n); + } - it('returns plan with proven-only override when pipelining off and prunePending is set', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ - checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, - rollup: publisher.rollupContract, - signatureContext, - log: createLogger('test'), - pipeliningEnabled: false, - prunePending: { provenOverride: CheckpointNumber(0) }, - }); - expect(plan?.chainTipsOverride?.pending).toBeUndefined(); - expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(0)); - }); + function makeProposedParent(checkpointNumber: CheckpointNumber): ProposedCheckpointData { + return { + checkpointNumber, + header: CheckpointHeader.empty(), + archive: new AppendOnlyTreeSnapshot(Fr.random(), 1), + checkpointOutHash: Fr.random(), + startBlock: BlockNumber(1), + blockCount: 1, + totalManaUsed: 5000n, + feeAssetPriceModifier: 100n, + }; + } - it('attaches both parent and proven overrides when pipelining on and prunePending is set', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ + it('pins both pending and proven to the snapshot when no proposed/invalidate input is provided', async () => { + const plan = await buildCheckpointSimulationOverridesPlan({ checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, + checkpointedCheckpointNumber: CheckpointNumber(4), rollup: publisher.rollupContract, signatureContext, log: createLogger('test'), - pipeliningEnabled: true, - prunePending: { provenOverride: CheckpointNumber(0) }, }); - expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); - expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(0)); + expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(4)); + expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(4)); + expect(plan?.pendingCheckpointState).toBeUndefined(); }); - it('populates the per-checkpoint state from proposedCheckpointData when pipelining is enabled', async () => { - const proposedHeader = CheckpointHeader.empty({ slotNumber: SlotNumber(123) }); - const proposedArchive = new AppendOnlyTreeSnapshot(Fr.random(), 1); - const proposedOutHash = Fr.random(); - const proposedFeeHeader: FeeHeader = { - manaUsed: 3000n, - excessMana: 1000n, - ethPerFeeAsset: 500n, - congestionCost: 50n, - proverCost: 10n, - }; - jest.spyOn(publisher.rollupContract, 'getCheckpoint').mockResolvedValue({ feeHeader: proposedFeeHeader } as any); - jest.spyOn(publisher.rollupContract, 'getManaTarget').mockResolvedValue(10_000n); - - const proposedData: ProposedCheckpointData = { - checkpointNumber: CheckpointNumber(1), - header: proposedHeader, - archive: proposedArchive, - checkpointOutHash: proposedOutHash, - startBlock: BlockNumber(1), - blockCount: 1, - totalManaUsed: 5000n, - feeAssetPriceModifier: 100n, - }; + it('overrides the full pending checkpoint cell from a pipelined parent', async () => { + mockGrandparentFeeHeader(); + const proposedData = makeProposedParent(CheckpointNumber(1)); - const plan = await buildPipelinedParentSimulationOverridesPlan({ - checkpointNumber: CheckpointNumber(2), + const plan = await buildCheckpointSimulationOverridesPlan({ + checkpointNumber: checkpointNumberUnderTest, proposedCheckpointData: proposedData, + checkpointedCheckpointNumber: CheckpointNumber(0), rollup: publisher.rollupContract, signatureContext, log: createLogger('test'), - pipeliningEnabled: true, }); expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); - expect(plan?.pendingCheckpointState?.archive).toEqual(proposedArchive.root); - expect(plan?.pendingCheckpointState?.headerHash).toEqual(proposedHeader.hash()); - expect(plan?.pendingCheckpointState?.outHash).toEqual(proposedOutHash); - expect(plan?.pendingCheckpointState?.slotNumber).toEqual(SlotNumber(123)); + expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(1)); + expect(plan?.pendingCheckpointState?.archive).toEqual(proposedData.archive.root); + expect(plan?.pendingCheckpointState?.slotNumber).toEqual(proposedData.header.slotNumber); + expect(plan?.pendingCheckpointState?.headerHash).toEqual(proposedData.header.hash()); + expect(plan?.pendingCheckpointState?.outHash).toEqual(proposedData.checkpointOutHash); expect(plan?.pendingCheckpointState?.payloadDigest).toBeDefined(); expect(plan?.pendingCheckpointState?.feeHeader).toBeDefined(); }); - it('omits per-checkpoint state when proposedCheckpointData is undefined', async () => { - const plan = await buildPipelinedParentSimulationOverridesPlan({ + it('throws when the pipelined parent does not match the expected parent checkpoint', async () => { + const proposedData = makeProposedParent(CheckpointNumber(5)); + + await expect( + buildCheckpointSimulationOverridesPlan({ + checkpointNumber: checkpointNumberUnderTest, + proposedCheckpointData: proposedData, + checkpointedCheckpointNumber: CheckpointNumber(0), + rollup: publisher.rollupContract, + signatureContext, + log: createLogger('test'), + }), + ).rejects.toThrow(/does not match expected parent/); + }); + + it('throws when both proposedCheckpointData and invalidateToPendingCheckpointNumber are provided', async () => { + const proposedData = makeProposedParent(CheckpointNumber(1)); + + await expect( + buildCheckpointSimulationOverridesPlan({ + checkpointNumber: checkpointNumberUnderTest, + proposedCheckpointData: proposedData, + invalidateToPendingCheckpointNumber: CheckpointNumber(0), + checkpointedCheckpointNumber: CheckpointNumber(0), + rollup: publisher.rollupContract, + signatureContext, + log: createLogger('test'), + }), + ).rejects.toThrow(/mutually exclusive/); + }); + + it('sets pending and proven from an invalidation rollback without archive/fee overrides', async () => { + const plan = await buildCheckpointSimulationOverridesPlan({ checkpointNumber: checkpointNumberUnderTest, - proposedCheckpointData: undefined, + invalidateToPendingCheckpointNumber: CheckpointNumber(0), + checkpointedCheckpointNumber: CheckpointNumber(2), rollup: publisher.rollupContract, signatureContext, log: createLogger('test'), - pipeliningEnabled: true, }); - expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); + expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(0)); + expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(0)); expect(plan?.pendingCheckpointState).toBeUndefined(); }); }); diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts index de0d8138b7c2..23ed57fb1e9a 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts @@ -301,6 +301,7 @@ describe('CheckpointProposalJob Timing Tests', () => { epoch, checkpointNumber, BlockNumber.ZERO, + CheckpointNumber(checkpointNumber - 1), proposer, publisher, attestorAddress, @@ -405,7 +406,7 @@ describe('CheckpointProposalJob Timing Tests', () => { publisher.enqueueGovernanceCastSignal.mockResolvedValue(true); publisher.enqueueSlashingActions.mockResolvedValue(true); publisher.sendRequestsAt.mockResolvedValue({ - result: { receipt: { status: 'success' } as any, errorMsg: undefined }, + result: { receipt: { status: 'success' } as any }, successfulActions: ['propose'], failedActions: [], sentActions: ['propose'], @@ -1047,6 +1048,7 @@ describe('CheckpointProposalJob Timing Tests', () => { epoch, checkpointNumber, BlockNumber.ZERO, + CheckpointNumber(checkpointNumber - 1), proposer, publisher, attestorAddress, diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts index 6c8af0a66a07..209e04b4856b 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts @@ -66,10 +66,7 @@ import { DutyAlreadySignedError, SlashingProtectionError } from '@aztec/validato import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js'; import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js'; -import { - buildPipelinedParentSimulationOverridesPlan, - buildSubmissionSimulationOverridesPlan, -} from './chain_state_overrides.js'; +import { buildCheckpointSimulationOverridesPlan } from './chain_state_overrides.js'; import type { CheckpointProposalJobMetricsRecorder } from './checkpoint_proposal_job_metrics.js'; import { CheckpointVoter } from './checkpoint_voter.js'; import { SequencerInterruptedError } from './errors.js'; @@ -110,11 +107,12 @@ export class CheckpointProposalJob implements Traceable { private pendingL1Submission: Promise | undefined; /** - * Build-time chain state overrides used both during build (globals + invariant checks) and - * later for enqueue-time submission validation. May carry the pipelined parent override, the - * pretend-proof-landed (`proven`) override at an epoch boundary, or both. + * Chain state overrides built once per slot in proposeCheckpoint after the checkpoint is + * complete. Carries the pending parent override (archive + slot + fee header) for pipelining, + * or the invalidation pending override when rolling back. Consumed by + * publisher.validateBlockHeader before broadcast. */ - private pipelinedParentSimulationOverridesPlan?: SimulationOverridesPlan; + private checkpointSimulationOverridesPlan?: SimulationOverridesPlan; private getSignatureContext(): CoordinationSignatureContext { return this.signatureContext; @@ -126,6 +124,7 @@ export class CheckpointProposalJob implements Traceable { private readonly targetEpoch: EpochNumber, private readonly checkpointNumber: CheckpointNumber, private readonly syncedToBlockNumber: BlockNumber, + private readonly checkpointedCheckpointNumber: CheckpointNumber, // TODO(palla/mbps): Can we remove the proposer in favor of attestorAddress? Need to check fisherman-node flows. private readonly proposer: EthAddress | undefined, private readonly publisher: SequencerPublisher, @@ -153,7 +152,6 @@ export class CheckpointProposalJob implements Traceable { public readonly tracer: Tracer, bindings?: LoggerBindings, private readonly proposedCheckpointData?: ProposedCheckpointData, - private readonly prunePending?: { provenOverride: CheckpointNumber }, ) { this.log = createLogger('sequencer:checkpoint-proposal', { ...bindings, @@ -215,11 +213,7 @@ export class CheckpointProposalJob implements Traceable { // signature verification to fail silently inside Multicall3. Delay submission to the // start of `targetSlot` so the tx mines in the slot the vote was signed for. if (!this.config.fishermanMode) { - const isPipelining = this.epochCache.isProposerPipeliningEnabled(); - const submitAfter = isPipelining - ? new Date(Number(getTimestampForSlot(this.targetSlot, this.l1Constants)) * 1000) - : this.dateProvider.nowAsDate(); - this.pendingL1Submission = this.publisher.sendRequestsAt(submitAfter).then(() => {}); + this.pendingL1Submission = this.publisher.sendRequestsAt(this.targetSlot).then(() => {}); } return undefined; } @@ -278,12 +272,7 @@ export class CheckpointProposalJob implements Traceable { } // Send whatever was enqueued: votes + (propose | invalidation | nothing). - // Compute the earliest time to submit: pipeline slot start when pipelining, now otherwise. - const submitAfter = isPipelining - ? new Date(Number(getTimestampForSlot(this.targetSlot, this.l1Constants)) * 1000) - : new Date(this.dateProvider.now()); - - const l1Response = await this.publisher.sendRequestsAt(submitAfter); + const l1Response = await this.publisher.sendRequestsAt(this.targetSlot); const proposedAction = l1Response?.successfulActions.find(a => a === 'propose'); if (proposedAction) { this.logCheckpointEvent('published', `Checkpoint published for slot ${this.targetSlot}`, { @@ -363,25 +352,8 @@ export class CheckpointProposalJob implements Traceable { } } - const isPipelining = this.epochCache.isProposerPipeliningEnabled(); - const enqueueSimulationOverridesPlan = buildSubmissionSimulationOverridesPlan({ - pipelinedParentPlan: this.pipelinedParentSimulationOverridesPlan, - invalidateToPendingCheckpointNumber: this.invalidateCheckpoint?.forcePendingCheckpointNumber, - lastArchiveRoot: checkpoint.header.lastArchiveRoot, - pipeliningEnabled: isPipelining, - }); - - const preCheckSimulationOverridesPlan = buildSubmissionSimulationOverridesPlan({ - pipelinedParentPlan: undefined, - invalidateToPendingCheckpointNumber: this.invalidateCheckpoint?.forcePendingCheckpointNumber, - lastArchiveRoot: checkpoint.header.lastArchiveRoot, - pipeliningEnabled: isPipelining, - }); - await this.publisher.enqueueProposeCheckpoint(checkpoint, attestations, attestationsSignature, { txTimeoutAt, - simulationOverridesPlan: enqueueSimulationOverridesPlan, - preCheckSimulationOverridesPlan, }); } @@ -563,25 +535,26 @@ export class CheckpointProposalJob implements Traceable { this.publisher.enqueueInvalidateCheckpoint(this.invalidateCheckpoint); } - // Create checkpoint builder for the slot. - // When pipelining, force the proposed checkpoint number and fee header to our parent so the - // fee computation sees the same chain tip that L1 will see once the previous pipelined checkpoint lands. + // Build the simulation plan for this slot. When pipelining, this overrides L1's view of + // pending/archive/fee-header to "as if the proposed parent had landed", so both the + // mana-min-fee simulation (in the globals builder) and the pre-broadcast + // validateBlockHeader see the chain tip the eventual L1 send will see. const isPipelining = this.epochCache.isProposerPipeliningEnabled(); - this.pipelinedParentSimulationOverridesPlan = await buildPipelinedParentSimulationOverridesPlan({ + this.checkpointSimulationOverridesPlan = await buildCheckpointSimulationOverridesPlan({ checkpointNumber: this.checkpointNumber, - proposedCheckpointData: this.proposedCheckpointData, + proposedCheckpointData: isPipelining ? this.proposedCheckpointData : undefined, + invalidateToPendingCheckpointNumber: this.invalidateCheckpoint?.forcePendingCheckpointNumber, + checkpointedCheckpointNumber: this.checkpointedCheckpointNumber, rollup: this.publisher.rollupContract, signatureContext: this.signatureContext, log: this.log, - pipeliningEnabled: isPipelining, - prunePending: this.prunePending, }); const checkpointGlobalVariables = await this.globalsBuilder.buildCheckpointGlobalVariables( coinbase, feeRecipient, this.targetSlot, - this.pipelinedParentSimulationOverridesPlan, + this.checkpointSimulationOverridesPlan, ); // Collect L1 to L2 messages for the checkpoint and compute their hash @@ -606,7 +579,7 @@ export class CheckpointProposalJob implements Traceable { // Anchor the modifier to the predicted parent fee header: L1 will apply it against // that, not against the latest published checkpoint (which lags by one under pipelining). const predictedParentEthPerFeeAssetE12 = - this.pipelinedParentSimulationOverridesPlan?.pendingCheckpointState?.feeHeader?.ethPerFeeAsset; + this.checkpointSimulationOverridesPlan?.pendingCheckpointState?.feeHeader?.ethPerFeeAsset; const feeAssetPriceModifier = await this.publisher.getFeeAssetPriceModifier(predictedParentEthPerFeeAssetE12); // Create a long-lived forked world state for the checkpoint builder @@ -631,7 +604,8 @@ export class CheckpointProposalJob implements Traceable { const checkpointProposalOptions: CheckpointProposalOptions = { publishFullTxs: !!this.config.publishTxsWithProposals, - broadcastInvalidCheckpointProposal: this.config.broadcastInvalidBlockProposal, + broadcastInvalidCheckpointProposal: + this.config.broadcastInvalidCheckpointProposalOnly || this.config.broadcastInvalidBlockProposal, }; let blocksInCheckpoint: L2Block[] = []; @@ -763,6 +737,25 @@ export class CheckpointProposalJob implements Traceable { return { checkpoint, proposal: undefined!, blockProposedAt: this.dateProvider.now() }; } + // Validate the header against L1 state before broadcasting. + // If this fails the slot is aborted before any gossip work; state drift between here + // and the eventual L1 send is caught by the bundle simulate at send time. + try { + await this.publisher.validateBlockHeader(checkpoint.header, this.checkpointSimulationOverridesPlan); + } catch (err) { + this.log.error(`Pre-broadcast header validation failed for slot ${this.targetSlot}; aborting`, err, { + slot: this.targetSlot, + checkpointNumber: this.checkpointNumber, + }); + this.metrics.recordCheckpointProposalFailed('header_validation_failed'); + this.eventEmitter.emit('header-validation-failed', { + slot: this.targetSlot, + checkpointNumber: this.checkpointNumber, + reason: err instanceof Error ? err.message : String(err), + }); + return undefined; + } + // Create the checkpoint proposal and broadcast it const proposal = await this.validatorClient.createCheckpointProposal( checkpoint.header, @@ -887,7 +880,12 @@ export class CheckpointProposalJob implements Traceable { usedTxs.forEach(tx => txHashesAlreadyIncluded.add(tx.txHash.toString())); // Sign the block proposal. This will throw if HA signing fails. - const proposal = await this.createBlockProposal(block, inHash, usedTxs, blockProposalOptions); + const proposal = await this.createBlockProposal(block, inHash, usedTxs, { + ...blockProposalOptions, + broadcastInvalidBlockProposal: + blockProposalOptions.broadcastInvalidBlockProposal || + block.indexWithinCheckpoint === this.config.invalidBlockProposalIndexWithinCheckpoint, + }); // Sync the proposed block to the archiver to make it available, only after we've managed to sign the proposal, // so we avoid polluting our archive with a block that would fail. @@ -1107,6 +1105,9 @@ export class CheckpointProposalJob implements Traceable { // `buildSlot` is the wall-clock slot during which the block was actually built. this.eventEmitter.emit('block-proposed', { blockNumber: block.number, + blockHash, + checkpointNumber: this.checkpointNumber, + indexWithinCheckpoint: block.indexWithinCheckpoint, slot: this.targetSlot, buildSlot: this.slotNow, }); diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_voter.ha.integration.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_voter.ha.integration.test.ts index 3a641f2bb8b3..d60279e32230 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_voter.ha.integration.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_voter.ha.integration.test.ts @@ -138,12 +138,16 @@ describe('CheckpointVoter HA Integration', () => { txUtils.client = { account: validatorAccount, getCode: () => Promise.resolve('0x1234' as `0x${string}`), + getGasPrice: () => Promise.resolve(1n), + getBlock: () => Promise.resolve({ timestamp: 0n } as any), } as any; txUtils.getSenderAddress.mockReturnValue(EthAddress.fromString(validatorAccount.address)); + txUtils.getSenderBalance.mockResolvedValue(10_000_000_000_000_000_000n); // 10 ETH txUtils.simulate.mockResolvedValue({ gasUsed: 100000n, result: '0x', }); + (txUtils as any).bumpGasLimit = (val: bigint) => val + (val * 20n) / 100n; // Mock getCode to return non-empty bytecode for governance/slashing payloads txUtils.getCode.mockResolvedValue('0x1234' as any); return txUtils; @@ -690,7 +694,8 @@ describe('CheckpointVoter HA Integration', () => { status: 'success', logs: [], } as any, - errorMsg: undefined, + stats: undefined, + multicallData: '0x', }); // Each node enqueues their respective votes diff --git a/yarn-project/sequencer-client/src/sequencer/events.ts b/yarn-project/sequencer-client/src/sequencer/events.ts index a0fa73c011e4..9d8aa54df437 100644 --- a/yarn-project/sequencer-client/src/sequencer/events.ts +++ b/yarn-project/sequencer-client/src/sequencer/events.ts @@ -1,4 +1,5 @@ -import type { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import type { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; +import type { BlockHash } from '@aztec/stdlib/block'; import type { Action } from '../publisher/sequencer-publisher.js'; import type { SequencerState } from './utils.js'; @@ -18,10 +19,14 @@ export type SequencerEvents = { * * - `hadProposedParent` indicates whether the build saw a proposed (pipelined) parent * checkpoint that hasn't landed on L1 yet. - * - `provenOverride` is the assumed proven checkpoint number when the proven-override - * for a pending prune was applied; `undefined` when no override was applied. - * - `simulatedPending` is the pending checkpoint passed to L1 simulation (when - * pipelining or invalidating; undefined otherwise). + * - `provenOverride` is the assumed proven checkpoint number pinned for the L1 + * simulation. The plan always pins both chain tips to short-circuit `canPruneAtTime`, + * so this is populated whenever a simulation plan was built — the value either + * matches the on-chain proven snapshot (defensive pin) or the assumed-proven + * checkpoint when building optimistically across a pruning boundary. + * - `simulatedPending` is the pending checkpoint passed to L1 simulation. The plan + * always pins both chain tips to short-circuit `canPruneAtTime`, so this reflects + * either the pipelined/invalidated tip or the on-chain pending snapshot. */ ['preparing-checkpoint']: (args: { targetSlot: SlotNumber; @@ -33,8 +38,26 @@ export type SequencerEvents = { ['proposer-rollup-check-failed']: (args: { reason: string; slot: SlotNumber }) => void; ['block-tx-count-check-failed']: (args: { minTxs: number; availableTxs: number; slot: SlotNumber }) => void; ['block-build-failed']: (args: { reason: string; slot: SlotNumber }) => void; - ['block-proposed']: (args: { blockNumber: BlockNumber; slot: SlotNumber; buildSlot: SlotNumber }) => void; + ['block-proposed']: (args: { + blockNumber: BlockNumber; + blockHash: BlockHash; + checkpointNumber: CheckpointNumber; + indexWithinCheckpoint: IndexWithinCheckpoint; + slot: SlotNumber; + buildSlot: SlotNumber; + }) => void; ['checkpoint-empty']: (args: { slot: SlotNumber }) => void; + /** + * Emitted when the proposer's pre-broadcast `validateBlockHeader` simulation fails. This is a + * last-chance check before we gossip a checkpoint proposal: a failure here means the header + * would not be accepted by L1 (e.g. archive mismatch, stale chain tip, or some other state + * drift between when we built the checkpoint and when we are about to broadcast it). + */ + ['header-validation-failed']: (args: { + slot: SlotNumber; + checkpointNumber: CheckpointNumber; + reason: string; + }) => void; ['checkpoint-publish-failed']: (args: { slot: SlotNumber; successfulActions?: Action[]; diff --git a/yarn-project/sequencer-client/src/sequencer/index.ts b/yarn-project/sequencer-client/src/sequencer/index.ts index 9f9721707764..4db5f7152b2a 100644 --- a/yarn-project/sequencer-client/src/sequencer/index.ts +++ b/yarn-project/sequencer-client/src/sequencer/index.ts @@ -1,3 +1,5 @@ +export * from './automine/automine_factory.js'; +export * from './automine/automine_sequencer.js'; export * from './checkpoint_proposal_job.js'; export * from './checkpoint_voter.js'; export * from './config.js'; diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index b2f0828f5341..d17475a5fee7 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -222,7 +222,7 @@ describe('sequencer', () => { publisher.enqueueGovernanceCastSignal.mockResolvedValue(true); publisher.enqueueSlashingActions.mockResolvedValue(true); publisher.sendRequestsAt.mockResolvedValue({ - result: { receipt: { status: 'success' } as any, errorMsg: undefined }, + result: { receipt: { status: 'success' } as any }, successfulActions: ['propose'], failedActions: [], sentActions: ['propose'], @@ -242,6 +242,11 @@ describe('sequencer', () => { rollupContract = mockDeep(); rollupContract.isEscapeHatchOpen.mockResolvedValue(false); + // Default rollup reads used by pipelined fee-header derivation. + rollupContract.getCheckpoint.mockResolvedValue({ + feeHeader: { manaUsed: 0n, excessMana: 0n, ethPerFeeAsset: 1n, congestionCost: 0n, proverCost: 0n }, + } as any); + rollupContract.getManaTarget.mockResolvedValue(10_000n); globalVariableBuilder = mock(); globalVariableBuilder.buildGlobalVariables.mockResolvedValue(globalVariables); @@ -563,7 +568,7 @@ describe('sequencer', () => { pub.enqueueGovernanceCastSignal.mockResolvedValue(true); pub.enqueueSlashingActions.mockResolvedValue(true); pub.sendRequestsAt.mockResolvedValue({ - result: { receipt: { status: 'success' } as any, errorMsg: undefined }, + result: { receipt: { status: 'success' } as any }, successfulActions: ['propose'], failedActions: [], sentActions: ['propose'], @@ -671,7 +676,10 @@ describe('sequencer', () => { expect(slasherClient.getProposerActions).toHaveBeenCalledWith(SlotNumber(1)); expect(publisher.enqueueSlashingActions).toHaveBeenCalled(); expect(publisher.enqueueGovernanceCastSignal).toHaveBeenCalled(); - expect(publisher.sendRequests).toHaveBeenCalled(); + // Submission goes through sendRequestsAt so the bundle simulate's block.timestamp + // override matches the slot the EIP-712 signatures were generated for. + expect(publisher.sendRequestsAt).toHaveBeenCalled(); + expect(publisher.sendRequests).not.toHaveBeenCalled(); // But checkpoint proposal must not start expect(publisher.enqueueProposeCheckpoint).not.toHaveBeenCalled(); @@ -694,16 +702,16 @@ describe('sequencer', () => { await sequencer.work(); expect(publisher.enqueueSlashingActions).toHaveBeenCalledTimes(1); - expect(publisher.sendRequests).toHaveBeenCalledTimes(1); + expect(publisher.sendRequestsAt).toHaveBeenCalledTimes(1); publisher.enqueueSlashingActions.mockClear(); - publisher.sendRequests.mockClear(); + publisher.sendRequestsAt.mockClear(); slasherClient.getProposerActions.mockClear(); await sequencer.work(); expect(slasherClient.getProposerActions).not.toHaveBeenCalled(); expect(publisher.enqueueSlashingActions).not.toHaveBeenCalled(); - expect(publisher.sendRequests).not.toHaveBeenCalled(); + expect(publisher.sendRequestsAt).not.toHaveBeenCalled(); }); }); @@ -757,7 +765,8 @@ describe('sequencer', () => { expect.any(EthAddress), expect.any(Function), ); - expect(publisher.sendRequests).toHaveBeenCalled(); + // Votes are submitted via sendRequestsAt (fire-and-forget, scheduled at target slot start). + expect(publisher.sendRequestsAt).toHaveBeenCalled(); }); it('should not vote when sync fails and within time limit', async () => { @@ -817,18 +826,19 @@ describe('sequencer', () => { // First attempt should succeed await sequencer.work(); expect(publisher.enqueueSlashingActions).toHaveBeenCalledTimes(1); - expect(publisher.sendRequests).toHaveBeenCalledTimes(1); + // Votes are submitted via sendRequestsAt (fire-and-forget, scheduled at target slot start). + expect(publisher.sendRequestsAt).toHaveBeenCalledTimes(1); // Reset mocks publisher.enqueueSlashingActions.mockClear(); - publisher.sendRequests.mockClear(); + publisher.sendRequestsAt.mockClear(); slasherClient.getProposerActions.mockClear(); // Second attempt in the same slot should be skipped await sequencer.work(); expect(slasherClient.getProposerActions).not.toHaveBeenCalled(); expect(publisher.enqueueSlashingActions).not.toHaveBeenCalled(); - expect(publisher.sendRequests).not.toHaveBeenCalled(); + expect(publisher.sendRequestsAt).not.toHaveBeenCalled(); }); }); @@ -1114,7 +1124,7 @@ describe('sequencer', () => { const simulationOverridesPlan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; expect(simulationOverridesPlan?.chainTipsOverride?.pending).toEqual(CheckpointNumber(1)); - expect(simulationOverridesPlan?.pendingCheckpointState?.archive).toEqual(expect.anything()); + // The archive root is passed directly as the first arg to canProposeAt (not inside the plan). }); it('skips proposal when checkpoint exceeds pipeline depth', async () => { @@ -1177,15 +1187,19 @@ describe('sequencer', () => { expect(publisher.canProposeAt).not.toHaveBeenCalled(); }); - it('calls L1 check without archive override when no proposed checkpoint', async () => { + it('pins both chain tips to the on-chain pending snapshot when no proposed checkpoint applies', async () => { await setupSingleTxBlock(); await sequencer.work(); - expect(publisher.canProposeAt.mock.calls.at(-1)?.[2]).toBeUndefined(); + // The default `getL2Tips` mock has checkpointed.checkpoint.number == CheckpointNumber.ZERO. + const plan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; + expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber.ZERO); + expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber.ZERO); + expect(plan?.pendingCheckpointState).toBeUndefined(); }); - it('calls L1 check without overrides when not pipelining', async () => { + it('pins both chain tips to the on-chain pending snapshot when not pipelining', async () => { await setupSingleTxBlock(); // Override back to non-pipelining @@ -1204,23 +1218,13 @@ describe('sequencer', () => { await sequencer.work(); - expect(publisher.canProposeAt.mock.calls.at(-1)?.[2]).toBeUndefined(); - }); - - it('attaches proven override equal to real pending when isPruneDueAtSlot returns true', async () => { - await setupSingleTxBlock(); - - // No proposed checkpoint, so we exercise the standalone proven override path. - // The default `getL2Tips` mock has checkpointed.checkpoint.number == CheckpointNumber.ZERO. - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(true); - - await sequencer.work(); - const plan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; + expect(plan?.chainTipsOverride?.pending).toEqual(CheckpointNumber.ZERO); expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber.ZERO); + expect(plan?.pendingCheckpointState).toBeUndefined(); }); - it('uses the simulated pending as the proven override when the caller overrides pending', async () => { + it('mirrors pending onto proven when the caller overrides pending via pipelining', async () => { await setupSingleTxBlock(); // Set up a pipelined parent (pending override = parentCheckpointNumber = 1). @@ -1278,9 +1282,6 @@ describe('sequencer', () => { feeAssetPriceModifier: 0n, } satisfies ProposedCheckpointData); - // The sequencer sets proven == simulated pending so canPruneAtTime short-circuits to false. - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(true); - await sequencer.work(); const plan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; @@ -1288,52 +1289,25 @@ describe('sequencer', () => { expect(plan?.chainTipsOverride?.proven).toEqual(CheckpointNumber(1)); }); - it('does not attach proven override when isPruneDueAtSlot returns false', async () => { - await setupSingleTxBlock(); - - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(false); - - await sequencer.work(); - - const plan = publisher.canProposeAt.mock.calls.at(-1)?.[2]; - expect(plan?.chainTipsOverride?.proven).toBeUndefined(); - }); - - it('emits preparing-checkpoint with provenOverride when prune is due', async () => { + it('emits preparing-checkpoint with snapshot-pinned tips when no override applies', async () => { await setupSingleTxBlock(); - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(true); - const events: any[] = []; sequencer.on('preparing-checkpoint', args => events.push(args)); await sequencer.work(); expect(events).toHaveLength(1); + // With no pipelined or invalidation override, both `pending` and `proven` are pinned to the + // on-chain pending snapshot (checkpointedCheckpointNumber) so `canPruneAtTime` short-circuits + // and a live re-read inside `makeChainTipsOverride` can't reintroduce a phantom prune. + // `provenOverride` mirrors the pinned proven tip whenever a plan was built. expect(events[0]).toEqual({ targetSlot: SlotNumber(2), checkpointNumber: expect.anything(), hadProposedParent: false, provenOverride: CheckpointNumber.ZERO, - simulatedPending: undefined, - }); - }); - - it('emits preparing-checkpoint without provenOverride when no prune is due', async () => { - await setupSingleTxBlock(); - - l2BlockSource.isPruneDueAtSlot.mockResolvedValue(false); - - const events: any[] = []; - sequencer.on('preparing-checkpoint', args => events.push(args)); - - await sequencer.work(); - - expect(events).toHaveLength(1); - expect(events[0]).toMatchObject({ - targetSlot: SlotNumber(2), - hadProposedParent: false, - provenOverride: undefined, + simulatedPending: CheckpointNumber.ZERO, }); }); }); diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index e49c922f378c..6dda210dad1a 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -1,6 +1,6 @@ import { getKzg } from '@aztec/blob-lib'; import type { EpochCache } from '@aztec/epoch-cache'; -import { NoCommitteeError, type RollupContract, SimulationOverridesBuilder } from '@aztec/ethereum/contracts'; +import { NoCommitteeError, type RollupContract } from '@aztec/ethereum/contracts'; import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { merge, omit, pick } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -14,7 +14,7 @@ import type { SlasherClientInterface } from '@aztec/slasher'; import type { BlockData, L2BlockSink, L2BlockSource, ValidateCheckpointResult } from '@aztec/stdlib/block'; import type { Checkpoint, ProposedCheckpointData } from '@aztec/stdlib/checkpoint'; import type { ChainConfig } from '@aztec/stdlib/config'; -import { getSlotStartBuildTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; +import { getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers'; import { type ResolvedSequencerConfig, type SequencerConfig, @@ -33,7 +33,7 @@ import { DefaultSequencerConfig } from '../config.js'; import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js'; import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js'; import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js'; -import { buildPipelinedParentSimulationOverridesPlan } from './chain_state_overrides.js'; +import { buildCheckpointSimulationOverridesPlan } from './chain_state_overrides.js'; import { CheckpointProposalJob } from './checkpoint_proposal_job.js'; import { CheckpointProposalJobMetrics } from './checkpoint_proposal_job_metrics.js'; import { CheckpointVoter } from './checkpoint_voter.js'; @@ -312,7 +312,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter TypedEventEmitter TypedEventEmitter TypedEventEmitter TypedEventEmitter TypedEventEmitter TypedEventEmitter { - this.log.error(`Failed to publish votes despite sync failure for slot ${slot}`, err, { slot }); - }); - } else { - await publisher.sendRequests(); - } + void publisher.sendRequestsAt(targetSlot).catch(err => { + this.log.error(`Failed to publish votes despite sync failure for slot ${slot}`, err, { slot }); + }); } /** @@ -892,9 +883,10 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter ({ [Attributes.SLOT_NUMBER]: slot })) protected async tryVoteWhenEscapeHatchOpen(args: { slot: SlotNumber; + targetSlot: SlotNumber; proposer: EthAddress | undefined; }): Promise { - const { slot, proposer } = args; + const { slot, targetSlot, proposer } = args; // Prevent duplicate attempts in the same slot if (this.lastSlotForFallbackVote === slot) { @@ -907,10 +899,19 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter TypedEventEmitter { + this.log.error(`Failed to publish escape-hatch votes for slot ${slot}`, err, { slot, targetSlot }); + }); } /** diff --git a/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md b/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md index f736c83c867d..6519f4aab32f 100644 --- a/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md +++ b/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md @@ -250,9 +250,9 @@ Click on an opcode name to view its detailed documentation. * **[🔗ECADD](opcodes/ecadd.md)**: Grumpkin elliptic curve addition * Opcode `0x42` ```javascript - M[dstOffset:dstOffset+3] = grumpkinAdd( - /*point1=*/{x: M[p1XOffset], y: M[p1YOffset], isInfinite: M[p1IsInfiniteOffset]}, - /*point2=*/{x: M[p2XOffset], y: M[p2YOffset], isInfinite: M[p2IsInfiniteOffset]} + M[dstOffset:dstOffset+1] = grumpkinAdd( + /*point1=*/{x: M[p1XOffset], y: M[p1YOffset]}, + /*point2=*/{x: M[p2XOffset], y: M[p2YOffset]} ) ``` * **[🔗TORADIXBE](opcodes/toradixbe.md)**: Convert to radix (big-endian) diff --git a/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md b/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md index 7e570e0eb2de..7cc324facb14 100644 --- a/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md +++ b/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md @@ -12,7 +12,7 @@ M[dstOffset] = contractInstance.exists ? 1 : 0; M[dstOffset+1] = contractInstanc ## Details -Looks up contract instance by address and retrieves the specified member. This opcode can get contract instance information for any contract address, not just the currently executing one. Returns existence flag (Uint1) and member value (FIELD). If the contract does not exist, the member value is set to 0. Supported enum values: `[DEPLOYER=0, CLASS_ID, INIT_HASH]`. +Looks up contract instance by address and retrieves the specified member. This opcode can get contract instance information for any contract address, not just the currently executing one. Returns existence flag (Uint1) and member value (FIELD). If the contract does not exist, the member value is set to 0. Supported enum values: `[DEPLOYER=0, CLASS_ID, INIT_HASH, IMMUTABLES_HASH]`. ## Contract Classes and Instances @@ -32,6 +32,7 @@ This separation allows for: | **Deployer Address** | The address of the account that deployed this contract instance. | | **Class ID** | The identifier of the contract class that this instance uses for its code. | | **Initialization Hash** | A hash of the constructor arguments used when the contract instance was deployed. | +| **Immutables Hash** | A hash of the immutable storage values declared by a contract instance when it was deployed. | **Example**: To check if a contract at a given `address` is an instance of a known `CLASS_ID`: 1. Use `GETCONTRACTINSTANCE` with the `address` and the `CLASS_ID` member enum. diff --git a/yarn-project/simulator/docs/avm/public-tx-simulation.md b/yarn-project/simulator/docs/avm/public-tx-simulation.md index 54a27fbeafd8..1896a7fff258 100644 --- a/yarn-project/simulator/docs/avm/public-tx-simulation.md +++ b/yarn-project/simulator/docs/avm/public-tx-simulation.md @@ -35,7 +35,7 @@ The app logic phase contains the main application functionality. This is where m - State changes from app logic are rolled back - Side effects from private's revertible portion are also discarded - Teardown still executes -- The transaction appears on-chain with `APP_LOGIC_REVERTED` status +- The transaction appears on-chain with `REVERTED` status ### TEARDOWN Phase (Revertible, Always Runs) diff --git a/yarn-project/simulator/src/public/avm/apps_tests/avm_test.test.ts b/yarn-project/simulator/src/public/avm/apps_tests/avm_test.test.ts index a2961338479e..d61fba0c8f46 100644 --- a/yarn-project/simulator/src/public/avm/apps_tests/avm_test.test.ts +++ b/yarn-project/simulator/src/public/avm/apps_tests/avm_test.test.ts @@ -47,6 +47,19 @@ describe('AVM simulator apps tests: AvmTestContract', () => { const expectContractInstance = instances[1]; const argsField = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + // Pinned grumpkin-Poseidon2 Schnorr signature (mirrors the C++ `pinned_test_vector_large` + // and noir-lang/schnorr v0.4.0's `pinned_vector_large`). Passing these in as calldata + // (rather than baking them into Noir as constants) keeps MSM + Poseidon2 from being folded + // by the Noir compiler. + const schnorrInputs = [ + Fr.fromHexString('0x065812e335a97c2108ea8cf4ccfe2f9dd6b117a0714f5e18461575be93f61da6'), // pubkey.x + Fr.fromHexString('0x1a915003e8ec534f9a15d926a7ded478e178468ccc4f28e236e67450a55ac622'), // pubkey.y + Fr.fromHexString('0xf3bc3b7147acb9c621fd9f72dbf15ffa'), // sig_s.lo + Fr.fromHexString('0x08599f379f0301dfefdbd0272554454d'), // sig_s.hi + Fr.fromHexString('0x97065383ebbbd76620398792bd259bc2'), // sig_e.lo + Fr.fromHexString('0x2ceaee87f45b7a417f0ffb05451a8c92'), // sig_e.hi + Fr.fromHexString('0x0123456789abcdef0fedcba9876543210123456789abcdef0fedcba987654321'), // message + ]; const args = [ argsField, argsU8, @@ -54,6 +67,8 @@ describe('AVM simulator apps tests: AvmTestContract', () => { /*expectedDeployer=*/ expectContractInstance.deployer, /*expectedClassId=*/ expectContractInstance.currentContractClassId, /*expectedInitializationHash=*/ expectContractInstance.initializationHash, + /*expectedImmutablesHash=*/ expectContractInstance.immutablesHash, + /*schnorrInputs=*/ schnorrInputs, /*skip_strictly_limited_side_effects=*/ false, ]; const results = await simTester.simulateCall(sender, /*address=*/ testContractAddress, 'bulk_testing', args); diff --git a/yarn-project/simulator/src/public/avm/avm_simulator.test.ts b/yarn-project/simulator/src/public/avm/avm_simulator.test.ts index a9354bfe30bf..baf7c9685884 100644 --- a/yarn-project/simulator/src/public/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/public/avm/avm_simulator.test.ts @@ -6,7 +6,6 @@ import { pedersenCommit, pedersenHash } from '@aztec/foundation/crypto/pedersen' import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon'; import { sha256 } from '@aztec/foundation/crypto/sha256'; import { Fq, Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import type { Fieldable } from '@aztec/foundation/serialize'; import { AvmGadgetsTestContract } from '@aztec/noir-test-contracts.js/AvmGadgetsTest'; import { AvmTestContract } from '@aztec/noir-test-contracts.js/AvmTest'; @@ -23,7 +22,7 @@ import { siloNoteHash, siloNullifier, } from '@aztec/stdlib/hash'; -import { PublicKeys } from '@aztec/stdlib/keys'; +import { PublicKey, PublicKeys } from '@aztec/stdlib/keys'; import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/stdlib/testing'; import { NativeWorldStateService } from '@aztec/world-state'; @@ -257,10 +256,8 @@ describe('AVM simulator: transpiled Noir contracts', () => { const calldata = new CallDataArray([ new Fr(1), // P1x new Fr(17631683881184975370165255887551781615748388533673675138860n), // P1y - new Fr(0), // P1inf new Fr(1), // P2x new Fr(17631683881184975370165255887551781615748388533673675138860n), // P2y - new Fr(0), // P2inf ]); const context = initContext({ env: initExecutionEnvironment({ calldata }) }); @@ -278,7 +275,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.reverted).toBe(false); const g3 = await Grumpkin.mul(Grumpkin.generator, new Fq(3)); - expect(results.output.readAll()).toEqual([g3.x, g3.y, Fr.ZERO]); + expect(results.output.readAll()).toEqual([g3.x, g3.y]); }); describe('msm', () => { @@ -298,7 +295,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const g3 = await Grumpkin.mul(Grumpkin.generator, new Fq(3)); const g20 = await Grumpkin.mul(Grumpkin.generator, new Fq(20)); const expectedResult = await Grumpkin.add(g3, g20); - expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y, Fr.ZERO]); + expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y]); }); it('with a zero', async () => { @@ -315,7 +312,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.reverted).toBe(false); const expectedResult = await Grumpkin.mul(Grumpkin.generator, new Fq(3)); - expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y, Fr.ZERO]); + expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y]); }); const fqToLimbs = (fq: Fq): [bigint, bigint] => { @@ -340,7 +337,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const g1 = await Grumpkin.mul(Grumpkin.generator, scalar); const g2 = await Grumpkin.mul(Grumpkin.generator, scalar2); const expectedResult = await Grumpkin.add(g1, g2); - expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y, Fr.ZERO]); + expect(results.output.readAll()).toEqual([expectedResult.x, expectedResult.y]); }); }); @@ -352,11 +349,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(false); - // This doesnt include infinites const expectedResult = (await pedersenCommit([Buffer.from([100]), Buffer.from([1])], 20)).map(f => new Fr(f)); - // TODO: Come back to the handling of infinities when we confirm how they're handled in bb - const isInf = expectedResult[0] === new Fr(0) && expectedResult[1] === new Fr(0); - expectedResult.push(new Fr(isInf)); expect(results.output.readAll()).toEqual(expectedResult); }); @@ -452,7 +445,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { * Can run these as follows to measure sha256 instruction execution counts: * for i in 10 20 30 40 50 60 70 80 90 100 255 256 511 512 2048; do * echo sha-ing $i...; - * LOG_LEVEL=debug yarn test src/avm/avm_simulator.test.ts -t "sha256_hash_$i " &> sha$i.log; + * LOG_LEVEL="debug; info: json-rpc, simulator" yarn test src/avm/avm_simulator.test.ts -t "sha256_hash_$i " &> sha$i.log; * done * for i in 10 20 30 40 50 60 70 80 90 100 255 256 511 512 2048; do * echo sha256 of $i bytes $(grep -Eo 'Executed .* instructions.* Gas' sha$i.log); @@ -914,24 +907,27 @@ describe('AVM simulator: transpiled Noir contracts', () => { const context = createContext(calldata); // Contract instance must match noir const contractInstance = new SerializableContractInstance({ - version: 1 as const, + version: 2 as const, salt: new Fr(0x123), deployer: AztecAddress.fromBigInt(0x456n), currentContractClassId: new Fr(0x789), originalContractClassId: new Fr(0x789), initializationHash: new Fr(0x101112), + immutablesHash: new Fr(0x202221), publicKeys: new PublicKeys( - new Point(new Fr(0x131415), new Fr(0x161718), false), - new Point(new Fr(0x192021), new Fr(0x222324), false), - new Point(new Fr(0x252627), new Fr(0x282930), false), - new Point(new Fr(0x313233), new Fr(0x343536), false), + new Fr(0x131415), + new PublicKey(new Fr(0x192021), new Fr(0x222324)), + new Fr(0x252627), + new Fr(0x313233), ), }); const contractInstanceWithAddress = contractInstance.withAddress(address); - // mock once per enum value (deployer, classId, initializationHash) + // mock once per enum value (deployer, classId, initializationHash, immutablesHash) mockGetContractInstance(contractsDB, contractInstanceWithAddress); mockGetContractInstance(contractsDB, contractInstanceWithAddress); mockGetContractInstance(contractsDB, contractInstanceWithAddress); + mockGetContractInstance(contractsDB, contractInstanceWithAddress); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); diff --git a/yarn-project/simulator/src/public/avm/fixtures/utils.ts b/yarn-project/simulator/src/public/avm/fixtures/utils.ts index b9034b629890..382fdd2a9764 100644 --- a/yarn-project/simulator/src/public/avm/fixtures/utils.ts +++ b/yarn-project/simulator/src/public/avm/fixtures/utils.ts @@ -128,17 +128,20 @@ export async function createContractClassAndInstance( const constructorAbi = getContractFunctionAbi('constructor', contractArtifact); const { publicKeys } = await deriveKeys(new Fr(seed)); const initializationHash = await computeInitializationHash(constructorAbi, constructorArgs); + const immutablesHash = new Fr(seed + 1); const contractInstance = originalContractClassId === undefined ? await makeContractInstanceFromClassId(contractClass.id, seed, { deployer, initializationHash, + immutablesHash, publicKeys, }) : await makeContractInstanceFromClassId(originalContractClassId, seed, { deployer, initializationHash, currentClassId: contractClass.id, + immutablesHash, publicKeys, }); diff --git a/yarn-project/simulator/src/public/avm/opcodes/contract.test.ts b/yarn-project/simulator/src/public/avm/opcodes/contract.test.ts index c13063491558..cc459424acd6 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/contract.test.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/contract.test.ts @@ -16,6 +16,7 @@ describe('Contract opcodes', () => { let deployer: AztecAddress; let contractClassId: Fr; let initializationHash: Fr; + let immutablesHash: Fr; let persistableState: jest.Mocked; let context: AvmContext; @@ -26,6 +27,7 @@ describe('Contract opcodes', () => { deployer = contractInstance.deployer; contractClassId = contractInstance.currentContractClassId; initializationHash = contractInstance.initializationHash; + immutablesHash = contractInstance.immutablesHash; persistableState = mock(); context = initContext({ persistableState }); }); @@ -54,6 +56,7 @@ describe('Contract opcodes', () => { [ContractInstanceMember.DEPLOYER, () => deployer.toField()], [ContractInstanceMember.CLASS_ID, () => contractClassId.toField()], [ContractInstanceMember.INIT_HASH, () => initializationHash.toField()], + [ContractInstanceMember.IMMUTABLES_HASH, () => immutablesHash.toField()], ])('GETCONTRACTINSTANCE member instruction ', (memberEnum: ContractInstanceMember, valueGetter: () => Fr) => { it(`Should read '${ContractInstanceMember[memberEnum]}' correctly`, async () => { const value = valueGetter(); @@ -87,6 +90,7 @@ describe('Contract opcodes', () => { [ContractInstanceMember.DEPLOYER], [ContractInstanceMember.CLASS_ID], [ContractInstanceMember.INIT_HASH], + [ContractInstanceMember.IMMUTABLES_HASH], ])( 'GETCONTRACTINSTANCE member instruction works when contract does not exist', (memberEnum: ContractInstanceMember) => { @@ -124,7 +128,7 @@ describe('Contract opcodes', () => { /*memberEnum=*/ invalidEnum, ); await expect(instruction.execute(context)).rejects.toThrow( - `Invalid GETCONSTRACTINSTANCE member enum ${invalidEnum}`, + `Invalid GETCONTRACTINSTANCE member enum ${invalidEnum}`, ); }); }); diff --git a/yarn-project/simulator/src/public/avm/opcodes/contract.ts b/yarn-project/simulator/src/public/avm/opcodes/contract.ts index 801a894fbd0a..28f7ece9440d 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/contract.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/contract.ts @@ -9,6 +9,7 @@ export enum ContractInstanceMember { DEPLOYER, CLASS_ID, INIT_HASH, + IMMUTABLES_HASH, } export class GetContractInstance extends Instruction { @@ -41,7 +42,7 @@ export class GetContractInstance extends Instruction { ); if (!(this.memberEnum in ContractInstanceMember)) { - throw new InstructionExecutionError(`Invalid GETCONSTRACTINSTANCE member enum ${this.memberEnum}`); + throw new InstructionExecutionError(`Invalid GETCONTRACTINSTANCE member enum ${this.memberEnum}`); } const operands = [this.addressOffset, this.dstOffset]; @@ -64,6 +65,9 @@ export class GetContractInstance extends Instruction { case ContractInstanceMember.INIT_HASH: memberValue = new Field(instance.initializationHash); break; + case ContractInstanceMember.IMMUTABLES_HASH: + memberValue = new Field(instance.immutablesHash); + break; } } diff --git a/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts b/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts index 8e144efaed91..8c12fa4a9039 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts @@ -5,7 +5,7 @@ import { Point } from '@aztec/foundation/curves/grumpkin'; import { beforeEach } from '@jest/globals'; import type { AvmContext } from '../avm_context.js'; -import { Field, Uint1, Uint32 } from '../avm_memory_types.js'; +import { Field, Uint32 } from '../avm_memory_types.js'; import { EcAddPointNotOnCurveError } from '../errors.js'; import { initContext } from '../fixtures/initializers.js'; import { EcAdd } from './ec_add.js'; @@ -24,20 +24,16 @@ describe('EC Instructions', () => { ...Buffer.from('1234', 'hex'), // indirect ...Buffer.from('1235', 'hex'), // p1x ...Buffer.from('1236', 'hex'), // p1y - ...Buffer.from('0000', 'hex'), // p1IsInfinite ...Buffer.from('1237', 'hex'), // p2x ...Buffer.from('1238', 'hex'), // p2y - ...Buffer.from('0001', 'hex'), // p2IsInfinite ...Buffer.from('1239', 'hex'), // dstOffset ]); const inst = new EcAdd( /*addressing_mode=*/ 0x1234, /*p1X=*/ 0x1235, /*p1Y=*/ 0x1236, - /*p1IsInfinite=*/ 0, /*p2X=*/ 0x1237, /*p2Y=*/ 0x1238, - /*p2IsInfinite=*/ 1, /*dstOffset=*/ 0x1239, ); @@ -48,41 +44,24 @@ describe('EC Instructions', () => { it(`Should double correctly`, async () => { const x = new Field(Grumpkin.generator.x); const y = new Field(Grumpkin.generator.y); - const zero = new Uint1(0); context.machineState.memory.set(0, x); context.machineState.memory.set(1, y); - context.machineState.memory.set(2, zero); - context.machineState.memory.set(3, x); - context.machineState.memory.set(4, y); - context.machineState.memory.set(5, zero); - // context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - const pIsInfinite = context.machineState.memory.get(8).toNumber() === 1; - const actual = new Point( - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - pIsInfinite, + context.machineState.memory.set(2, x); + context.machineState.memory.set(3, y); + // context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, ); + + const actual = new Point(context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()); const expected = await Grumpkin.add(Grumpkin.generator, Grumpkin.generator); expect(actual).toEqual(expected); - expect(context.machineState.memory.get(8).toFr().equals(Fr.ZERO)).toBe(true); }); it('Should add correctly', async () => { const G2 = await Grumpkin.add(Grumpkin.generator, Grumpkin.generator); - const zero = new Uint1(0); const x1 = new Field(Grumpkin.generator.x); const y1 = new Field(Grumpkin.generator.y); @@ -91,36 +70,21 @@ describe('EC Instructions', () => { context.machineState.memory.set(0, x1); context.machineState.memory.set(1, y1); - context.machineState.memory.set(2, zero); - context.machineState.memory.set(3, x2); - context.machineState.memory.set(4, y2); - context.machineState.memory.set(5, zero); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - const actual = new Point( - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - false, + context.machineState.memory.set(2, x2); + context.machineState.memory.set(3, y2); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, ); + + const actual = new Point(context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()); const G3 = await Grumpkin.add(Grumpkin.generator, G2); expect(actual).toEqual(G3); - expect(context.machineState.memory.get(8).toFr().equals(Fr.ZERO)).toBe(true); }); it('Should add correctly with rhs being infinity', async () => { - const zero = new Uint1(0); - const one = new Uint1(1); + const zero = new Field(0); const x = new Field(Grumpkin.generator.x); const y = new Field(Grumpkin.generator.y); @@ -128,103 +92,67 @@ describe('EC Instructions', () => { // Point 1 is not infinity context.machineState.memory.set(0, x); context.machineState.memory.set(1, y); - context.machineState.memory.set(2, zero); // Point 2 is infinity - context.machineState.memory.set(3, x); - context.machineState.memory.set(4, y); - context.machineState.memory.set(5, one); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - expect([ - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - context.machineState.memory.get(8).toNumber(), - ]).toEqual([x.toFr(), y.toFr(), 0]); + context.machineState.memory.set(2, zero); + context.machineState.memory.set(3, zero); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, + ); + + expect([context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()]).toEqual([ + x.toFr(), + y.toFr(), + ]); }); it('Should add correctly with lhs being infinity', async () => { - const zero = new Uint1(0); - const one = new Uint1(1); + const zero = new Field(0); const x = new Field(Grumpkin.generator.x); const y = new Field(Grumpkin.generator.y); // Point 1 is infinity - context.machineState.memory.set(0, x); - context.machineState.memory.set(1, y); - context.machineState.memory.set(2, one); + context.machineState.memory.set(0, zero); + context.machineState.memory.set(1, zero); // Point 2 is not infinity - context.machineState.memory.set(3, x); - context.machineState.memory.set(4, y); - context.machineState.memory.set(5, zero); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - expect([ - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - context.machineState.memory.get(8).toNumber(), - ]).toEqual([x.toFr(), y.toFr(), 0]); + context.machineState.memory.set(2, x); + context.machineState.memory.set(3, y); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, + ); + + expect([context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()]).toEqual([ + x.toFr(), + y.toFr(), + ]); }); it('Should add correctly with both being infinity', async () => { - const one = new Uint1(1); - - const x = new Field(Grumpkin.generator.x); - const y = new Field(Grumpkin.generator.y); + const zero = new Field(0); // Point 1 is infinity - context.machineState.memory.set(0, x); - context.machineState.memory.set(1, y); - context.machineState.memory.set(2, one); + context.machineState.memory.set(0, zero); + context.machineState.memory.set(1, zero); // Point 2 is infinity - context.machineState.memory.set(3, x); - context.machineState.memory.set(4, y); - context.machineState.memory.set(5, one); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - expect([ - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - context.machineState.memory.get(8).toNumber(), - ]).toEqual([Fr.ZERO, Fr.ZERO, 1]); + context.machineState.memory.set(2, zero); + context.machineState.memory.set(3, zero); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, + ); + + expect([context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()]).toEqual([ + Fr.ZERO, + Fr.ZERO, + ]); }); it('Should add correctly with none infinity adding up to infinity', async () => { - const zero = new Uint1(0); - // Point 1 is a "random" point on the curve const x1 = new Field(2165030248772332382647339664685760681662697934905450801078761197378150920554n); const y1 = new Field(1518479793551399970960577643223827307749147426195887130444945641264602004320n); @@ -234,29 +162,19 @@ describe('EC Instructions', () => { context.machineState.memory.set(0, x1); context.machineState.memory.set(1, y1); - context.machineState.memory.set(2, zero); - context.machineState.memory.set(3, x2); - context.machineState.memory.set(4, y2); - context.machineState.memory.set(5, zero); - context.machineState.memory.set(6, new Uint32(6)); - - await new EcAdd( - /*addressing_mode=*/ 0, - /*p1X=*/ 0, - /*p1Y=*/ 1, - /*p1IsInfinite=*/ 2, - /*p2X=*/ 3, - /*p2Y=*/ 4, - /*p2IsInfinite=*/ 5, - /*dstOffset=*/ 6, - ).execute(context); - - expect([ - context.machineState.memory.get(6).toFr(), - context.machineState.memory.get(7).toFr(), - context.machineState.memory.get(8).toNumber(), - ]).toEqual([Fr.ZERO, Fr.ZERO, 1]); + context.machineState.memory.set(2, x2); + context.machineState.memory.set(3, y2); + context.machineState.memory.set(4, new Uint32(4)); + + await new EcAdd(/*addressing_mode=*/ 0, /*p1X=*/ 0, /*p1Y=*/ 1, /*p2X=*/ 2, /*p2Y=*/ 3, /*dstOffset=*/ 4).execute( + context, + ); + + expect([context.machineState.memory.get(4).toFr(), context.machineState.memory.get(5).toFr()]).toEqual([ + Fr.ZERO, + Fr.ZERO, + ]); }); }); @@ -265,29 +183,16 @@ describe('EC Instructions', () => { const validPoint = await Point.random(); const p1xOffset = 0; const p1yOffset = 1; - const p1IsInfiniteOffset = 2; - const p2xOffset = 3; - const p2yOffset = 4; - const p2IsInfiniteOffset = 5; - const dstOffset = 6; + const p2xOffset = 2; + const p2yOffset = 3; + const dstOffset = 4; context.machineState.memory.set(p1xOffset, new Field(new Fr(1))); // p1x (point is invalid) context.machineState.memory.set(p1yOffset, new Field(new Fr(1))); // p1y (point is invalid) - context.machineState.memory.set(p1IsInfiniteOffset, new Uint1(0)); // p1IsInfinite context.machineState.memory.set(p2xOffset, new Field(validPoint.x)); // p2x context.machineState.memory.set(p2yOffset, new Field(validPoint.y)); // p2y - context.machineState.memory.set(p2IsInfiniteOffset, new Uint1(validPoint.isInfinite ? 1 : 0)); // p2IsInfinite await expect( - new EcAdd( - /*addressing_mode=*/ 0, - p1xOffset, - p1yOffset, - p1IsInfiniteOffset, - p2xOffset, - p2yOffset, - p2IsInfiniteOffset, - dstOffset, - ).execute(context), + new EcAdd(/*addressing_mode=*/ 0, p1xOffset, p1yOffset, p2xOffset, p2yOffset, dstOffset).execute(context), ).rejects.toThrow(EcAddPointNotOnCurveError); }); @@ -295,29 +200,16 @@ describe('EC Instructions', () => { const validPoint = await Point.random(); const p1xOffset = 0; const p1yOffset = 1; - const p1IsInfiniteOffset = 2; - const p2xOffset = 3; - const p2yOffset = 4; - const p2IsInfiniteOffset = 5; - const dstOffset = 6; + const p2xOffset = 2; + const p2yOffset = 3; + const dstOffset = 4; context.machineState.memory.set(p1xOffset, new Field(validPoint.x)); // p1x context.machineState.memory.set(p1yOffset, new Field(validPoint.y)); // p1y - context.machineState.memory.set(p1IsInfiniteOffset, new Uint1(validPoint.isInfinite ? 1 : 0)); // p1IsInfinite context.machineState.memory.set(p2xOffset, new Field(new Fr(1))); // p2x (point is invalid) context.machineState.memory.set(p2yOffset, new Field(new Fr(1))); // p2y (point is invalid) - context.machineState.memory.set(p2IsInfiniteOffset, new Uint1(0)); // p2IsInfinite await expect( - new EcAdd( - /*addressing_mode=*/ 0, - p1xOffset, - p1yOffset, - p1IsInfiniteOffset, - p2xOffset, - p2yOffset, - p2IsInfiniteOffset, - dstOffset, - ).execute(context), + new EcAdd(/*addressing_mode=*/ 0, p1xOffset, p1yOffset, p2xOffset, p2yOffset, dstOffset).execute(context), ).rejects.toThrow(EcAddPointNotOnCurveError); }); }); diff --git a/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts b/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts index 19e3c1adc6ca..d21ca41561d3 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts @@ -2,7 +2,7 @@ import { Grumpkin } from '@aztec/foundation/crypto/grumpkin'; import { Point } from '@aztec/foundation/curves/grumpkin'; import type { AvmContext } from '../avm_context.js'; -import { Field, TypeTag, Uint1 } from '../avm_memory_types.js'; +import { Field, TypeTag } from '../avm_memory_types.js'; import { EcAddPointNotOnCurveError } from '../errors.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; import { Addressing } from './addressing_mode.js'; @@ -18,10 +18,8 @@ export class EcAdd extends Instruction { OperandType.UINT16, // indirect OperandType.UINT16, // p1X OperandType.UINT16, // p1Y - OperandType.UINT16, // p1IsInfinite OperandType.UINT16, // p2X OperandType.UINT16, // p2Y - OperandType.UINT16, // p2IsInfinite OperandType.UINT16, // dst ]; @@ -29,10 +27,8 @@ export class EcAdd extends Instruction { private addressingMode: number, private p1XOffset: number, private p1YOffset: number, - private p1IsInfiniteOffset: number, private p2XOffset: number, private p2YOffset: number, - private p2IsInfiniteOffset: number, private dstOffset: number, ) { super(); @@ -46,51 +42,38 @@ export class EcAdd extends Instruction { this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()), ); - const operands = [ - this.p1XOffset, - this.p1YOffset, - this.p1IsInfiniteOffset, - this.p2XOffset, - this.p2YOffset, - this.p2IsInfiniteOffset, - this.dstOffset, - ]; - const [p1XOffset, p1YOffset, p1IsInfiniteOffset, p2XOffset, p2YOffset, p2IsInfiniteOffset, dstOffset] = - addressing.resolve(operands, memory); + const operands = [this.p1XOffset, this.p1YOffset, this.p2XOffset, this.p2YOffset, this.dstOffset]; + const [p1XOffset, p1YOffset, p2XOffset, p2YOffset, dstOffset] = addressing.resolve(operands, memory); memory.checkTags(TypeTag.FIELD, p1XOffset, p1YOffset, p2XOffset, p2YOffset); - memory.checkTags(TypeTag.UINT1, p1IsInfiniteOffset, p2IsInfiniteOffset); const p1X = memory.get(p1XOffset); const p1Y = memory.get(p1YOffset); - const p1IsInfinite = memory.get(p1IsInfiniteOffset).toNumber() === 1; - const p1 = new Point(p1X.toFr(), p1Y.toFr(), p1IsInfinite); - if (!p1.isOnGrumpkin()) { + const p1 = new Point(p1X.toFr(), p1Y.toFr()); + if (!p1.isOnCurve()) { throw new EcAddPointNotOnCurveError(/*pointIndex=*/ 1, p1); } const p2X = memory.get(p2XOffset); const p2Y = memory.get(p2YOffset); - // unused. Point doesn't store this information - const p2IsInfinite = memory.get(p2IsInfiniteOffset).toNumber() === 1; - const p2 = new Point(p2X.toFr(), p2Y.toFr(), p2IsInfinite); - if (!p2.isOnGrumpkin()) { + const p2 = new Point(p2X.toFr(), p2Y.toFr()); + if (!p2.isOnCurve()) { throw new EcAddPointNotOnCurveError(/*pointIndex=*/ 2, p2); } let dest; - if (p1IsInfinite && p2IsInfinite) { - dest = Point.ZERO; - } else if (p1IsInfinite) { + if (p1.isInfinite && p2.isInfinite) { + dest = Point.INFINITY; + } else if (p1.isInfinite) { dest = p2; - } else if (p2IsInfinite) { + } else if (p2.isInfinite) { dest = p1; } else { // TS<>BB ecc add communication is broken for points that add up to infinity. // However, here we know that both points are on the curve, and that none is infinity // so we can check for the case where you add p + (-p) = infinity. if (p1.x.equals(p2.x) && !p1.y.equals(p2.y)) { - dest = Point.ZERO; + dest = Point.INFINITY; } else { dest = await Grumpkin.add(p1, p2); } @@ -99,7 +82,5 @@ export class EcAdd extends Instruction { // Important to use setSlice() and not set() in the two following statements as // this checks that the offsets lie within memory range. memory.setSlice(dstOffset, [new Field(dest.x), new Field(dest.y)]); - // Check representation of infinity for grumpkin - memory.setSlice(dstOffset + 2, [new Uint1(dest.equals(Point.ZERO) ? 1 : 0)]); } } diff --git a/yarn-project/simulator/src/public/fixtures/bulk_test.ts b/yarn-project/simulator/src/public/fixtures/bulk_test.ts index 0e600ad8be42..a551014e13fc 100644 --- a/yarn-project/simulator/src/public/fixtures/bulk_test.ts +++ b/yarn-project/simulator/src/public/fixtures/bulk_test.ts @@ -31,6 +31,19 @@ export async function bulkTest( const expectContractInstance = avmTestContract; const argsField = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + // Pinned grumpkin-Poseidon2 Schnorr signature (mirrors the C++ `pinned_test_vector_large` + // and noir-lang/schnorr v0.4.0's `pinned_vector_large`). Passing these in as calldata + // (rather than baking them into Noir as constants) keeps MSM + Poseidon2 from being folded + // by the Noir compiler. + const schnorrInputs = [ + Fr.fromHexString('0x065812e335a97c2108ea8cf4ccfe2f9dd6b117a0714f5e18461575be93f61da6'), // pubkey.x + Fr.fromHexString('0x1a915003e8ec534f9a15d926a7ded478e178468ccc4f28e236e67450a55ac622'), // pubkey.y + Fr.fromHexString('0xf3bc3b7147acb9c621fd9f72dbf15ffa'), // sig_s.lo + Fr.fromHexString('0x08599f379f0301dfefdbd0272554454d'), // sig_s.hi + Fr.fromHexString('0x97065383ebbbd76620398792bd259bc2'), // sig_e.lo + Fr.fromHexString('0x2ceaee87f45b7a417f0ffb05451a8c92'), // sig_e.hi + Fr.fromHexString('0x0123456789abcdef0fedcba9876543210123456789abcdef0fedcba987654321'), // message + ]; const args = [ argsField, argsU8, @@ -38,6 +51,8 @@ export async function bulkTest( /*expectedDeployer=*/ expectContractInstance.deployer, /*expectedClassId=*/ expectContractInstance.currentContractClassId, /*expectedInitializationHash=*/ expectContractInstance.initializationHash, + /*expectedImmutablesHash=*/ expectContractInstance.immutablesHash, + /*schnorrInputs=*/ schnorrInputs, /*skip_strictly_limited_side_effects=*/ false, ]; @@ -121,6 +136,15 @@ export async function megaBulkTest( //const argsField7 = [15, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); //const argsField8 = [17, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + const schnorrInputs = [ + Fr.fromHexString('0x065812e335a97c2108ea8cf4ccfe2f9dd6b117a0714f5e18461575be93f61da6'), // pubkey.x + Fr.fromHexString('0x1a915003e8ec534f9a15d926a7ded478e178468ccc4f28e236e67450a55ac622'), // pubkey.y + Fr.fromHexString('0xf3bc3b7147acb9c621fd9f72dbf15ffa'), // sig_s.lo + Fr.fromHexString('0x08599f379f0301dfefdbd0272554454d'), // sig_s.hi + Fr.fromHexString('0x97065383ebbbd76620398792bd259bc2'), // sig_e.lo + Fr.fromHexString('0x2ceaee87f45b7a417f0ffb05451a8c92'), // sig_e.hi + Fr.fromHexString('0x0123456789abcdef0fedcba9876543210123456789abcdef0fedcba987654321'), // message + ]; const genArgs = (argsField: Fr[]) => [ argsField, argsU8, @@ -128,6 +152,8 @@ export async function megaBulkTest( /*expectedDeployer=*/ expectContractInstance.deployer.toField(), /*expectedClassId=*/ expectContractInstance.currentContractClassId.toField(), /*expectedInitializationHash=*/ expectContractInstance.initializationHash.toField(), + /*expectedImmutablesHash=*/ expectContractInstance.immutablesHash.toField(), + /*schnorrInputs=*/ schnorrInputs, // Must skip strictly limited side effects (logs, messages) so we can spam the bulk test several times. /*skip_strictly_limited_side_effects=*/ true, ]; diff --git a/yarn-project/simulator/src/public/fixtures/opcode_spammer.ts b/yarn-project/simulator/src/public/fixtures/opcode_spammer.ts index 88e9a1663eb3..dd4322029d81 100644 --- a/yarn-project/simulator/src/public/fixtures/opcode_spammer.ts +++ b/yarn-project/simulator/src/public/fixtures/opcode_spammer.ts @@ -1339,20 +1339,16 @@ export const SPAM_CONFIGS: Partial> = { setup: [ { offset: 0, value: new Field(Grumpkin.generator.x) }, // p1X = G.x { offset: 1, value: new Field(Grumpkin.generator.y) }, // p1Y = G.y - { offset: 2, value: new Uint1(0n) }, // p1IsInfinite = false - { offset: 3, value: new Field(Grumpkin.generator.x) }, // p2X = G.x - { offset: 4, value: new Field(Grumpkin.generator.y) }, // p2Y = G.y - { offset: 5, value: new Uint1(0n) }, // p2IsInfinite = false + { offset: 2, value: new Field(Grumpkin.generator.x) }, // p2X = G.x + { offset: 3, value: new Field(Grumpkin.generator.y) }, // p2Y = G.y ], targetInstructions: () => [ new EcAdd( /*addressing_mode=*/ 0, /*p1XOffset=*/ 0, /*p1YOffset=*/ 1, - /*p1IsInfiniteOffset=*/ 2, - /*p2XOffset=*/ 3, - /*p2YOffset=*/ 4, - /*p2IsInfiniteOffset=*/ 5, + /*p2XOffset=*/ 2, + /*p2YOffset=*/ 3, /*dstOffset=*/ 0, ), ], diff --git a/yarn-project/simulator/src/public/fixtures/utils.ts b/yarn-project/simulator/src/public/fixtures/utils.ts index 2c0a5a275b79..d1e4c3532863 100644 --- a/yarn-project/simulator/src/public/fixtures/utils.ts +++ b/yarn-project/simulator/src/public/fixtures/utils.ts @@ -233,17 +233,13 @@ export async function addNewContractInstanceToTx( contractInstance: ContractInstanceWithAddress, skipNullifierInsertion = false, ) { - // can't use publicKeys.toFields() because it includes isInfinite which - // is not broadcast in such private logs + // Only ivpk_m is broadcast as a point (x, y); the other three keys are hashes. const publicKeysAsFields = [ - contractInstance.publicKeys.masterNullifierPublicKey.x, - contractInstance.publicKeys.masterNullifierPublicKey.y, - contractInstance.publicKeys.masterIncomingViewingPublicKey.x, - contractInstance.publicKeys.masterIncomingViewingPublicKey.y, - contractInstance.publicKeys.masterOutgoingViewingPublicKey.x, - contractInstance.publicKeys.masterOutgoingViewingPublicKey.y, - contractInstance.publicKeys.masterTaggingPublicKey.x, - contractInstance.publicKeys.masterTaggingPublicKey.y, + contractInstance.publicKeys.npkMHash, + contractInstance.publicKeys.ivpkM.x, + contractInstance.publicKeys.ivpkM.y, + contractInstance.publicKeys.ovpkMHash, + contractInstance.publicKeys.tpkMHash, ]; const logFields = [ CONTRACT_INSTANCE_PUBLISHED_EVENT_TAG, @@ -252,6 +248,7 @@ export async function addNewContractInstanceToTx( new Fr(contractInstance.salt), contractInstance.currentContractClassId, contractInstance.initializationHash, + contractInstance.immutablesHash, ...publicKeysAsFields, contractInstance.deployer.toField(), ]; diff --git a/yarn-project/simulator/src/public/hinting_db_sources.ts b/yarn-project/simulator/src/public/hinting_db_sources.ts index 85f8ab422ccf..71c7a99c9239 100644 --- a/yarn-project/simulator/src/public/hinting_db_sources.ts +++ b/yarn-project/simulator/src/public/hinting_db_sources.ts @@ -83,6 +83,7 @@ export class HintingPublicContractsDB implements PublicContractsDBInterface { instance.currentContractClassId, instance.originalContractClassId, instance.initializationHash, + instance.immutablesHash, instance.publicKeys, ), ); diff --git a/yarn-project/simulator/src/public/public_processor/apps_tests/deployments.test.ts b/yarn-project/simulator/src/public/public_processor/apps_tests/deployments.test.ts index 1183b99f0cfd..d8a6353581f3 100644 --- a/yarn-project/simulator/src/public/public_processor/apps_tests/deployments.test.ts +++ b/yarn-project/simulator/src/public/public_processor/apps_tests/deployments.test.ts @@ -249,7 +249,7 @@ describe.each([ expect(processedTxs[0].revertCode).toEqual(RevertCode.OK); // Second tx should revert in app logic (failed transfer) - expect(processedTxs[1].revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(processedTxs[1].revertCode).toEqual(RevertCode.REVERTED); // Third tx should succeed (mint), proving first contract is still accessible expect(processedTxs[2].revertCode).toEqual(RevertCode.OK); diff --git a/yarn-project/simulator/src/public/public_processor/public_processor.test.ts b/yarn-project/simulator/src/public/public_processor/public_processor.test.ts index abc3aedf918e..8cb98a15451b 100644 --- a/yarn-project/simulator/src/public/public_processor/public_processor.test.ts +++ b/yarn-project/simulator/src/public/public_processor/public_processor.test.ts @@ -21,14 +21,14 @@ import { strict as assert } from 'assert'; import { type MockProxy, mock } from 'jest-mock-extended'; import { PublicContractsDB } from '../public_db_sources.js'; -import type { PublicTxSimulator } from '../public_tx_simulator/public_tx_simulator.js'; +import type { PublicTxSimulatorInterface } from '../public_tx_simulator/index.js'; import { GuardedMerkleTreeOperations } from './guarded_merkle_tree.js'; import { PublicProcessor } from './public_processor.js'; describe('public_processor', () => { let merkleTree: MockProxy; let contractsDB: PublicContractsDB; - let publicTxSimulator: MockProxy; + let publicTxSimulator: MockProxy>; let mockedEnqueuedCallsResult: PublicTxResult; @@ -78,7 +78,7 @@ describe('public_processor', () => { beforeEach(() => { merkleTree = mock(); contractsDB = new PublicContractsDB(mock()); - publicTxSimulator = mock(); + publicTxSimulator = mock>(); const stateReference = StateReference.empty(); mockedEnqueuedCallsResult = PublicTxResult.empty(); @@ -136,7 +136,7 @@ describe('public_processor', () => { it('runs a tx with reverted enqueued public calls', async function () { const tx = await mockTxWithPublicCalls(); - mockedEnqueuedCallsResult.revertCode = RevertCode.APP_LOGIC_REVERTED; + mockedEnqueuedCallsResult.revertCode = RevertCode.REVERTED; const [processed, failed] = await processor.process([tx]); @@ -239,6 +239,32 @@ describe('public_processor', () => { expect(failed.length).toBe(1); }); + it('aborts in-flight tx processing and cancels the simulator', async function () { + const tx = await mockTxWithPublicCalls(); + const controller = new AbortController(); + + let finishSimulation!: () => void; + const simulationFinished = new Promise(resolve => { + finishSimulation = resolve; + }); + + publicTxSimulator.simulate.mockImplementation(async () => { + controller.abort(); + await simulationFinished; + return mockedEnqueuedCallsResult; + }); + publicTxSimulator.cancel.mockImplementation(() => { + finishSimulation(); + return Promise.resolve(); + }); + + const [processed, failed] = await processor.process([tx], { signal: controller.signal }); + + expect(processed).toEqual([]); + expect(failed).toEqual([]); + expect(publicTxSimulator.cancel).toHaveBeenCalled(); + }); + // Flakey timing test that's totally dependent on system load/architecture etc. it.skip('does not go past the deadline', async function () { const txs = await timesParallel(3, seed => mockTxWithPublicCalls({ seed })); diff --git a/yarn-project/simulator/src/public/public_processor/public_processor.ts b/yarn-project/simulator/src/public/public_processor/public_processor.ts index 6f8523d6096b..8a4e9c16c463 100644 --- a/yarn-project/simulator/src/public/public_processor/public_processor.ts +++ b/yarn-project/simulator/src/public/public_processor/public_processor.ts @@ -3,7 +3,7 @@ import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider, Timer, elapsed, executeTimeout } from '@aztec/foundation/timer'; +import { DateProvider, Timer, elapsed, execWithSignal } from '@aztec/foundation/timer'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry'; import { computeFeePayerBalanceLeafSlot, computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice'; @@ -123,6 +123,17 @@ class PublicProcessorTimeoutError extends Error { } } +class PublicProcessorAbortError extends Error { + constructor(message: string = 'Aborted while processing tx') { + super(message); + this.name = 'PublicProcessorAbortError'; + } +} + +function isPublicProcessorInterruptError(err: any) { + return err?.name === 'PublicProcessorTimeoutError' || err?.name === 'PublicProcessorAbortError'; +} + /** * Converts Txs lifted from the P2P module into ProcessedTx objects by executing * any public function calls in them. Txs with private calls only are unaffected. @@ -159,7 +170,7 @@ export class PublicProcessor implements Traceable { limits: PublicProcessorLimits = {}, validator: PublicProcessorValidator = {}, ): Promise<[ProcessedTx[], FailedTx[], Tx[], NestedProcessReturnValues[], DebugLog[]]> { - const { maxTransactions, deadline, maxBlockGas, maxBlobFields, isBuildingProposal } = limits; + const { maxTransactions, deadline, maxBlockGas, maxBlobFields, isBuildingProposal, signal } = limits; const { preprocessValidator, nullifierCache } = validator; const result: ProcessedTx[] = []; const usedTxs: Tx[] = []; @@ -182,11 +193,15 @@ export class PublicProcessor implements Traceable { break; } - // Bail if we've hit the deadline + // Bail if we've hit the deadline or have been interrupted. if (deadline && this.dateProvider.now() > +deadline) { this.log.warn(`Stopping tx processing due to timeout.`); break; } + if (signal?.aborted) { + this.log.warn(`Stopping tx processing due to abort signal.`); + break; + } const txHash = tx.getTxHash().toString(); @@ -240,7 +255,7 @@ export class PublicProcessor implements Traceable { try { const [txProcessingTimeMs, [processedTx, returnValues, txDebugLogs]] = await elapsed(() => - this.processTx(tx, deadline), + this.processTx(tx, deadline, signal), ); // Inject a fake processing failure after N txs if requested @@ -311,15 +326,11 @@ export class PublicProcessor implements Traceable { // Commit the tx-level contracts checkpoint on success this.contractsDB.commitCheckpoint(); } catch (err: any) { - if (err?.name === 'PublicProcessorTimeoutError') { - this.log.warn(`Stopping tx processing due to timeout.`); - // We hit the transaction execution deadline. - // There may still be a transaction executing on a worker thread (C++ via NAPI). - // Signal cancellation AND WAIT for the simulation to actually stop. - // This is critical because C++ might be in the middle of a slow operation (e.g., pad_trees) - // and won't check the cancellation flag until that operation completes. - // Without waiting, we'd proceed to revert checkpoints while C++ is still writing to state. - // Wait for C++ to stop gracefully. + if (isPublicProcessorInterruptError(err)) { + const interruptReason = err.name === 'PublicProcessorTimeoutError' ? 'timeout' : 'abort signal'; + this.log.warn(`Stopping tx processing due to ${interruptReason}.`); + // The tx may still be executing on a worker thread (C++ via NAPI). + // Signal cancellation AND WAIT for the simulation to actually stop before touching fork checkpoints. await this.publicTxSimulator.cancel?.(); // Now stop the guarded fork to prevent any further TS-side access to the world state. @@ -407,9 +418,10 @@ export class PublicProcessor implements Traceable { private async processTx( tx: Tx, deadline: Date | undefined, + signal: AbortSignal | undefined, ): Promise<[ProcessedTx, NestedProcessReturnValues[], DebugLog[]]> { const [time, [processedTx, returnValues, debugLogs]] = await elapsed(() => - this.processTxWithinDeadline(tx, deadline), + this.processTxWithinDeadline(tx, deadline, signal), ); this.log.verbose( @@ -463,10 +475,11 @@ export class PublicProcessor implements Traceable { this.metrics.recordTreeInsertions(Number(treeInsertionEnd - treeInsertionStart) / 1_000); } - /** Processes the given tx within deadline. Returns timeout if deadline is hit. */ + /** Processes the given tx within deadline or until the signal is aborted. */ private async processTxWithinDeadline( tx: Tx, deadline: Date | undefined, + signal: AbortSignal | undefined, ): Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined, DebugLog[]]> { const innerProcessFn: () => Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined, DebugLog[]]> = tx.hasPublicCalls() ? () => this.processTxWithPublicCalls(tx) : () => this.processPrivateOnlyTx(tx); @@ -483,27 +496,38 @@ export class PublicProcessor implements Traceable { } : innerProcessFn; - if (!deadline) { + const processingSignal = this.getProcessingSignal(tx, deadline, signal); + if (!processingSignal) { return await processFn(); } - const txHash = tx.getTxHash(); + return await execWithSignal( + () => processFn(), + processingSignal, + signal => + signal.reason?.name === 'TimeoutError' ? new PublicProcessorTimeoutError() : new PublicProcessorAbortError(), + ); + } + + private getProcessingSignal(tx: Tx, deadline: Date | undefined, signal: AbortSignal | undefined) { + if (!deadline) { + return signal; + } + const timeout = +deadline - this.dateProvider.now(); if (timeout <= 0) { throw new PublicProcessorTimeoutError(); } + const txHash = tx.getTxHash(); this.log.debug(`Processing tx ${txHash.toString()} within ${timeout}ms`, { deadline: deadline.toISOString(), now: new Date(this.dateProvider.now()).toISOString(), txHash, }); - return await executeTimeout( - () => processFn(), - timeout, - () => new PublicProcessorTimeoutError(), - ); + const timeoutSignal = AbortSignal.timeout(timeout); + return signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal; } /** diff --git a/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.test.ts b/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.test.ts index 337bd982431d..64a6cf8b585b 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.test.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.test.ts @@ -691,7 +691,7 @@ describe('public_tx_simulator', () => { const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); // tx reports app logic failure expect(txResult.findRevertReason()).toEqual(appLogicFailure); @@ -812,7 +812,7 @@ describe('public_tx_simulator', () => { const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.TEARDOWN_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); expect(txResult.findRevertReason()).toEqual(teardownFailure); const expectedSetupGas = enqueuedCallGasUsed; @@ -921,7 +921,7 @@ describe('public_tx_simulator', () => { const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.BOTH_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); // tx reports app logic failure expect(txResult.findRevertReason()).toEqual(appLogicFailure); @@ -1246,7 +1246,7 @@ describe('public_tx_simulator', () => { }); const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); const revertReason = txResult.findRevertReason(); expect(revertReason).toBeDefined(); expect(revertReason?.getOriginalMessage()).toContain(new NullifierLimitReachedError().message); @@ -1269,7 +1269,7 @@ describe('public_tx_simulator', () => { throw new NoteHashLimitReachedError(); }); const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); const revertReason = txResult.findRevertReason(); expect(revertReason).toBeDefined(); expect(revertReason?.getOriginalMessage()).toContain(new NoteHashLimitReachedError().message); @@ -1296,7 +1296,7 @@ describe('public_tx_simulator', () => { }); const txResult = await simulator.simulate(tx); - expect(txResult.revertCode).toEqual(RevertCode.APP_LOGIC_REVERTED); + expect(txResult.revertCode).toEqual(RevertCode.REVERTED); const revertReason = txResult.findRevertReason(); expect(revertReason).toBeDefined(); expect(revertReason?.getOriginalMessage()).toContain(new L2ToL1MessageLimitReachedError().message); diff --git a/yarn-project/slasher/README.md b/yarn-project/slasher/README.md index fd8aa439b041..fca7713ef588 100644 --- a/yarn-project/slasher/README.md +++ b/yarn-project/slasher/README.md @@ -81,16 +81,10 @@ Key features: List of all slashable offenses in the system: ### DATA_WITHHOLDING -**Description**: The data required for proving an epoch was not made publicly available. -**Detection**: EpochPruneWatcher detects when an epoch cannot be proven due to missing data. -**Target**: Committee members of the affected epoch. -**Time Unit**: Epoch-based offense. - -### VALID_EPOCH_PRUNED -**Description**: An epoch was not successfully proven within the proof submission window. -**Detection**: EpochPruneWatcher monitors epochs that expire without valid proofs. -**Target**: Committee members of the unpruned epoch. -**Time Unit**: Epoch-based offense. +**Description**: The transaction data for a published checkpoint was not made available within the tolerance window. +**Detection**: DataWithholdingWatcher checks each published checkpoint's txs against the local mempool once `slashDataWithholdingToleranceSlots` full slots have elapsed past the checkpoint's slot (i.e. at `slotStart(checkpoint.slot + slashDataWithholdingToleranceSlots + 1)`). +**Target**: Validators who attested to the checkpoint. +**Time Unit**: Slot-based offense (the checkpoint's slot). ### INACTIVITY **Description**: A proposer failed to attest or propose blocks during their assigned slots. @@ -116,15 +110,15 @@ List of all slashable offenses in the system: **Target**: Block proposer. **Time Unit**: Slot-based offense. -### ATTESTED_DESCENDANT_OF_INVALID -**Description**: A committee member attested to a block built on top of an invalid ancestor. -**Detection**: AttestationsBlockWatcher tracks invalid blocks and their descendants. -**Target**: Committee members who attested to the descendant block. +### PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS +**Description**: A proposer published a checkpoint to L1 that builds on an invalid checkpoint (one with invalid or insufficient attestations). +**Detection**: AttestationsBlockWatcher tracks invalid checkpoints and their descendants. +**Target**: Proposer of the descendant checkpoint. **Time Unit**: Slot-based offense. ### DUPLICATE_PROPOSAL -**Description**: A proposer sent multiple block or checkpoint proposals for the same position (slot and indexWithinCheckpoint for blocks, or slot for checkpoints) with different content. Since each slot has exactly one designated proposer, sending conflicting proposals is equivocation. -**Detection**: Detected in the P2P layer when proposals are received. The AttestationPool tracks proposals by position; when a second proposal arrives for the same position with a different archive, it flags the duplicate. The first duplicate is propagated (Accept) so other validators can witness the offense. +**Description**: A proposer sent multiple block or checkpoint proposals for the same position (slot and indexWithinCheckpoint for blocks, or slot for checkpoints) with different content. Since each slot has exactly one designated proposer, sending conflicting proposals is equivocation. This also covers the case where a proposer broadcasts one checkpoint proposal via P2P but submits a different checkpoint to L1 for the same slot. +**Detection**: Detected in two places. (1) The P2P layer flags duplicates when a second proposal arrives for the same position with a different archive; the AttestationPool tracks proposals by position and the first duplicate is propagated (Accept) so other validators can witness the offense. (2) CheckpointEquivocationWatcher compares the archive root of each L1-confirmed checkpoint against retained signed P2P checkpoint proposals from the same slot's proposer and flags any mismatch. **Target**: Proposer who broadcast the duplicate proposal. **Time Unit**: Slot-based offense. @@ -134,6 +128,12 @@ List of all slashable offenses in the system: **Target**: Committee members who attested in the invalid proposal slot. **Time Unit**: Slot-based offense. +### BROADCASTED_INVALID_CHECKPOINT_PROPOSAL +**Description**: A proposer broadcast an invalid checkpoint proposal, either one that terminates before a higher-index block proposal signed by the same proposer in the same slot, one whose signed header does not match deterministic validator recomputation, or one with a malformed fee asset price modifier. +**Detection**: BroadcastedInvalidCheckpointProposalWatcher scans retained P2P proposal evidence and compares checkpoint archive roots to signed block proposals from the same slot and signer. ValidatorClient also validates checkpoint proposals during the all-nodes callback and emits this offense when checkpoint header recomputation fails or the signed fee asset price modifier is malformed. +**Target**: Proposer who broadcast the invalid checkpoint proposal. +**Time Unit**: Slot-based offense. + ## Configuration ### L1 System Settings (L1ContractsConfig) @@ -150,26 +150,31 @@ Considerations: - The `slashingQuorumSize` should be more than half and less than the total number of validators in a round, so that we require a majority to slash. The number of validators in a round is the committee size times the number of epochs in a round. - The bigger a `slashingRoundSizeInEpochs`, the bigger the upper bound on the quorum size. This increases security, as we need more validators to agree before slashing. However, it also makes slashing slower, and more expensive to execute in terms of gas. -- The `slashingOffsetInRounds` is required because the validators in a given slashing round must vote for _past_ offenses. Otherwise, if someone commits an offense near the end of a round, they can get away with their offense without the validators being able to collect enough votes to slash them. The offset needs to be big enough so that all offenses are discoverable, so this value should be strictly greater than the proof submission window in order to be able to slash for epoch prunes or data withholding. +- The `slashingOffsetInRounds` is required because the validators in a given slashing round must vote for _past_ offenses. Otherwise, if someone commits an offense near the end of a round, they can get away with their offense without the validators being able to collect enough votes to slash them. The offset needs to be big enough so that all offenses are discoverable, so this value should be strictly greater than the data-withholding tolerance window so that there is time to detect missing data and vote. - The `slashingExecutionDelayInRounds` allows vetoers to stop an invalid slash. This should be large enough to give vetoers time to act, but strictly smaller than the validator exit window, so an offender cannot escape before they are slashed. It should also be small enough so that an offender that would be kicked out does not get picked up to be a committee member again before their slash is executed. In other words, if a validator commits a serious enough offense that we want them out of the validator set as soon as possible, the execution delay should not allow them to be chosen to participate in another committee. ### Local Node Configuration (SlasherConfig) These settings are configured locally on each validator node: +Block and checkpoint validation settings are expected to be the same across all validators. Slashing relies on +validators making the same deterministic validity decisions for block and checkpoint proposals; operators should not run +with divergent validation limits. + - `slashGracePeriodL2Slots`: Number of initial L2 slots where slashing is disabled - `slashOffenseExpirationRounds`: Number of rounds after which pending offenses expire - `slashValidatorsAlways`: Array of validator addresses that should always be slashed - `slashValidatorsNever`: Array of validator addresses that should never be slashed (own validator addresses are automatically added to this list) - `slashInactivityTargetPercentage`: Percentage of misses during an epoch to be slashed for INACTIVITY - `slashInactivityConsecutiveEpochThreshold`: How many consecutive inactive epochs are needed to trigger an INACTIVITY slash on a validator -- `slashPrunePenalty`: Penalty for VALID_EPOCH_PRUNED - `slashDataWithholdingPenalty`: Penalty for DATA_WITHHOLDING +- `slashDataWithholdingToleranceSlots`: Number of full L2 slots to wait after a checkpoint's slot before declaring its txs missing - `slashInactivityPenalty`: Penalty for INACTIVITY - `slashBroadcastedInvalidBlockPenalty`: Penalty for BROADCASTED_INVALID_BLOCK_PROPOSAL +- `slashBroadcastedInvalidCheckpointProposalPenalty`: Penalty for BROADCASTED_INVALID_CHECKPOINT_PROPOSAL - `slashDuplicateProposalPenalty`: Penalty for DUPLICATE_PROPOSAL - `slashProposeInvalidAttestationsPenalty`: Penalty for PROPOSED_INSUFFICIENT_ATTESTATIONS and PROPOSED_INCORRECT_ATTESTATIONS -- `slashAttestDescendantOfInvalidPenalty`: Penalty for ATTESTED_DESCENDANT_OF_INVALID +- `slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty`: Penalty for PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS - `slashAttestInvalidCheckpointProposalPenalty`: Penalty for ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL - `slashUnknownPenalty`: Default penalty for unknown offense types - `slashMaxPayloadSize`: Limits the number of **unique validators** (across all committees and epochs in a round) that receive non-zero votes. When this cap is hit, the lowest-severity validator-epoch pairs are zeroed out first, so the most severe slashes are always preserved. Note that multiple offenses for the same validator in the same epoch are summed and counted as a single validator entry against this limit. @@ -187,25 +192,34 @@ Details about specific offenses in the system: Inactivity slashing is one of the most critical, since it allows purging validators that are not fulfilling their duties, which could potentially bring the chain to a halt. This slashing must be aggressive enough to balance out the rate of the entry queue, in case the queue is filled with inactive validators. Furthermore, if enough inactive validators join the system, it may become impossible to gather enough quorum to pass any governance proposal. -Inactivity slashing is handled by the `Sentinel` which monitors performance of all validators slot-by-slot. With the multiple-blocks-per-slot model, block proposals and checkpoints are distinct concepts: proposers build multiple blocks per slot, but attestations are only for checkpoints. After each slot, the sentinel assigns one of the following to the proposer for the slot: -- `checkpoint-mined` if the checkpoint was added to L1 -- `checkpoint-proposed` if the checkpoint received at least one attestation, but didn't make it to L1 -- `checkpoint-missed` if blocks were proposed but the checkpoint received no attestations -- `blocks-missed` if no block proposals were sent for this slot at all +Inactivity slashing is handled by the `Sentinel` (in `aztec-node/src/sentinel/`), which monitors performance of all validators slot-by-slot. With the multiple-blocks-per-slot model, block proposals and checkpoints are distinct concepts: proposers build multiple blocks per slot, but attestations are only for checkpoints. After each slot, the sentinel assigns one of the following to the proposer for the slot, in highest-confidence order: + +- `checkpoint-mined` — a checkpoint covering this slot has landed on L1 +- `checkpoint-valid` — the local node re-executed a checkpoint proposal for this slot successfully +- `checkpoint-invalid` — the local node re-executed a checkpoint proposal for this slot and rejected it (header / archive / out-hash mismatch, limit breach, etc.). Proposer-fault +- `checkpoint-unvalidated` — a checkpoint proposal arrived but the local node could not validate it (missing blocks/txs, timeout). Treated as proposer-fault +- `checkpoint-missed` — block proposals seen on P2P but no checkpoint proposal at all +- `blocks-missed` — no block proposals seen for this slot at all + +Re-execution outcomes are read from the `CheckpointReexecutionTracker`, which the validator client populates at every early-return in `validateCheckpointProposal`. The same tracker is consumed by the data-withholding watcher via `hasReexecuted(checkpointNumber, archiveRoot)`. + +Each non-proposer committee member is assigned one of: +- `attestation-sent` if their checkpoint attestation was seen on L1 or on the P2P network +- `attestation-missed` if the proposer status was `checkpoint-mined` or `checkpoint-valid` but no checkpoint attestation was seen +- none in any other case -And assigns one of the following to each validator (these refer to checkpoint attestations): -- `attestation-sent` if there was a `checkpoint-proposed` or `checkpoint-mined` and a checkpoint attestation from this validator was seen on either on L1 or on the P2P network -- `attestation-missed` if there was a `checkpoint-proposed` or `checkpoint-mined` but no checkpoint attestation was seen -- none if the slot was a `blocks-missed` +`blocks-missed`, `checkpoint-missed`, `checkpoint-invalid`, and `checkpoint-unvalidated` all count as proposer inactivity for the slot. -Both `blocks-missed` and `checkpoint-missed` count as proposer inactivity. +The sentinel evaluates an epoch once `sentinelEpochEndBufferSlots` (default 2) L2 slots have elapsed past the epoch's last slot AND the per-slot recorder has covered that last slot. Epoch evaluation does not wait for an L1 proof — it relies on local-state evidence (the re-execution tracker plus L1 checkpoint landings) — so inactive validators are slashed promptly regardless of prover availability. -Once an epoch is proven, the sentinel computes the _proven performance_ for the epoch for each validator. Note that we wait until the epoch is proven so we know that the data for all blocks in the epoch was available, and validators who did not attest were effectively inactive. Then, for each validator such that: +At end-of-epoch evaluation, for each validator such that: ``` -total_failures = count(blocks-missed) + count(checkpoint-missed) + count(attestation-missed) +total_failures = count(blocks-missed) + count(checkpoint-missed) + + count(checkpoint-invalid) + count(checkpoint-unvalidated) + + count(attestation-missed) total = count(checkpoint-*) + count(blocks-*) + count(attestation-*) -total_failures / total >= slash_inactivity_target_percentage +total_failures / total >= slashInactivityTargetPercentage ``` -They are voted to be slashed for inactivity. Note that, if `slashInactivityConsecutiveEpochThreshold` is greater than one, we first check if the above is true for the last `threshold` times the given validator was part of a committee, and only then trigger the offense. +they are voted to be slashed for inactivity. If `slashInactivityConsecutiveEpochThreshold` is greater than one, the above must also hold for the last `threshold` times the validator was part of a committee. diff --git a/yarn-project/slasher/src/config.ts b/yarn-project/slasher/src/config.ts index 26102d3bb805..ddc934f02b62 100644 --- a/yarn-project/slasher/src/config.ts +++ b/yarn-project/slasher/src/config.ts @@ -16,16 +16,19 @@ export const DefaultSlasherConfig: SlasherConfig = { slashOverridePayload: undefined, slashValidatorsAlways: [], // Empty by default slashValidatorsNever: [], // Empty by default - slashPrunePenalty: BigInt(slasherDefaultEnv.SLASH_PRUNE_PENALTY), slashDataWithholdingPenalty: BigInt(slasherDefaultEnv.SLASH_DATA_WITHHOLDING_PENALTY), + slashDataWithholdingToleranceSlots: slasherDefaultEnv.SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS, slashInactivityTargetPercentage: slasherDefaultEnv.SLASH_INACTIVITY_TARGET_PERCENTAGE, slashInactivityConsecutiveEpochThreshold: slasherDefaultEnv.SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD, slashBroadcastedInvalidBlockPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_BLOCK_PENALTY), + slashBroadcastedInvalidCheckpointProposalPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY), slashDuplicateProposalPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_PROPOSAL_PENALTY), slashDuplicateAttestationPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_ATTESTATION_PENALTY), slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY), slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY), - slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY), + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: BigInt( + slasherDefaultEnv.SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY, + ), slashAttestInvalidCheckpointProposalPenalty: BigInt( slasherDefaultEnv.SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY, ), @@ -66,21 +69,27 @@ export const slasherConfigMappings: ConfigMappingsType = { .map(addr => EthAddress.fromString(addr)), defaultValue: DefaultSlasherConfig.slashValidatorsNever, }, - slashPrunePenalty: { - env: 'SLASH_PRUNE_PENALTY', - description: 'Penalty amount for slashing validators of a valid pruned epoch (set to 0 to disable).', - ...bigintConfigHelper(DefaultSlasherConfig.slashPrunePenalty), - }, slashDataWithholdingPenalty: { env: 'SLASH_DATA_WITHHOLDING_PENALTY', description: 'Penalty amount for slashing validators for data withholding (set to 0 to disable).', ...bigintConfigHelper(DefaultSlasherConfig.slashDataWithholdingPenalty), }, + slashDataWithholdingToleranceSlots: { + env: 'SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS', + description: + 'Number of full L2 slots that must elapse after a checkpoint slot before declaring its txs missing and slashing its attesters for data withholding.', + ...numberConfigHelper(DefaultSlasherConfig.slashDataWithholdingToleranceSlots), + }, slashBroadcastedInvalidBlockPenalty: { env: 'SLASH_INVALID_BLOCK_PENALTY', description: 'Penalty amount for slashing a validator for an invalid block proposed via p2p.', ...bigintConfigHelper(DefaultSlasherConfig.slashBroadcastedInvalidBlockPenalty), }, + slashBroadcastedInvalidCheckpointProposalPenalty: { + env: 'SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY', + description: 'Penalty amount for slashing a validator for an invalid checkpoint proposal proposed via p2p.', + ...bigintConfigHelper(DefaultSlasherConfig.slashBroadcastedInvalidCheckpointProposalPenalty), + }, slashDuplicateProposalPenalty: { env: 'SLASH_DUPLICATE_PROPOSAL_PENALTY', description: 'Penalty amount for slashing a validator for sending duplicate proposals.', @@ -124,11 +133,11 @@ export const slasherConfigMappings: ConfigMappingsType = { description: 'Penalty amount for slashing a proposer that proposed invalid attestations (set to 0 to disable).', ...bigintConfigHelper(DefaultSlasherConfig.slashProposeInvalidAttestationsPenalty), }, - slashAttestDescendantOfInvalidPenalty: { - env: 'SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY', + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: { + env: 'SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY', description: - 'Penalty amount for slashing a validator that attested to a descendant of an invalid block (set to 0 to disable).', - ...bigintConfigHelper(DefaultSlasherConfig.slashAttestDescendantOfInvalidPenalty), + 'Penalty amount for slashing a proposer that published a checkpoint building on an invalid checkpoint (set to 0 to disable).', + ...bigintConfigHelper(DefaultSlasherConfig.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty), }, slashAttestInvalidCheckpointProposalPenalty: { env: 'SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY', diff --git a/yarn-project/slasher/src/index.ts b/yarn-project/slasher/src/index.ts index 797815fceec6..d947aad82568 100644 --- a/yarn-project/slasher/src/index.ts +++ b/yarn-project/slasher/src/index.ts @@ -1,6 +1,8 @@ export * from './config.js'; -export * from './watchers/epoch_prune_watcher.js'; +export * from './watchers/data_withholding_watcher.js'; export * from './watchers/attestations_block_watcher.js'; +export * from './watchers/broadcasted_invalid_checkpoint_proposal_watcher.js'; +export * from './watchers/checkpoint_equivocation_watcher.js'; export * from './slasher_client.js'; export * from './slash_offenses_collector.js'; export * from './slasher_client_interface.js'; diff --git a/yarn-project/slasher/src/slash_offenses_collector.test.ts b/yarn-project/slasher/src/slash_offenses_collector.test.ts index c599ac0866a8..01b7957d2fdd 100644 --- a/yarn-project/slasher/src/slash_offenses_collector.test.ts +++ b/yarn-project/slasher/src/slash_offenses_collector.test.ts @@ -164,7 +164,7 @@ describe('SlashOffensesCollector', () => { { validator: validator3, amount: 1500000000000000000n, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 175n, // slot 175 >= 110 }, ]; @@ -201,7 +201,7 @@ describe('SlashOffensesCollector', () => { expect(offensesByValidator[validator3.toString()]).toMatchObject({ validator: validator3, amount: 1500000000000000000n, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 175n, }); }); diff --git a/yarn-project/slasher/src/stores/offenses_store.test.ts b/yarn-project/slasher/src/stores/offenses_store.test.ts index 6215e541cbca..2aeba6e6aea7 100644 --- a/yarn-project/slasher/src/stores/offenses_store.test.ts +++ b/yarn-project/slasher/src/stores/offenses_store.test.ts @@ -107,7 +107,7 @@ describe('SlasherOffensesStore', () => { it('should handle large amounts and epoch/slot values', async () => { const largeAmount = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'); // Max uint128 const largeEpochOrSlot = BigInt(1_000_000_000); - const offense = createOffense(EthAddress.random(), largeAmount, OffenseType.VALID_EPOCH_PRUNED, largeEpochOrSlot); + const offense = createOffense(EthAddress.random(), largeAmount, OffenseType.INACTIVITY, largeEpochOrSlot); await store.addOffense(offense); @@ -119,7 +119,12 @@ describe('SlasherOffensesStore', () => { it('should preserve offense data across store operations', async () => { const validator = EthAddress.fromString('0x1234567890abcdef1234567890abcdef12345678'); - const offense = createOffense(validator, 12345n, OffenseType.ATTESTED_DESCENDANT_OF_INVALID, 54321n); + const offense = createOffense( + validator, + 12345n, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, + 54321n, + ); await store.addOffense(offense); @@ -127,7 +132,9 @@ describe('SlasherOffensesStore', () => { expect(pendingOffenses).toHaveLength(1); expect(pendingOffenses[0].validator.toString()).toBe(validator.toString()); expect(pendingOffenses[0].amount).toBe(12345n); - expect(pendingOffenses[0].offenseType).toBe(OffenseType.ATTESTED_DESCENDANT_OF_INVALID); + expect(pendingOffenses[0].offenseType).toBe( + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, + ); expect(pendingOffenses[0].epochOrSlot).toBe(54321n); }); diff --git a/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts b/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts index 5d418ebbd49c..933362d00cde 100644 --- a/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts +++ b/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts @@ -176,14 +176,14 @@ describe('AttestationsBlockWatcher', () => { expect(handler).toHaveBeenCalledWith([ { validator: attestor1, - amount: config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 2n, }, { validator: attestor2, - amount: config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 2n, }, ] satisfies WantToSlashArgs[]); diff --git a/yarn-project/slasher/src/watchers/attestations_block_watcher.ts b/yarn-project/slasher/src/watchers/attestations_block_watcher.ts index b9d1dcdfd068..cd02e7312c5b 100644 --- a/yarn-project/slasher/src/watchers/attestations_block_watcher.ts +++ b/yarn-project/slasher/src/watchers/attestations_block_watcher.ts @@ -1,6 +1,7 @@ import { EpochCache } from '@aztec/epoch-cache'; import { SlotNumber } from '@aztec/foundation/branded-types'; import { merge, pick } from '@aztec/foundation/collection'; +import { FifoSet } from '@aztec/foundation/fifo-set'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { type InvalidCheckpointDetectedEvent, @@ -8,7 +9,6 @@ import { L2BlockSourceEvents, type ValidateCheckpointNegativeResult, } from '@aztec/stdlib/block'; -import type { CheckpointInfo } from '@aztec/stdlib/checkpoint'; import { OffenseType } from '@aztec/stdlib/slashing'; import EventEmitter from 'node:events'; @@ -17,9 +17,10 @@ import type { SlasherConfig } from '../config.js'; import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; const AttestationsBlockWatcherConfigKeys = [ - 'slashAttestDescendantOfInvalidPenalty', + 'slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty', 'slashProposeInvalidAttestationsPenalty', ] as const; +const MAX_INVALID_CHECKPOINTS = 100; type AttestationsBlockWatcherConfig = Pick; @@ -32,11 +33,8 @@ type AttestationsBlockWatcherConfig = Pick WatcherEmitter) implements Watcher { private log: Logger = createLogger('attestations-block-watcher'); - // Only keep track of the last N invalid checkpoints - private maxInvalidCheckpoints = 100; - - // All invalid archive roots seen - private invalidArchiveRoots: Set = new Set(); + // Recently seen invalid archive roots. + private invalidArchiveRoots = FifoSet.withLimit(MAX_INVALID_CHECKPOINTS); private config: AttestationsBlockWatcherConfig; @@ -98,8 +96,7 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher reason: validationResult.valid === false ? validationResult.reason : 'unknown', }); - // Store the invalid checkpoint - this.addInvalidCheckpoint(event.validationResult.checkpoint); + this.invalidArchiveRoots.add(checkpoint.archive.toString()); // Slash the proposer of the invalid checkpoint this.slashProposer(event.validationResult); @@ -127,8 +124,8 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher WANT_TO_SLASH_EVENT, attestors.map(attestor => ({ validator: attestor, - amount: this.config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: this.config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: BigInt(SlotNumber(checkpoint.slotNumber)), })), ); @@ -181,14 +178,4 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher } } } - - private addInvalidCheckpoint(checkpoint: CheckpointInfo) { - this.invalidArchiveRoots.add(checkpoint.archive.toString()); - - // Prune old entries if we exceed the maximum - if (this.invalidArchiveRoots.size > this.maxInvalidCheckpoints) { - const oldestKey = this.invalidArchiveRoots.keys().next().value!; - this.invalidArchiveRoots.delete(oldestKey); - } - } } diff --git a/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.test.ts b/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.test.ts new file mode 100644 index 000000000000..5d8432b9d3d2 --- /dev/null +++ b/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.test.ts @@ -0,0 +1,290 @@ +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types'; +import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import { EmptyL1RollupConstants } from '@aztec/stdlib/epoch-helpers'; +import type { P2PClient } from '@aztec/stdlib/interfaces/server'; +import type { BlockProposal, CheckpointProposalCore } from '@aztec/stdlib/p2p'; +import { OffenseType } from '@aztec/stdlib/slashing'; +import { + makeBlockHeader, + makeBlockProposal, + makeCheckpointHeader, + makeCheckpointProposal, +} from '@aztec/stdlib/testing'; + +import { jest } from '@jest/globals'; +import { type MockProxy, mock } from 'jest-mock-extended'; + +import { DefaultSlasherConfig, type SlasherConfig } from '../config.js'; +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs } from '../watcher.js'; +import { BroadcastedInvalidCheckpointProposalWatcher } from './broadcasted_invalid_checkpoint_proposal_watcher.js'; + +describe('BroadcastedInvalidCheckpointProposalWatcher', () => { + let p2pClient: MockProxy>; + let l2BlockSource: MockProxy>; + let epochCache: MockProxy>; + let config: SlasherConfig; + let watcher: BroadcastedInvalidCheckpointProposalWatcher; + let handler: jest.MockedFunction<(args: WantToSlashArgs[]) => void>; + + beforeEach(() => { + p2pClient = mock>(); + l2BlockSource = mock>(); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(12)); + epochCache = mock>(); + epochCache.getSlotNow.mockReturnValue(SlotNumber(12)); + epochCache.getL1Constants.mockReturnValue({ + ...EmptyL1RollupConstants, + epochDuration: 8, + ethereumSlotDuration: 12, + }); + config = { + ...DefaultSlasherConfig, + slashBroadcastedInvalidCheckpointProposalPenalty: 11n, + }; + watcher = new BroadcastedInvalidCheckpointProposalWatcher(p2pClient, l2BlockSource, epochCache, config, 4); + handler = jest.fn(); + watcher.on(WANT_TO_SLASH_EVENT, handler); + }); + + const makeBlocks = async (signer: Secp256k1Signer, slot: SlotNumber, count: number): Promise => + await Promise.all( + Array.from({ length: count }, (_, index) => + makeBlockProposal({ + signer, + blockHeader: makeBlockHeader(index + 1, { slotNumber: slot }), + archiveRoot: Fr.random(), + indexWithinCheckpoint: IndexWithinCheckpoint(index), + }), + ), + ); + + const makeCheckpointCore = async ( + signer: Secp256k1Signer, + slot: SlotNumber, + terminalBlock: BlockProposal, + includeLastBlock = false, + ): Promise => { + const checkpoint = await makeCheckpointProposal({ + signer, + checkpointHeader: makeCheckpointHeader(1, { slotNumber: slot }), + archiveRoot: terminalBlock.archive, + lastBlock: includeLastBlock + ? { + blockHeader: terminalBlock.blockHeader, + indexWithinCheckpoint: terminalBlock.indexWithinCheckpoint, + txHashes: terminalBlock.txHashes, + } + : undefined, + }); + return checkpoint.toCore(); + }; + + const mockProposals = ( + slot: SlotNumber, + blockProposals: BlockProposal[], + checkpointProposals: CheckpointProposalCore[], + ) => + p2pClient.getProposalsForSlot.mockImplementation(querySlot => + Promise.resolve( + querySlot === slot ? { blockProposals, checkpointProposals } : { blockProposals: [], checkpointProposals: [] }, + ), + ); + + it('slashes when higher-index block proposals arrive before a truncated checkpoint proposal', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scanSlot(slot); + + expect(handler).toHaveBeenCalledWith([ + { + validator: signer.address, + amount: 11n, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: 10n, + }, + ]); + }); + + it('slashes when a higher-index proposal arrives after an earlier non-slashing scan', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, blocks.slice(0, 2), [checkpoint]); + + await watcher.scanSlot(slot); + expect(handler).not.toHaveBeenCalled(); + + mockProposals(slot, blocks, [checkpoint]); + await watcher.scanSlot(slot); + + expect(handler).toHaveBeenCalledTimes(1); + expect(handler.mock.calls[0][0][0].validator).toEqual(signer.address); + }); + + it('infers the terminal proposal from a retained block reconstructed out of embedded lastBlock', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpointWithLastBlock = await makeCheckpointProposal({ + signer, + checkpointHeader: makeCheckpointHeader(1, { slotNumber: slot }), + archiveRoot: blocks[1].archive, + lastBlock: { + blockHeader: blocks[1].blockHeader, + indexWithinCheckpoint: blocks[1].indexWithinCheckpoint, + txHashes: blocks[1].txHashes, + }, + }); + mockProposals(slot, [checkpointWithLastBlock.getBlockProposal()!, blocks[2]], [checkpointWithLastBlock.toCore()]); + + await watcher.scanSlot(slot); + + expect(handler).toHaveBeenCalledTimes(1); + expect(handler.mock.calls[0][0][0].validator).toEqual(signer.address); + }); + + it('does not slash when the checkpoint terminates at the highest known block', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[3]); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scanSlot(slot); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('does not slash without a matching signed terminal block proposal', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const missingTerminal = await makeBlockProposal({ + signer, + blockHeader: makeBlockHeader(99, { slotNumber: slot }), + archiveRoot: Fr.random(), + indexWithinCheckpoint: IndexWithinCheckpoint(1), + }); + const checkpoint = await makeCheckpointCore(signer, slot, missingTerminal); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scanSlot(slot); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('does not slash when the higher-index block is signed by a different validator', async () => { + const signer = Secp256k1Signer.random(); + const otherSigner = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 2); + const higherBlock = (await makeBlocks(otherSigner, slot, 3))[2]; + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, [...blocks, higherBlock], [checkpoint]); + + await watcher.scanSlot(slot); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('does not emit duplicate offenses on repeated scans', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scanSlot(slot); + await watcher.scanSlot(slot); + + expect(handler).toHaveBeenCalledTimes(1); + }); + + it('scans a lookback of closed slots', async () => { + const signer = Secp256k1Signer.random(); + const slot = SlotNumber(10); + const blocks = await makeBlocks(signer, slot, 4); + const checkpoint = await makeCheckpointCore(signer, slot, blocks[1]); + mockProposals(slot, blocks, [checkpoint]); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot).toHaveBeenCalledWith(SlotNumber(7)); + expect(p2pClient.getProposalsForSlot).toHaveBeenCalledWith(SlotNumber(10)); + expect(handler).toHaveBeenCalledTimes(1); + }); + + it('anchors the scan at the archiver synced L2 slot, not the wallclock', async () => { + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(9)); + epochCache.getSlotNow.mockReturnValue(SlotNumber(20)); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot.mock.calls.map(([slot]) => slot)).toEqual([ + SlotNumber(4), + SlotNumber(5), + SlotNumber(6), + SlotNumber(7), + ]); + }); + + it('falls back to the wallclock when the archiver has not yet synced', async () => { + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(undefined); + epochCache.getSlotNow.mockReturnValue(SlotNumber(12)); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot.mock.calls.map(([slot]) => slot)).toEqual([ + SlotNumber(7), + SlotNumber(8), + SlotNumber(9), + SlotNumber(10), + ]); + }); + + it('does not expand the scan window when L1 stalls but wallclock keeps moving', async () => { + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(12)); + epochCache.getSlotNow.mockReturnValue(SlotNumber(12)); + + await watcher.scan(); + p2pClient.getProposalsForSlot.mockClear(); + epochCache.getSlotNow.mockReturnValue(SlotNumber(50)); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot.mock.calls.map(([slot]) => slot)).toEqual([ + SlotNumber(7), + SlotNumber(8), + SlotNumber(9), + SlotNumber(10), + ]); + }); + + it('only expands beyond the lookback for newly closed slots', async () => { + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); + + await watcher.scan(); + p2pClient.getProposalsForSlot.mockClear(); + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(13)); + + await watcher.scan(); + + expect(p2pClient.getProposalsForSlot.mock.calls.map(([slot]) => slot)).toEqual([ + SlotNumber(8), + SlotNumber(9), + SlotNumber(10), + SlotNumber(11), + ]); + }); +}); diff --git a/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts b/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts new file mode 100644 index 000000000000..1e9249b2cdf4 --- /dev/null +++ b/yarn-project/slasher/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts @@ -0,0 +1,199 @@ +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { SlotNumber } from '@aztec/foundation/branded-types'; +import { merge, pick } from '@aztec/foundation/collection'; +import type { EthAddress } from '@aztec/foundation/eth-address'; +import { FifoSet } from '@aztec/foundation/fifo-set'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { RunningPromise } from '@aztec/foundation/running-promise'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import type { P2PClient, SlasherConfig } from '@aztec/stdlib/interfaces/server'; +import type { BlockProposal, CheckpointProposalCore } from '@aztec/stdlib/p2p'; +import { OffenseType } from '@aztec/stdlib/slashing'; + +import EventEmitter from 'node:events'; + +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; + +const BroadcastedInvalidCheckpointProposalWatcherConfigKeys = [ + 'slashBroadcastedInvalidCheckpointProposalPenalty', +] as const; + +const SCAN_SLOT_LAG = 1; +const DEFAULT_SCAN_SLOT_LOOKBACK = 4; + +type BroadcastedInvalidCheckpointProposalWatcherConfig = Pick< + SlasherConfig, + (typeof BroadcastedInvalidCheckpointProposalWatcherConfigKeys)[number] +>; + +type ProposalsForSlot = Awaited>; +type P2PProposalsForSlotSource = Pick; + +type SignedBlockProposal = { + proposal: BlockProposal; + signer: EthAddress; +}; + +/** Detects truncated-checkpoint proposal offenses from retained signed P2P proposals. */ +export class BroadcastedInvalidCheckpointProposalWatcher + extends (EventEmitter as new () => WatcherEmitter) + implements Watcher +{ + private readonly log: Logger = createLogger('broadcasted-invalid-checkpoint-proposal-watcher'); + private readonly runningPromise: RunningPromise; + private readonly emittedOffenses: FifoSet; + private readonly scanSlotLookback: number; + private config: BroadcastedInvalidCheckpointProposalWatcherConfig; + private lastScannedSlot: SlotNumber | undefined; + + constructor( + private readonly p2pClient: P2PProposalsForSlotSource, + private readonly l2BlockSource: Pick, + private readonly epochCache: Pick, + config: BroadcastedInvalidCheckpointProposalWatcherConfig, + scanSlotLookback = DEFAULT_SCAN_SLOT_LOOKBACK, + ) { + super(); + const constants = epochCache.getL1Constants(); + this.config = pick(config, ...BroadcastedInvalidCheckpointProposalWatcherConfigKeys); + this.scanSlotLookback = Math.max(1, scanSlotLookback); + + // Bound emitted offenses to the number of slots we rescan. This watcher currently tracks one offense type, + // and at most one offense of that type can be emitted per slot. + const offenseTypes = 1; + this.emittedOffenses = FifoSet.withLimit(offenseTypes * this.scanSlotLookback); + + const intervalMs = Math.max(1000, (constants.ethereumSlotDuration * 1000) / 4); + this.runningPromise = new RunningPromise(() => this.scan(), this.log, intervalMs); + this.log.info('BroadcastedInvalidCheckpointProposalWatcher initialized', { + scanSlotLookback: this.scanSlotLookback, + }); + } + + public updateConfig(config: Partial): void { + this.config = merge(this.config, pick(config, ...BroadcastedInvalidCheckpointProposalWatcherConfigKeys)); + this.log.verbose('BroadcastedInvalidCheckpointProposalWatcher config updated', this.config); + } + + public start(): Promise { + this.runningPromise.start(); + return Promise.resolve(); + } + + public stop(): Promise { + return this.runningPromise.stop(); + } + + /** + * Scans newly closed slots, plus a small lookback for late-arriving proposals. Anchors + * `currentSlot` at the archiver's last synced L2 slot. + */ + public async scan(): Promise { + if (this.config.slashBroadcastedInvalidCheckpointProposalPenalty <= 0n) { + return; + } + + const currentSlot = (await this.l2BlockSource.getSyncedL2SlotNumber()) ?? this.epochCache.getSlotNow(); + if (currentSlot <= SlotNumber(SCAN_SLOT_LAG)) { + return; + } + + const newestSlotToConsider = SlotNumber(currentSlot - 1 - SCAN_SLOT_LAG); + const oldestLookbackSlot = SlotNumber(Math.max(0, newestSlotToConsider - this.scanSlotLookback + 1)); + const oldestUnscannedSlot = + this.lastScannedSlot === undefined ? oldestLookbackSlot : SlotNumber(this.lastScannedSlot + 1); + const oldestSlot = SlotNumber(Math.min(oldestLookbackSlot, oldestUnscannedSlot)); + for (let slot = oldestSlot; slot <= newestSlotToConsider; slot++) { + await this.scanSlot(SlotNumber(slot)); + } + this.lastScannedSlot = newestSlotToConsider; + } + + /** Scans a single slot. Public for tests. */ + public async scanSlot(slot: SlotNumber): Promise { + if (this.config.slashBroadcastedInvalidCheckpointProposalPenalty <= 0n) { + return; + } + + const proposals = await this.p2pClient.getProposalsForSlot(slot); + const slashArgs = this.getSlashArgsForProposals(slot, proposals).filter(args => this.markAsNewOffense(args)); + if (slashArgs.length === 0) { + return; + } + + this.log.info(`Detected broadcasted invalid checkpoint proposal offense`, { + slot, + offenses: slashArgs.map(args => ({ + validator: args.validator.toString(), + offenseType: args.offenseType, + epochOrSlot: args.epochOrSlot, + })), + }); + this.emit(WANT_TO_SLASH_EVENT, slashArgs); + } + + private getSlashArgsForProposals(slot: SlotNumber, proposals: ProposalsForSlot): WantToSlashArgs[] { + const offenders = this.findOffenders(proposals.blockProposals, proposals.checkpointProposals); + // we expect one proposer per slot today. + return [...offenders.values()].map(validator => ({ + validator, + amount: this.config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: BigInt(slot), + })); + } + + private findOffenders(blockProposals: BlockProposal[], checkpointProposals: CheckpointProposalCore[]) { + const blocksBySigner = this.getSignedBlocksBySigner(blockProposals); + const offenders = new Map(); + + for (const checkpoint of checkpointProposals) { + const checkpointSigner = checkpoint.getSender(); + if (!checkpointSigner) { + continue; + } + + const signerKey = checkpointSigner.toString(); + const signerBlocks = blocksBySigner.get(signerKey) ?? []; + const terminalBlocks = signerBlocks.filter( + ({ proposal }) => proposal.slotNumber === checkpoint.slotNumber && proposal.archive.equals(checkpoint.archive), + ); + if (terminalBlocks.length === 0) { + continue; + } + + const hasTruncatedHigherBlock = terminalBlocks.some(terminalBlock => + signerBlocks.some( + ({ proposal }) => + proposal.slotNumber === checkpoint.slotNumber && + proposal.indexWithinCheckpoint > terminalBlock.proposal.indexWithinCheckpoint, + ), + ); + if (hasTruncatedHigherBlock) { + offenders.set(signerKey, checkpointSigner); + } + } + + return offenders; + } + + private getSignedBlocksBySigner(blockProposals: BlockProposal[]): Map { + const blocksBySigner = new Map(); + for (const proposal of blockProposals) { + const signer = proposal.getSender(); + if (!signer) { + continue; + } + const signerKey = signer.toString(); + const signerBlocks = blocksBySigner.get(signerKey) ?? []; + signerBlocks.push({ proposal, signer }); + blocksBySigner.set(signerKey, signerBlocks); + } + return blocksBySigner; + } + + private markAsNewOffense(args: WantToSlashArgs): boolean { + const key = `${args.validator.toString()}-${args.offenseType}-${args.epochOrSlot}`; + return this.emittedOffenses.addIfAbsent(key); + } +} diff --git a/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.test.ts b/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.test.ts new file mode 100644 index 000000000000..8b6fe48f2fde --- /dev/null +++ b/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.test.ts @@ -0,0 +1,120 @@ +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { EthAddress } from '@aztec/foundation/eth-address'; +import { + type ArchiverEmitter, + type CheckpointEquivocationDetectedEvent, + type L2BlockSourceEventEmitter, + L2BlockSourceEvents, +} from '@aztec/stdlib/block'; +import { OffenseType } from '@aztec/stdlib/slashing'; + +import { jest } from '@jest/globals'; +import { type MockProxy, mock } from 'jest-mock-extended'; +import EventEmitter from 'node:events'; + +import { DefaultSlasherConfig, type SlasherConfig } from '../config.js'; +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs } from '../watcher.js'; +import { CheckpointEquivocationWatcher } from './checkpoint_equivocation_watcher.js'; + +describe('CheckpointEquivocationWatcher', () => { + let archiverEmitter: ArchiverEmitter; + let l2BlockSource: Pick; + let epochCache: MockProxy>; + let config: SlasherConfig; + let watcher: CheckpointEquivocationWatcher; + let handler: jest.MockedFunction<(args: WantToSlashArgs[]) => void>; + + const makeEvent = ( + overrides: Partial = {}, + ): CheckpointEquivocationDetectedEvent => ({ + type: L2BlockSourceEvents.CheckpointEquivocationDetected, + slotNumber: SlotNumber(10), + checkpointNumber: CheckpointNumber(2), + l1ArchiveRoot: Fr.random(), + proposedArchiveRoot: Fr.random(), + ...overrides, + }); + + beforeEach(async () => { + archiverEmitter = new EventEmitter() as unknown as ArchiverEmitter; + l2BlockSource = { events: archiverEmitter }; + epochCache = mock>(); + epochCache.getProposerAttesterAddressInSlot.mockResolvedValue(EthAddress.random()); + config = { + ...DefaultSlasherConfig, + slashDuplicateProposalPenalty: 23n, + }; + watcher = new CheckpointEquivocationWatcher(l2BlockSource, epochCache, config); + handler = jest.fn(); + watcher.on(WANT_TO_SLASH_EVENT, handler); + await watcher.start(); + }); + + afterEach(async () => { + await watcher.stop(); + }); + + const emitAndFlush = async (event: CheckpointEquivocationDetectedEvent) => { + archiverEmitter.emit(L2BlockSourceEvents.CheckpointEquivocationDetected, event); + // Allow the async handler to settle. + await new Promise(resolve => setImmediate(resolve)); + }; + + it('emits a DUPLICATE_PROPOSAL slash for the slot proposer when divergence is detected', async () => { + const proposer = EthAddress.random(); + epochCache.getProposerAttesterAddressInSlot.mockResolvedValueOnce(proposer); + + await emitAndFlush(makeEvent()); + + expect(handler).toHaveBeenCalledWith([ + { + validator: proposer, + amount: 23n, + offenseType: OffenseType.DUPLICATE_PROPOSAL, + epochOrSlot: 10n, + }, + ]); + }); + + it('does not emit when there is no proposer for the slot', async () => { + epochCache.getProposerAttesterAddressInSlot.mockResolvedValueOnce(undefined); + + await emitAndFlush(makeEvent()); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('does not emit when the penalty is zero', async () => { + await watcher.stop(); + config = { ...config, slashDuplicateProposalPenalty: 0n }; + watcher = new CheckpointEquivocationWatcher(l2BlockSource, epochCache, config); + handler = jest.fn(); + watcher.on(WANT_TO_SLASH_EVENT, handler); + await watcher.start(); + + await emitAndFlush(makeEvent()); + + expect(handler).not.toHaveBeenCalled(); + }); + + it('emits separately for distinct slots', async () => { + const proposer = EthAddress.random(); + epochCache.getProposerAttesterAddressInSlot.mockResolvedValue(proposer); + + await emitAndFlush(makeEvent({ slotNumber: SlotNumber(10) })); + await emitAndFlush(makeEvent({ slotNumber: SlotNumber(11) })); + + expect(handler).toHaveBeenCalledTimes(2); + expect(handler.mock.calls[0][0][0].epochOrSlot).toBe(10n); + expect(handler.mock.calls[1][0][0].epochOrSlot).toBe(11n); + }); + + it('does not slash after stop()', async () => { + await watcher.stop(); + await emitAndFlush(makeEvent()); + + expect(handler).not.toHaveBeenCalled(); + }); +}); diff --git a/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.ts b/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.ts new file mode 100644 index 000000000000..887986a8ba7e --- /dev/null +++ b/yarn-project/slasher/src/watchers/checkpoint_equivocation_watcher.ts @@ -0,0 +1,98 @@ +import type { EpochCacheInterface } from '@aztec/epoch-cache'; +import { merge, pick } from '@aztec/foundation/collection'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { + type CheckpointEquivocationDetectedEvent, + type L2BlockSourceEventEmitter, + L2BlockSourceEvents, +} from '@aztec/stdlib/block'; +import type { SlasherConfig } from '@aztec/stdlib/interfaces/server'; +import { OffenseType } from '@aztec/stdlib/slashing'; + +import EventEmitter from 'node:events'; + +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; + +const CheckpointEquivocationWatcherConfigKeys = ['slashDuplicateProposalPenalty'] as const; + +type CheckpointEquivocationWatcherConfig = Pick< + SlasherConfig, + (typeof CheckpointEquivocationWatcherConfigKeys)[number] +>; + +type EquivocationEventSource = Pick; +type ProposerLookup = Pick; + +/** + * Slashes the slot proposer for DUPLICATE_PROPOSAL when the archiver detects that a + * locally-stored proposed checkpoint disagrees with the L1-confirmed checkpoint at the + * same slot. Both are signed by the slot proposer (the proposed one by accepting it via + * P2P or building it locally; the L1 one by submission), so the proposer equivocated. + */ +export class CheckpointEquivocationWatcher extends (EventEmitter as new () => WatcherEmitter) implements Watcher { + private readonly log: Logger = createLogger('checkpoint-equivocation-watcher'); + private readonly handler: (args: CheckpointEquivocationDetectedEvent) => void; + private config: CheckpointEquivocationWatcherConfig; + + constructor( + private readonly l2BlockSource: EquivocationEventSource, + private readonly epochCache: ProposerLookup, + config: CheckpointEquivocationWatcherConfig, + ) { + super(); + this.config = pick(config, ...CheckpointEquivocationWatcherConfigKeys); + this.handler = event => { + this.onEquivocationDetected(event).catch(err => + this.log.error('Failed to handle checkpoint equivocation event', err), + ); + }; + this.log.info('CheckpointEquivocationWatcher initialized'); + } + + public updateConfig(config: Partial): void { + this.config = merge(this.config, pick(config, ...CheckpointEquivocationWatcherConfigKeys)); + this.log.verbose('CheckpointEquivocationWatcher config updated', this.config); + } + + public start(): Promise { + this.l2BlockSource.events.on(L2BlockSourceEvents.CheckpointEquivocationDetected, this.handler); + return Promise.resolve(); + } + + public stop(): Promise { + this.l2BlockSource.events.off(L2BlockSourceEvents.CheckpointEquivocationDetected, this.handler); + return Promise.resolve(); + } + + /** Public for tests. */ + public async onEquivocationDetected(event: CheckpointEquivocationDetectedEvent): Promise { + if (this.config.slashDuplicateProposalPenalty <= 0n) { + return; + } + + const proposer = await this.epochCache.getProposerAttesterAddressInSlot(event.slotNumber); + if (!proposer) { + this.log.warn(`Cannot attribute checkpoint equivocation: no proposer for slot ${event.slotNumber}`, { + slotNumber: event.slotNumber, + checkpointNumber: event.checkpointNumber, + }); + return; + } + + const slashArgs: WantToSlashArgs = { + validator: proposer, + amount: this.config.slashDuplicateProposalPenalty, + offenseType: OffenseType.DUPLICATE_PROPOSAL, + epochOrSlot: BigInt(event.slotNumber), + }; + + this.log.info(`Detected checkpoint equivocation offense`, { + slotNumber: event.slotNumber, + checkpointNumber: event.checkpointNumber, + l1ArchiveRoot: event.l1ArchiveRoot.toString(), + proposedArchiveRoot: event.proposedArchiveRoot.toString(), + validator: proposer.toString(), + }); + this.emit(WANT_TO_SLASH_EVENT, [slashArgs]); + } +} diff --git a/yarn-project/slasher/src/watchers/data_withholding_watcher.test.ts b/yarn-project/slasher/src/watchers/data_withholding_watcher.test.ts new file mode 100644 index 000000000000..310eaf3c3b62 --- /dev/null +++ b/yarn-project/slasher/src/watchers/data_withholding_watcher.test.ts @@ -0,0 +1,340 @@ +import type { EpochCache } from '@aztec/epoch-cache'; +import { SlotNumber } from '@aztec/foundation/branded-types'; +import { EthAddress } from '@aztec/foundation/eth-address'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; +import type { ITxProvider, P2PApi } from '@aztec/stdlib/interfaces/server'; +import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { OffenseType } from '@aztec/stdlib/slashing'; +import { TxHash } from '@aztec/stdlib/tx'; + +import { type MockProxy, mock } from 'jest-mock-extended'; + +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs } from '../watcher.js'; +import { DataWithholdingWatcher } from './data_withholding_watcher.js'; + +class TestDataWithholdingWatcher extends DataWithholdingWatcher { + public attestersBySlot = new Map(); + + protected override extractAttesters(published: PublishedCheckpoint): Promise { + return Promise.resolve(this.attestersBySlot.get(published.checkpoint.header.slotNumber) ?? []); + } +} + +describe('DataWithholdingWatcher', () => { + const TOLERANCE = 3; + const PENALTY = 1_000_000_000_000_000_000n; + const signatureContext: CoordinationSignatureContext = { + chainId: 31337, + rollupAddress: EthAddress.fromNumber(1), + }; + + let epochCache: MockProxy; + let l2BlockSource: MockProxy>; + let txProvider: MockProxy>; + let p2p: MockProxy>; + let reexecutionTracker: MockProxy>; + let watcher: TestDataWithholdingWatcher; + let l1Constants: L1RollupConstants; + + beforeEach(() => { + epochCache = mock(); + l2BlockSource = mock>(); + txProvider = mock>(); + p2p = mock>(); + p2p.getCheckpointAttestationsForSlot.mockResolvedValue([]); + reexecutionTracker = mock>(); + reexecutionTracker.getTxsCollectedRecord.mockReturnValue(undefined); + + l1Constants = { + l1StartBlock: 1n, + l1GenesisTime: 1_700_000_000n, + slotDuration: 24, + epochDuration: 8, + ethereumSlotDuration: 12, + proofSubmissionEpochs: 1, + targetCommitteeSize: 48, + rollupManaLimit: Number.MAX_SAFE_INTEGER, + }; + epochCache.getL1Constants.mockReturnValue(l1Constants); + + watcher = new TestDataWithholdingWatcher( + epochCache as EpochCache, + l2BlockSource, + txProvider, + p2p, + reexecutionTracker, + signatureContext, + { + slashDataWithholdingPenalty: PENALTY, + slashDataWithholdingToleranceSlots: TOLERANCE, + }, + ); + }); + + afterEach(async () => { + await watcher.stop(); + }); + + /** + * Builds a minimal published-checkpoint shape carrying just the fields the watcher reads: + * `checkpoint.{header.slotNumber, number, archive.root, blocks[*].{header.getSlot, body.txEffects[*].txHash}}`. + * Each block's header.getSlot() returns the checkpoint's slot (single-block-per-checkpoint test default). + */ + const makePublished = (slot: number, txCount: number, blockCount = 1): PublishedCheckpoint => { + const blocks = Array.from({ length: blockCount }, () => ({ + header: { getSlot: () => SlotNumber(slot) }, + body: { txEffects: Array.from({ length: txCount }, () => ({ txHash: TxHash.random() })) }, + })); + return { + checkpoint: { + header: { slotNumber: SlotNumber(slot) }, + number: slot, + archive: { root: { toString: () => `archive-${slot}` } }, + blocks, + }, + } as unknown as PublishedCheckpoint; + }; + + /** Configures the synced-slot fallback used by start() and seeds initial slot. */ + const startAtSlot = async (initialSlot: number) => { + l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(initialSlot)); + await watcher.start(); + }; + + /** Sets the watcher's "current slot" as seen by `work()` (via the archiver's synced slot). */ + const setSyncedSlot = (slot: number) => l2BlockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(slot)); + + /** Captures emitted slash args. */ + const captureEmits = (): WantToSlashArgs[][] => { + const captured: WantToSlashArgs[][] = []; + watcher.on(WANT_TO_SLASH_EVENT, args => captured.push(args)); + return captured; + }; + + /** Mocks `hasTxs` so the given hashes report as missing and all others as present. */ + const mockMissing = (missingHashes: TxHash[]) => { + const missingSet = new Set(missingHashes.map(h => h.toString())); + txProvider.hasTxs.mockImplementation((hashes: TxHash[]) => + Promise.resolve(hashes.map(h => !missingSet.has(h.toString()))), + ); + }; + + it('does nothing on a tick before tolerance has elapsed', async () => { + await startAtSlot(0); + setSyncedSlot(TOLERANCE - 1); + const captured = captureEmits(); + + await watcher.work(); + + expect(l2BlockSource.getCheckpoint).not.toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('does not look back before its initial slot', async () => { + await startAtSlot(100); + setSyncedSlot(100 + TOLERANCE); + const captured = captureEmits(); + + await watcher.work(); + + expect(l2BlockSource.getCheckpoint).not.toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('skips slots with no published checkpoint', async () => { + await startAtSlot(10); + setSyncedSlot(17); + l2BlockSource.getCheckpoint.mockResolvedValue(undefined); + const captured = captureEmits(); + + await watcher.work(); + + expect(l2BlockSource.getCheckpoint).toHaveBeenCalledWith({ slot: SlotNumber(11) }); + expect(l2BlockSource.getCheckpoint).toHaveBeenCalledWith({ slot: SlotNumber(12) }); + expect(l2BlockSource.getCheckpoint).toHaveBeenCalledWith({ slot: SlotNumber(13) }); + expect(captured).toHaveLength(0); + }); + + it('does not slash when all block proposals report collected=true (skips mempool probe)', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 2); + l2BlockSource.getCheckpoint.mockResolvedValue(published); + reexecutionTracker.getTxsCollectedRecord.mockReturnValue(true); + watcher.attestersBySlot.set(slot, [EthAddress.random(), EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + + expect(txProvider.hasTxs).not.toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('falls back to mempool probe when some blocks have collected=false (DW tolerance may permit late arrivals)', async () => { + // A `false` record means we missed the re-execution deadline, but the DW tolerance window + // gives more time for txs to propagate. The watcher must consult the mempool to decide. + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 2, 2); + l2BlockSource.getCheckpoint.mockResolvedValue(published); + reexecutionTracker.getTxsCollectedRecord.mockImplementation((_s, idx) => (idx === 0 ? true : false)); + + // Mempool now reports both txs as available — late arrival saves the proposer. + mockMissing([]); + watcher.attestersBySlot.set(slot, [EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + + expect(txProvider.hasTxs).toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('falls back to mempool probe when records are partial (some undefined, no false)', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 1, 2); + l2BlockSource.getCheckpoint.mockResolvedValue(published); + reexecutionTracker.getTxsCollectedRecord.mockImplementation((_s, idx) => (idx === 0 ? true : undefined)); + + const missing = published.checkpoint.blocks[1].body.txEffects[0].txHash; + mockMissing([missing]); + const attester = EthAddress.random(); + watcher.attestersBySlot.set(slot, [attester]); + const captured = captureEmits(); + + await watcher.work(); + + expect(txProvider.hasTxs).toHaveBeenCalled(); + expect(captured).toHaveLength(1); + expect(captured[0][0].offenseType).toBe(OffenseType.DATA_WITHHOLDING); + }); + + it('does not slash on partial records when mempool probe finds all txs available', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 2); + l2BlockSource.getCheckpoint.mockResolvedValue(published); + reexecutionTracker.getTxsCollectedRecord.mockReturnValue(undefined); + mockMissing([]); + watcher.attestersBySlot.set(slot, [EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + + expect(txProvider.hasTxs).toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('emits a slash for the per-checkpoint attesters when mempool probe reports missing', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 3); + const missingHash = published.checkpoint.blocks[0].body.txEffects[0].txHash; + l2BlockSource.getCheckpoint.mockResolvedValue(published); + mockMissing([missingHash]); + + const attesterA = EthAddress.random(); + const attesterB = EthAddress.random(); + watcher.attestersBySlot.set(slot, [attesterA, attesterB]); + + const captured = captureEmits(); + + await watcher.work(); + + expect(captured).toHaveLength(1); + expect(captured[0]).toEqual([ + { + validator: attesterA, + amount: PENALTY, + offenseType: OffenseType.DATA_WITHHOLDING, + epochOrSlot: BigInt(slot), + }, + { + validator: attesterB, + amount: PENALTY, + offenseType: OffenseType.DATA_WITHHOLDING, + epochOrSlot: BigInt(slot), + }, + ]); + }); + + it('does not re-emit for the same slot on subsequent ticks', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 1); + const missing = published.checkpoint.blocks[0].body.txEffects[0].txHash; + l2BlockSource.getCheckpoint.mockResolvedValue(published); + mockMissing([missing]); + watcher.attestersBySlot.set(slot, [EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + expect(captured).toHaveLength(1); + + await watcher.work(); + expect(captured).toHaveLength(1); + expect(l2BlockSource.getCheckpoint).toHaveBeenCalledTimes(1); + }); + + it('respects penalty=0 as a disable switch', async () => { + watcher.updateConfig({ slashDataWithholdingPenalty: 0n }); + await startAtSlot(10); + setSyncedSlot(10 + TOLERANCE + 5); + + const captured = captureEmits(); + await watcher.work(); + + expect(l2BlockSource.getCheckpoint).not.toHaveBeenCalled(); + expect(captured).toHaveLength(0); + }); + + it('does not slash a checkpoint with no recoverable attesters even if txs are missing', async () => { + await startAtSlot(10); + setSyncedSlot(11 + TOLERANCE + 1); + + const slot = 11; + const published = makePublished(slot, 1); + const missing = published.checkpoint.blocks[0].body.txEffects[0].txHash; + l2BlockSource.getCheckpoint.mockResolvedValue(published); + mockMissing([missing]); + watcher.attestersBySlot.set(slot, []); + const captured = captureEmits(); + + await watcher.work(); + + expect(captured).toHaveLength(0); + }); + + it('sets epochOrSlot to the checkpoint slot, not its epoch (slot-keyed offense)', async () => { + await startAtSlot(0); + setSyncedSlot(1 + TOLERANCE + 1); + + const slot = 1; + const published = makePublished(slot, 1); + const missing = published.checkpoint.blocks[0].body.txEffects[0].txHash satisfies TxHash; + l2BlockSource.getCheckpoint.mockResolvedValue(published); + mockMissing([missing]); + watcher.attestersBySlot.set(slot, [EthAddress.random()]); + const captured = captureEmits(); + + await watcher.work(); + + expect(captured).toHaveLength(1); + expect(captured[0][0].epochOrSlot).toEqual(BigInt(slot)); + }); +}); diff --git a/yarn-project/slasher/src/watchers/data_withholding_watcher.ts b/yarn-project/slasher/src/watchers/data_withholding_watcher.ts new file mode 100644 index 000000000000..091c2be823f6 --- /dev/null +++ b/yarn-project/slasher/src/watchers/data_withholding_watcher.ts @@ -0,0 +1,227 @@ +import type { EpochCache } from '@aztec/epoch-cache'; +import { CheckpointProposalHash, SlotNumber } from '@aztec/foundation/branded-types'; +import { compactArray, merge, pick } from '@aztec/foundation/collection'; +import type { EthAddress } from '@aztec/foundation/eth-address'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { RunningPromise } from '@aztec/foundation/promise'; +import type { L2BlockSource } from '@aztec/stdlib/block'; +import { getAttestationInfoFromPublishedCheckpoint } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import type { ITxProvider, P2PApi, SlasherConfig } from '@aztec/stdlib/interfaces/server'; +import { ConsensusPayload, type CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { OffenseType } from '@aztec/stdlib/slashing'; +import type { TxHash } from '@aztec/stdlib/tx'; + +import EventEmitter from 'node:events'; + +import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; + +const DataWithholdingWatcherConfigKeys = ['slashDataWithholdingPenalty', 'slashDataWithholdingToleranceSlots'] as const; + +type DataWithholdingWatcherConfig = Pick; + +/** + * Detects data-withholding offenses by probing the local mempool for the txs in published + * checkpoints once they are old enough that an honest node should have collected them. + * + * Per AZIP-7: once `slashDataWithholdingToleranceSlots` full slots have elapsed after the + * checkpoint's slot — i.e. at `slotStart(checkpoint.slot + slashDataWithholdingToleranceSlots + * + 1)` — if any tx from the checkpoint's blocks is still missing locally, the checkpoint's + * attesters are considered at fault for not making the data available, and we emit a slash + * for them. + * + * The watcher ticks at quarter-eth-slot cadence (matching the Sentinel template). On boot it + * floors processing at the current slot — restart-time gaps are accepted and not back-filled, + * matching the Sentinel approach. + */ +export class DataWithholdingWatcher extends (EventEmitter as new () => WatcherEmitter) implements Watcher { + private runningPromise: RunningPromise; + private initialSlot: SlotNumber | undefined; + private lastCheckedSlot: SlotNumber | undefined; + private config: DataWithholdingWatcherConfig; + + constructor( + private readonly epochCache: EpochCache, + private readonly l2BlockSource: Pick, + private readonly txProvider: Pick, + private readonly p2p: Pick, + private readonly reexecutionTracker: Pick, + private readonly signatureContext: CoordinationSignatureContext, + config: DataWithholdingWatcherConfig, + private readonly log: Logger = createLogger('data-withholding-watcher'), + ) { + super(); + this.config = pick(config, ...DataWithholdingWatcherConfigKeys); + const interval = (epochCache.getL1Constants().ethereumSlotDuration * 1000) / 4; + this.runningPromise = new RunningPromise(this.work.bind(this), log, interval); + this.log.verbose(`DataWithholdingWatcher initialized`, this.config); + } + + public async start(): Promise { + // Floor processing at the archiver's synced slot rather than the wallclock — restart-time + // gaps before the archiver catches up are accepted and not back-filled. Falls back to the + // wallclock if the archiver isn't ready yet (cold start). + const syncedSlot = await this.l2BlockSource.getSyncedL2SlotNumber(); + this.initialSlot = syncedSlot ?? this.epochCache.getSlotNow(); + this.log.info(`Starting data-withholding watcher with initial slot ${this.initialSlot}`); + this.runningPromise.start(); + } + + public stop(): Promise { + return this.runningPromise.stop(); + } + + public updateConfig(config: Partial): void { + this.config = merge(this.config, pick(config, ...DataWithholdingWatcherConfigKeys)); + this.log.verbose('DataWithholdingWatcher config updated', this.config); + } + + /** + * Runs every tick. Walks newly-eligible slots and probes their checkpoints for data + * availability; emits a DATA_WITHHOLDING slash for any checkpoint whose txs are missing. + */ + public async work(): Promise { + if (this.initialSlot === undefined) { + return; + } + + if (this.config.slashDataWithholdingPenalty === 0n) { + return; // disabled + } + + // tolerance is the number of full slots that must elapse after the checkpoint's slot + // before we declare its data missing. For checkpoint slot S, we therefore process S + // only once we are in slot `S + tolerance + 1` or later. Drive this off the archiver's + // synced slot rather than the wallclock so we don't make claims about slots we haven't + // fully ingested yet (archiver may lag behind L1). + const tolerance = this.config.slashDataWithholdingToleranceSlots; + const currentSlot = (await this.l2BlockSource.getSyncedL2SlotNumber()) ?? this.epochCache.getSlotNow(); + if (currentSlot <= tolerance) { + return; + } + + const targetSlot = SlotNumber(currentSlot - tolerance - 1); + if (targetSlot <= this.initialSlot) { + return; + } + + const startSlot = this.lastCheckedSlot === undefined ? this.initialSlot : this.lastCheckedSlot; + for (let slot = SlotNumber(startSlot + 1); slot <= targetSlot; slot = SlotNumber(slot + 1)) { + try { + await this.processSlot(slot); + } catch (err) { + this.log.error(`Error processing slot ${slot} for data-withholding check`, err, { slot }); + } + this.lastCheckedSlot = slot; + } + } + + /** Probes the checkpoint at the given slot, if any, and emits a slash on missing txs. */ + private async processSlot(slot: SlotNumber): Promise { + const published = await this.l2BlockSource.getCheckpoint({ slot }); + if (!published) { + this.log.trace(`No published checkpoint at slot ${slot}`, { slot }); + return; + } + + const checkpointNumber = published.checkpoint.number; + + // Per-block tx-collection records (true | false | undefined) for every block in this + // published checkpoint. Captured by the validator's proposal handler at the moment of + // tx collection (i.e. by the *re-execution* deadline). Used as a positive short-circuit + // only: a `true` for every block means we know the data was available locally, so this + // checkpoint cannot be a data-withholding offense. A `false` does *not* trigger a slash + // on its own — the re-execution deadline is much earlier than the data-withholding + // tolerance window, so missing txs at that earlier deadline may still arrive in time. + // Anything other than all-true falls through to the mempool probe, which respects the + // tolerance window. + const collectionRecords = published.checkpoint.blocks.map((block, idx) => + this.reexecutionTracker.getTxsCollectedRecord(block.header.getSlot(), idx), + ); + + if (collectionRecords.every(r => r === true)) { + this.log.trace(`All blocks for checkpoint at slot ${slot} were collected locally; skipping`, { + slot, + checkpointNumber, + }); + return; + } + + const txHashes: TxHash[] = published.checkpoint.blocks.flatMap(block => + block.body.txEffects.map(txEffect => txEffect.txHash), + ); + + if (txHashes.length === 0) { + this.log.trace(`Checkpoint at slot ${slot} has no txs`, { slot }); + return; + } + + const availability = await this.txProvider.hasTxs(txHashes); + const missingTxs = txHashes.filter((_, i) => !availability[i]); + if (missingTxs.length === 0) { + this.log.trace(`All ${txHashes.length} txs available for checkpoint at slot ${slot}`, { slot }); + return; + } + + const attesters = await this.extractAttesters(published); + + if (attesters.length === 0) { + this.log.warn(`Detected data withholding at slot ${slot} but no recoverable attesters`, { + slot, + checkpointNumber, + missingTxs: missingTxs.map(h => h.toString()), + records: collectionRecords, + }); + return; + } + + this.log.warn(`Detected data withholding at slot ${slot}. Slashing ${attesters.length} attesters.`, { + slot, + checkpointNumber, + missingTxs: missingTxs.map(h => h.toString()), + records: collectionRecords, + attesters: attesters.map(a => a.toString()), + }); + + const args: WantToSlashArgs[] = attesters.map(validator => ({ + validator, + amount: this.config.slashDataWithholdingPenalty, + offenseType: OffenseType.DATA_WITHHOLDING, + epochOrSlot: BigInt(slot), + })); + this.emit(WANT_TO_SLASH_EVENT, args); + } + + /** + * Returns the union of: + * 1. attesters whose signatures landed in the published checkpoint on L1, and + * 2. attesters we observed signing the same proposal on p2p (the proposer publishes as + * soon as it has hit committee quorum, so honest peer attestations that arrive after + * that point are dropped — but they still vouched for the data and + * should be slashed for withholding it). + * + * + * Exposed as protected so tests can substitute a deterministic recovery without having + * to construct real secp256k1 signatures. + */ + protected async extractAttesters(published: PublishedCheckpoint): Promise { + const fromL1 = getAttestationInfoFromPublishedCheckpoint(published, this.signatureContext) + .filter(info => info.status === 'recovered-from-signature') + .map(info => info.address); + + const slot = published.checkpoint.header.slotNumber; + const proposalPayloadHash = CheckpointProposalHash.fromBuffer( + ConsensusPayload.fromCheckpoint(published.checkpoint, this.signatureContext).getPayloadHash(), + ); + const fromP2p = await this.p2p + .getCheckpointAttestationsForSlot(slot, proposalPayloadHash) + .then(attestations => attestations.map(a => a.getSender())); + + // Dedupe + const all = new Map(); + for (const addr of compactArray([...fromL1, ...fromP2p])) { + all.set(addr.toString(), addr); + } + return [...all.values()]; + } +} diff --git a/yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts b/yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts deleted file mode 100644 index cca7caf88caa..000000000000 --- a/yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts +++ /dev/null @@ -1,260 +0,0 @@ -import type { EpochCache } from '@aztec/epoch-cache'; -import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; -import { EthAddress } from '@aztec/foundation/eth-address'; -import { sleep } from '@aztec/foundation/sleep'; -import { L2Block, type L2BlockSourceEventEmitter, L2BlockSourceEvents } from '@aztec/stdlib/block'; -import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; -import type { - ICheckpointBlockBuilder, - ICheckpointsBuilder, - ITxProvider, - MerkleTreeWriteOperations, -} from '@aztec/stdlib/interfaces/server'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; -import { OffenseType } from '@aztec/stdlib/slashing'; -import { Tx } from '@aztec/stdlib/tx'; - -import { jest } from '@jest/globals'; -import { type MockProxy, mock } from 'jest-mock-extended'; -import EventEmitter from 'node:events'; -import type { Hex } from 'viem'; - -import { WANT_TO_SLASH_EVENT, type WantToSlashArgs } from '../watcher.js'; -import { EpochPruneWatcher } from './epoch_prune_watcher.js'; - -describe('EpochPruneWatcher', () => { - let watcher: EpochPruneWatcher; - let l2BlockSource: L2BlockSourceEventEmitter; - let l1ToL2MessageSource: MockProxy; - let epochCache: MockProxy; - let txProvider: MockProxy>; - let checkpointsBuilder: MockProxy; - let checkpointBuilder: MockProxy; - let fork: MockProxy; - - let ts: bigint; - let l1Constants: L1RollupConstants; - - const validEpochPrunedPenalty = BigInt(1000000000000000000n); - const dataWithholdingPenalty = BigInt(2000000000000000000n); - - beforeEach(async () => { - l2BlockSource = new MockL2BlockSource() as unknown as L2BlockSourceEventEmitter; - l1ToL2MessageSource = mock(); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue([]); - epochCache = mock(); - txProvider = mock>(); - checkpointsBuilder = mock(); - checkpointBuilder = mock(); - fork = mock(); - checkpointsBuilder.getFork.mockResolvedValue(fork); - checkpointsBuilder.startCheckpoint.mockResolvedValue(checkpointBuilder); - - ts = BigInt(Math.ceil(Date.now() / 1000)); - l1Constants = { - l1StartBlock: 1n, - l1GenesisTime: ts, - slotDuration: 24, - epochDuration: 8, - ethereumSlotDuration: 12, - proofSubmissionEpochs: 1, - targetCommitteeSize: 48, - rollupManaLimit: Number.MAX_SAFE_INTEGER, - }; - - epochCache.getL1Constants.mockReturnValue(l1Constants); - - watcher = new EpochPruneWatcher(l2BlockSource, l1ToL2MessageSource, epochCache, txProvider, checkpointsBuilder, { - slashPrunePenalty: validEpochPrunedPenalty, - slashDataWithholdingPenalty: dataWithholdingPenalty, - }); - await watcher.start(); - }); - - afterEach(async () => { - await watcher.stop(); - }); - - it('should emit WANT_TO_SLASH_EVENT when a validator is in a pruned epoch when data is unavailable', async () => { - const emitSpy = jest.spyOn(watcher, 'emit'); - const epochNumber = EpochNumber(1); - const checkpointNumber = CheckpointNumber(1); - - const block = await L2Block.random( - BlockNumber(12), // block number - { - txsPerBlock: 4, - slotNumber: SlotNumber(10), - checkpointNumber, - }, - ); - txProvider.getAvailableTxs.mockResolvedValue({ txs: [], missingTxs: [block.body.txEffects[0].txHash] }); - - const committee: Hex[] = [ - '0x0000000000000000000000000000000000000abc', - '0x0000000000000000000000000000000000000def', - ]; - epochCache.getCommitteeForEpoch.mockResolvedValue({ - committee: committee.map(EthAddress.fromString), - seed: 0n, - epoch: epochNumber, - isEscapeHatchOpen: false, - }); - - l2BlockSource.events.emit(L2BlockSourceEvents.L2PruneUnproven, { - epochNumber: EpochNumber(1), - blocks: [block], - type: L2BlockSourceEvents.L2PruneUnproven, - }); - - // Just need to yield to the event loop to clear our synchronous promises - await sleep(0); - - expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ - { - validator: EthAddress.fromString(committee[0]), - amount: dataWithholdingPenalty, - offenseType: OffenseType.DATA_WITHHOLDING, - epochOrSlot: BigInt(epochNumber), - }, - { - validator: EthAddress.fromString(committee[1]), - amount: dataWithholdingPenalty, - offenseType: OffenseType.DATA_WITHHOLDING, - epochOrSlot: BigInt(epochNumber), - }, - ] satisfies WantToSlashArgs[]); - }); - - it('should slash if the data is available and the epoch could have been proven', async () => { - const emitSpy = jest.spyOn(watcher, 'emit'); - const checkpointNumber = CheckpointNumber(1); - - const block = await L2Block.random( - BlockNumber(12), // block number - { - txsPerBlock: 4, - slotNumber: SlotNumber(10), - checkpointNumber, - }, - ); - const tx = Tx.random(); - txProvider.getAvailableTxs.mockResolvedValue({ txs: [tx], missingTxs: [] }); - checkpointBuilder.buildBlock.mockResolvedValue({ - block: block, - failedTxs: [], - numTxs: 1, - } as any); - - const committee: Hex[] = [ - '0x0000000000000000000000000000000000000abc', - '0x0000000000000000000000000000000000000def', - ]; - epochCache.getCommitteeForEpoch.mockResolvedValue({ - committee: committee.map(EthAddress.fromString), - seed: 0n, - epoch: EpochNumber(1), - isEscapeHatchOpen: false, - }); - - l2BlockSource.events.emit(L2BlockSourceEvents.L2PruneUnproven, { - epochNumber: EpochNumber(1), - blocks: [block], - type: L2BlockSourceEvents.L2PruneUnproven, - }); - - // Just need to yield to the event loop to clear our synchronous promises - await sleep(0); - - expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ - { - validator: EthAddress.fromString(committee[0]), - amount: validEpochPrunedPenalty, - offenseType: OffenseType.VALID_EPOCH_PRUNED, - epochOrSlot: 1n, - }, - { - validator: EthAddress.fromString(committee[1]), - amount: validEpochPrunedPenalty, - offenseType: OffenseType.VALID_EPOCH_PRUNED, - epochOrSlot: 1n, - }, - ] satisfies WantToSlashArgs[]); - - expect(checkpointsBuilder.startCheckpoint).toHaveBeenCalled(); - expect(checkpointBuilder.buildBlock).toHaveBeenCalledWith( - [tx], - block.header.globalVariables.blockNumber, - block.header.globalVariables.timestamp, - { isBuildingProposal: false, minValidTxs: 0 }, - ); - }); - - it('should not slash if the data is available but the epoch could not have been proven', async () => { - const emitSpy = jest.spyOn(watcher, 'emit'); - const checkpointNumber = CheckpointNumber(1); - - const blockFromL1 = await L2Block.random( - BlockNumber(12), // block number - { - txsPerBlock: 1, - slotNumber: SlotNumber(10), - checkpointNumber, - }, - ); - - const blockFromBuilder = await L2Block.random( - BlockNumber(13), // block number - { - txsPerBlock: 1, - slotNumber: SlotNumber(10), - checkpointNumber, - }, - ); - const tx = Tx.random(); - txProvider.getAvailableTxs.mockResolvedValue({ txs: [tx], missingTxs: [] }); - checkpointBuilder.buildBlock.mockResolvedValue({ - block: blockFromBuilder, - failedTxs: [], - numTxs: 1, - } as any); - - const committee: Hex[] = [ - '0x0000000000000000000000000000000000000abc', - '0x0000000000000000000000000000000000000def', - ]; - epochCache.getCommitteeForEpoch.mockResolvedValue({ - committee: committee.map(EthAddress.fromString), - seed: 0n, - epoch: EpochNumber(1), - isEscapeHatchOpen: false, - }); - - l2BlockSource.events.emit(L2BlockSourceEvents.L2PruneUnproven, { - epochNumber: EpochNumber(1), - blocks: [blockFromL1], - type: L2BlockSourceEvents.L2PruneUnproven, - }); - - // Just need to yield to the event loop to clear our synchronous promises - await sleep(0); - - expect(emitSpy).not.toHaveBeenCalled(); - - expect(checkpointsBuilder.startCheckpoint).toHaveBeenCalled(); - expect(checkpointBuilder.buildBlock).toHaveBeenCalledWith( - [tx], - blockFromL1.header.globalVariables.blockNumber, - blockFromL1.header.globalVariables.timestamp, - { isBuildingProposal: false, minValidTxs: 0 }, - ); - }); -}); - -class MockL2BlockSource { - public readonly events = new EventEmitter(); - public getCheckpoints = () => []; - public getCheckpointsData = () => []; - - constructor() {} -} diff --git a/yarn-project/slasher/src/watchers/epoch_prune_watcher.ts b/yarn-project/slasher/src/watchers/epoch_prune_watcher.ts deleted file mode 100644 index bfbed6d1f552..000000000000 --- a/yarn-project/slasher/src/watchers/epoch_prune_watcher.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { EpochCache } from '@aztec/epoch-cache'; -import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types'; -import { chunkBy, merge, pick } from '@aztec/foundation/collection'; -import type { Fr } from '@aztec/foundation/curves/bn254'; -import { type Logger, createLogger } from '@aztec/foundation/log'; -import { - EthAddress, - L2Block, - type L2BlockSourceEventEmitter, - L2BlockSourceEvents, - type L2PruneUnprovenEvent, -} from '@aztec/stdlib/block'; -import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers'; -import type { - ICheckpointBlockBuilder, - ICheckpointsBuilder, - ITxProvider, - MerkleTreeWriteOperations, - SlasherConfig, -} from '@aztec/stdlib/interfaces/server'; -import { type L1ToL2MessageSource, computeCheckpointOutHash } from '@aztec/stdlib/messaging'; -import { OffenseType, getOffenseTypeName } from '@aztec/stdlib/slashing'; -import type { CheckpointGlobalVariables } from '@aztec/stdlib/tx'; -import { - ReExFailedTxsError, - ReExStateMismatchError, - TransactionsNotAvailableError, - ValidatorError, -} from '@aztec/stdlib/validators'; - -import EventEmitter from 'node:events'; - -import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; - -const EpochPruneWatcherPenaltiesConfigKeys = ['slashPrunePenalty', 'slashDataWithholdingPenalty'] as const; - -type EpochPruneWatcherPenalties = Pick; - -/** - * This watcher is responsible for detecting chain prunes and creating slashing arguments for the committee. - * It only wants to slash if: - * - the transactions are not available - * - OR the archive roots match when re-building all the blocks in the epoch (i.e. the epoch *could* have been proven) - */ -export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter) implements Watcher { - private log: Logger = createLogger('epoch-prune-watcher'); - - // Store bound function reference for proper listener removal - private boundHandlePruneL2Blocks = this.handlePruneL2Blocks.bind(this); - - private penalties: EpochPruneWatcherPenalties; - - constructor( - private l2BlockSource: L2BlockSourceEventEmitter, - private l1ToL2MessageSource: L1ToL2MessageSource, - private epochCache: EpochCache, - private txProvider: Pick, - private checkpointsBuilder: ICheckpointsBuilder, - penalties: EpochPruneWatcherPenalties, - ) { - super(); - this.penalties = pick(penalties, ...EpochPruneWatcherPenaltiesConfigKeys); - this.log.verbose( - `EpochPruneWatcher initialized with penalties: valid epoch pruned=${penalties.slashPrunePenalty} data withholding=${penalties.slashDataWithholdingPenalty}`, - ); - } - - public start() { - this.l2BlockSource.events.on(L2BlockSourceEvents.L2PruneUnproven, this.boundHandlePruneL2Blocks); - return Promise.resolve(); - } - - public stop() { - this.l2BlockSource.events.removeListener(L2BlockSourceEvents.L2PruneUnproven, this.boundHandlePruneL2Blocks); - return Promise.resolve(); - } - - public updateConfig(config: Partial): void { - this.penalties = merge(this.penalties, pick(config, ...EpochPruneWatcherPenaltiesConfigKeys)); - this.log.verbose('EpochPruneWatcher config updated', this.penalties); - } - - private handlePruneL2Blocks(event: L2PruneUnprovenEvent): void { - const { blocks, epochNumber } = event; - void this.processPruneL2Blocks(blocks, epochNumber).catch(err => - this.log.error('Error processing pruned L2 blocks', err, { epochNumber }), - ); - } - - private async emitSlashForEpoch(offense: OffenseType, epochNumber: EpochNumber): Promise { - const validators = await this.getValidatorsForEpoch(epochNumber); - if (validators.length === 0) { - this.log.warn(`No validators found for epoch ${epochNumber} (cannot slash for ${getOffenseTypeName(offense)})`); - return; - } - const args = this.validatorsToSlashingArgs(validators, offense, epochNumber); - this.log.verbose(`Created slash for ${getOffenseTypeName(offense)} at epoch ${epochNumber}`, args); - this.emit(WANT_TO_SLASH_EVENT, args); - } - - private async processPruneL2Blocks(blocks: L2Block[], epochNumber: EpochNumber): Promise { - try { - const l1Constants = this.epochCache.getL1Constants(); - const epochBlocks = blocks.filter(b => getEpochAtSlot(b.header.getSlot(), l1Constants) === epochNumber); - this.log.info( - `Detected chain prune. Validating epoch ${epochNumber} with blocks ${epochBlocks[0]?.number} to ${epochBlocks[epochBlocks.length - 1]?.number}.`, - { blocks: epochBlocks.map(b => b.toBlockInfo()) }, - ); - - await this.validateBlocks(epochBlocks, epochNumber); - this.log.info(`Pruned epoch ${epochNumber} was valid. Want to slash committee for not having it proven.`); - await this.emitSlashForEpoch(OffenseType.VALID_EPOCH_PRUNED, epochNumber); - } catch (error) { - if (error instanceof TransactionsNotAvailableError) { - this.log.info(`Data for pruned epoch ${epochNumber} was not available. Will want to slash.`, { - message: error.message, - }); - await this.emitSlashForEpoch(OffenseType.DATA_WITHHOLDING, epochNumber); - } else { - this.log.error(`Error while validating pruned epoch ${epochNumber}. Will not want to slash.`, error); - } - } - } - - public async validateBlocks(blocks: L2Block[], epochNumber: EpochNumber): Promise { - if (blocks.length === 0) { - return; - } - - // Sort blocks by block number and group by checkpoint - const sortedBlocks = [...blocks].sort((a, b) => a.number - b.number); - const blocksByCheckpoint = chunkBy(sortedBlocks, b => b.checkpointNumber); - - // Get prior checkpoints in the epoch (in case this was a partial prune) to extract the out hashes - const priorCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsData({ epoch: epochNumber })) - .filter(c => c.checkpointNumber < sortedBlocks[0].checkpointNumber) - .map(c => c.checkpointOutHash); - let previousCheckpointOutHashes: Fr[] = [...priorCheckpointOutHashes]; - - const fork = await this.checkpointsBuilder.getFork( - BlockNumber(sortedBlocks[0].header.globalVariables.blockNumber - 1), - ); - try { - for (const checkpointBlocks of blocksByCheckpoint) { - await this.validateCheckpoint(checkpointBlocks, previousCheckpointOutHashes, fork); - - // Compute checkpoint out hash from all blocks in this checkpoint - const checkpointOutHash = computeCheckpointOutHash( - checkpointBlocks.map(b => b.body.txEffects.map(tx => tx.l2ToL1Msgs)), - ); - previousCheckpointOutHashes = [...previousCheckpointOutHashes, checkpointOutHash]; - } - } finally { - await fork.close(); - } - } - - private async validateCheckpoint( - checkpointBlocks: L2Block[], - previousCheckpointOutHashes: Fr[], - fork: MerkleTreeWriteOperations, - ): Promise { - const checkpointNumber = checkpointBlocks[0].checkpointNumber; - this.log.debug(`Validating pruned checkpoint ${checkpointNumber} with ${checkpointBlocks.length} blocks`); - - // Get L1ToL2Messages once for the entire checkpoint - const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber); - - // Build checkpoint constants from first block's global variables - const gv = checkpointBlocks[0].header.globalVariables; - const constants: CheckpointGlobalVariables = { - chainId: gv.chainId, - version: gv.version, - slotNumber: gv.slotNumber, - timestamp: gv.timestamp, - coinbase: gv.coinbase, - feeRecipient: gv.feeRecipient, - gasFees: gv.gasFees, - }; - - // Start checkpoint builder once for all blocks in this checkpoint - const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint( - checkpointNumber, - constants, - 0n, // feeAssetPriceModifier is not used for validation of the checkpoint content - l1ToL2Messages, - previousCheckpointOutHashes, - fork, - this.log.getBindings(), - ); - - // Validate all blocks in the checkpoint sequentially - for (const block of checkpointBlocks) { - await this.validateBlockInCheckpoint(block, checkpointBuilder); - } - } - - private async validateBlockInCheckpoint( - blockFromL1: L2Block, - checkpointBuilder: ICheckpointBlockBuilder, - ): Promise { - this.log.debug(`Validating pruned block ${blockFromL1.header.globalVariables.blockNumber}`); - const txHashes = blockFromL1.body.txEffects.map(txEffect => txEffect.txHash); - // We load txs from the mempool directly, since the TxCollector running in the background has already been - // trying to fetch them from nodes or via reqresp. If we haven't managed to collect them by now, - // it's likely that they are not available in the network at all. - const { txs, missingTxs } = await this.txProvider.getAvailableTxs(txHashes); - - if (missingTxs && missingTxs.length > 0) { - throw new TransactionsNotAvailableError(missingTxs); - } - - const gv = blockFromL1.header.globalVariables; - const { block, failedTxs, numTxs } = await checkpointBuilder.buildBlock(txs, gv.blockNumber, gv.timestamp, { - isBuildingProposal: false, - minValidTxs: 0, - }); - - if (numTxs !== txs.length) { - // This should be detected by state mismatch, but this makes it easier to debug. - throw new ValidatorError(`Built block with ${numTxs} txs, expected ${txs.length}`); - } - if (failedTxs.length > 0) { - throw new ReExFailedTxsError(failedTxs.length); - } - if (!block.archive.root.equals(blockFromL1.archive.root)) { - throw new ReExStateMismatchError(blockFromL1.archive.root, block.archive.root); - } - } - - private async getValidatorsForEpoch(epochNumber: EpochNumber): Promise { - const { committee } = await this.epochCache.getCommitteeForEpoch(epochNumber); - if (!committee) { - this.log.trace(`No committee found for epoch ${epochNumber}`); - return []; - } - return committee; - } - - private validatorsToSlashingArgs( - validators: EthAddress[], - offenseType: OffenseType, - epochOrSlot: EpochNumber, - ): WantToSlashArgs[] { - const penalty = - offenseType === OffenseType.DATA_WITHHOLDING - ? this.penalties.slashDataWithholdingPenalty - : this.penalties.slashPrunePenalty; - return validators.map(v => ({ - validator: v, - amount: penalty, - offenseType, - epochOrSlot: BigInt(epochOrSlot), - })); - } -} diff --git a/yarn-project/sqlite3mc-wasm/scripts/vendor.sh b/yarn-project/sqlite3mc-wasm/scripts/vendor.sh index c4abb0a2ae28..0ea4d3bad4c2 100755 --- a/yarn-project/sqlite3mc-wasm/scripts/vendor.sh +++ b/yarn-project/sqlite3mc-wasm/scripts/vendor.sh @@ -75,7 +75,11 @@ WORK_DIR=$(mktemp -d) trap 'rm -rf "$WORK_DIR"' EXIT echo "==> Downloading ${ASSET}" -curl -fsSL -o "$WORK_DIR/$ASSET" "$URL" +# Retries cover transient DNS / TLS failures on CI runners — a one-off +# `Could not resolve host: release-assets.githubusercontent.com` here has +# dequeued the merge train. +curl -fsSL --retry 5 --retry-delay 2 --retry-all-errors --retry-connrefused \ + -o "$WORK_DIR/$ASSET" "$URL" echo "==> Verifying zip SHA256" ACTUAL_SHA=$(sha256sum "$WORK_DIR/$ASSET" | awk '{print $1}') diff --git a/yarn-project/stdlib/src/abi/decoder.test.ts b/yarn-project/stdlib/src/abi/decoder.test.ts index 6a19c8483296..2992dd4aeb30 100644 --- a/yarn-project/stdlib/src/abi/decoder.test.ts +++ b/yarn-project/stdlib/src/abi/decoder.test.ts @@ -236,12 +236,6 @@ describe('decoder', () => { kind: 'field', }, }, - { - name: 'is_infinite', - type: { - kind: 'boolean', - }, - }, ], }, ], @@ -257,19 +251,10 @@ describe('decoder', () => { Fr.fromBuffer(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')), // address Fr.fromBuffer(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')), // point.x Fr.fromBuffer(Buffer.from('0000000000000000000000000000000000000000000000000000000000000002', 'hex')), // point.y - Fr.fromBuffer(Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')), // point.is_infinite ], ); - expect(decoded).toEqual([ - 1n, - 2n, - false, - 'xyz', - AztecAddress.fromBigInt(1n), - // eslint-disable-next-line camelcase - { x: 1n, y: 2n, is_infinite: false }, - ]); + expect(decoded).toEqual([1n, 2n, false, 'xyz', AztecAddress.fromBigInt(1n), { x: 1n, y: 2n }]); }); it('decodes Option::Some as the wrapped value', () => { diff --git a/yarn-project/stdlib/src/abi/utils.ts b/yarn-project/stdlib/src/abi/utils.ts index a1dea3316468..cd18b8394a0f 100644 --- a/yarn-project/stdlib/src/abi/utils.ts +++ b/yarn-project/stdlib/src/abi/utils.ts @@ -59,10 +59,10 @@ export function isPublicKeysStruct(abiType: AbiType) { abiType.kind === 'struct' && abiType.path === 'aztec::protocol_types::public_keys::PublicKeys' && abiType.fields.length === 4 && - abiType.fields[0].name === 'npk_m' && + abiType.fields[0].name === 'npk_m_hash' && abiType.fields[1].name === 'ivpk_m' && - abiType.fields[2].name === 'ovpk_m' && - abiType.fields[3].name === 'tpk_m' + abiType.fields[2].name === 'ovpk_m_hash' && + abiType.fields[3].name === 'tpk_m_hash' ); } diff --git a/yarn-project/stdlib/src/avm/avm.ts b/yarn-project/stdlib/src/avm/avm.ts index 339fe4271467..a5f2a4963bf3 100644 --- a/yarn-project/stdlib/src/avm/avm.ts +++ b/yarn-project/stdlib/src/avm/avm.ts @@ -130,6 +130,7 @@ export class AvmContractInstanceHint { public readonly currentContractClassId: Fr, public readonly originalContractClassId: Fr, public readonly initializationHash: Fr, + public readonly immutablesHash: Fr, public readonly publicKeys: PublicKeys, ) {} @@ -143,6 +144,7 @@ export class AvmContractInstanceHint { currentContractClassId: schemas.Fr, originalContractClassId: schemas.Fr, initializationHash: schemas.Fr, + immutablesHash: schemas.Fr, publicKeys: PublicKeys.schema, }) .transform( @@ -154,6 +156,7 @@ export class AvmContractInstanceHint { currentContractClassId, originalContractClassId, initializationHash, + immutablesHash, publicKeys, }) => new AvmContractInstanceHint( @@ -164,6 +167,7 @@ export class AvmContractInstanceHint { currentContractClassId, originalContractClassId, initializationHash, + immutablesHash, publicKeys, ), ); @@ -188,6 +192,7 @@ export class AvmContractInstanceHint { Fr.fromPlainObject(obj.currentContractClassId), Fr.fromPlainObject(obj.originalContractClassId), Fr.fromPlainObject(obj.initializationHash), + Fr.fromPlainObject(obj.immutablesHash), PublicKeys.fromPlainObject(obj.publicKeys), ); } diff --git a/yarn-project/stdlib/src/avm/message_pack.ts b/yarn-project/stdlib/src/avm/message_pack.ts index f07953876e2c..d1d75790f8e9 100644 --- a/yarn-project/stdlib/src/avm/message_pack.ts +++ b/yarn-project/stdlib/src/avm/message_pack.ts @@ -64,13 +64,22 @@ function setUpMessagePackExtensions() { addExtension({ Class: Point, write: (p: Point) => { - assert(!p.inf, 'Cannot serialize infinity'); - // TODO: should these be Frs? + // TODO: Now that we use a 2 elt point representation, we should be able to handle infs here. + // However this opens possible bad paths with public keys and requires sanitised conversion between + // BB's inf representation (see below), and ours/Noir's (0, 0), and empty points from BB, when inf + // does not actually pass through. + assert(!p.isInfinite, 'Cannot serialize infinity'); return { x: new Fq(p.x.toBigInt()), y: new Fq(p.y.toBigInt()) }; }, read: (data: { x: Fq; y: Fq }) => { + // Note: BB encodes infinity as x == y == Buffer of all ones. + // Infinity should never pass through here, but for correctness: + const ALL_ONES = (1n << 256n) - 1n; + if (data.x.toBigInt() === ALL_ONES && data.y.toBigInt() === ALL_ONES) { + return Point.INFINITY; + } // Convert Fq back to Fr for Point constructor - return new Point(new Fr(data.x.toBigInt()), new Fr(data.y.toBigInt()), false); + return new Point(new Fr(data.x.toBigInt()), new Fr(data.y.toBigInt())); }, }); // EthAddress is a class that has a buffer in TS, but is itself just a field in C++. diff --git a/yarn-project/stdlib/src/avm/revert_code.ts b/yarn-project/stdlib/src/avm/revert_code.ts index 810c779d563b..23d054af08e7 100644 --- a/yarn-project/stdlib/src/avm/revert_code.ts +++ b/yarn-project/stdlib/src/avm/revert_code.ts @@ -28,12 +28,6 @@ export class RevertCode { } static readonly OK: RevertCode = new RevertCode(RevertCodeEnum.OK); static readonly REVERTED: RevertCode = new RevertCode(RevertCodeEnum.REVERTED); - /** @deprecated Use REVERTED instead. */ - static readonly APP_LOGIC_REVERTED: RevertCode = RevertCode.REVERTED; - /** @deprecated Use REVERTED instead. */ - static readonly TEARDOWN_REVERTED: RevertCode = RevertCode.REVERTED; - /** @deprecated Use REVERTED instead. */ - static readonly BOTH_REVERTED: RevertCode = RevertCode.REVERTED; public getCode(): RevertCodeEnum { return this.code; diff --git a/yarn-project/stdlib/src/aztec-address/aztec-address.test.ts b/yarn-project/stdlib/src/aztec-address/aztec-address.test.ts index 2efab96544e7..d00329824a02 100644 --- a/yarn-project/stdlib/src/aztec-address/aztec-address.test.ts +++ b/yarn-project/stdlib/src/aztec-address/aztec-address.test.ts @@ -40,7 +40,7 @@ describe('aztec-address', () => { it("reconstructs an address's point", async () => { const address = await AztecAddress.random(); const point = await address.toAddressPoint(); - expect(point.isOnGrumpkin()).toEqual(true); + expect(point.isOnCurve()).toEqual(true); }); it('throws for an invalid address', async () => { diff --git a/yarn-project/stdlib/src/block/l2_block_source.ts b/yarn-project/stdlib/src/block/l2_block_source.ts index c8ac9b303b33..429e36da59d7 100644 --- a/yarn-project/stdlib/src/block/l2_block_source.ts +++ b/yarn-project/stdlib/src/block/l2_block_source.ts @@ -293,6 +293,7 @@ export type ArchiverEmitter = TypedEventEmitter<{ [L2BlockSourceEvents.L2BlockProven]: (args: L2BlockProvenEvent) => void; [L2BlockSourceEvents.InvalidAttestationsCheckpointDetected]: (args: InvalidCheckpointDetectedEvent) => void; [L2BlockSourceEvents.L2BlocksCheckpointed]: (args: L2CheckpointEvent) => void; + [L2BlockSourceEvents.CheckpointEquivocationDetected]: (args: CheckpointEquivocationDetectedEvent) => void; }>; export interface L2BlockSourceEventEmitter extends L2BlockSource { events: ArchiverEmitter; @@ -374,6 +375,7 @@ export enum L2BlockSourceEvents { L2BlockProven = 'l2BlockProven', L2BlocksCheckpointed = 'l2BlocksCheckpointed', InvalidAttestationsCheckpointDetected = 'invalidCheckpointDetected', + CheckpointEquivocationDetected = 'checkpointEquivocationDetected', } export type L2BlockProvenEvent = { @@ -404,3 +406,15 @@ export type InvalidCheckpointDetectedEvent = { type: 'invalidCheckpointDetected'; validationResult: ValidateCheckpointNegativeResult; }; + +/** + * Emitted when a local proposed checkpoint is found to disagree with the L1-confirmed + * checkpoint at the same slot. The slot proposer signed both — equivocation. + */ +export type CheckpointEquivocationDetectedEvent = { + type: 'checkpointEquivocationDetected'; + slotNumber: SlotNumber; + checkpointNumber: CheckpointNumber; + l1ArchiveRoot: Fr; + proposedArchiveRoot: Fr; +}; diff --git a/yarn-project/stdlib/src/block/l2_block_stream/l2_tips_store_base.ts b/yarn-project/stdlib/src/block/l2_block_stream/l2_tips_store_base.ts index 676e732b665b..9637ff5fd17d 100644 --- a/yarn-project/stdlib/src/block/l2_block_stream/l2_tips_store_base.ts +++ b/yarn-project/stdlib/src/block/l2_block_stream/l2_tips_store_base.ts @@ -213,11 +213,30 @@ export abstract class L2TipsStoreBase implements L2BlockStreamEventHandler, L2Bl await this.saveTag('finalized', event.block); const finalizedCheckpointNumber = await this.getCheckpointNumberForBlock(event.block.number); - await this.deleteBlockHashesBefore(event.block.number); - await this.deleteBlockToCheckpointBefore(event.block.number); + // Cap the deletion bound at the lowest live tip. This should always be the finalized tip, but + // we have hit bugs where this is not the case. Deleting the block hash, block-to-checkpoint mapping, + // or enclosing checkpoint object for a live tip would dangle subsequent `getBlockId`/`getCheckpointId` + // lookups and lock the block stream into an error loop. + const tips = await Promise.all([ + this.getTip('proposed'), + this.getTip('proposedCheckpoint'), + this.getTip('checkpointed'), + this.getTip('proven'), + ]); + const liveTipBlocks = tips.filter((t): t is BlockNumber => t !== undefined && t > 0); + const safeBlockBound = BlockNumber(Math.min(event.block.number, ...liveTipBlocks)); + await this.deleteBlockHashesBefore(safeBlockBound); + await this.deleteBlockToCheckpointBefore(safeBlockBound); if (finalizedCheckpointNumber !== undefined) { - await this.deleteCheckpointsBefore(finalizedCheckpointNumber); + const tipCheckpoints = await Promise.all(liveTipBlocks.map(b => this.getCheckpointNumberForBlock(b))); + const safeCheckpointBound = CheckpointNumber( + Math.min( + finalizedCheckpointNumber, + ...tipCheckpoints.filter((c): c is CheckpointNumber => c !== undefined && c > 0), + ), + ); + await this.deleteCheckpointsBefore(safeCheckpointBound); } }); } diff --git a/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.test.ts b/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.test.ts new file mode 100644 index 000000000000..7aec09513992 --- /dev/null +++ b/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.test.ts @@ -0,0 +1,168 @@ +import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { Fr } from '@aztec/foundation/curves/bn254'; + +import { CheckpointReexecutionTracker } from './checkpoint_reexecution_tracker.js'; + +describe('CheckpointReexecutionTracker', () => { + let tracker: CheckpointReexecutionTracker; + + beforeEach(() => { + tracker = new CheckpointReexecutionTracker(); + }); + + it('records and queries `valid` outcomes by (checkpoint number, archive root)', () => { + const cp = CheckpointNumber(7); + const archive = Fr.random(); + tracker.recordOutcome(SlotNumber(42), archive, 'valid', cp); + + expect(tracker.hasReexecuted(cp, archive)).toBe(true); + expect(tracker.hasReexecuted(cp, Fr.random())).toBe(false); + expect(tracker.hasReexecuted(CheckpointNumber(8), archive)).toBe(false); + }); + + it('hasReexecuted is true only for `valid` outcomes', () => { + const cp = CheckpointNumber(1); + const archive = Fr.random(); + + tracker.recordOutcome(SlotNumber(1), archive, 'invalid', cp); + expect(tracker.hasReexecuted(cp, archive)).toBe(false); + + tracker.recordOutcome(SlotNumber(1), archive, 'unvalidated', cp); + expect(tracker.hasReexecuted(cp, archive)).toBe(false); + + tracker.recordOutcome(SlotNumber(1), archive, 'valid', cp); + expect(tracker.hasReexecuted(cp, archive)).toBe(true); + }); + + it('exposes outcomes by slot', () => { + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'invalid', CheckpointNumber(2)); + tracker.recordOutcome(SlotNumber(30), Fr.random(), 'unvalidated', CheckpointNumber(3)); + + expect(tracker.getOutcomeForSlot(SlotNumber(10))).toBe('valid'); + expect(tracker.getOutcomeForSlot(SlotNumber(20))).toBe('invalid'); + expect(tracker.getOutcomeForSlot(SlotNumber(30))).toBe('unvalidated'); + expect(tracker.getOutcomeForSlot(SlotNumber(99))).toBeUndefined(); + }); + + it('records slot-only outcomes when checkpoint number is unknown', () => { + const archive = Fr.random(); + tracker.recordOutcome(SlotNumber(5), archive, 'invalid'); + + expect(tracker.getOutcomeForSlot(SlotNumber(5))).toBe('invalid'); + expect(tracker.hasReexecuted(CheckpointNumber(0), archive)).toBe(false); + }); + + it('tracks competing archive roots at the same checkpoint independently', () => { + const cp = CheckpointNumber(5); + const archiveA = Fr.random(); + const archiveB = Fr.random(); + + tracker.recordOutcome(SlotNumber(50), archiveB, 'invalid', cp); + tracker.recordOutcome(SlotNumber(51), archiveA, 'valid', cp); + + expect(tracker.hasReexecuted(cp, archiveA)).toBe(true); + expect(tracker.hasReexecuted(cp, archiveB)).toBe(false); + }); + + it('removeBefore drops entries below the cutoff and clears their slot index', () => { + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'valid', CheckpointNumber(2)); + tracker.recordOutcome(SlotNumber(30), Fr.random(), 'valid', CheckpointNumber(3)); + + tracker.removeBefore(CheckpointNumber(3)); + + expect(tracker.getOutcomeForSlot(SlotNumber(10))).toBeUndefined(); + expect(tracker.getOutcomeForSlot(SlotNumber(20))).toBeUndefined(); + expect(tracker.getOutcomeForSlot(SlotNumber(30))).toBe('valid'); + }); + + it('overwrites a prior outcome for the same (checkpoint, archive)', () => { + const cp = CheckpointNumber(1); + const archive = Fr.random(); + tracker.recordOutcome(SlotNumber(1), archive, 'unvalidated', cp); + tracker.recordOutcome(SlotNumber(1), archive, 'valid', cp); + + expect(tracker.hasReexecuted(cp, archive)).toBe(true); + expect(tracker.getOutcomeForSlot(SlotNumber(1))).toBe('valid'); + }); + + it('removeBefore drops slot-only entries older than the highest removed slot', () => { + // Slot-only entries (no checkpoint number) cannot be reached via byCheckpoint pruning. + // Without slot-watermark pruning they would accumulate forever. + tracker.recordOutcome(SlotNumber(5), Fr.random(), 'unvalidated'); + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordOutcome(SlotNumber(12), Fr.random(), 'unvalidated'); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'valid', CheckpointNumber(2)); + tracker.recordOutcome(SlotNumber(25), Fr.random(), 'unvalidated'); + + tracker.removeBefore(CheckpointNumber(2)); + + expect(tracker.getOutcomeForSlot(SlotNumber(5))).toBeUndefined(); + expect(tracker.getOutcomeForSlot(SlotNumber(10))).toBeUndefined(); + // Slot 12 is above the highest removed slot (10) + expect(tracker.getOutcomeForSlot(SlotNumber(12))).toBe('unvalidated'); + expect(tracker.getOutcomeForSlot(SlotNumber(20))).toBe('valid'); + expect(tracker.getOutcomeForSlot(SlotNumber(25))).toBe('unvalidated'); + }); + + describe('recordTxsCollected', () => { + it('records and queries by (slot, indexWithinCheckpoint) with three-valued result', () => { + tracker.recordTxsCollected(SlotNumber(11), 0, true); + tracker.recordTxsCollected(SlotNumber(11), 1, false); + + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 0)).toBe(true); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 1)).toBe(false); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 2)).toBeUndefined(); + expect(tracker.getTxsCollectedRecord(SlotNumber(99), 0)).toBeUndefined(); + }); + + it('preserves prior txsCollected entries when recordOutcome fires for the same slot', () => { + tracker.recordTxsCollected(SlotNumber(11), 0, true); + tracker.recordTxsCollected(SlotNumber(11), 1, false); + + tracker.recordOutcome(SlotNumber(11), Fr.random(), 'valid', CheckpointNumber(7)); + + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 0)).toBe(true); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 1)).toBe(false); + expect(tracker.getOutcomeForSlot(SlotNumber(11))).toBe('valid'); + }); + + it('overwrites a prior collected value at the same (slot, index)', () => { + tracker.recordTxsCollected(SlotNumber(11), 0, false); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 0)).toBe(false); + + tracker.recordTxsCollected(SlotNumber(11), 0, true); + expect(tracker.getTxsCollectedRecord(SlotNumber(11), 0)).toBe(true); + }); + + it('removeBefore drops txsCollected entries together with their slot', () => { + tracker.recordTxsCollected(SlotNumber(10), 0, true); + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordTxsCollected(SlotNumber(20), 0, false); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'valid', CheckpointNumber(2)); + + tracker.removeBefore(CheckpointNumber(2)); + + expect(tracker.getTxsCollectedRecord(SlotNumber(10), 0)).toBeUndefined(); + expect(tracker.getTxsCollectedRecord(SlotNumber(20), 0)).toBe(false); + }); + + it('removeBefore drops standalone txsCollected entries via the slot watermark', () => { + // recordTxsCollected without a subsequent recordOutcome creates a slot-only entry with + // no checkpoint number; it must still be reachable by the slot-watermark cleanup. + tracker.recordTxsCollected(SlotNumber(5), 0, true); + tracker.recordOutcome(SlotNumber(10), Fr.random(), 'valid', CheckpointNumber(1)); + tracker.recordTxsCollected(SlotNumber(12), 0, true); + tracker.recordOutcome(SlotNumber(20), Fr.random(), 'valid', CheckpointNumber(2)); + + tracker.removeBefore(CheckpointNumber(2)); + + expect(tracker.getTxsCollectedRecord(SlotNumber(5), 0)).toBeUndefined(); + expect(tracker.getTxsCollectedRecord(SlotNumber(10), 0)).toBeUndefined(); + // Slot 12 is above the highest removed slot (10), so it survives. + expect(tracker.getTxsCollectedRecord(SlotNumber(12), 0)).toBe(true); + expect(tracker.getOutcomeForSlot(SlotNumber(20))).toBe('valid'); + }); + }); +}); diff --git a/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.ts b/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.ts new file mode 100644 index 000000000000..c4b85c73e2ea --- /dev/null +++ b/yarn-project/stdlib/src/checkpoint/checkpoint_reexecution_tracker.ts @@ -0,0 +1,167 @@ +import type { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import type { Fr } from '@aztec/foundation/curves/bn254'; + +/** + * Outcome of attempting to re-execute a checkpoint proposal locally. + * + * - `valid` — re-execution succeeded and the computed checkpoint matched the proposal. + * - `invalid` — the proposal disagreed with the computed checkpoint, or violated a deterministic + * constraint (limits, signatures, etc). + * - `unvalidated` — the local node could not complete validation for non-deterministic reasons + * (missing blocks/txs, timeouts, infra errors). Treated as proposer-fault for + * slashing but surfaced separately for telemetry. + */ +export type ReexecutionOutcome = 'valid' | 'invalid' | 'unvalidated'; + +/** + * Tracks two pieces of per-slot state collected during proposal handling: + * + * 1. Whether each block proposal's transactions were successfully collected locally + * (keyed by `slot` + `indexWithinCheckpoint`). Consumed by the data-withholding watcher. + * 2. The outcome of locally re-executing each checkpoint proposal (keyed by + * `(checkpointNumber, archiveRoot)` and by `slot`). Consumed by the data-withholding + * watcher (via `hasReexecuted`) and the sentinel (via `getOutcomeForSlot`). + * + * Both pieces of state live on the same per-slot `Entry`, so cleanup via `removeBefore` + * naturally drops everything for a pruned slot in one step. + */ +interface Entry { + // Set by recordOutcome — these may be undefined until the checkpoint proposal has been + // evaluated. recordTxsCollected may create an Entry before any of them are known. + checkpointNumber: CheckpointNumber | undefined; + archiveRoot: string | undefined; + outcome: ReexecutionOutcome | undefined; + + slot: SlotNumber; + + // Per block-proposal at this slot: indexWithinCheckpoint → true (collected) | false (failed to collect). + txsCollected: Map; +} + +export class CheckpointReexecutionTracker { + private readonly byCheckpoint = new Map>(); + private readonly bySlot = new Map(); + + /** + * Record the outcome of evaluating a checkpoint proposal. + * @param slot - Slot the proposal was for. Always required. + * @param archiveRoot - Archive root in the proposal. + * @param outcome - Outcome of evaluation. + * @param checkpointNumber - Checkpoint number, if known. Required for `valid` outcomes; optional + * for `invalid`/`unvalidated` because some early rejections fire before blocks are loaded. + */ + public recordOutcome( + slot: SlotNumber, + archiveRoot: Fr, + outcome: ReexecutionOutcome, + checkpointNumber?: CheckpointNumber, + ): void { + const archiveRootStr = archiveRoot.toString(); + + // Preserve any per-block txsCollected already accumulated for this slot. + const existing = this.bySlot.get(slot); + const entry: Entry = { + checkpointNumber, + archiveRoot: archiveRootStr, + slot, + outcome, + txsCollected: existing?.txsCollected ?? new Map(), + }; + + if (checkpointNumber !== undefined) { + let archives = this.byCheckpoint.get(checkpointNumber); + if (!archives) { + archives = new Map(); + this.byCheckpoint.set(checkpointNumber, archives); + } + archives.set(archiveRootStr, entry); + } + + this.bySlot.set(slot, entry); + } + + /** + * Record whether the local node successfully collected the transactions for a block proposal. + * Called from the validator's proposal handler immediately after tx collection completes + * (regardless of whether re-execution will subsequently succeed). The data-withholding + * watcher consults these records as an authoritative signal: tx availability now is too + * weak (txs may have been evicted from the mempool by the time the watcher runs), but a + * record that the txs *were* available at proposal time still vouches for the proposer. + * + * @param slot - Slot the block proposal was for. + * @param indexWithinCheckpoint - Index of the block within its enclosing checkpoint. + * @param collected - True if every tx in the proposal was collected locally before deadline. + */ + public recordTxsCollected(slot: SlotNumber, indexWithinCheckpoint: number, collected: boolean): void { + let entry = this.bySlot.get(slot); + if (!entry) { + entry = { + checkpointNumber: undefined, + archiveRoot: undefined, + slot, + outcome: undefined, + txsCollected: new Map(), + }; + this.bySlot.set(slot, entry); + } + entry.txsCollected.set(indexWithinCheckpoint, collected); + } + + /** + * Returns true if the given (checkpoint number, archive root) has been successfully + * re-executed locally (outcome `valid`). + */ + public hasReexecuted(checkpointNumber: CheckpointNumber, archiveRoot: Fr): boolean { + return this.byCheckpoint.get(checkpointNumber)?.get(archiveRoot.toString())?.outcome === 'valid'; + } + + /** Returns the recorded outcome for a given slot, or undefined if no proposal was evaluated. */ + public getOutcomeForSlot(slot: SlotNumber): ReexecutionOutcome | undefined { + return this.bySlot.get(slot)?.outcome; + } + + /** + * Returns the recorded tx-collection result for a block proposal at the given slot and + * `indexWithinCheckpoint`, or `undefined` if no record exists. + * + * Three-valued by design: + * - `true` — we collected every tx for this block proposal before the deadline. + * - `false` — we tried and failed (missing txs at the deadline). + * - `undefined` — no record (e.g. we never saw the block proposal). Callers should fall + * back to a current-state check (e.g. mempool probe) for this case. + */ + public getTxsCollectedRecord(slot: SlotNumber, indexWithinCheckpoint: number): boolean | undefined { + return this.bySlot.get(slot)?.txsCollected.get(indexWithinCheckpoint); + } + + /** Drops entries for checkpoints with `number < checkpointNumber`. */ + public removeBefore(checkpointNumber: CheckpointNumber): void { + // Track the highest slot among checkpoints we're pruning. Once we know it, any slot + // strictly below that watermark is older than the most recently pruned checkpoint and + // can be dropped from `bySlot` too — including slot-only entries (no checkpoint number) + // which would otherwise leak, because removing by checkpoint number can't reach them. + let maxRemovedSlot: SlotNumber | undefined; + for (const [n, archives] of this.byCheckpoint) { + if (n < checkpointNumber) { + for (const entry of archives.values()) { + // Only drop the slot index if it still points at the entry we're removing. + if (this.bySlot.get(entry.slot) === entry) { + this.bySlot.delete(entry.slot); + } + if (maxRemovedSlot === undefined || entry.slot > maxRemovedSlot) { + maxRemovedSlot = entry.slot; + } + } + this.byCheckpoint.delete(n); + } + } + + if (maxRemovedSlot !== undefined) { + for (const slot of [...this.bySlot.keys()]) { + if (slot < maxRemovedSlot) { + this.bySlot.delete(slot); + } + } + } + } +} diff --git a/yarn-project/stdlib/src/checkpoint/index.ts b/yarn-project/stdlib/src/checkpoint/index.ts index 33dec7639e8c..cff0a7d04b2d 100644 --- a/yarn-project/stdlib/src/checkpoint/index.ts +++ b/yarn-project/stdlib/src/checkpoint/index.ts @@ -1,6 +1,7 @@ export * from './checkpoint.js'; export * from './checkpoint_data.js'; export * from './checkpoint_info.js'; +export * from './checkpoint_reexecution_tracker.js'; export * from './digest.js'; export * from './previous_checkpoint_out_hashes.js'; export * from './published_checkpoint.js'; diff --git a/yarn-project/stdlib/src/contract/complete_address.test.ts b/yarn-project/stdlib/src/contract/complete_address.test.ts index 0d68a3366609..c9f610801965 100644 --- a/yarn-project/stdlib/src/contract/complete_address.test.ts +++ b/yarn-project/stdlib/src/contract/complete_address.test.ts @@ -3,6 +3,7 @@ import { Point } from '@aztec/foundation/curves/grumpkin'; import { AztecAddress } from '../aztec-address/index.js'; import { computeAddress } from '../keys/derivation.js'; +import { hashPublicKey } from '../keys/public_key.js'; import { PublicKeys } from '../keys/public_keys.js'; import { CompleteAddress } from './complete_address.js'; @@ -47,7 +48,12 @@ describe('CompleteAddress', () => { const partialAddress = Fr.fromHexString('0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de'); - const publicKeys = new PublicKeys(npkM, ivpkM, ovpkM, tpkM); + const publicKeys = new PublicKeys( + await hashPublicKey(npkM), + ivpkM, + await hashPublicKey(ovpkM), + await hashPublicKey(tpkM), + ); // Compute the expected address from the public keys and partial address const expectedAddress = await computeAddress(publicKeys, partialAddress); diff --git a/yarn-project/stdlib/src/contract/complete_address.ts b/yarn-project/stdlib/src/contract/complete_address.ts index 4b0442ebbb40..cea9fc138c2e 100644 --- a/yarn-project/stdlib/src/contract/complete_address.ts +++ b/yarn-project/stdlib/src/contract/complete_address.ts @@ -38,7 +38,8 @@ export class CompleteAddress { } /** Size in bytes of an instance */ - static readonly SIZE_IN_BYTES = 32 * 10; + // address (1 Fr) + publicKeys (1 Fr hash + 1 Point + 2 Fr hashes = 5 Fr) + partialAddress (1 Fr) = 7 Fr + static readonly SIZE_IN_BYTES = 32 * 7; static get schema() { return hexSchemaFor(CompleteAddress); @@ -54,8 +55,11 @@ export class CompleteAddress { static async fromSecretKeyAndPartialAddress(secretKey: Fr, partialAddress: Fr): Promise { const { publicKeys } = await deriveKeys(secretKey); - const address = await computeAddress(publicKeys, partialAddress); + return await this.fromPublicKeysAndPartialAddress(publicKeys, partialAddress); + } + static async fromPublicKeysAndPartialAddress(publicKeys: PublicKeys, partialAddress: Fr): Promise { + const address = await computeAddress(publicKeys, partialAddress); return new CompleteAddress(address, publicKeys, partialAddress); } @@ -87,7 +91,7 @@ export class CompleteAddress { * @returns A readable string representation of the complete address. */ public toReadableString(): string { - return `Address: ${this.address.toString()}\nMaster Nullifier Public Key: ${this.publicKeys.masterNullifierPublicKey.toString()}\nMaster Incoming Viewing Public Key: ${this.publicKeys.masterIncomingViewingPublicKey.toString()}\nMaster Outgoing Viewing Public Key: ${this.publicKeys.masterOutgoingViewingPublicKey.toString()}\nMaster Tagging Public Key: ${this.publicKeys.masterTaggingPublicKey.toString()}\nPartial Address: ${this.partialAddress.toString()}\n`; + return `Address: ${this.address.toString()}\nNpkM hash: ${this.publicKeys.npkMHash.toString()}\nIvpkM: ${this.publicKeys.ivpkM.toString()}\nOvpkM hash: ${this.publicKeys.ovpkMHash.toString()}\nTpkM hash: ${this.publicKeys.tpkMHash.toString()}\nPartial Address: ${this.partialAddress.toString()}\n`; } /** diff --git a/yarn-project/stdlib/src/contract/contract_address.test.ts b/yarn-project/stdlib/src/contract/contract_address.test.ts index def2ccb6bac6..5470ca43e78e 100644 --- a/yarn-project/stdlib/src/contract/contract_address.test.ts +++ b/yarn-project/stdlib/src/contract/contract_address.test.ts @@ -23,19 +23,18 @@ describe('ContractAddress', () => { `"0x2f43fe475e50f6066260038fd16fa97029a76395b2d38388808e60bc24651a0c"`, ); }); - it('computeSaltedInitializationHash', async () => { const mockInstance = { initializationHash: new Fr(1), salt: new Fr(2), deployer: AztecAddress.fromField(new Fr(4)), + immutablesHash: new Fr(3), }; const result = await computeSaltedInitializationHash(mockInstance); expect(result.toString()).toMatchInlineSnapshot( - `"0x2175c2437c52b1bfae8eed40f2e9968546a7053272f94f3937c52ed7e0018349"`, + `"0x093c5f7e0d5a56a1fce27bb347233fd1884db1ff78573c5b9b2de9d3fe8babe1"`, ); }); - it('computeInitializationHash', async () => { const mockInitFn: FunctionAbi = { functionType: FunctionType.PRIVATE, @@ -53,17 +52,16 @@ describe('ContractAddress', () => { `"0x08b683284b4344302193cb36c05f043d4225e2d88d9e0f6ffde12547098cab98"`, ); }); - it('computeInitializationHash empty', async () => { const result = await computeInitializationHash(undefined, []); expect(result).toEqual(Fr.ZERO); }); - it('computeContractAddressFromInstance', async () => { const secretKey = new Fr(2n); const salt = new Fr(3n); const contractClassId = new Fr(4n); const initializationHash = new Fr(5n); + const immutablesHash = new Fr(6n); const deployer = AztecAddress.fromField(new Fr(7)); const publicKeys = (await deriveKeys(secretKey)).publicKeys; const instance = { @@ -73,14 +71,14 @@ describe('ContractAddress', () => { currentContractClassId: contractClassId, initializationHash, deployer, - version: 1 as const, + immutablesHash, + version: 2 as const, }; - const [ms, address] = await elapsed(computeContractAddressFromInstance(instance)); const logger = createLogger('stdlib:contract_address:test'); logger.info(`Computed contract address from instance in ${ms}ms`); expect(address.toString()).toMatchInlineSnapshot( - `"0x260f462e7ae7b7031cdb5e41a691a265d7debe6863d8a12887b97f5f8e5d7727"`, + `"0x2527876b96f9da428aaec968da7a89018db43c78dcdb2e7246060dc37e49e0ac"`, ); }); }); diff --git a/yarn-project/stdlib/src/contract/contract_address.ts b/yarn-project/stdlib/src/contract/contract_address.ts index 6376a263a9d4..a5c36107b344 100644 --- a/yarn-project/stdlib/src/contract/contract_address.ts +++ b/yarn-project/stdlib/src/contract/contract_address.ts @@ -13,9 +13,9 @@ import type { ContractInstance } from './interfaces/contract_instance.js'; /** * Returns the deployment address for a given contract instance. * ``` - * salted_initialization_hash = poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, [salt, initialization_hash, deployer]) + * salted_initialization_hash = poseidon2(DOM_SEP__SALTED_INITIALIZATION_HASH, [salt, initialization_hash, deployer, immutables_hash]) * partial_address = poseidon2(DOM_SEP__PARTIAL_ADDRESS, [contract_class_id, salted_initialization_hash]) - * address = ((poseidon2(DOM_SEP__CONTRACT_ADDRESS_V1, [public_keys_hash, partial_address]) * G) + ivpk_m).x <- the x-coordinate of the address point + * address = ((poseidon2(DOM_SEP__CONTRACT_ADDRESS_V2, [public_keys_hash, partial_address]) * G) + ivpk_m).x <- the x-coordinate of the address point * ``` * @param instance - A contract instance for which to calculate the deployment address. */ @@ -34,7 +34,7 @@ export async function computeContractAddressFromInstance( */ export async function computePartialAddress( instance: - | Pick + | Pick | { originalContractClassId: Fr; saltedInitializationHash: Fr }, ): Promise { const saltedInitializationHash = @@ -53,10 +53,10 @@ export async function computePartialAddress( * @param instance - Contract instance for which to compute the salted initialization hash. */ export function computeSaltedInitializationHash( - instance: Pick, + instance: Pick, ): Promise { return poseidon2HashWithSeparator( - [instance.salt, instance.initializationHash, instance.deployer], + [instance.salt, instance.initializationHash, instance.deployer, instance.immutablesHash], DomainSeparator.SALTED_INITIALIZATION_HASH, ); } diff --git a/yarn-project/stdlib/src/contract/contract_instance.ts b/yarn-project/stdlib/src/contract/contract_instance.ts index d3dcb4b79f8c..7be8330eeea5 100644 --- a/yarn-project/stdlib/src/contract/contract_instance.ts +++ b/yarn-project/stdlib/src/contract/contract_instance.ts @@ -20,7 +20,7 @@ import { } from './contract_address.js'; import type { ContractInstance, ContractInstanceWithAddress } from './interfaces/contract_instance.js'; -const VERSION = 1 as const; +const VERSION = 2 as const; export type ContractInstantiationData = { constructorArtifact?: FunctionAbi | string; @@ -29,6 +29,7 @@ export type ContractInstantiationData = { salt: Fr; publicKeys?: PublicKeys; deployer?: AztecAddress; + immutablesHash?: Fr; }; export class SerializableContractInstance { @@ -38,6 +39,7 @@ export class SerializableContractInstance { public readonly currentContractClassId: Fr; public readonly originalContractClassId: Fr; public readonly initializationHash: Fr; + public readonly immutablesHash: Fr; public readonly publicKeys: PublicKeys; constructor(instance: ContractInstance) { @@ -49,6 +51,7 @@ export class SerializableContractInstance { this.currentContractClassId = instance.currentContractClassId; this.originalContractClassId = instance.originalContractClassId; this.initializationHash = instance.initializationHash; + this.immutablesHash = instance.immutablesHash; this.publicKeys = instance.publicKeys; } @@ -60,6 +63,7 @@ export class SerializableContractInstance { this.currentContractClassId, this.originalContractClassId, this.initializationHash, + this.immutablesHash, this.publicKeys, ); } @@ -78,6 +82,7 @@ export class SerializableContractInstance { currentContractClassId: reader.readObject(Fr), originalContractClassId: reader.readObject(Fr), initializationHash: reader.readObject(Fr), + immutablesHash: reader.readObject(Fr), publicKeys: reader.readObject(PublicKeys), }); } @@ -90,6 +95,7 @@ export class SerializableContractInstance { currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), ...opts, }); @@ -103,6 +109,7 @@ export class SerializableContractInstance { currentContractClassId: Fr.zero(), originalContractClassId: Fr.zero(), initializationHash: Fr.zero(), + immutablesHash: Fr.zero(), publicKeys: PublicKeys.default(), }); } @@ -130,15 +137,17 @@ export async function getContractInstanceFromInstantiationParams( ) : await computeInitializationHash(constructorArtifact, args); const publicKeys = opts.publicKeys ?? PublicKeys.default(); + const immutablesHash = opts.immutablesHash ?? Fr.ZERO; const instance: ContractInstance = { currentContractClassId: contractClass.id, originalContractClassId: contractClass.id, initializationHash, + immutablesHash, publicKeys, salt: opts.salt, deployer, - version: 1, + version: 2, }; return { ...instance, address: await computeContractAddressFromInstance(instance) }; diff --git a/yarn-project/stdlib/src/contract/interfaces/contract_instance.ts b/yarn-project/stdlib/src/contract/interfaces/contract_instance.ts index 6e7f986b1ce1..2d992dbac99c 100644 --- a/yarn-project/stdlib/src/contract/interfaces/contract_instance.ts +++ b/yarn-project/stdlib/src/contract/interfaces/contract_instance.ts @@ -6,7 +6,7 @@ import { AztecAddress } from '../../aztec-address/index.js'; import { PublicKeys } from '../../keys/public_keys.js'; import { schemas, zodFor } from '../../schemas/index.js'; -const VERSION = 1 as const; +const VERSION = 2 as const; /** * A contract instance is a concrete deployment of a contract class. It always references a contract class, @@ -26,6 +26,8 @@ export interface ContractInstance { originalContractClassId: Fr; /** Hash of the selector and arguments to the constructor. */ initializationHash: Fr; + /** Hash of Immutables Values the contract is deployed with. */ + immutablesHash: Fr; /** Public keys associated with this instance. */ publicKeys: PublicKeys; } @@ -40,6 +42,7 @@ export const ContractInstanceSchema = zodFor()( currentContractClassId: schemas.Fr, originalContractClassId: schemas.Fr, initializationHash: schemas.Fr, + immutablesHash: schemas.Fr, publicKeys: PublicKeys.schema, }), ); @@ -54,12 +57,13 @@ export const ContractInstanceWithAddressSchema = zodFor { originalContractClassId: expect.any(Fr), deployer: expect.any(AztecAddress), initializationHash: expect.any(Fr), + immutablesHash: expect.any(Fr), publicKeys: expect.any(PublicKeys), salt: expect.any(Fr), - version: 1, + version: 2, }); }); @@ -578,9 +579,10 @@ class MockArchiver implements ArchiverApi { originalContractClassId: Fr.random(), deployer: await AztecAddress.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), salt: Fr.random(), - version: 1, + version: 2, }; } getContractClassIds(): Promise { diff --git a/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts b/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts index 127d58eb453e..89b3d50fa901 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts @@ -57,6 +57,14 @@ describe('AztecNodeAdminApiSchema', () => { await context.client.resumeSync(); }); + it('pauseSequencer', async () => { + await context.client.pauseSequencer(); + }); + + it('resumeSequencer', async () => { + await context.client.resumeSequencer(); + }); + it('getSlashOffenses', async () => { const offenses = await context.client.getSlashOffenses('all'); expect(offenses).toHaveLength(1); @@ -107,19 +115,20 @@ class MockAztecNodeAdmin implements AztecNodeAdmin { slashAmountLarge: 2000n, slashValidatorsAlways: [], slashValidatorsNever: [], - slashPrunePenalty: 1000n, slashDataWithholdingPenalty: 1000n, + slashDataWithholdingToleranceSlots: 3, slashInactivityTargetPercentage: 0.5, slashInactivityConsecutiveEpochThreshold: 1, slashInactivityPenalty: 1000n, slashBroadcastedInvalidBlockPenalty: 1n, + slashBroadcastedInvalidCheckpointProposalPenalty: 1n, slashDuplicateProposalPenalty: 1n, slashDuplicateAttestationPenalty: 1n, slashAttestInvalidCheckpointProposalPenalty: 1000n, secondsBeforeInvalidatingBlockAsCommitteeMember: 0, secondsBeforeInvalidatingBlockAsNonCommitteeMember: 0, slashProposeInvalidAttestationsPenalty: 1000n, - slashAttestDescendantOfInvalidPenalty: 1000n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1000n, slashOffenseExpirationRounds: 4, slashMaxPayloadSize: 50, slashUnknownPenalty: 1000n, @@ -152,6 +161,12 @@ class MockAztecNodeAdmin implements AztecNodeAdmin { resumeSync(): Promise { return Promise.resolve(); } + pauseSequencer(): Promise { + return Promise.resolve(); + } + resumeSequencer(): Promise { + return Promise.resolve(); + } reloadKeystore(): Promise { return Promise.resolve(); } diff --git a/yarn-project/stdlib/src/interfaces/aztec-node-admin.ts b/yarn-project/stdlib/src/interfaces/aztec-node-admin.ts index 409acb28e569..66ce9d00ad76 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node-admin.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node-admin.ts @@ -48,6 +48,15 @@ export interface AztecNodeAdmin { /** Resumes archiver and world state syncing. */ resumeSync(): Promise; + /** + * Pauses block production. Pending txs remain in the mempool; no new blocks will be + * produced until {@link resumeSequencer} is called. Throws if no sequencer is running. + */ + pauseSequencer(): Promise; + + /** Resumes block production previously paused via {@link pauseSequencer}. */ + resumeSequencer(): Promise; + /** Returns all offenses applicable for the given round. */ getSlashOffenses(round: bigint | 'all' | 'current'): Promise; @@ -108,6 +117,8 @@ export const AztecNodeAdminApiSchema: ApiSchemaFor = { }), pauseSync: z.function({ input: z.tuple([]), output: z.void() }), resumeSync: z.function({ input: z.tuple([]), output: z.void() }), + pauseSequencer: z.function({ input: z.tuple([]), output: z.void() }), + resumeSequencer: z.function({ input: z.tuple([]), output: z.void() }), getSlashOffenses: z.function({ input: z.tuple([z.union([z.bigint(), z.literal('all'), z.literal('current')])]), output: z.array(OffenseSchema), diff --git a/yarn-project/stdlib/src/interfaces/aztec-node.test.ts b/yarn-project/stdlib/src/interfaces/aztec-node.test.ts index f7ba90236a4b..53edceea3df1 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node.test.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node.test.ts @@ -428,7 +428,7 @@ describe('AztecNodeApiSchema', () => { missedProposals: { currentStreak: 0, count: 0, total: 1 }, history: [{ slot: SlotNumber(1), status: 'checkpoint-mined' }], }, - allTimeProvenPerformance: [], + allTimeEpochPerformance: [], lastProcessedSlot: SlotNumber(10), initialSlot: SlotNumber(1), slotWindow: 100, @@ -453,7 +453,7 @@ describe('AztecNodeApiSchema', () => { missedProposals: { currentStreak: 0, count: 0, total: 0 }, history: [{ slot: SlotNumber(5), status: 'attestation-sent' }], }, - allTimeProvenPerformance: [], + allTimeEpochPerformance: [], lastProcessedSlot: SlotNumber(10), initialSlot: SlotNumber(5), slotWindow: 5, @@ -492,9 +492,10 @@ describe('AztecNodeApiSchema', () => { originalContractClassId: expect.any(Fr), deployer: expect.any(AztecAddress), initializationHash: expect.any(Fr), + immutablesHash: expect.any(Fr), publicKeys: expect.any(PublicKeys), salt: expect.any(Fr), - version: 1, + version: 2, }); }); @@ -845,11 +846,12 @@ class MockAztecNode implements AztecNode { async getContract(address: AztecAddress): Promise { expect(address).toBeInstanceOf(AztecAddress); const instance = { - version: 1 as const, + version: 2 as const, currentContractClassId: Fr.random(), originalContractClassId: Fr.random(), deployer: await AztecAddress.random(), initializationHash: Fr.random(), + immutablesHash: Fr.random(), publicKeys: await PublicKeys.random(), salt: Fr.random(), address: await AztecAddress.random(), diff --git a/yarn-project/stdlib/src/interfaces/block-builder.ts b/yarn-project/stdlib/src/interfaces/block-builder.ts index 6a2f49bb4209..8e09e36c1320 100644 --- a/yarn-project/stdlib/src/interfaces/block-builder.ts +++ b/yarn-project/stdlib/src/interfaces/block-builder.ts @@ -45,6 +45,8 @@ export type PublicProcessorLimits = { maxBlobFields?: number; /** Deadline for processing the txs. Processor will stop as soon as it hits this time. */ deadline?: Date; + /** Signal for interrupting processing before the deadline. */ + signal?: AbortSignal; /** Whether this processor is building a proposal (as opposed to re-executing one). Skipping txs due to gas or blob limits is only done during proposal building. */ isBuildingProposal?: boolean; }; diff --git a/yarn-project/stdlib/src/interfaces/configs.ts b/yarn-project/stdlib/src/interfaces/configs.ts index c85ebc7a4f6e..83453f405fe4 100644 --- a/yarn-project/stdlib/src/interfaces/configs.ts +++ b/yarn-project/stdlib/src/interfaces/configs.ts @@ -64,6 +64,14 @@ export interface SequencerConfig { skipInvalidateBlockAsProposer?: boolean; /** Broadcast invalid block proposals with corrupted state (for testing only) */ broadcastInvalidBlockProposal?: boolean; + /** Broadcast an invalid block proposal only at this indexWithinCheckpoint (for testing only) */ + invalidBlockProposalIndexWithinCheckpoint?: number; + /** + * Broadcast invalid checkpoint proposals (with corrupted archive) while keeping the underlying + * block proposals valid (for testing only). When unset, the checkpoint follows + * `broadcastInvalidBlockProposal`. + */ + broadcastInvalidCheckpointProposalOnly?: boolean; /** Inject a fake attestation (for testing only) */ injectFakeAttestation?: boolean; /** Inject a malleable attestation with a high-s value (for testing only) */ @@ -121,6 +129,8 @@ export const SequencerConfigSchema = zodFor()( secondsBeforeInvalidatingBlockAsCommitteeMember: z.number(), secondsBeforeInvalidatingBlockAsNonCommitteeMember: z.number(), broadcastInvalidBlockProposal: z.boolean().optional(), + invalidBlockProposalIndexWithinCheckpoint: z.number().int().nonnegative().optional(), + broadcastInvalidCheckpointProposalOnly: z.boolean().optional(), injectFakeAttestation: z.boolean().optional(), injectHighSValueAttestation: z.boolean().optional(), injectUnrecoverableSignatureAttestation: z.boolean().optional(), @@ -149,6 +159,7 @@ type SequencerConfigOptionalKeys = | 'fakeThrowAfterProcessingTxCount' | 'l1PublishingTime' | 'txPublicSetupAllowListExtend' + | 'invalidBlockProposalIndexWithinCheckpoint' | 'minValidTxsPerBlock' | 'minBlocksForCheckpoint' | 'maxTxsPerBlock' diff --git a/yarn-project/stdlib/src/interfaces/p2p.ts b/yarn-project/stdlib/src/interfaces/p2p.ts index 111a3b9becb7..902bd069e41e 100644 --- a/yarn-project/stdlib/src/interfaces/p2p.ts +++ b/yarn-project/stdlib/src/interfaces/p2p.ts @@ -2,7 +2,9 @@ import type { CheckpointProposalHash, SlotNumber } from '@aztec/foundation/brand import { z } from 'zod'; +import type { BlockProposal } from '../p2p/block_proposal.js'; import { CheckpointAttestation } from '../p2p/checkpoint_attestation.js'; +import type { CheckpointProposalCore } from '../p2p/checkpoint_proposal.js'; import { type ApiSchemaFor, optional, schemas } from '../schemas/index.js'; import { Tx } from '../tx/tx.js'; import { TxHash } from '../tx/tx_hash.js'; @@ -67,6 +69,12 @@ export interface P2PApi { export interface P2PClient extends P2PApi { /** Manually adds checkpoint attestations to the p2p client attestation pool. */ addOwnCheckpointAttestations(attestations: CheckpointAttestation[]): Promise; + + /** Returns retained signed proposals for a slot. */ + getProposalsForSlot(slot: SlotNumber): Promise<{ + blockProposals: BlockProposal[]; + checkpointProposals: CheckpointProposalCore[]; + }>; } export const P2PApiSchema: ApiSchemaFor = { diff --git a/yarn-project/stdlib/src/interfaces/slasher.ts b/yarn-project/stdlib/src/interfaces/slasher.ts index 9e71e16e0f16..d3e99d003342 100644 --- a/yarn-project/stdlib/src/interfaces/slasher.ts +++ b/yarn-project/stdlib/src/interfaces/slasher.ts @@ -10,14 +10,20 @@ export interface SlasherConfig { slashValidatorsNever: EthAddress[]; // Array of validator addresses slashInactivityTargetPercentage: number; // 0-1, 0.9 means 90%. Must be greater than 0 slashInactivityConsecutiveEpochThreshold: number; // Number of consecutive epochs a validator must be inactive before slashing - slashPrunePenalty: bigint; slashDataWithholdingPenalty: bigint; + /** + * Number of full L2 slots that must elapse after a checkpoint's slot before declaring its + * txs missing and slashing the checkpoint's attesters for data withholding. With tolerance + * = N and checkpoint slot S, the check fires at the start of slot `S + N + 1`. + */ + slashDataWithholdingToleranceSlots: number; slashInactivityPenalty: bigint; slashBroadcastedInvalidBlockPenalty: bigint; + slashBroadcastedInvalidCheckpointProposalPenalty: bigint; slashDuplicateProposalPenalty: bigint; slashDuplicateAttestationPenalty: bigint; slashProposeInvalidAttestationsPenalty: bigint; - slashAttestDescendantOfInvalidPenalty: bigint; + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: bigint; slashAttestInvalidCheckpointProposalPenalty: bigint; slashUnknownPenalty: bigint; slashOffenseExpirationRounds: number; // Number of rounds after which pending offenses expire @@ -31,15 +37,20 @@ export const SlasherConfigSchema = zodFor()( slashOverridePayload: schemas.EthAddress.optional(), slashValidatorsAlways: z.array(schemas.EthAddress), slashValidatorsNever: z.array(schemas.EthAddress), - slashPrunePenalty: schemas.BigInt, slashDataWithholdingPenalty: schemas.BigInt, + // Tolerated as undefined to allow validating responses from older node images that + // predate the per-slot data-withholding watcher (PR #23116). + slashDataWithholdingToleranceSlots: z.number().default(3), slashInactivityTargetPercentage: z.number(), slashInactivityConsecutiveEpochThreshold: z.number(), slashInactivityPenalty: schemas.BigInt, slashProposeInvalidAttestationsPenalty: schemas.BigInt, + // Tolerated as undefined to allow validating responses from older node images that + // predate this slasher penalty being added. + slashBroadcastedInvalidCheckpointProposalPenalty: schemas.BigInt.default(0n), slashDuplicateProposalPenalty: schemas.BigInt, slashDuplicateAttestationPenalty: schemas.BigInt, - slashAttestDescendantOfInvalidPenalty: schemas.BigInt, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: schemas.BigInt, slashAttestInvalidCheckpointProposalPenalty: schemas.BigInt, slashUnknownPenalty: schemas.BigInt, slashOffenseExpirationRounds: z.number(), diff --git a/yarn-project/stdlib/src/interfaces/tx_provider.ts b/yarn-project/stdlib/src/interfaces/tx_provider.ts index 4113b69cae5f..b434b8052c42 100644 --- a/yarn-project/stdlib/src/interfaces/tx_provider.ts +++ b/yarn-project/stdlib/src/interfaces/tx_provider.ts @@ -7,6 +7,12 @@ import type { PeerId } from '@libp2p/interface'; export interface ITxProvider { getAvailableTxs(txHashes: TxHash[]): Promise<{ txs: Tx[]; missingTxs: TxHash[] }>; + /** + * Checks whether each tx hash is currently held by the local tx pool. Returns a parallel + * boolean array (one entry per input hash). Does not fetch from the network. + */ + hasTxs(txHashes: TxHash[]): Promise; + getTxsForBlockProposal( blockProposal: BlockProposal, blockNumber: number, diff --git a/yarn-project/stdlib/src/interfaces/validator.ts b/yarn-project/stdlib/src/interfaces/validator.ts index 1a8f9fddd19d..1c9b850ef613 100644 --- a/yarn-project/stdlib/src/interfaces/validator.ts +++ b/yarn-project/stdlib/src/interfaces/validator.ts @@ -66,6 +66,9 @@ export type ValidatorClientConfig = ValidatorHASignerConfig & /** Agree to attest to equivocated checkpoint proposals (for testing purposes only) */ attestToEquivocatedProposals?: boolean; + /** Accept proposal validation regardless of slot timing (for testing only) */ + skipProposalSlotValidation?: boolean; + /** Maximum L2 gas per block for validation. Proposals exceeding this limit are rejected. */ validateMaxL2BlockGas?: number; @@ -84,6 +87,7 @@ export type ValidatorClientFullConfig = ValidatorClientConfig & Pick< SlasherConfig, | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' @@ -107,6 +111,7 @@ export const ValidatorClientConfigSchema = zodFor { it('computing public keys hash matches Noir', async () => { - const masterNullifierPublicKey = new Point(new Fr(1), new Fr(2), false); - const masterIncomingViewingPublicKey = new Point(new Fr(3), new Fr(4), false); - const masterOutgoingViewingPublicKey = new Point(new Fr(5), new Fr(6), false); - const masterTaggingPublicKey = new Point(new Fr(7), new Fr(8), false); - const publicKeysHash = await new PublicKeys( - masterNullifierPublicKey, - masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, + new Fr(11n), + new PublicKey(new Fr(3n), new Fr(4n)), + new Fr(22n), + new Fr(33n), ).hash(); expect(publicKeysHash.toString()).toMatchInlineSnapshot( - `"0x056998309f6c119e4d753e404f94fef859dddfa530a9379634ceb0854b29bf7a"`, + `"0x0b8c7b67576d3ac859a7fab578b2b2e305c67eba9e133b0fa46af8d19a50b8fc"`, ); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data @@ -29,13 +24,12 @@ describe('🔑', () => { publicKeysHash.toString(), ); }); - it('Pre address from partial matches Noir', async () => { const publicKeysHash = new Fr(1n); const partialAddress = new Fr(2n); const address = await computePreaddress(publicKeysHash, partialAddress); expect(address.toString()).toMatchInlineSnapshot( - `"0x286c7755f2924b1e53b00bcaf1adaffe7287bd74bba7a02f4ab867e3892d28da"`, + `"0x0fa1c698858df1a99170cd39d5f4bfad6d0d60f1f8afa3dc92281ee60b36f3bb"`, ); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data @@ -45,26 +39,28 @@ describe('🔑', () => { address.toString(), ); }); - it('Address matches Noir', async () => { - const npkM = Point.fromString( + const npkM = PublicKey.fromString( '0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7', ); - const ivpkM = Point.fromString( + const ivpkM = PublicKey.fromString( '0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95', ); - const ovpkM = Point.fromString( + const ovpkM = PublicKey.fromString( '0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c4840c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b', ); - const tpkM = Point.fromString( + const tpkM = PublicKey.fromString( '0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a7622f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a', ); - - const publicKeys = new PublicKeys(npkM, ivpkM, ovpkM, tpkM); + const publicKeys = new PublicKeys( + await hashPublicKey(npkM), + ivpkM, + await hashPublicKey(ovpkM), + await hashPublicKey(tpkM), + ); const partialAddress = Fr.fromHexString('0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de'); - const address = (await computeAddress(publicKeys, partialAddress)).toString(); - expect(address).toMatchInlineSnapshot(`"0x2f66081d4bb077fbe8e8abe96a3516a713a3d7e34360b4e985da0da95092b37d"`); + expect(address).toMatchInlineSnapshot(`"0x05f9c48c02e4dbd18d7e165f999c3b8426abb1911476f48e68deef42475d6145"`); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data updateInlineTestData( diff --git a/yarn-project/stdlib/src/keys/derivation.ts b/yarn-project/stdlib/src/keys/derivation.ts index 0ed89aaeb438..9b4765a8aef3 100644 --- a/yarn-project/stdlib/src/keys/derivation.ts +++ b/yarn-project/stdlib/src/keys/derivation.ts @@ -7,6 +7,7 @@ import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin'; import { AztecAddress } from '../aztec-address/index.js'; import type { KeyPrefix } from './key_types.js'; +import { PublicKey, hashPublicKey } from './public_key.js'; import { PublicKeys } from './public_keys.js'; import { getKeyGenerator } from './utils.js'; @@ -44,18 +45,18 @@ export function deriveSigningKey(secretKey: Fr): GrumpkinScalar { } export function computePreaddress(publicKeysHash: Fr, partialAddress: Fr) { - return poseidon2HashWithSeparator([publicKeysHash, partialAddress], DomainSeparator.CONTRACT_ADDRESS_V1); + return poseidon2HashWithSeparator([publicKeysHash, partialAddress], DomainSeparator.CONTRACT_ADDRESS_V2); } export async function computeAddress(publicKeys: PublicKeys, partialAddress: Fr): Promise { // Given public keys and a partial address, we can compute our address in the following steps. - // 1. preaddress = poseidon2([publicKeysHash, partialAddress], DomainSeparator.CONTRACT_ADDRESS_V1); + // 1. preaddress = poseidon2([publicKeysHash, partialAddress], DomainSeparator.CONTRACT_ADDRESS_V2); // 2. addressPoint = (preaddress * G) + ivpk_m // 3. address = addressPoint.x const preaddress = await computePreaddress(await publicKeys.hash(), partialAddress); const address = await Grumpkin.add( await derivePublicKeyFromSecretKey(new Fq(preaddress.toBigInt())), - publicKeys.masterIncomingViewingPublicKey, + publicKeys.ivpkM, ); return new AztecAddress(address.x); @@ -83,7 +84,7 @@ export async function computeAddressSecret(preaddress: Fr, ivsk: Fq) { return addressSecretCandidate; } -export function derivePublicKeyFromSecretKey(secretKey: Fq) { +export function derivePublicKeyFromSecretKey(secretKey: Fq): Promise { return Grumpkin.mul(Grumpkin.generator, secretKey); } @@ -106,12 +107,15 @@ export async function deriveKeys(secretKey: Fr) { const masterOutgoingViewingPublicKey = await derivePublicKeyFromSecretKey(masterOutgoingViewingSecretKey); const masterTaggingPublicKey = await derivePublicKeyFromSecretKey(masterTaggingSecretKey); - // We hash the public keys to get the public keys hash + // The non-owner-visible PublicKeys carries hashes for npk/ovpk/tpk and the raw + // point only for ivpk_m. The npk/ovpk/tpk raw points are also returned alongside so the key + // store can persist them under `${account}-{n|ov|t}pk_m` (only their hashes live in publicKeys). + // The ivpk_m point isn't returned separately because it already lives in publicKeys.ivpkM. const publicKeys = new PublicKeys( - masterNullifierPublicKey, + await hashPublicKey(masterNullifierPublicKey), masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, + await hashPublicKey(masterOutgoingViewingPublicKey), + await hashPublicKey(masterTaggingPublicKey), ); return { @@ -119,6 +123,9 @@ export async function deriveKeys(secretKey: Fr) { masterIncomingViewingSecretKey, masterOutgoingViewingSecretKey, masterTaggingSecretKey, + masterNullifierPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, publicKeys, }; } diff --git a/yarn-project/stdlib/src/keys/public_key.ts b/yarn-project/stdlib/src/keys/public_key.ts index aa5f388ef9a3..1bc5fbc2966d 100644 --- a/yarn-project/stdlib/src/keys/public_key.ts +++ b/yarn-project/stdlib/src/keys/public_key.ts @@ -1,4 +1,28 @@ -import type { Point } from '@aztec/foundation/curves/grumpkin'; +import { DomainSeparator } from '@aztec/constants'; +import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { Point } from '@aztec/foundation/curves/grumpkin'; -/** Represents a user public key. */ +/** + * Hashes a public key. + * + * Mirrors Noir's `hash_public_key` in `noir-protocol-circuits/crates/types/src/public_keys.nr`: + * `Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, [pk.x, pk.y])`. + * + * This is distinct from Noir's generic `Hash` impl for `EmbeddedCurvePoint` (`noir_stdlib/src/embedded_curve_ops.nr`), + * which simply absorbs `x` then `y` into a `Hasher` state with no domain separator. That generic impl is unsuitable + * for hashing keys at the protocol boundary, where the domain separator is required to prevent collisions with hashes + * of other Grumpkin points (e.g. note commitments, nullifiers). + */ +export function hashPublicKey(pk: PublicKey): Promise { + return poseidon2HashWithSeparator([pk.x, pk.y], DomainSeparator.SINGLE_PUBLIC_KEY_HASH); +} + +/** + * Represents a user public key. + * + * Structurally identical to a Grumpkin `Point`; exposed as a distinct name so call sites read as "public key" where + * that's the domain meaning. + */ export type PublicKey = Point; +export const PublicKey = Point; diff --git a/yarn-project/stdlib/src/keys/public_keys.test.ts b/yarn-project/stdlib/src/keys/public_keys.test.ts index feba8ed89f1a..635fb05df198 100644 --- a/yarn-project/stdlib/src/keys/public_keys.test.ts +++ b/yarn-project/stdlib/src/keys/public_keys.test.ts @@ -1,7 +1,7 @@ import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import { updateInlineTestData } from '@aztec/foundation/testing/files'; +import { PublicKey } from './public_key.js'; import { PublicKeys } from './public_keys.js'; describe('PublicKeys', () => { @@ -19,16 +19,11 @@ describe('PublicKeys', () => { }); it('computes public keys hash', async () => { - const keys = new PublicKeys( - new Point(new Fr(1n), new Fr(2n), false), - new Point(new Fr(3n), new Fr(4n), false), - new Point(new Fr(5n), new Fr(6n), false), - new Point(new Fr(7n), new Fr(8n), false), - ); + const keys = new PublicKeys(new Fr(11n), new PublicKey(new Fr(3n), new Fr(4n)), new Fr(22n), new Fr(33n)); const hash = await keys.hash(); expect(hash.toString()).toMatchInlineSnapshot( - `"0x056998309f6c119e4d753e404f94fef859dddfa530a9379634ceb0854b29bf7a"`, + `"0x0b8c7b67576d3ac859a7fab578b2b2e305c67eba9e133b0fa46af8d19a50b8fc"`, ); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data @@ -44,7 +39,7 @@ describe('PublicKeys', () => { const hash = await keys.hash(); expect(hash.toString()).toMatchInlineSnapshot( - `"0x023547e676dba19784188825b901a0e70d8ad978300d21d6185a54281b734da0"`, + `"0x147a900f3e1abdfcc56355d65ab9bebb1016400cb9d81ee1c977d0df16bb198c"`, ); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data diff --git a/yarn-project/stdlib/src/keys/public_keys.ts b/yarn-project/stdlib/src/keys/public_keys.ts index 130fcf07c06d..9a0e2beb9c59 100644 --- a/yarn-project/stdlib/src/keys/public_keys.ts +++ b/yarn-project/stdlib/src/keys/public_keys.ts @@ -1,17 +1,13 @@ import { DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, - DEFAULT_NPK_M_X, - DEFAULT_NPK_M_Y, - DEFAULT_OVPK_M_X, - DEFAULT_OVPK_M_Y, - DEFAULT_TPK_M_X, - DEFAULT_TPK_M_Y, + DEFAULT_NPK_M_HASH, + DEFAULT_OVPK_M_HASH, + DEFAULT_TPK_M_HASH, DomainSeparator, } from '@aztec/constants'; import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { Point } from '@aztec/foundation/curves/grumpkin'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { bufferToHex, withoutHexPrefix } from '@aztec/foundation/string'; @@ -19,108 +15,107 @@ import type { FieldsOf } from '@aztec/foundation/types'; import { z } from 'zod'; -import type { PublicKey } from './public_key.js'; +import { PublicKey, hashPublicKey } from './public_key.js'; +/** + * A non-owner's view of an account's master public keys. + * + * Only `ivpkM` is exposed as a point (since address derivation needs the curve + * point in-circuit); the other three keys are exposed as their `hashPublicKey` digests. + */ export class PublicKeys { public constructor( - /** Master nullifier public key */ - public masterNullifierPublicKey: PublicKey, + /** Hash of the master nullifier public key */ + public npkMHash: Fr, /** Master incoming viewing public key */ - public masterIncomingViewingPublicKey: PublicKey, - /** Master outgoing viewing public key */ - public masterOutgoingViewingPublicKey: PublicKey, - /** Master tagging viewing public key */ - public masterTaggingPublicKey: PublicKey, + public ivpkM: PublicKey, + /** Hash of the master outgoing viewing public key */ + public ovpkMHash: Fr, + /** Hash of the master tagging public key */ + public tpkMHash: Fr, ) {} static get schema() { return z .object({ - masterNullifierPublicKey: schemas.Point, - masterIncomingViewingPublicKey: schemas.Point, - masterOutgoingViewingPublicKey: schemas.Point, - masterTaggingPublicKey: schemas.Point, + npkMHash: schemas.Fr, + ivpkM: schemas.Point, + ovpkMHash: schemas.Fr, + tpkMHash: schemas.Fr, }) .transform(PublicKeys.from); } static from(fields: FieldsOf) { - return new PublicKeys( - fields.masterNullifierPublicKey, - fields.masterIncomingViewingPublicKey, - fields.masterOutgoingViewingPublicKey, - fields.masterTaggingPublicKey, - ); + return new PublicKeys(fields.npkMHash, fields.ivpkM, fields.ovpkMHash, fields.tpkMHash); } /** * Creates a PublicKeys from a plain object without Zod validation. - * This method is optimized for performance and skips validation, making it suitable - * for deserializing trusted data (e.g., from C++ via MessagePack). - * @param obj - Plain object containing PublicKeys fields - * @returns A PublicKeys instance + * Suitable for deserializing trusted data (e.g., from C++ via MessagePack). */ static fromPlainObject(obj: any): PublicKeys { if (obj instanceof PublicKeys) { return obj; } return new PublicKeys( - Point.fromPlainObject(obj.masterNullifierPublicKey), - Point.fromPlainObject(obj.masterIncomingViewingPublicKey), - Point.fromPlainObject(obj.masterOutgoingViewingPublicKey), - Point.fromPlainObject(obj.masterTaggingPublicKey), + Fr.fromPlainObject(obj.npkMHash), + PublicKey.fromPlainObject(obj.ivpkM), + Fr.fromPlainObject(obj.ovpkMHash), + Fr.fromPlainObject(obj.tpkMHash), ); } - hash() { - return this.isEmpty() - ? Fr.ZERO - : poseidon2HashWithSeparator( - [ - this.masterNullifierPublicKey, - this.masterIncomingViewingPublicKey, - this.masterOutgoingViewingPublicKey, - this.masterTaggingPublicKey, - ], - DomainSeparator.PUBLIC_KEYS_HASH, - ); + async hash() { + if (this.isEmpty()) { + return Fr.ZERO; + } + // Mirror Noir's `PublicKeys::hash`: hash the four single-key digests under + // DOM_SEP__PUBLIC_KEYS_HASH. `ivpk_m` must be reduced to its single-key digest first + // (Poseidon2 over [x, y]); passing the Point directly would omit the DOM_SEP__SINGLE_PUBLIC_KEY_HASH + const ivpkMHash = await hashPublicKey(this.ivpkM); + return poseidon2HashWithSeparator( + [this.npkMHash, ivpkMHash, this.ovpkMHash, this.tpkMHash], + DomainSeparator.PUBLIC_KEYS_HASH, + ); } isEmpty() { - return ( - this.masterNullifierPublicKey.isZero() && - this.masterIncomingViewingPublicKey.isZero() && - this.masterOutgoingViewingPublicKey.isZero() && - this.masterTaggingPublicKey.isZero() - ); + return this.npkMHash.isZero() && this.ivpkM.isZero() && this.ovpkMHash.isZero() && this.tpkMHash.isZero(); } static default(): PublicKeys { + // Precomputed `hash_public_key(Point { DEFAULT_*_X, DEFAULT_*_Y })` for npk/ovpk/tpk. + // Sourced from constants.gen.ts (originally defined in + // noir-protocol-circuits/crates/types/src/constants.nr); a self-test in public_keys.nr + // (`default_hashes_match_default_points`) catches drift between the *_HASH constants and + // the underlying X/Y points. return new PublicKeys( - new Point(new Fr(DEFAULT_NPK_M_X), new Fr(DEFAULT_NPK_M_Y), false), - new Point(new Fr(DEFAULT_IVPK_M_X), new Fr(DEFAULT_IVPK_M_Y), false), - new Point(new Fr(DEFAULT_OVPK_M_X), new Fr(DEFAULT_OVPK_M_Y), false), - new Point(new Fr(DEFAULT_TPK_M_X), new Fr(DEFAULT_TPK_M_Y), false), + new Fr(DEFAULT_NPK_M_HASH), + new PublicKey(new Fr(DEFAULT_IVPK_M_X), new Fr(DEFAULT_IVPK_M_Y)), + new Fr(DEFAULT_OVPK_M_HASH), + new Fr(DEFAULT_TPK_M_HASH), ); } static async random(): Promise { - return new PublicKeys(await Point.random(), await Point.random(), await Point.random(), await Point.random()); + const npkM = await PublicKey.random(); + const ovpkM = await PublicKey.random(); + const tpkM = await PublicKey.random(); + return new PublicKeys( + await hashPublicKey(npkM), + await PublicKey.random(), + await hashPublicKey(ovpkM), + await hashPublicKey(tpkM), + ); } - /** - * Determines if this PublicKeys instance is equal to the given PublicKeys instance. - * Equality is based on the content of their respective buffers. - * - * @param other - The PublicKeys instance to compare against. - * @returns True if the buffers of both instances are equal, false otherwise. - */ equals(other: PublicKeys): boolean { return ( - this.masterNullifierPublicKey.equals(other.masterNullifierPublicKey) && - this.masterIncomingViewingPublicKey.equals(other.masterIncomingViewingPublicKey) && - this.masterOutgoingViewingPublicKey.equals(other.masterOutgoingViewingPublicKey) && - this.masterTaggingPublicKey.equals(other.masterTaggingPublicKey) + this.npkMHash.equals(other.npkMHash) && + this.ivpkM.equals(other.ivpkM) && + this.ovpkMHash.equals(other.ovpkMHash) && + this.tpkMHash.equals(other.tpkMHash) ); } @@ -131,77 +126,46 @@ export class PublicKeys { * @returns A Buffer representation of the PublicKeys instance. */ toBuffer(): Buffer { - return serializeToBuffer([ - this.masterNullifierPublicKey, - this.masterIncomingViewingPublicKey, - this.masterOutgoingViewingPublicKey, - this.masterTaggingPublicKey, - ]); + return serializeToBuffer([this.npkMHash, this.ivpkM, this.ovpkMHash, this.tpkMHash]); } - /** - * Creates an PublicKeys instance from a given buffer or BufferReader. - * If the input is a Buffer, it wraps it in a BufferReader before processing. - * Throws an error if the input length is not equal to the expected size. - * - * @param buffer - The input buffer or BufferReader containing the address data. - * @returns - A new PublicKeys instance with the extracted address data. - */ static fromBuffer(buffer: Buffer | BufferReader): PublicKeys { const reader = BufferReader.asReader(buffer); - const masterNullifierPublicKey = reader.readObject(Point); - const masterIncomingViewingPublicKey = reader.readObject(Point); - const masterOutgoingViewingPublicKey = reader.readObject(Point); - const masterTaggingPublicKey = reader.readObject(Point); - return new PublicKeys( - masterNullifierPublicKey, - masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, - ); + const npkMHash = Fr.fromBuffer(reader); + const ivpkM = reader.readObject(PublicKey); + const ovpkMHash = Fr.fromBuffer(reader); + const tpkMHash = Fr.fromBuffer(reader); + return new PublicKeys(npkMHash, ivpkM, ovpkMHash, tpkMHash); } toNoirStruct() { - // We need to use lowercase identifiers as those are what the noir interface expects - + // We need to use lowercase identifiers as those are what the noir interface expects. + /* eslint-disable camelcase */ return { - // TODO(#6337): Directly dump account.publicKeys here - /* eslint-disable camelcase */ - npk_m: this.masterNullifierPublicKey.toWrappedNoirStruct(), - ivpk_m: this.masterIncomingViewingPublicKey.toWrappedNoirStruct(), - ovpk_m: this.masterOutgoingViewingPublicKey.toWrappedNoirStruct(), - tpk_m: this.masterTaggingPublicKey.toWrappedNoirStruct(), - /* eslint-enable camelcase */ + npk_m_hash: this.npkMHash, + ivpk_m: this.ivpkM.toWrappedNoirStruct(), + ovpk_m_hash: this.ovpkMHash, + tpk_m_hash: this.tpkMHash, }; + /* eslint-enable camelcase */ } /** - * Serializes the payload to an array of fields - * @returns The fields of the payload + * Wire-format fields matching Noir's struct flattening of `PublicKeys`: + * `[npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash]` (5 fields). */ toFields(): Fr[] { - return [ - ...this.masterNullifierPublicKey.toFields(), - ...this.masterIncomingViewingPublicKey.toFields(), - ...this.masterOutgoingViewingPublicKey.toFields(), - ...this.masterTaggingPublicKey.toFields(), - ]; + return [this.npkMHash, this.ivpkM.x, this.ivpkM.y, this.ovpkMHash, this.tpkMHash]; } - // TOOD: This is used in foundation/src/abi/encoder. This is probably non-optimal but I did not want - // to spend too much time on the encoder now. It probably needs a refactor. + // Used in foundation/src/abi/encoder. Probably non-optimal but the encoder needs a refactor. encodeToNoir(): Fr[] { return this.toFields(); } static fromFields(fields: Fr[] | FieldReader): PublicKeys { const reader = FieldReader.asReader(fields); - return new PublicKeys( - reader.readObject(Point), - reader.readObject(Point), - reader.readObject(Point), - reader.readObject(Point), - ); + return new PublicKeys(reader.readField(), reader.readObject(PublicKey), reader.readField(), reader.readField()); } toString() { diff --git a/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts b/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts index 2595068e7f6d..286be1c2b64f 100644 --- a/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts +++ b/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts @@ -27,6 +27,7 @@ import { type CoordinationSignatureType, EMPTY_COORDINATION_SIGNATURE_CONTEXT, type Signable, + coordinationSignatureContextEquals, getCoordinationSignatureTypedData, readCoordinationSignatureContext, recoverCoordinationSigner, @@ -99,9 +100,28 @@ export class CheckpointProposal extends Gossipable implements Signable { public readonly signatureContext: CoordinationSignatureContext, /** Optional last block info, including its own signature for BlockProposal extraction */ - public readonly lastBlock?: CheckpointLastBlock, + public readonly lastBlock?: CheckpointLastBlock | BlockProposal, ) { super(); + + // Check that last block properties match those of the checkpoint. + if (lastBlock && 'inHash' in lastBlock && !lastBlock.inHash.equals(checkpointHeader.inHash)) { + throw new Error( + `CheckpointProposal lastBlock inHash ${lastBlock.inHash} does not match checkpoint inHash ${checkpointHeader.inHash}`, + ); + } + if (lastBlock && 'archiveRoot' in lastBlock && !lastBlock.archiveRoot.equals(archive)) { + throw new Error( + `CheckpointProposal lastBlock archive ${lastBlock.archiveRoot} does not match checkpoint archive ${archive}`, + ); + } + if ( + lastBlock && + 'signatureContext' in lastBlock && + !coordinationSignatureContextEquals(lastBlock.signatureContext, signatureContext) + ) { + throw new Error(`CheckpointProposal lastBlock signatureContext does not match checkpoint signatureContext`); + } } override generateP2PMessageIdentifier(): Promise { diff --git a/yarn-project/stdlib/src/slashing/helpers.test.ts b/yarn-project/stdlib/src/slashing/helpers.test.ts index cc2d7c00e56d..5820e4aec091 100644 --- a/yarn-project/stdlib/src/slashing/helpers.test.ts +++ b/yarn-project/stdlib/src/slashing/helpers.test.ts @@ -178,7 +178,7 @@ describe('SlashingHelpers', () => { it('handles epoch-based offense that spans multiple rounds', () => { const offense = { epochOrSlot: 2n, // epoch 2 = slot 8 - offenseType: OffenseType.DATA_WITHHOLDING, + offenseType: OffenseType.INACTIVITY, }; const round = getRoundForOffense(offense, constants); expect(round).toEqual(0n); // slot 8 / roundSize 10 = round 0 @@ -187,7 +187,7 @@ describe('SlashingHelpers', () => { it('handles epoch-based offense when round is multiple of epoch duration', () => { const offense = { epochOrSlot: 2n, // epoch 2 = slot 8 - offenseType: OffenseType.DATA_WITHHOLDING, + offenseType: OffenseType.INACTIVITY, }; const round = getRoundForOffense(offense, { ...constants, slashingRoundSize: 8 }); expect(round).toEqual(1n); // slot 8 / roundSize 8 = round 1 @@ -197,12 +197,12 @@ describe('SlashingHelpers', () => { describe('getPenaltyForOffense', () => { it('returns the configured penalty for attesting to invalid checkpoint proposal', () => { const penalty = getPenaltyForOffense(OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, { - slashAttestDescendantOfInvalidPenalty: 1n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1n, slashBroadcastedInvalidBlockPenalty: 2n, + slashBroadcastedInvalidCheckpointProposalPenalty: 11n, slashDuplicateProposalPenalty: 3n, slashDuplicateAttestationPenalty: 4n, slashAttestInvalidCheckpointProposalPenalty: 5n, - slashPrunePenalty: 6n, slashDataWithholdingPenalty: 7n, slashUnknownPenalty: 8n, slashInactivityPenalty: 9n, @@ -211,5 +211,22 @@ describe('SlashingHelpers', () => { expect(penalty).toBe(5n); }); + + it('returns the configured penalty for broadcasting invalid checkpoint proposal', () => { + const penalty = getPenaltyForOffense(OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, { + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1n, + slashBroadcastedInvalidBlockPenalty: 2n, + slashBroadcastedInvalidCheckpointProposalPenalty: 11n, + slashDuplicateProposalPenalty: 3n, + slashDuplicateAttestationPenalty: 4n, + slashAttestInvalidCheckpointProposalPenalty: 5n, + slashDataWithholdingPenalty: 7n, + slashUnknownPenalty: 8n, + slashInactivityPenalty: 9n, + slashProposeInvalidAttestationsPenalty: 10n, + }); + + expect(penalty).toBe(11n); + }); }); }); diff --git a/yarn-project/stdlib/src/slashing/helpers.ts b/yarn-project/stdlib/src/slashing/helpers.ts index 21ca279597f1..24df1ee11617 100644 --- a/yarn-project/stdlib/src/slashing/helpers.ts +++ b/yarn-project/stdlib/src/slashing/helpers.ts @@ -48,12 +48,12 @@ export function getPenaltyForOffense( offense: OffenseType, config: Pick< SlasherConfig, - | 'slashAttestDescendantOfInvalidPenalty' + | 'slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty' | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' - | 'slashPrunePenalty' | 'slashDataWithholdingPenalty' | 'slashUnknownPenalty' | 'slashInactivityPenalty' @@ -61,8 +61,6 @@ export function getPenaltyForOffense( >, ) { switch (offense) { - case OffenseType.VALID_EPOCH_PRUNED: - return config.slashPrunePenalty; case OffenseType.DATA_WITHHOLDING: return config.slashDataWithholdingPenalty; case OffenseType.INACTIVITY: @@ -70,10 +68,12 @@ export function getPenaltyForOffense( case OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS: case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS: return config.slashProposeInvalidAttestationsPenalty; - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: - return config.slashAttestDescendantOfInvalidPenalty; + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: + return config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty; case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: return config.slashBroadcastedInvalidBlockPenalty; + case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: + return config.slashBroadcastedInvalidCheckpointProposalPenalty; case OffenseType.DUPLICATE_PROPOSAL: return config.slashDuplicateProposalPenalty; case OffenseType.DUPLICATE_ATTESTATION: @@ -92,8 +92,10 @@ export function getPenaltyForOffense( /** Returns whether the `epochOrSlot` field for an offense references an epoch or a slot */ export function getTimeUnitForOffense(offense: OffenseType): 'epoch' | 'slot' { switch (offense) { - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: + case OffenseType.DATA_WITHHOLDING: + case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: case OffenseType.DUPLICATE_PROPOSAL: case OffenseType.DUPLICATE_ATTESTATION: case OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL: @@ -101,9 +103,7 @@ export function getTimeUnitForOffense(offense: OffenseType): 'epoch' | 'slot' { case OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS: return 'slot'; case OffenseType.INACTIVITY: - case OffenseType.DATA_WITHHOLDING: case OffenseType.UNKNOWN: - case OffenseType.VALID_EPOCH_PRUNED: return 'epoch'; default: { const _exhaustiveCheck: never = offense; diff --git a/yarn-project/stdlib/src/slashing/serialization.test.ts b/yarn-project/stdlib/src/slashing/serialization.test.ts index 9c84b476a351..f4c6d664acd0 100644 --- a/yarn-project/stdlib/src/slashing/serialization.test.ts +++ b/yarn-project/stdlib/src/slashing/serialization.test.ts @@ -92,7 +92,7 @@ describe('slashing/serialization', () => { const validator2 = EthAddress.fromString('0x2222222222222222222222222222222222222222'); const offense1 = createOffense(validator1, 500n, OffenseType.DATA_WITHHOLDING, 25n); - const offense2 = createOffense(validator2, 750n, OffenseType.VALID_EPOCH_PRUNED, 30n); + const offense2 = createOffense(validator2, 750n, OffenseType.INACTIVITY, 30n); const serialized1 = serializeOffense(offense1); const deserialized1 = deserializeOffense(serialized1); @@ -107,7 +107,7 @@ describe('slashing/serialization', () => { expect(deserialized2.validator).toEqual(validator2); expect(deserialized2.amount).toEqual(750n); - expect(deserialized2.offenseType).toEqual(OffenseType.VALID_EPOCH_PRUNED); + expect(deserialized2.offenseType).toEqual(OffenseType.INACTIVITY); expect(deserialized2.epochOrSlot).toEqual(30n); // Ensure they produce different serialized data @@ -118,7 +118,7 @@ describe('slashing/serialization', () => { const originalOffense = createOffense( EthAddress.random(), 12345n, - OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, 98765n, ); @@ -160,7 +160,7 @@ describe('slashing/serialization', () => { const epochOffenses = [ OffenseType.INACTIVITY, OffenseType.DATA_WITHHOLDING, - OffenseType.VALID_EPOCH_PRUNED, + OffenseType.INACTIVITY, OffenseType.UNKNOWN, ]; @@ -168,7 +168,7 @@ describe('slashing/serialization', () => { const slotOffenses = [ OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS, OffenseType.PROPOSED_INCORRECT_ATTESTATIONS, - OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL, ]; diff --git a/yarn-project/stdlib/src/slashing/types.ts b/yarn-project/stdlib/src/slashing/types.ts index 6a72b45c061b..45aa9f31dddc 100644 --- a/yarn-project/stdlib/src/slashing/types.ts +++ b/yarn-project/stdlib/src/slashing/types.ts @@ -6,10 +6,8 @@ import { schemas, zodFor } from '../schemas/index.js'; export enum OffenseType { UNKNOWN = 0, - /** The data for proving an epoch was not publicly available, we slash its committee */ + /** The data for the txs in a published checkpoint was not available within the tolerance window, we slash the checkpoint's attesters */ DATA_WITHHOLDING = 1, - /** An epoch was not successfully proven in time, we slash its committee */ - VALID_EPOCH_PRUNED = 2, /** A proposer failed to attest or propose during an epoch according to the Sentinel */ INACTIVITY = 3, /** A proposer sent an invalid block proposal over the p2p network to the committee */ @@ -18,14 +16,16 @@ export enum OffenseType { PROPOSED_INSUFFICIENT_ATTESTATIONS = 5, /** A proposer pushed to L1 a block with incorrect committee attestations (ie signature from a non-committee member) */ PROPOSED_INCORRECT_ATTESTATIONS = 6, - /** A committee member attested to a block that was built as a descendent of an invalid block (as in a block with invalid attestations) */ - ATTESTED_DESCENDANT_OF_INVALID = 7, + /** A proposer published a checkpoint to L1 that builds on an invalid checkpoint (as in a checkpoint with invalid or insufficient attestations) */ + PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS = 7, /** A proposer sent duplicate proposals for the same position (slot, indexWithinCheckpoint for blocks or slot for checkpoints) */ DUPLICATE_PROPOSAL = 8, /** A validator signed attestations for different proposals at the same slot (equivocation) */ DUPLICATE_ATTESTATION = 9, /** A committee member attested to a checkpoint proposal in a slot with an invalid block proposal */ ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL = 10, + /** A proposer broadcast an invalid checkpoint proposal, detected by retained evidence or deterministic recomputation */ + BROADCASTED_INVALID_CHECKPOINT_PROPOSAL = 11, } export function getOffenseTypeName(offense: OffenseType) { @@ -34,8 +34,6 @@ export function getOffenseTypeName(offense: OffenseType) { return 'unknown'; case OffenseType.DATA_WITHHOLDING: return 'data_withholding'; - case OffenseType.VALID_EPOCH_PRUNED: - return 'valid_epoch_pruned'; case OffenseType.INACTIVITY: return 'inactivity'; case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: @@ -44,14 +42,16 @@ export function getOffenseTypeName(offense: OffenseType) { return 'proposed_insufficient_attestations'; case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS: return 'proposed_incorrect_attestations'; - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: - return 'attested_descendant_of_invalid'; + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: + return 'proposed_descendant_of_checkpoint_with_invalid_attestations'; case OffenseType.DUPLICATE_PROPOSAL: return 'duplicate_proposal'; case OffenseType.DUPLICATE_ATTESTATION: return 'duplicate_attestation'; case OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL: return 'attested_to_invalid_checkpoint_proposal'; + case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: + return 'broadcasted_invalid_checkpoint_proposal'; default: throw new Error(`Unknown offense type: ${offense}`); } @@ -62,15 +62,15 @@ export const OffenseTypeSchema = z.nativeEnum(OffenseType); export const OffenseToBigInt: Record = { [OffenseType.UNKNOWN]: 0n, [OffenseType.DATA_WITHHOLDING]: 1n, - [OffenseType.VALID_EPOCH_PRUNED]: 2n, [OffenseType.INACTIVITY]: 3n, [OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL]: 4n, [OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS]: 5n, [OffenseType.PROPOSED_INCORRECT_ATTESTATIONS]: 6n, - [OffenseType.ATTESTED_DESCENDANT_OF_INVALID]: 7n, + [OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS]: 7n, [OffenseType.DUPLICATE_PROPOSAL]: 8n, [OffenseType.DUPLICATE_ATTESTATION]: 9n, [OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL]: 10n, + [OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL]: 11n, }; export function bigIntToOffense(offense: bigint): OffenseType { @@ -79,8 +79,6 @@ export function bigIntToOffense(offense: bigint): OffenseType { return OffenseType.UNKNOWN; case 1n: return OffenseType.DATA_WITHHOLDING; - case 2n: - return OffenseType.VALID_EPOCH_PRUNED; case 3n: return OffenseType.INACTIVITY; case 4n: @@ -90,13 +88,15 @@ export function bigIntToOffense(offense: bigint): OffenseType { case 6n: return OffenseType.PROPOSED_INCORRECT_ATTESTATIONS; case 7n: - return OffenseType.ATTESTED_DESCENDANT_OF_INVALID; + return OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS; case 8n: return OffenseType.DUPLICATE_PROPOSAL; case 9n: return OffenseType.DUPLICATE_ATTESTATION; case 10n: return OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL; + case 11n: + return OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL; default: throw new Error(`Unknown offense: ${offense}`); } diff --git a/yarn-project/stdlib/src/slashing/votes.test.ts b/yarn-project/stdlib/src/slashing/votes.test.ts index 17cad2d71862..9cd770f16ca8 100644 --- a/yarn-project/stdlib/src/slashing/votes.test.ts +++ b/yarn-project/stdlib/src/slashing/votes.test.ts @@ -275,13 +275,13 @@ describe('SlashingHelpers', () => { { validator: mockValidator1, amount: 7n, - offenseType: OffenseType.DATA_WITHHOLDING, + offenseType: OffenseType.INACTIVITY, epochOrSlot: 3n, }, { validator: mockValidator1, amount: 5n, - offenseType: OffenseType.VALID_EPOCH_PRUNED, + offenseType: OffenseType.INACTIVITY, epochOrSlot: 3n, }, ]; @@ -530,10 +530,10 @@ describe('SlashingHelpers', () => { // Truncation must cut one validator (not one offense record). const offenses: Offense[] = [ { validator: mockValidator1, amount: 15n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, - { validator: mockValidator1, amount: 8n, offenseType: OffenseType.DATA_WITHHOLDING, epochOrSlot: 5n }, - { validator: mockValidator1, amount: 5n, offenseType: OffenseType.VALID_EPOCH_PRUNED, epochOrSlot: 5n }, + { validator: mockValidator1, amount: 8n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, + { validator: mockValidator1, amount: 5n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, { validator: mockValidator2, amount: 20n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, - { validator: mockValidator2, amount: 5n, offenseType: OffenseType.DATA_WITHHOLDING, epochOrSlot: 5n }, + { validator: mockValidator2, amount: 5n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, { validator: mockValidator3, amount: 10n, offenseType: OffenseType.INACTIVITY, epochOrSlot: 5n }, ]; diff --git a/yarn-project/stdlib/src/tests/factories.ts b/yarn-project/stdlib/src/tests/factories.ts index e4a987249fca..a20585ad65ce 100644 --- a/yarn-project/stdlib/src/tests/factories.ts +++ b/yarn-project/stdlib/src/tests/factories.ts @@ -123,7 +123,7 @@ import { PublicCallRequest, PublicCallRequestArrayLengths, } from '../kernel/public_call_request.js'; -import { PublicKeys, computeAddress } from '../keys/index.js'; +import { PublicKey, PublicKeys, computeAddress, hashPublicKey } from '../keys/index.js'; import { ExtendedDirectionalAppTaggingSecret } from '../logs/extended_directional_app_tagging_secret.js'; import { ContractClassLog, ContractClassLogFields } from '../logs/index.js'; import { PrivateLog } from '../logs/private_log.js'; @@ -252,7 +252,7 @@ function makeScopedReadRequest(n: number): ScopedReadRequest { * @returns A KeyValidationRequest. */ function makeKeyValidationRequests(seed: number): KeyValidationRequest { - return new KeyValidationRequest(makePoint(seed), fr(seed + 2)); + return new KeyValidationRequest(fr(seed), fr(seed + 2)); } /** @@ -577,7 +577,7 @@ export function makeVerificationKeyAsFields(size: number): VerificationKeyAsFiel * @returns A point. */ export function makePoint(seed = 1): Point { - return new Point(fr(seed), fr(seed + 1), false); + return new Point(fr(seed), fr(seed + 1)); } /** @@ -1220,8 +1220,13 @@ export async function makeMapAsync(size: number, fn: (i: number) => Promise<[ export async function makePublicKeys(seed = 0): Promise { const f = (offset: number) => Grumpkin.mul(Grumpkin.generator, new Fq(seed + offset)); - - return new PublicKeys(await f(0), await f(1), await f(2), await f(3)); + const ivpkM = await f(1); + return new PublicKeys( + await hashPublicKey(await f(0)), + ivpkM, + await hashPublicKey(await f(2)), + await hashPublicKey(await f(3)), + ); } export async function makeContractInstanceFromClassId( @@ -1230,6 +1235,7 @@ export async function makeContractInstanceFromClassId( overrides?: { deployer?: AztecAddress; initializationHash?: Fr; + immutablesHash?: Fr; publicKeys?: PublicKeys; currentClassId?: Fr; }, @@ -1238,21 +1244,24 @@ export async function makeContractInstanceFromClassId( const initializationHash = overrides?.initializationHash ?? new Fr(seed + 1); const deployer = overrides?.deployer ?? new AztecAddress(new Fr(seed + 2)); const publicKeys = overrides?.publicKeys ?? (await makePublicKeys(seed + 3)); + const immutablesHash = overrides?.immutablesHash ?? new Fr(seed + 4); const partialAddress = await computePartialAddress({ originalContractClassId: classId, salt, initializationHash, + immutablesHash, deployer, }); const address = await computeAddress(publicKeys, partialAddress); return new SerializableContractInstance({ - version: 1, + version: 2, salt, deployer, currentContractClassId: overrides?.currentClassId ?? classId, originalContractClassId: classId, initializationHash, + immutablesHash, publicKeys, }).withAddress(address); } @@ -1430,11 +1439,12 @@ export function makeAvmContractInstanceHint(seed = 0): AvmContractInstanceHint { new Fr(seed + 0x4), new Fr(seed + 0x5), new Fr(seed + 0x6), + new Fr(seed + 0x7), new PublicKeys( - new Point(new Fr(seed + 0x7), new Fr(seed + 0x8), false), - new Point(new Fr(seed + 0x9), new Fr(seed + 0x10), false), - new Point(new Fr(seed + 0x11), new Fr(seed + 0x12), false), - new Point(new Fr(seed + 0x13), new Fr(seed + 0x14), false), + new Fr(seed + 0x7), + new PublicKey(new Fr(seed + 0x9), new Fr(seed + 0x10)), + new Fr(seed + 0x11), + new Fr(seed + 0x13), ), ); } diff --git a/yarn-project/stdlib/src/tx/tx_receipt.test.ts b/yarn-project/stdlib/src/tx/tx_receipt.test.ts index 8be605399c4f..0c2044f37fad 100644 --- a/yarn-project/stdlib/src/tx/tx_receipt.test.ts +++ b/yarn-project/stdlib/src/tx/tx_receipt.test.ts @@ -42,22 +42,12 @@ describe('TxReceipt', () => { }); it('isSuccess returns false for reverted execution', () => { - const receipt = new TxReceipt( - TxHash.random(), - TxStatus.PROPOSED, - TxExecutionResult.APP_LOGIC_REVERTED, - undefined, - ); + const receipt = new TxReceipt(TxHash.random(), TxStatus.PROPOSED, TxExecutionResult.REVERTED, undefined); expect(receipt.hasExecutionSucceeded()).toBe(false); }); it('isReverted returns true for reverted execution', () => { - const receipt = new TxReceipt( - TxHash.random(), - TxStatus.PROPOSED, - TxExecutionResult.APP_LOGIC_REVERTED, - undefined, - ); + const receipt = new TxReceipt(TxHash.random(), TxStatus.PROPOSED, TxExecutionResult.REVERTED, undefined); expect(receipt.hasExecutionReverted()).toBe(true); }); diff --git a/yarn-project/stdlib/src/tx/tx_receipt.ts b/yarn-project/stdlib/src/tx/tx_receipt.ts index 348806510344..446855f44237 100644 --- a/yarn-project/stdlib/src/tx/tx_receipt.ts +++ b/yarn-project/stdlib/src/tx/tx_receipt.ts @@ -32,15 +32,6 @@ export const SortedTxStatuses: TxStatus[] = [ export enum TxExecutionResult { SUCCESS = 'success', REVERTED = 'reverted', - /** @deprecated Use REVERTED instead. */ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - APP_LOGIC_REVERTED = 'reverted', - /** @deprecated Use REVERTED instead. */ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - TEARDOWN_REVERTED = 'reverted', - /** @deprecated Use REVERTED instead. */ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - BOTH_REVERTED = 'reverted', } /** diff --git a/yarn-project/stdlib/src/validators/schemas.ts b/yarn-project/stdlib/src/validators/schemas.ts index 33a8de976c86..15bc07beb498 100644 --- a/yarn-project/stdlib/src/validators/schemas.ts +++ b/yarn-project/stdlib/src/validators/schemas.ts @@ -14,7 +14,9 @@ import type { export const ValidatorStatusInSlotSchema = zodFor()( z.enum([ 'checkpoint-mined', - 'checkpoint-proposed', + 'checkpoint-valid', + 'checkpoint-invalid', + 'checkpoint-unvalidated', 'checkpoint-missed', 'blocks-missed', 'attestation-sent', @@ -74,7 +76,7 @@ export const ValidatorsStatsSchema = zodFor()( export const SingleValidatorStatsSchema = zodFor()( z.object({ validator: ValidatorStatsSchema, - allTimeProvenPerformance: z.array( + allTimeEpochPerformance: z.array( z.object({ missed: schemas.Integer, total: schemas.Integer, diff --git a/yarn-project/stdlib/src/validators/types.ts b/yarn-project/stdlib/src/validators/types.ts index bf005e4537d1..4adedf0dab43 100644 --- a/yarn-project/stdlib/src/validators/types.ts +++ b/yarn-project/stdlib/src/validators/types.ts @@ -3,9 +3,28 @@ import type { EthAddress } from '@aztec/foundation/eth-address'; export type ValidatorStatusType = 'proposer' | 'attestation'; +/** + * Per-slot status for a validator. + * + * Proposer statuses (six-case taxonomy): + * - `blocks-missed` — no block proposals seen for the slot (case 1). + * - `checkpoint-missed` — block proposals seen but no checkpoint proposal (case 2). + * - `checkpoint-unvalidated` — checkpoint proposal seen but local re-execution couldn't + * validate (missing txs, timeouts, etc.) (case 3). + * - `checkpoint-invalid` — checkpoint proposal re-executed and rejected as invalid (case 4). + * - `checkpoint-valid` — checkpoint proposal re-executed locally as valid (case 5). + * - `checkpoint-mined` — checkpoint published on L1 (case 6). + * + * Attestor statuses: + * - `attestation-sent` — attestation observed on P2P or in the published checkpoint. + * - `attestation-missed` — committee member did not attest to a checkpoint proposal that + * was observed locally or published on L1. + */ export type ValidatorStatusInSlot = | 'checkpoint-mined' - | 'checkpoint-proposed' + | 'checkpoint-valid' + | 'checkpoint-invalid' + | 'checkpoint-unvalidated' | 'checkpoint-missed' | 'blocks-missed' | 'attestation-sent' @@ -41,7 +60,7 @@ export type ValidatorsEpochPerformance = Record<`0x${string}`, { missed: number; export type SingleValidatorStats = { validator: ValidatorStats; - allTimeProvenPerformance: { missed: number; total: number; epoch: EpochNumber }[]; + allTimeEpochPerformance: { missed: number; total: number; epoch: EpochNumber }[]; lastProcessedSlot?: SlotNumber; initialSlot?: SlotNumber; slotWindow: number; diff --git a/yarn-project/telemetry-client/src/attributes.ts b/yarn-project/telemetry-client/src/attributes.ts index df2686e844f3..adf11f85dced 100644 --- a/yarn-project/telemetry-client/src/attributes.ts +++ b/yarn-project/telemetry-client/src/attributes.ts @@ -96,7 +96,6 @@ export const VALIDATOR_STATUS = 'aztec.validator_status'; export const P2P_ID = 'aztec.p2p.id'; export const P2P_REQ_RESP_PROTOCOL = 'aztec.p2p.req_resp.protocol'; -export const P2P_REQ_RESP_BATCH_REQUESTS_COUNT = 'aztec.p2p.req_resp.batch_requests_count'; /** The state of a peer (Healthy, Disconnect, Banned) */ export const P2P_PEER_SCORE_STATE = 'aztec.p2p.peer_score_state'; export const POOL_NAME = 'aztec.pool.name'; diff --git a/yarn-project/telemetry-client/src/config.ts b/yarn-project/telemetry-client/src/config.ts index 4e705c7a6fcf..814aa2474ba8 100644 --- a/yarn-project/telemetry-client/src/config.ts +++ b/yarn-project/telemetry-client/src/config.ts @@ -17,6 +17,8 @@ export interface TelemetryClientConfig { otelExportTimeoutMs: number; otelExcludeMetrics: string[]; otelIncludeMetrics: string[]; + otelMinTraceDurationMs: number; + otelBspMaxQueueSize: number; } export const telemetryClientConfigMappings: ConfigMappingsType = { @@ -57,6 +59,16 @@ export const telemetryClientConfigMappings: ConfigMappingsType[1]): void { + this.spans.push(...spans); + resultCallback({ code: ExportResultCode.SUCCESS }); + } + + shutdown(): Promise { + return Promise.resolve(); + } +} + +const log = { warn: () => {} } as any; + +function makeSpan(durationMs: number, statusCode = SpanStatusCode.OK): ReadableSpan { + const seconds = Math.floor(durationMs / 1000); + const nanos = (durationMs - seconds * 1000) * 1_000_000; + return { + attributes: {}, + droppedAttributesCount: 0, + droppedEventsCount: 0, + droppedLinksCount: 0, + duration: [seconds, nanos], + ended: true, + endTime: [seconds, nanos], + events: [], + instrumentationLibrary: {} as any, + kind: SpanKind.INTERNAL, + links: [], + name: `span-${durationMs}`, + resource: {} as any, + spanContext: () => ({ spanId: '0'.repeat(16), traceFlags: 1, traceId: '0'.repeat(32) }), + startTime: [0, 0], + status: { code: statusCode }, + }; +} + +describe('MonitoredBatchSpanProcessor', () => { + it('does not export successful spans shorter than the configured duration', async () => { + const exporter = new CollectingSpanExporter(); + const processor = new MonitoredBatchSpanProcessor(exporter, log, { minTraceDurationMs: 10 }); + + processor.onEnd(makeSpan(9)); + processor.onEnd(makeSpan(10)); + await processor.forceFlush(); + + expect(exporter.spans.map(span => span.name)).toEqual(['span-10']); + }); + + it('exports short error spans', async () => { + const exporter = new CollectingSpanExporter(); + const processor = new MonitoredBatchSpanProcessor(exporter, log, { minTraceDurationMs: 10 }); + + processor.onEnd(makeSpan(1, SpanStatusCode.ERROR)); + await processor.forceFlush(); + + expect(exporter.spans.map(span => span.name)).toEqual(['span-1']); + }); + + it('allows short successful spans when the minimum duration is disabled', async () => { + const exporter = new CollectingSpanExporter(); + const processor = new MonitoredBatchSpanProcessor(exporter, log, { minTraceDurationMs: 0 }); + + processor.onEnd(makeSpan(1)); + await processor.forceFlush(); + + expect(exporter.spans.map(span => span.name)).toEqual(['span-1']); + }); +}); diff --git a/yarn-project/telemetry-client/src/monitored_batch_span_processor.ts b/yarn-project/telemetry-client/src/monitored_batch_span_processor.ts index 669c136f8aaf..c5fd7bb81918 100644 --- a/yarn-project/telemetry-client/src/monitored_batch_span_processor.ts +++ b/yarn-project/telemetry-client/src/monitored_batch_span_processor.ts @@ -1,12 +1,19 @@ import type { Logger } from '@aztec/foundation/log'; -import type { Context } from '@opentelemetry/api'; +import { type Context, SpanStatusCode } from '@opentelemetry/api'; +import { hrTimeToMilliseconds } from '@opentelemetry/core'; import type { SpanExporter } from '@opentelemetry/sdk-trace-base'; import { BatchSpanProcessor, type BufferConfig, type ReadableSpan, type Span } from '@opentelemetry/sdk-trace-node'; /** Minimum interval between drop warnings to avoid log spam. */ const DROP_WARNING_INTERVAL_MS = 30_000; +const DEFAULT_MIN_TRACE_DURATION_MS = 10; + +export type MonitoredBatchSpanProcessorConfig = BufferConfig & { + minTraceDurationMs?: number; +}; + /** * Wraps BatchSpanProcessor to emit warnings when spans are dropped due to a full queue. * The standard BatchSpanProcessor silently discards spans when its internal queue reaches @@ -14,6 +21,7 @@ const DROP_WARNING_INTERVAL_MS = 30_000; */ export class MonitoredBatchSpanProcessor extends BatchSpanProcessor { private readonly maxQueueSize: number; + private readonly minTraceDurationMs: number; private readonly log: Logger; private approxQueueSize = 0; @@ -21,10 +29,11 @@ export class MonitoredBatchSpanProcessor extends BatchSpanProcessor { private totalDropped = 0; private lastWarningTime = 0; - constructor(exporter: SpanExporter, log: Logger, config?: BufferConfig) { + constructor(exporter: SpanExporter, log: Logger, config?: MonitoredBatchSpanProcessorConfig) { const maxQueueSize = config?.maxQueueSize ?? 2048; super(exporter, { ...config, maxQueueSize }); this.maxQueueSize = maxQueueSize; + this.minTraceDurationMs = Math.max(0, config?.minTraceDurationMs ?? DEFAULT_MIN_TRACE_DURATION_MS); this.log = log; } @@ -33,6 +42,10 @@ export class MonitoredBatchSpanProcessor extends BatchSpanProcessor { } override onEnd(span: ReadableSpan): void { + if (this.shouldDropShortSpan(span)) { + return; + } + if (this.approxQueueSize >= this.maxQueueSize) { this.droppedSinceLastWarning++; this.totalDropped++; @@ -57,6 +70,14 @@ export class MonitoredBatchSpanProcessor extends BatchSpanProcessor { await super.shutdown(); } + private shouldDropShortSpan(span: ReadableSpan): boolean { + return ( + this.minTraceDurationMs > 0 && + span.status.code !== SpanStatusCode.ERROR && + hrTimeToMilliseconds(span.duration) < this.minTraceDurationMs + ); + } + private maybeLogDropWarning(): void { const now = Date.now(); if (now - this.lastWarningTime >= DROP_WARNING_INTERVAL_MS) { diff --git a/yarn-project/telemetry-client/src/otel.ts b/yarn-project/telemetry-client/src/otel.ts index 42d698ab6ed0..a67cb76ef637 100644 --- a/yarn-project/telemetry-client/src/otel.ts +++ b/yarn-project/telemetry-client/src/otel.ts @@ -374,7 +374,12 @@ export class OpenTelemetryClient implements TelemetryClient { const tracerProvider = new NodeTracerProvider({ resource, spanProcessors: config.tracesCollectorUrl - ? [new MonitoredBatchSpanProcessor(new OTLPTraceExporter({ url: config.tracesCollectorUrl.href }), log)] + ? [ + new MonitoredBatchSpanProcessor(new OTLPTraceExporter({ url: config.tracesCollectorUrl.href }), log, { + maxQueueSize: config.otelBspMaxQueueSize, + minTraceDurationMs: config.otelMinTraceDurationMs, + }), + ] : [], }); diff --git a/yarn-project/telemetry-client/src/otel_propagation.ts b/yarn-project/telemetry-client/src/otel_propagation.ts index dad50b793829..4e0751d2d442 100644 --- a/yarn-project/telemetry-client/src/otel_propagation.ts +++ b/yarn-project/telemetry-client/src/otel_propagation.ts @@ -1,3 +1,5 @@ +import type { DiagnosticsMiddleware } from '@aztec/foundation/json-rpc/server'; + import { ROOT_CONTEXT, type Span, SpanKind, SpanStatusCode, propagation } from '@opentelemetry/api'; import type Koa from 'koa'; @@ -17,7 +19,7 @@ export function getOtelJsonRpcPropagationMiddleware( const context = propagation.extract(ROOT_CONTEXT, ctx.request.headers); const method = (ctx.request.body as any)?.method; return tracer.startActiveSpan( - `JsonRpcServer.${method ?? 'unknown'}`, + `JsonRpcServer.${method ?? 'batch'}`, { kind: SpanKind.SERVER }, context, async (span: Span): Promise => { @@ -48,3 +50,42 @@ export function getOtelJsonRpcPropagationMiddleware( ); }; } + +export function getOtelJsonRpcDiagnosticsMiddleware(): DiagnosticsMiddleware { + return function otelJsonRpcDiagnostics(ctx, next) { + const [namespace, method] = splitNamespace(ctx.method); + const scope = namespace ?? 'UnknownHandler'; + const tracer = getTelemetryClient().getTracer(scope); + return tracer.startActiveSpan( + `${scope}.${method}`, + { kind: SpanKind.INTERNAL, attributes: { [ATTR_JSONRPC_METHOD]: ctx.method } }, + async span => { + if (ctx.id !== null) { + span.setAttribute(ATTR_JSONRPC_REQUEST_ID, ctx.id); + } + + try { + await next(); + span.setStatus({ code: SpanStatusCode.OK }); + } catch (err) { + span.setStatus({ code: SpanStatusCode.ERROR, message: err instanceof Error ? err.message : String(err) }); + if (typeof err === 'string' || err instanceof Error) { + span.recordException(err); + } + throw err; + } finally { + span.end(); + } + }, + ); + }; +} + +function splitNamespace(fullMethod: string): [namespace: string | undefined, method: string] { + const idx = fullMethod.indexOf('_'); + if (idx > -1) { + return [fullMethod.slice(0, idx), fullMethod.slice(idx + 1)]; + } else { + return [undefined, fullMethod]; + } +} diff --git a/yarn-project/telemetry-client/src/start.ts b/yarn-project/telemetry-client/src/start.ts index 6006b001dd9f..4204cede80ce 100644 --- a/yarn-project/telemetry-client/src/start.ts +++ b/yarn-project/telemetry-client/src/start.ts @@ -19,7 +19,12 @@ export async function initTelemetryClient( return telemetry; } - if (config.metricsCollectorUrl || config.publicMetricsCollectorUrl) { + if ( + config.metricsCollectorUrl || + config.publicMetricsCollectorUrl || + config.tracesCollectorUrl || + config.logsCollectorUrl + ) { log.info(`Using OpenTelemetry client with custom collector`); // Lazy load OpenTelemetry to avoid loading heavy deps at startup const { OpenTelemetryClient } = await import('./otel.js'); diff --git a/yarn-project/telemetry-client/src/telemetry.ts b/yarn-project/telemetry-client/src/telemetry.ts index 5e304b61619c..25e1fd07149c 100644 --- a/yarn-project/telemetry-client/src/telemetry.ts +++ b/yarn-project/telemetry-client/src/telemetry.ts @@ -48,7 +48,6 @@ type BannedMetricAttributeNames = (typeof Attributes)[ | 'TX_HASH' | 'PROVING_JOB_ID' | 'P2P_ID' - | 'P2P_REQ_RESP_BATCH_REQUESTS_COUNT' | 'TARGET_ADDRESS' | 'MANA_USED' | 'TOTAL_INSTRUCTIONS']; diff --git a/yarn-project/txe/src/index.ts b/yarn-project/txe/src/index.ts index 225e77f85a86..d745b11df297 100644 --- a/yarn-project/txe/src/index.ts +++ b/yarn-project/txe/src/index.ts @@ -200,10 +200,7 @@ class TXEDispatcher { if (!TXEArtifactsCacheInFlight.has(cacheKey)) { const compute = async () => { const keys = await deriveKeys(secret); - const args = [ - keys.publicKeys.masterIncomingViewingPublicKey.x, - keys.publicKeys.masterIncomingViewingPublicKey.y, - ]; + const args = [keys.publicKeys.ivpkM.x, keys.publicKeys.ivpkM.y]; const computedArtifact: ContractArtifactWithHash = { ...SchnorrAccountContractArtifact, // Artifact hash is *very* expensive to compute, so we do it here once diff --git a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts index 0b0bf3316f2f..8338c84defae 100644 --- a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts +++ b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts @@ -63,6 +63,7 @@ import { PrivateToPublicAccumulatedData, PublicCallRequest, } from '@aztec/stdlib/kernel'; +import { hashPublicKey } from '@aztec/stdlib/keys'; import { ChonkProof } from '@aztec/stdlib/proofs'; import { makeGlobalVariables } from '@aztec/stdlib/testing'; import { MerkleTreeId } from '@aztec/stdlib/trees'; @@ -282,7 +283,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl async addAuthWitness(address: AztecAddress, messageHash: Fr) { const account = await this.accountStore.getAccount(address); - const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey); + const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM); + const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash); const schnorr = new Schnorr(); const signature = await schnorr.constructSignature(messageHash, privateKey); diff --git a/yarn-project/txe/src/rpc_translator.ts b/yarn-project/txe/src/rpc_translator.ts index bef1d2f19ce2..de4c456f42ea 100644 --- a/yarn-project/txe/src/rpc_translator.ts +++ b/yarn-project/txe/src/rpc_translator.ts @@ -245,6 +245,7 @@ export class RPCTranslator { instance.deployer.toField(), instance.currentContractClassId, instance.initializationHash, + instance.immutablesHash, ...instance.publicKeys.toFields(), ]), ]); @@ -647,6 +648,7 @@ export class RPCTranslator { instance.deployer.toField(), instance.currentContractClassId, instance.initializationHash, + instance.immutablesHash, ...instance.publicKeys.toFields(), ].map(toSingle), ); @@ -662,12 +664,24 @@ export class RPCTranslator { // with two fields: `some` (a boolean) and `value` (a field array in this case). if (result === undefined) { // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size. - return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(13).fill(new Fr(0)))]); + // Wire shape: [npk_m_hash, ivpk_m.x, ivpk_m.y, ovpk_m_hash, tpk_m_hash, partial_address] = 6 fields. + return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(6).fill(new Fr(0)))]); } else { - // Data was found so we set `some` to 1 and return it along with `value`. + // The Noir side hand-decodes a `[Field; 6]` here (see aztec-nr/aztec/src/oracle/keys.nr), so we + // emit the 5-field PublicKeys shape + partial_address explicitly + // rather than going through `publicKeys.toFields()` (which is the struct-flattened 6-field + // wire for oracle returns that decode via struct shape). + const { publicKeys, partialAddress } = result; return toForeignCallResult([ toSingle(new Fr(1)), - toArray([...result.publicKeys.toFields(), result.partialAddress]), + toArray([ + publicKeys.npkMHash, + publicKeys.ivpkM.x, + publicKeys.ivpkM.y, + publicKeys.ovpkMHash, + publicKeys.tpkMHash, + partialAddress, + ]), ]); } } @@ -1116,6 +1130,19 @@ export class RPCTranslator { ]); } + // eslint-disable-next-line camelcase + async aztec_avm_getContractInstanceImmutablesHash(foreignAddress: ForeignCallSingle) { + const address = addressFromSingle(foreignAddress); + + const instance = await this.handlerAsUtility().getContractInstance(address); + + return toForeignCallResult([ + toSingle(instance.immutablesHash), + // AVM requires an extra boolean indicating the instance was found + toSingle(new Fr(1)), + ]); + } + // eslint-disable-next-line camelcase async aztec_avm_sender() { const sender = await this.handlerAsAvm().sender(); diff --git a/yarn-project/txe/src/state_machine/dummy_p2p_client.ts b/yarn-project/txe/src/state_machine/dummy_p2p_client.ts index 25bc4085dc75..db5b1c2626c1 100644 --- a/yarn-project/txe/src/state_machine/dummy_p2p_client.ts +++ b/yarn-project/txe/src/state_machine/dummy_p2p_client.ts @@ -13,12 +13,17 @@ import type { PeerId, ReqRespSubProtocol, ReqRespSubProtocolHandler, - ReqRespSubProtocolValidators, StatusMessage, } from '@aztec/p2p'; import type { EthAddress, L2BlockStreamEvent, L2Tips } from '@aztec/stdlib/block'; import type { ITxProvider, PeerInfo } from '@aztec/stdlib/interfaces/server'; -import type { BlockProposal, CheckpointAttestation, CheckpointProposal, TopicType } from '@aztec/stdlib/p2p'; +import type { + BlockProposal, + CheckpointAttestation, + CheckpointProposal, + CheckpointProposalCore, + TopicType, +} from '@aztec/stdlib/p2p'; import type { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx'; export class DummyP2P implements P2P { @@ -159,6 +164,13 @@ export class DummyP2P implements P2P { throw new Error('DummyP2P does not implement "addOwnCheckpointAttestations"'); } + public getProposalsForSlot(_slot: SlotNumber): Promise<{ + blockProposals: BlockProposal[]; + checkpointProposals: CheckpointProposalCore[]; + }> { + return Promise.resolve({ blockProposals: [], checkpointProposals: [] }); + } + public getL2BlockHash(_number: number): Promise { throw new Error('DummyP2P does not implement "getL2BlockHash"'); } @@ -207,11 +219,7 @@ export class DummyP2P implements P2P { return Promise.resolve(); } - addReqRespSubProtocol( - _subProtocol: ReqRespSubProtocol, - _handler: ReqRespSubProtocolHandler, - _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol], - ): Promise { + addReqRespSubProtocol(_subProtocol: ReqRespSubProtocol, _handler: ReqRespSubProtocolHandler): Promise { throw new Error('DummyP2P does not implement "addReqRespSubProtocol".'); } handleAuthRequestFromPeer(_authRequest: AuthRequest, _peerId: PeerId): Promise { diff --git a/yarn-project/validator-client/README.md b/yarn-project/validator-client/README.md index 73f08f82fd69..4205a31e117e 100644 --- a/yarn-project/validator-client/README.md +++ b/yarn-project/validator-client/README.md @@ -156,15 +156,16 @@ Time | Proposer | Validator ## Configuration -| Flag | Purpose | -| ------------------------------------- | -------------------------------------------------------------------------------------- | -| `fishermanMode` | Validate proposals but don't broadcast attestations (monitoring only) | -| `alwaysReexecuteBlockProposals` | Force re-execution even when not in committee | -| `slashBroadcastedInvalidBlockPenalty` | Penalty amount for invalid proposals (0 = disabled) | -| `slashDuplicateProposalPenalty` | Penalty amount for duplicate proposals (0 = disabled) | -| `slashDuplicateAttestationPenalty` | Penalty amount for duplicate attestations (0 = disabled) | -| `attestationPollingIntervalMs` | How often to poll for attestations when collecting | -| `disabledValidators` | Validator addresses to exclude from duties | +| Flag | Purpose | +| -------------------------------------------------- | -------------------------------------------------------------------- | +| `fishermanMode` | Validate proposals but don't broadcast attestations (monitoring only) | +| `alwaysReexecuteBlockProposals` | Force re-execution even when not in committee | +| `slashBroadcastedInvalidBlockPenalty` | Penalty amount for invalid proposals (0 = disabled) | +| `slashBroadcastedInvalidCheckpointProposalPenalty` | Penalty amount for invalid checkpoint proposals (0 = disabled) | +| `slashDuplicateProposalPenalty` | Penalty amount for duplicate proposals (0 = disabled) | +| `slashDuplicateAttestationPenalty` | Penalty amount for duplicate attestations (0 = disabled) | +| `attestationPollingIntervalMs` | How often to poll for attestations when collecting | +| `disabledValidators` | Validator addresses to exclude from duties | ### High Availability (HA) Keystore diff --git a/yarn-project/validator-client/src/config.ts b/yarn-project/validator-client/src/config.ts index be8df0c0dd84..c283154fa2d5 100644 --- a/yarn-project/validator-client/src/config.ts +++ b/yarn-project/validator-client/src/config.ts @@ -79,6 +79,10 @@ export const validatorClientConfigMappings: ConfigMappingsType { - // For testing: change the archive to trigger state_mismatch validation failure. - // If there's a last block proposal, use its (already invalid) archive to keep signatures consistent - // so P2P validation passes and the slasher can detect the offense. + // For testing: corrupt the checkpoint so observers' checkpoint validation fails. + // + // Keep `archive` aligned with `lastBlockProposal.archiveRoot` so the archive-based lookup + // in `validateCheckpointProposal` (`getBlockData({ archive })`) still succeeds if (options.broadcastInvalidCheckpointProposal) { archive = lastBlockProposal?.archiveRoot ?? Fr.random(); + checkpointHeader = CheckpointHeader.from({ + ...checkpointHeader, + epochOutHash: Fr.random(), + }); this.log.warn(`Creating INVALID checkpoint proposal for slot ${checkpointHeader.slotNumber}`); } diff --git a/yarn-project/validator-client/src/factory.ts b/yarn-project/validator-client/src/factory.ts index 9917d528ca9f..02325c937789 100644 --- a/yarn-project/validator-client/src/factory.ts +++ b/yarn-project/validator-client/src/factory.ts @@ -4,6 +4,7 @@ import type { DateProvider } from '@aztec/foundation/timer'; import type { KeystoreManager } from '@aztec/node-keystore'; import { BlockProposalValidator, type P2PClient } from '@aztec/p2p'; import type { L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import type { TelemetryClient } from '@aztec/telemetry-client'; @@ -26,6 +27,7 @@ export function createProposalHandler( blobClient: BlobClientInterface; dateProvider: DateProvider; telemetry: TelemetryClient; + reexecutionTracker: CheckpointReexecutionTracker; }, ) { const metrics = new ValidatorMetrics(deps.telemetry); @@ -48,6 +50,7 @@ export function createProposalHandler( deps.epochCache, config, deps.blobClient, + deps.reexecutionTracker, metrics, deps.dateProvider, deps.telemetry, @@ -68,6 +71,7 @@ export function createValidatorClient( epochCache: EpochCache; keyStoreManager: KeystoreManager | undefined; blobClient: BlobClientInterface; + reexecutionTracker: CheckpointReexecutionTracker; slashingProtectionDb?: SlashingProtectionDatabase; }, ) { @@ -87,6 +91,7 @@ export function createValidatorClient( txProvider, deps.keyStoreManager, deps.blobClient, + deps.reexecutionTracker, deps.dateProvider, deps.telemetry, deps.slashingProtectionDb, diff --git a/yarn-project/validator-client/src/proposal_handler.test.ts b/yarn-project/validator-client/src/proposal_handler.test.ts index b464dd7cd7a9..e6634968ee6d 100644 --- a/yarn-project/validator-client/src/proposal_handler.test.ts +++ b/yarn-project/validator-client/src/proposal_handler.test.ts @@ -9,7 +9,7 @@ import { type FieldsOf, unfreeze } from '@aztec/foundation/types'; import type { P2P } from '@aztec/p2p'; import type { BlockProposalValidator } from '@aztec/p2p/msg_validators'; import type { BlockData, L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; -import type { Checkpoint } from '@aztec/stdlib/checkpoint'; +import { type Checkpoint, CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; import type { ITxProvider, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; @@ -98,6 +98,7 @@ describe('ProposalHandler checkpoint validation', () => { epochCache, config, mock(), + new CheckpointReexecutionTracker(), metrics, dateProvider, ); @@ -167,6 +168,7 @@ describe('ProposalHandler checkpoint validation', () => { epochCache, config, mock(), + new CheckpointReexecutionTracker(), metrics, dateProvider, ); @@ -328,7 +330,11 @@ describe('ProposalHandler checkpoint validation', () => { const proposal = await makeProposal({ archiveRoot, checkpointHeader: proposalHeader }); const result = await handler.handleCheckpointProposal(proposal, proposalInfo); - expect(result).toEqual({ isValid: false, reason: 'checkpoint_header_mismatch' }); + expect(result).toEqual({ + isValid: false, + reason: 'checkpoint_header_mismatch', + checkpointNumber: CheckpointNumber(1), + }); expect(mockDispose).toHaveBeenCalled(); }); @@ -342,7 +348,7 @@ describe('ProposalHandler checkpoint validation', () => { const proposal = await makeProposal({ archiveRoot, checkpointHeader: header }); const result = await handler.handleCheckpointProposal(proposal, proposalInfo); - expect(result).toEqual({ isValid: false, reason: 'archive_mismatch' }); + expect(result).toEqual({ isValid: false, reason: 'archive_mismatch', checkpointNumber: CheckpointNumber(1) }); }); it('returns out_hash_mismatch when epoch out hash differs', async () => { @@ -355,7 +361,7 @@ describe('ProposalHandler checkpoint validation', () => { const proposal = await makeProposal({ archiveRoot, checkpointHeader: header }); const result = await handler.handleCheckpointProposal(proposal, proposalInfo); - expect(result).toEqual({ isValid: false, reason: 'out_hash_mismatch' }); + expect(result).toEqual({ isValid: false, reason: 'out_hash_mismatch', checkpointNumber: CheckpointNumber(1) }); }); it('returns checkpoint_validation_failed when validateCheckpoint throws', async () => { @@ -370,7 +376,11 @@ describe('ProposalHandler checkpoint validation', () => { const proposal = await makeProposal({ archiveRoot, checkpointHeader: header }); const result = await handler.handleCheckpointProposal(proposal, proposalInfo); - expect(result).toEqual({ isValid: false, reason: 'checkpoint_validation_failed' }); + expect(result).toEqual({ + isValid: false, + reason: 'checkpoint_validation_failed', + checkpointNumber: CheckpointNumber(1), + }); }); it('returns isValid true when everything matches', async () => { diff --git a/yarn-project/validator-client/src/proposal_handler.ts b/yarn-project/validator-client/src/proposal_handler.ts index 34106e89a7f5..5eb403170670 100644 --- a/yarn-project/validator-client/src/proposal_handler.ts +++ b/yarn-project/validator-client/src/proposal_handler.ts @@ -20,6 +20,7 @@ import { DateProvider, Timer } from '@aztec/foundation/timer'; import type { P2P, PeerId } from '@aztec/p2p'; import { BlockProposalValidator } from '@aztec/p2p/msg_validators'; import type { BlockData, L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker, ReexecutionOutcome } from '@aztec/stdlib/checkpoint'; import { getPreviousCheckpointOutHashes, validateCheckpoint } from '@aztec/stdlib/checkpoint'; import { getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { Gas } from '@aztec/stdlib/gas'; @@ -45,6 +46,7 @@ import type { FullNodeCheckpointsBuilder } from './checkpoint_builder.js'; import type { ValidatorMetrics } from './metrics.js'; export type BlockProposalValidationFailureReason = + | 'invalid_signature' | 'invalid_proposal' | 'parent_block_not_found' | 'block_source_not_synced' @@ -57,6 +59,8 @@ export type BlockProposalValidationFailureReason = | 'failed_txs' | 'initial_state_mismatch' | 'timeout' + | 'block_proposal_beyond_checkpoint' + | 'checkpoint_proposal_equivocation' | 'unknown_error'; type ReexecuteTransactionsResult = { @@ -81,14 +85,73 @@ export type BlockProposalValidationFailureResult = { export type BlockProposalValidationResult = BlockProposalValidationSuccessResult | BlockProposalValidationFailureResult; +export type CheckpointProposalValidationFailureReason = + | 'invalid_signature' + | 'invalid_fee_asset_price_modifier' + | 'last_block_not_found' + | 'block_fetch_error' + | 'checkpoint_already_published' + | 'no_blocks_for_slot' + | 'last_block_archive_mismatch' + | 'too_many_blocks_in_checkpoint' + | 'checkpoint_header_mismatch' + | 'archive_mismatch' + | 'out_hash_mismatch' + | 'checkpoint_validation_failed'; + +/** + * Mapping from a checkpoint-proposal validation failure reason to the tracker outcome that + * `handleCheckpointProposal` should record. `undefined` means do not record (signature + * couldn't be verified, or the checkpoint is already on L1 so the question is moot). + */ +/* eslint-disable camelcase */ +const CHECKPOINT_VALIDATION_REASON_TO_OUTCOME: Record< + CheckpointProposalValidationFailureReason, + ReexecutionOutcome | undefined +> = { + invalid_signature: undefined, + invalid_fee_asset_price_modifier: 'invalid', + checkpoint_already_published: undefined, + last_block_not_found: 'unvalidated', + block_fetch_error: 'unvalidated', + no_blocks_for_slot: 'unvalidated', + last_block_archive_mismatch: 'invalid', + too_many_blocks_in_checkpoint: 'invalid', + checkpoint_header_mismatch: 'invalid', + archive_mismatch: 'invalid', + out_hash_mismatch: 'invalid', + checkpoint_validation_failed: 'invalid', +}; + +export type CheckpointProposalValidationSuccessResult = { + isValid: true; + checkpointNumber: CheckpointNumber; +}; + +export type CheckpointProposalValidationFailureResult = { + isValid: false; + reason: CheckpointProposalValidationFailureReason; + checkpointNumber?: CheckpointNumber; +}; + export type CheckpointProposalValidationResult = - | { isValid: true; checkpointNumber: CheckpointNumber } - | { isValid: false; reason: string }; + | CheckpointProposalValidationSuccessResult + | CheckpointProposalValidationFailureResult; + +export type CheckpointProposalValidationFailureCallback = ( + proposal: CheckpointProposalCore, + result: CheckpointProposalValidationFailureResult, + proposalInfo: LogData, +) => void | Promise; type CheckpointComputationResult = | { checkpointNumber: CheckpointNumber; reason?: undefined } | { checkpointNumber?: undefined; reason: 'invalid_proposal' | 'global_variables_mismatch' }; +type BlockProposalSlotValidationResult = + | { isValid: true } + | { isValid: false; reason: 'block_proposal_beyond_checkpoint' | 'checkpoint_proposal_equivocation' }; + /** Handles block and checkpoint proposals for both validator and non-validator nodes. */ export class ProposalHandler { public readonly tracer: Tracer; @@ -107,6 +170,11 @@ export class ProposalHandler { /** Returns current validator addresses for own-proposal detection. Set via register(). */ private getOwnValidatorAddresses?: () => string[]; + /** P2P proposal pool access for deciding when retained proposals should block archiver processing. */ + private p2pClient?: Pick; + + private checkpointProposalValidationFailureCallback?: CheckpointProposalValidationFailureCallback; + constructor( private checkpointsBuilder: FullNodeCheckpointsBuilder, private worldState: WorldStateSynchronizer, @@ -117,6 +185,7 @@ export class ProposalHandler { private epochCache: EpochCache, private config: ValidatorClientFullConfig, private blobClient: BlobClientInterface, + private reexecutionTracker: CheckpointReexecutionTracker, private metrics?: ValidatorMetrics, private dateProvider: DateProvider = new DateProvider(), telemetry: TelemetryClient = getTelemetryClient(), @@ -128,8 +197,32 @@ export class ProposalHandler { this.tracer = telemetry.getTracer('ProposalHandler'); } + public updateConfig(config: Partial): void { + this.config = { ...this.config, ...config }; + } + + public setCheckpointProposalValidationFailureCallback(callback?: CheckpointProposalValidationFailureCallback): void { + this.checkpointProposalValidationFailureCallback = callback; + } + + /** + * Records the proposer's own checkpoint proposal as a `valid` outcome in the re-execution + * tracker. Without this, the node's own checkpoint proposals never flow through + * `handleCheckpointProposal` (proposers don't validate their own proposals), so its sentinel + * sees no outcome for slots where it was the proposer and reports itself as inactive. + * + * `archive` should be the locally-computed archive (NOT the broadcast archive, which may have + * been deliberately corrupted in tests via `broadcastInvalidBlockProposal` / + * `broadcastInvalidCheckpointProposalOnly`). Recording the local archive correctly models the + * proposer's own view of its own work. + */ + public recordOwnCheckpointProposalAsValid(slot: SlotNumber, archive: Fr, checkpointNumber: CheckpointNumber): void { + this.reexecutionTracker.recordOutcome(slot, archive, 'valid', checkpointNumber); + } + /** * Registers handlers for block and checkpoint proposals on the p2p client. + * Records the p2p client so validation can inspect retained proposals. * Block proposals are registered for non-validator nodes (validators register their own enhanced handler). * The all-nodes checkpoint proposal handler is always registered for validation, caching, and pipelining. * @param archiver - Archiver reference for setting proposed checkpoints (pipelining) @@ -141,6 +234,7 @@ export class ProposalHandler { archiver?: Pick, getOwnValidatorAddresses?: () => string[], ): ProposalHandler { + this.p2pClient = p2pClient; this.archiver = archiver; this.getOwnValidatorAddresses = getOwnValidatorAddresses; @@ -190,6 +284,19 @@ export class ProposalHandler { proposer: proposal.getSender()?.toString(), }; + if (this.config.skipCheckpointProposalValidation) { + this.log.warn(`Skipping checkpoint proposal validation for slot ${proposal.slotNumber}`, proposalInfo); + return undefined; + } + + if (await this.epochCache.isEscapeHatchOpenAtSlot(proposal.slotNumber)) { + this.log.warn( + `Escape hatch open for slot ${proposal.slotNumber}, skipping checkpoint proposal validation`, + proposalInfo, + ); + return undefined; + } + // For own proposals, skip validation — the proposer already built and validated the checkpoint const proposer = proposal.getSender(); const ownAddresses = this.getOwnValidatorAddresses?.(); @@ -203,8 +310,18 @@ export class ProposalHandler { return undefined; } + if (this.config.skipCheckpointProposalValidation) { + this.log.warn( + `Skipping all-nodes checkpoint proposal validation for slot ${proposal.slotNumber}`, + proposalInfo, + ); + return undefined; + } + const result = await this.handleCheckpointProposal(proposal, proposalInfo); - if (result.isValid && this.archiver && this.epochCache.isProposerPipeliningEnabled()) { + if (!result.isValid) { + await this.checkpointProposalValidationFailureCallback?.(proposal, result, proposalInfo); + } else if (this.archiver && this.epochCache.isProposerPipeliningEnabled()) { const set = await this.setProposedCheckpointFromValidation(proposal); if (set) { this.metrics?.recordCheckpointProposalToPipelinedStateDuration(pipeliningTimer.ms()); @@ -233,7 +350,7 @@ export class ProposalHandler { // Reject proposals with invalid signatures if (!proposer) { this.log.warn(`Received proposal with invalid signature for slot ${slotNumber}`); - return { isValid: false, reason: 'invalid_proposal' }; + return { isValid: false, reason: 'invalid_signature' }; } const proposalInfo = { @@ -256,6 +373,16 @@ export class ProposalHandler { return { isValid: false, reason: 'invalid_proposal' }; } + const retainedSlotValidation = await this.validateNewBlockInSlot(proposal); + if (!retainedSlotValidation.isValid) { + this.log.info(`Block proposal conflicts with retained proposals, skipping archiver processing`, { + ...proposalInfo, + indexWithinCheckpoint: proposal.indexWithinCheckpoint, + reason: retainedSlotValidation.reason, + }); + return { isValid: false, blockNumber: proposal.blockNumber, reason: retainedSlotValidation.reason }; + } + // Ensure the block source is synced before checking for existing blocks, // since a proposed checkpoint prune may remove blocks we'd otherwise find. // This affects mostly the block_number_already_exists check, since a pending @@ -311,6 +438,9 @@ export class ProposalHandler { deadline: this.getReexecutionDeadline(slotNumber, config), }); + // Record the tx-collection outcome on the re-execution tracker + this.reexecutionTracker.recordTxsCollected(slotNumber, proposal.indexWithinCheckpoint, missingTxs.length === 0); + // If reexecution is disabled, bail. We were just interested in triggering tx collection. if (!shouldReexecute) { this.log.info( @@ -391,6 +521,26 @@ export class ProposalHandler { return { isValid: true, blockNumber, reexecutionResult }; } + private async validateNewBlockInSlot(blockProposal: BlockProposal): Promise { + if (!this.p2pClient) { + return { isValid: true }; + } + + const { blockProposals, checkpointProposals } = await this.p2pClient.getProposalsForSlot(blockProposal.slotNumber); + + if (checkpointProposals.length === 0) { + return { isValid: true }; + } else if (checkpointProposals.length > 1) { + return { isValid: false, reason: 'checkpoint_proposal_equivocation' }; + } else { + const checkpointProposal = checkpointProposals[0]; + const terminalBlock = blockProposals.find(block => block.archive.equals(checkpointProposal.archive)); + return terminalBlock !== undefined && blockProposal.indexWithinCheckpoint > terminalBlock.indexWithinCheckpoint + ? { isValid: false, reason: 'block_proposal_beyond_checkpoint' } + : { isValid: true }; + } + } + private async getParentBlock(proposal: BlockProposal): Promise<'genesis' | BlockData | undefined> { const parentArchive = proposal.blockHeader.lastArchive.root; const config = this.checkpointsBuilder.getConfig(); @@ -757,25 +907,38 @@ export class ProposalHandler { } const proposer = proposal.getSender(); + let result: CheckpointProposalValidationResult; if (!proposer) { this.log.warn(`Received checkpoint proposal with invalid signature for slot ${proposal.slotNumber}`); - const result: CheckpointProposalValidationResult = { isValid: false, reason: 'invalid_signature' }; - this.lastCheckpointValidationResult = { payloadHash, result }; - return result; - } - - if (!validateFeeAssetPriceModifier(proposal.feeAssetPriceModifier)) { + result = { isValid: false as const, reason: 'invalid_signature' }; + } else if (!validateFeeAssetPriceModifier(proposal.feeAssetPriceModifier)) { this.log.warn( `Received checkpoint proposal with invalid feeAssetPriceModifier ${proposal.feeAssetPriceModifier} for slot ${proposal.slotNumber}`, ); - const result: CheckpointProposalValidationResult = { isValid: false, reason: 'invalid_fee_asset_price_modifier' }; - this.lastCheckpointValidationResult = { payloadHash, result }; - return result; + result = { isValid: false, reason: 'invalid_fee_asset_price_modifier' }; + } else { + result = await this.validateCheckpointProposal(proposal, proposalInfo); } - const result = await this.validateCheckpointProposal(proposal, proposalInfo); this.lastCheckpointValidationResult = { payloadHash, result }; + // Record the outcome on the re-execution tracker. + const outcome = result.isValid ? ('valid' as const) : CHECKPOINT_VALIDATION_REASON_TO_OUTCOME[result.reason]; + if (outcome !== undefined) { + this.reexecutionTracker.recordOutcome(slot, proposal.archive, outcome, result.checkpointNumber); + } + + // Drop tracker entries for checkpoints that have reached L1 finality. + try { + const tips = await this.blockSource.getL2Tips(); + const finalizedCheckpointNumber = tips.finalized.checkpoint.number; + if (finalizedCheckpointNumber > 0) { + this.reexecutionTracker.removeBefore(CheckpointNumber(finalizedCheckpointNumber + 1)); + } + } catch (err) { + this.log.error(`Error pruning reexecution tracker`, err, proposalInfo); + } + // Upload blobs to filestore if validation passed (fire and forget) if (result.isValid) { this.tryUploadBlobsForCheckpoint(proposal, proposalInfo); @@ -794,18 +957,21 @@ export class ProposalHandler { ): Promise { const slot = proposal.slotNumber; - // Timeout block syncing at the start of the next slot + // Block-sync deadline = the moment the proposer can no longer publish this checkpoint to L1. + // With pipelining off that's the end of the proposal's own slot; with pipelining on the + // proposal is built one slot ahead, so the publication deadline is the start of the target + // slot. `getReexecutionDeadline` handles both cases. const config = this.checkpointsBuilder.getConfig(); - const nextSlotTimestampSeconds = Number(getTimestampForSlot(SlotNumber(slot + 1), config)); - const timeoutSeconds = Math.max(1, nextSlotTimestampSeconds - Math.floor(this.dateProvider.now() / 1000)); + const deadline = this.getReexecutionDeadline(slot, config); + const timeoutSeconds = Math.max(1, Math.floor((deadline.getTime() - this.dateProvider.now()) / 1000)); // Wait for last block to sync by archive - let lastBlockHeader; + let lastBlockData; try { - lastBlockHeader = await retryUntil( + lastBlockData = await retryUntil( async () => { await this.blockSource.syncImmediate(); - return (await this.blockSource.getBlockData({ archive: proposal.archive }))?.header; + return await this.blockSource.getBlockData({ archive: proposal.archive }); }, `waiting for block with archive ${proposal.archive.toString()} for slot ${slot}`, timeoutSeconds, @@ -820,22 +986,40 @@ export class ProposalHandler { return { isValid: false, reason: 'block_fetch_error' }; } - if (!lastBlockHeader) { + if (!lastBlockData) { this.log.warn(`Last block not found for checkpoint proposal`, proposalInfo); return { isValid: false, reason: 'last_block_not_found' }; } + // Refuse to attest if the block's enclosing checkpoint has already been published to L1. + const existingCheckpoint = await this.blockSource.getCheckpointData({ number: lastBlockData.checkpointNumber }); + if (existingCheckpoint) { + this.log.warn(`Refusing to attest to checkpoint proposal whose checkpoint is already on L1`, { + ...proposalInfo, + checkpointNumber: lastBlockData.checkpointNumber, + }); + return { + isValid: false, + reason: 'checkpoint_already_published', + checkpointNumber: lastBlockData.checkpointNumber, + }; + } + // Get all full blocks for the slot and checkpoint const blocks = await this.blockSource.getBlocksForSlot(slot); if (blocks.length === 0) { this.log.warn(`No blocks found for slot ${slot}`, proposalInfo); - return { isValid: false, reason: 'no_blocks_for_slot' }; + return { isValid: false, reason: 'no_blocks_for_slot', checkpointNumber: lastBlockData.checkpointNumber }; } // Ensure the last block for this slot matches the archive in the checkpoint proposal if (!blocks.at(-1)?.archive.root.equals(proposal.archive)) { this.log.warn(`Last block archive mismatch for checkpoint proposal`, proposalInfo); - return { isValid: false, reason: 'last_block_archive_mismatch' }; + return { + isValid: false, + reason: 'last_block_archive_mismatch', + checkpointNumber: lastBlockData.checkpointNumber, + }; } const maxBlocksPerCheckpoint = this.config.maxBlocksPerCheckpoint; @@ -845,7 +1029,11 @@ export class ProposalHandler { blocksInProposal: blocks.length, maxBlocksPerCheckpoint, }); - return { isValid: false, reason: 'too_many_blocks_in_checkpoint' }; + return { + isValid: false, + reason: 'too_many_blocks_in_checkpoint', + checkpointNumber: lastBlockData.checkpointNumber, + }; } this.log.debug(`Found ${blocks.length} blocks for slot ${slot}`, { @@ -899,7 +1087,7 @@ export class ProposalHandler { computed: computedCheckpoint.header.toInspect(), proposal: proposal.checkpointHeader.toInspect(), }); - return { isValid: false, reason: 'checkpoint_header_mismatch' }; + return { isValid: false, reason: 'checkpoint_header_mismatch', checkpointNumber }; } // Compare archive root with proposal @@ -909,7 +1097,7 @@ export class ProposalHandler { computed: computedCheckpoint.archive.root.toString(), proposal: proposal.archive.toString(), }); - return { isValid: false, reason: 'archive_mismatch' }; + return { isValid: false, reason: 'archive_mismatch', checkpointNumber }; } // Check that the accumulated epoch out hash matches the value in the proposal. @@ -925,7 +1113,7 @@ export class ProposalHandler { previousCheckpointOutHashes: previousCheckpointOutHashes.map(h => h.toString()), ...proposalInfo, }); - return { isValid: false, reason: 'out_hash_mismatch' }; + return { isValid: false, reason: 'out_hash_mismatch', checkpointNumber }; } // Final round of validations on the checkpoint, just in case. @@ -939,10 +1127,11 @@ export class ProposalHandler { }); } catch (err) { this.log.warn(`Checkpoint validation failed: ${err}`, proposalInfo); - return { isValid: false, reason: 'checkpoint_validation_failed' }; + return { isValid: false, reason: 'checkpoint_validation_failed', checkpointNumber }; } this.log.verbose(`Checkpoint proposal validation successful for slot ${slot}`, proposalInfo); + return { isValid: true, checkpointNumber }; } diff --git a/yarn-project/validator-client/src/validator.ha.integration.test.ts b/yarn-project/validator-client/src/validator.ha.integration.test.ts index 186561fd920b..070d48f2e365 100644 --- a/yarn-project/validator-client/src/validator.ha.integration.test.ts +++ b/yarn-project/validator-client/src/validator.ha.integration.test.ts @@ -17,6 +17,7 @@ import type { P2P, TxProvider } from '@aztec/p2p'; import { BlockProposalValidator } from '@aztec/p2p'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; +import { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { SlasherConfig, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; @@ -136,6 +137,7 @@ describe('ValidatorClient HA Integration', () => { Pick< SlasherConfig, | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' @@ -145,6 +147,7 @@ describe('ValidatorClient HA Integration', () => { disableValidator: false, disabledValidators: [], slashBroadcastedInvalidBlockPenalty: 1n, + slashBroadcastedInvalidCheckpointProposalPenalty: 1n, rollupAddress, l1ChainId: TEST_COORDINATION_SIGNATURE_CONTEXT.chainId, slashDuplicateProposalPenalty: 1n, @@ -193,6 +196,7 @@ describe('ValidatorClient HA Integration', () => { Pick< SlasherConfig, | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' @@ -226,6 +230,7 @@ describe('ValidatorClient HA Integration', () => { epochCache, config, blobClient, + new CheckpointReexecutionTracker(), metrics, dateProvider, getTelemetryClient(), diff --git a/yarn-project/validator-client/src/validator.integration.test.ts b/yarn-project/validator-client/src/validator.integration.test.ts index da2ff3670674..99d4caf2e609 100644 --- a/yarn-project/validator-client/src/validator.integration.test.ts +++ b/yarn-project/validator-client/src/validator.integration.test.ts @@ -21,7 +21,7 @@ import { TestTxProvider } from '@aztec/p2p/test-helpers'; import { protocolContractsHash } from '@aztec/protocol-contracts'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block'; -import { L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import { CheckpointReexecutionTracker, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; import { type L1RollupConstants, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { Gas, GasFees } from '@aztec/stdlib/gas'; import { tryStop } from '@aztec/stdlib/interfaces/server'; @@ -177,6 +177,7 @@ describe('ValidatorClient Integration', () => { disableValidator: false, disabledValidators: [], slashBroadcastedInvalidBlockPenalty: 10n, + slashBroadcastedInvalidCheckpointProposalPenalty: 10n, slashDuplicateProposalPenalty: 10n, slashDuplicateAttestationPenalty: 10n, slashAttestInvalidCheckpointProposalPenalty: 10n, @@ -197,6 +198,7 @@ describe('ValidatorClient Integration', () => { txProvider, keyStoreManager, blobClient, + new CheckpointReexecutionTracker(), dateProvider, ); diff --git a/yarn-project/validator-client/src/validator.test.ts b/yarn-project/validator-client/src/validator.test.ts index 6e3bc422f65e..d582a73c3575 100644 --- a/yarn-project/validator-client/src/validator.test.ts +++ b/yarn-project/validator-client/src/validator.test.ts @@ -30,6 +30,7 @@ import { import { OffenseType, WANT_TO_CLEAR_SLASH_EVENT, WANT_TO_SLASH_EVENT } from '@aztec/slasher'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { type BlockData, BlockHash, L2Block, type L2BlockSink, type L2BlockSource } from '@aztec/stdlib/block'; +import { type Checkpoint, CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import { type getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import type { SlasherConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; @@ -58,7 +59,7 @@ import type { } from './checkpoint_builder.js'; import { type ValidatorClientConfig, validatorClientConfigMappings } from './config.js'; import { HAKeyStore } from './key_store/ha_key_store.js'; -import { ProposalHandler } from './proposal_handler.js'; +import { type CheckpointProposalValidationFailureReason, ProposalHandler } from './proposal_handler.js'; import { ValidatorClient } from './validator.js'; function makeKeyStore(validator: { @@ -89,6 +90,7 @@ describe('ValidatorClient', () => { Pick< SlasherConfig, | 'slashBroadcastedInvalidBlockPenalty' + | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' | 'slashDuplicateAttestationPenalty' | 'slashAttestInvalidCheckpointProposalPenalty' @@ -115,6 +117,7 @@ describe('ValidatorClient', () => { p2pClient.getCheckpointAttestationsForSlot.mockImplementation(() => Promise.resolve([])); p2pClient.handleAuthRequestFromPeer.mockResolvedValue(StatusMessage.random()); p2pClient.broadcastCheckpointAttestations.mockResolvedValue(); + p2pClient.getProposalsForSlot.mockResolvedValue({ blockProposals: [], checkpointProposals: [] }); checkpointsBuilder = mock(); checkpointsBuilder.getConfig.mockReturnValue({ l1GenesisTime: 1n, @@ -182,6 +185,7 @@ describe('ValidatorClient', () => { disableValidator: false, disabledValidators: [], slashBroadcastedInvalidBlockPenalty: 1n, + slashBroadcastedInvalidCheckpointProposalPenalty: 1n, slashDuplicateProposalPenalty: 1n, slashDuplicateAttestationPenalty: 1n, slashAttestInvalidCheckpointProposalPenalty: 1n, @@ -209,6 +213,7 @@ describe('ValidatorClient', () => { txProvider, keyStoreManager, blobClient, + new CheckpointReexecutionTracker(), dateProvider, )) as ValidatorClient; }); @@ -343,6 +348,75 @@ describe('ValidatorClient', () => { const makeTxFromHash = (txHash: TxHash) => ({ getTxHash: () => txHash, txHash }) as Tx; const getExpectedWallClockDeadline = (currentSlot: SlotNumber) => new Date(Number(getTimestampForSlot(SlotNumber(currentSlot + 1), checkpointsBuilder.getConfig())) * 1000); + const makeCheckpointProposalForSlot = () => + makeCheckpointProposal({ + archiveRoot: proposal.archive, + checkpointHeader: makeCheckpointHeader(0, { slotNumber: proposal.slotNumber }), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber: BlockNumber(123), slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + const makeCheckpointProposalWithHeaderMismatch = async () => { + const proposalHeader = makeCheckpointHeader(0, { slotNumber: proposal.slotNumber }); + const computedHeader = makeCheckpointHeader(0, { + slotNumber: proposal.slotNumber, + totalManaUsed: new Fr(999), + }); + const checkpointProposal = await makeCheckpointProposal({ + archiveRoot: proposal.archive, + checkpointHeader: proposalHeader, + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + const checkpointBlock = { + ...blockBuildResult.block, + number: blockNumber, + header: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + archive: new AppendOnlyTreeSnapshot(proposal.archive, blockNumber), + checkpointNumber: CheckpointNumber(1), + } as unknown as L2Block; + const disposeFork = jest.fn(); + blockSource.getBlocksForSlot.mockResolvedValue([checkpointBlock]); + checkpointsBuilder.getFork.mockResolvedValue({ [Symbol.asyncDispose]: disposeFork } as any); + mockCheckpointBuilder.completeCheckpoint.mockResolvedValue({ + header: computedHeader, + archive: new AppendOnlyTreeSnapshot(proposal.archive, blockNumber), + getCheckpointOutHash: () => Fr.random(), + blocks: [checkpointBlock], + number: CheckpointNumber(1), + slot: proposal.slotNumber, + } as unknown as Checkpoint); + return { checkpointProposal, disposeFork }; + }; + const registerAllNodesCheckpointHandler = () => { + let checkpointHandler: Parameters[0] | undefined; + p2pClient.registerAllNodesCheckpointProposalHandler.mockImplementation(handler => { + checkpointHandler = handler; + }); + + validatorClient + .getProposalHandler() + .register(p2pClient, true, undefined, () => + validatorClient.getValidatorAddresses().map(address => address.toString()), + ); + + expect(checkpointHandler).toBeDefined(); + return checkpointHandler!; + }; + const getBroadcastedInvalidCheckpointProposalSlashEvents = ( + emitSpy: jest.SpiedFunction, + ) => + emitSpy.mock.calls.filter( + ([event, args]) => + event === WANT_TO_SLASH_EVENT && + Array.isArray(args) && + args[0]?.offenseType === OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + ); beforeEach(async () => { const emptyInHash = computeInHashFromL1ToL2Messages([]); @@ -447,6 +521,121 @@ describe('ValidatorClient', () => { expect(isValid).toBe(true); }); + it('does not push a block proposal beyond a retained checkpoint terminal block to the archiver', async () => { + validatorClient.updateConfig({ skipPushProposedBlocksToArchiver: false }); + validatorClient.getProposalHandler().register(p2pClient, true); + + const signer = Secp256k1Signer.random(); + const emptyInHash = computeInHashFromL1ToL2Messages([]); + const checkpointProposal = await makeCheckpointProposal({ + signer, + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + archiveRoot: Fr.random(), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + const terminalBlock = checkpointProposal.getBlockProposal()!; + + const terminalGlobals = terminalBlock.blockHeader.globalVariables; + const laterBlockHeader = makeBlockHeader(2, { + lastArchive: new AppendOnlyTreeSnapshot(terminalBlock.archive, terminalBlock.blockNumber), + blockNumber: BlockNumber(terminalBlock.blockNumber + 1), + slotNumber: proposal.slotNumber, + chainId: terminalGlobals.chainId, + version: terminalGlobals.version, + timestamp: terminalGlobals.timestamp, + coinbase: terminalGlobals.coinbase, + feeRecipient: terminalGlobals.feeRecipient, + gasFees: terminalGlobals.gasFees, + }); + const laterBlock = await makeBlockProposal({ + signer, + blockHeader: laterBlockHeader, + indexWithinCheckpoint: IndexWithinCheckpoint(1), + inHash: emptyInHash, + archiveRoot: Fr.random(), + }); + + epochCache.getProposerAttesterAddressInSlot.mockResolvedValue(signer.address); + p2pClient.getProposalsForSlot.mockResolvedValue({ + blockProposals: [terminalBlock, laterBlock], + checkpointProposals: [checkpointProposal.toCore()], + }); + + const terminalBlockData = { + header: terminalBlock.blockHeader, + archive: new AppendOnlyTreeSnapshot(terminalBlock.archive, terminalBlock.blockNumber), + blockHash: BlockHash.random(), + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: terminalBlock.indexWithinCheckpoint, + } as unknown as BlockData; + blockSource.getBlockData.mockImplementation(query => + Promise.resolve('number' in query ? undefined : terminalBlockData), + ); + + const blockAddedIfProcessed = { + ...blockBuildResult.block, + header: laterBlock.blockHeader, + body: { txEffects: times(laterBlock.txHashes.length, () => TxEffect.empty()) }, + archive: new AppendOnlyTreeSnapshot(laterBlock.archive, laterBlock.blockNumber), + checkpointNumber: CheckpointNumber(1), + indexWithinCheckpoint: laterBlock.indexWithinCheckpoint, + } as unknown as L2Block; + mockCheckpointBuilder.buildBlock.mockResolvedValue({ + ...blockBuildResult, + block: blockAddedIfProcessed, + numTxs: laterBlock.txHashes.length, + }); + worldState.fork.mockResolvedValue({ + close: () => Promise.resolve(), + [Symbol.asyncDispose]: () => Promise.resolve(), + getTreeInfo: () => Promise.resolve({ root: laterBlock.blockHeader.lastArchive.root.toBuffer() }), + } as never); + + const result = await validatorClient.getProposalHandler().handleBlockProposal(laterBlock, sender, true); + + expect(result).toMatchObject({ isValid: false, reason: 'block_proposal_beyond_checkpoint' }); + expect(blockSource.addBlock).not.toHaveBeenCalled(); + }); + + it('does not push a block proposal to the archiver when retained checkpoint proposals equivocate', async () => { + validatorClient.updateConfig({ skipPushProposedBlocksToArchiver: false }); + validatorClient.getProposalHandler().register(p2pClient, true); + + const emptyInHash = computeInHashFromL1ToL2Messages([]); + const checkpointProposal = await makeCheckpointProposal({ + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + archiveRoot: Fr.random(), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + const equivocatedCheckpointProposal = await makeCheckpointProposal({ + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + archiveRoot: Fr.random(), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + }); + + p2pClient.getProposalsForSlot.mockResolvedValue({ + blockProposals: [proposal], + checkpointProposals: [checkpointProposal.toCore(), equivocatedCheckpointProposal.toCore()], + }); + + const result = await validatorClient.getProposalHandler().handleBlockProposal(proposal, sender, true); + + expect(result).toMatchObject({ isValid: false, reason: 'checkpoint_proposal_equivocation' }); + expect(blockSource.addBlock).not.toHaveBeenCalled(); + }); + it('uses the next wall-clock slot as the tx collection deadline for pipelined proposals', async () => { const pipelineOffsetInSlots = 1; epochCache.isProposerPipeliningEnabled.mockReturnValue(true); @@ -821,6 +1010,167 @@ describe('ValidatorClient', () => { expect(emitSpy).not.toHaveBeenCalled(); }); + it('emits WANT_TO_SLASH_EVENT for checkpoint_header_mismatch checkpoint proposals', async () => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal, disposeFork } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + const proposer = checkpointProposal.getSender(); + expect(proposer).toBeDefined(); + expect(disposeFork).toHaveBeenCalled(); + expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ + { + validator: proposer!, + amount: config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: BigInt(checkpointProposal.slotNumber), + }, + ]); + }); + + it('emits WANT_TO_SLASH_EVENT for invalid fee asset price modifiers', async () => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const checkpointProposal = await makeCheckpointProposal({ + archiveRoot: proposal.archive, + checkpointHeader: makeCheckpointHeader(0, { slotNumber: proposal.slotNumber }), + lastBlock: { + blockHeader: makeBlockHeader(1, { blockNumber: BlockNumber(123), slotNumber: proposal.slotNumber }), + indexWithinCheckpoint: IndexWithinCheckpoint(0), + txHashes: proposal.txHashes, + }, + feeAssetPriceModifier: MAX_FEE_ASSET_PRICE_MODIFIER_BPS + 1n, + }); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + const proposer = checkpointProposal.getSender(); + expect(proposer).toBeDefined(); + expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ + { + validator: proposer!, + amount: config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: BigInt(checkpointProposal.slotNumber), + }, + ]); + }); + + it.each([ + 'archive_mismatch', + 'out_hash_mismatch', + 'last_block_archive_mismatch', + 'checkpoint_validation_failed', + ])('emits checkpoint proposal slash event for %s', async reason => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const checkpointProposal = await makeCheckpointProposalForSlot(); + jest.spyOn(validatorClient.getProposalHandler(), 'handleCheckpointProposal').mockResolvedValue({ + isValid: false, + reason, + }); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + const proposer = checkpointProposal.getSender(); + expect(proposer).toBeDefined(); + expect(emitSpy).toHaveBeenCalledWith(WANT_TO_SLASH_EVENT, [ + { + validator: proposer!, + amount: config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType: OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, + epochOrSlot: BigInt(checkpointProposal.slotNumber), + }, + ]); + }); + + it('does not emit checkpoint proposal slash event when the penalty is disabled', async () => { + validatorClient.updateConfig({ slashBroadcastedInvalidCheckpointProposalPenalty: 0n }); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + const attestations = await validatorClient.attestToCheckpointProposal(checkpointProposal, sender); + + expect(attestations).toBeUndefined(); + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(0); + }); + + it.each(['last_block_not_found', 'checkpoint_already_published'])( + 'does not emit checkpoint proposal slash event for %s', + async reason => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const checkpointProposal = await makeCheckpointProposalForSlot(); + jest.spyOn(validatorClient.getProposalHandler(), 'handleCheckpointProposal').mockResolvedValue({ + isValid: false, + reason, + }); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(0); + }, + ); + + it('emits checkpoint proposal slash event once for repeated invalid proposals', async () => { + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(1); + }); + + it('emits slash event even if validator is not in the current committee', async () => { + epochCache.filterInCommittee.mockResolvedValue([]); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(1); + }); + + it('emits checkpoint proposal slash event in fisherman mode', async () => { + validatorClient.updateConfig({ fishermanMode: true }); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(1); + }); + + it('does not emit checkpoint proposal slash event while escape hatch is open', async () => { + epochCache.isEscapeHatchOpenAtSlot.mockResolvedValue(true); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(0); + }); + + it('does not emit checkpoint proposal slash event when checkpoint validation is skipped', async () => { + validatorClient.updateConfig({ skipCheckpointProposalValidation: true }); + const checkpointHandler = registerAllNodesCheckpointHandler(); + const { checkpointProposal } = await makeCheckpointProposalWithHeaderMismatch(); + const emitSpy = jest.spyOn(validatorClient, 'emit'); + + await checkpointHandler(checkpointProposal, sender); + + expect(getBroadcastedInvalidCheckpointProposalSlashEvents(emitSpy)).toHaveLength(0); + }); + it('should request txs for validating pinning the sender', async () => { const isValid = await validatorClient.validateBlockProposal(proposal, sender); expect(isValid).toBe(true); diff --git a/yarn-project/validator-client/src/validator.ts b/yarn-project/validator-client/src/validator.ts index cf8d510edd3a..c7721e1ea66f 100644 --- a/yarn-project/validator-client/src/validator.ts +++ b/yarn-project/validator-client/src/validator.ts @@ -5,6 +5,7 @@ import { CheckpointNumber, EpochNumber, IndexWithinCheckpoint, SlotNumber } from import { Fr } from '@aztec/foundation/curves/bn254'; import type { EthAddress } from '@aztec/foundation/eth-address'; import type { Signature } from '@aztec/foundation/eth-signature'; +import { FifoSet } from '@aztec/foundation/fifo-set'; import { type LogData, type Logger, createLogger } from '@aztec/foundation/log'; import { RunningPromise } from '@aztec/foundation/running-promise'; import { sleep } from '@aztec/foundation/sleep'; @@ -21,6 +22,7 @@ import { } from '@aztec/slasher'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { CommitteeAttestationsAndSigners, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; +import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers'; import type { ITxProvider, @@ -59,20 +61,50 @@ import { HAKeyStore } from './key_store/ha_key_store.js'; import type { ExtendedValidatorKeyStore } from './key_store/interface.js'; import { NodeKeystoreAdapter } from './key_store/node_keystore_adapter.js'; import { ValidatorMetrics } from './metrics.js'; -import { type BlockProposalValidationFailureReason, ProposalHandler } from './proposal_handler.js'; +import { + type BlockProposalValidationFailureReason, + type CheckpointProposalValidationFailureReason, + type CheckpointProposalValidationFailureResult, + ProposalHandler, +} from './proposal_handler.js'; // We maintain a set of proposers who have proposed invalid blocks. // Just cap the set to avoid unbounded growth. const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000; const MAX_TRACKED_INVALID_PROPOSAL_SLOTS = 1000; +const MAX_TRACKED_INVALID_CHECKPOINT_PROPOSALS = 1000; const MAX_TRACKED_BAD_ATTESTATIONS = 10_000; // What errors from the block proposal handler result in slashing const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT: BlockProposalValidationFailureReason[] = [ 'state_mismatch', 'failed_txs', + 'global_variables_mismatch', + 'invalid_proposal', + 'parent_block_wrong_slot', + 'in_hash_mismatch', ]; +const SLASHABLE_CHECKPOINT_PROPOSAL_VALIDATION_RESULT: Record = { + // enabled + ['invalid_fee_asset_price_modifier']: true, + ['checkpoint_header_mismatch']: true, + // These late mismatches should normally be caught by earlier checks, but if reached after validating the local + // checkpoint inputs, the proposer-signed payload disagrees with deterministic recomputation. + ['archive_mismatch']: true, + ['out_hash_mismatch']: true, + ['no_blocks_for_slot']: true, + ['too_many_blocks_in_checkpoint']: true, + ['checkpoint_validation_failed']: true, + ['last_block_archive_mismatch']: true, + + // disabled + ['invalid_signature']: false, + ['last_block_not_found']: false, + ['block_fetch_error']: false, + ['checkpoint_already_published']: false, +}; + /** * Validator Client */ @@ -95,10 +127,11 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) /** Tracks the last epoch in which each attester successfully submitted at least one attestation. */ private lastAttestedEpochByAttester: Map = new Map(); - private proposersOfInvalidBlocks: Set = new Set(); - private slotsWithInvalidBlockProposals: Set = new Set(); - private slotsWithProposalEquivocation: Set = new Set(); - private badAttestationOffenseKeys: Set = new Set(); + private proposersOfInvalidBlocks = FifoSet.withLimit(MAX_PROPOSERS_OF_INVALID_BLOCKS); + private slotsWithInvalidBlockProposals = FifoSet.withLimit(MAX_TRACKED_INVALID_PROPOSAL_SLOTS); + private invalidCheckpointProposalOffenseKeys = FifoSet.withLimit(MAX_TRACKED_INVALID_CHECKPOINT_PROPOSALS); + private slotsWithProposalEquivocation = FifoSet.withLimit(MAX_TRACKED_INVALID_PROPOSAL_SLOTS); + private badAttestationOffenseKeys = FifoSet.withLimit(MAX_TRACKED_BAD_ATTESTATIONS); /** Tracks the last checkpoint proposal we attested to, to prevent equivocation. */ private lastAttestedProposal?: CheckpointProposalCore; @@ -132,6 +165,9 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) this.getSignatureContext(), this.log.createChild('validation-service'), ); + this.proposalHandler.setCheckpointProposalValidationFailureCallback((proposal, result, proposalInfo) => + this.handleInvalidCheckpointProposal(proposal, result, proposalInfo), + ); // Refresh epoch cache every second to trigger alert if participation in committee changes this.epochCacheUpdateLoop = new RunningPromise(this.handleEpochCommitteeUpdate.bind(this), this.log, 1000); @@ -204,6 +240,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) txProvider: ITxProvider, keyStoreManager: KeystoreManager, blobClient: BlobClientInterface, + reexecutionTracker: CheckpointReexecutionTracker, dateProvider: DateProvider = new DateProvider(), telemetry: TelemetryClient = getTelemetryClient(), slashingProtectionDb?: SlashingProtectionDatabase, @@ -213,6 +250,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) txsPermitted: !config.disableTransactions, maxTxsPerBlock: config.validateMaxTxsPerBlock, maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint, + skipSlotValidation: config.skipProposalSlotValidation, signatureContext: { chainId: config.l1ChainId, rollupAddress: config.rollupAddress, @@ -228,6 +266,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) epochCache, config, blobClient, + reexecutionTracker, metrics, dateProvider, telemetry, @@ -317,6 +356,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) public updateConfig(config: Partial) { this.config = { ...this.config, ...config }; + this.proposalHandler.updateConfig(config); } public reloadKeystore(newManager: KeystoreManager): void { @@ -528,6 +568,11 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) return undefined; } + // Early-out for equivocation: refuses if we've already attested to a higher slot. + if (!this.shouldAttestToSlot(proposalSlotNumber)) { + return undefined; + } + // Ignore proposals from ourselves (may happen in HA setups) if (proposer && this.getValidatorAddresses().some(addr => addr.equals(proposer))) { this.log.debug(`Ignoring block proposal from self for slot ${proposalSlotNumber}`, { @@ -702,12 +747,6 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) return; } - // Trim the set if it's too big. - if (this.proposersOfInvalidBlocks.size > MAX_PROPOSERS_OF_INVALID_BLOCKS) { - // remove oldest proposer. `values` is guaranteed to be in insertion order. - this.proposersOfInvalidBlocks.delete(this.proposersOfInvalidBlocks.values().next().value!); - } - this.proposersOfInvalidBlocks.add(proposer.toString()); this.emit(WANT_TO_SLASH_EVENT, [ @@ -720,9 +759,57 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) ]); } + private handleInvalidCheckpointProposal( + proposal: CheckpointProposalCore, + result: CheckpointProposalValidationFailureResult, + proposalInfo: LogData, + ): void { + if (!SLASHABLE_CHECKPOINT_PROPOSAL_VALIDATION_RESULT[result.reason]) { + return; + } + + if (this.slashInvalidCheckpointProposal(proposal)) { + this.log.warn(`Slashing proposer for invalid checkpoint proposal`, { + ...proposalInfo, + reason: result.reason, + }); + } + } + + private slashInvalidCheckpointProposal(proposal: CheckpointProposalCore): boolean { + if (this.config.slashBroadcastedInvalidCheckpointProposalPenalty <= 0n) { + return false; + } + + const proposer = proposal.getSender(); + if (!proposer) { + this.log.warn(`Cannot slash checkpoint proposal with invalid signature`, { + slotNumber: proposal.slotNumber, + archive: proposal.archive.toString(), + }); + return false; + } + + const offenseType = OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL; + const offenseKey = `${proposer.toString()}:${offenseType}:${this.getSlotKey(proposal.slotNumber)}`; + if (!this.invalidCheckpointProposalOffenseKeys.addIfAbsent(offenseKey)) { + return false; + } + + this.emit(WANT_TO_SLASH_EVENT, [ + { + validator: proposer, + amount: this.config.slashBroadcastedInvalidCheckpointProposalPenalty, + offenseType, + epochOrSlot: BigInt(proposal.slotNumber), + }, + ]); + return true; + } + private markInvalidProposalSlot(slotNumber: SlotNumber): void { const slotKey = this.getSlotKey(slotNumber); - this.addToBoundedSet(this.slotsWithInvalidBlockProposals, slotKey, MAX_TRACKED_INVALID_PROPOSAL_SLOTS); + this.slotsWithInvalidBlockProposals.add(slotKey); } private handleCheckpointAttestation(attestation: CheckpointAttestation): void { @@ -750,7 +837,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) } const offenseKey = `${this.getSlotKey(slotNumber)}:${attester.toString()}`; - if (!this.addToBoundedSet(this.badAttestationOffenseKeys, offenseKey, MAX_TRACKED_BAD_ATTESTATIONS)) { + if (!this.badAttestationOffenseKeys.addIfAbsent(offenseKey)) { return; } @@ -776,7 +863,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) private handleDuplicateProposal(info: DuplicateProposalInfo): void { const { slot, proposer, type } = info; const slotKey = this.getSlotKey(slot); - this.addToBoundedSet(this.slotsWithProposalEquivocation, slotKey, MAX_TRACKED_INVALID_PROPOSAL_SLOTS); + this.slotsWithProposalEquivocation.add(slotKey); this.log.warn(`Triggering slash event for duplicate ${type} proposal from ${proposer.toString()} at slot ${slot}`, { proposer: proposer.toString(), @@ -828,17 +915,6 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) return slot.toString(); } - private addToBoundedSet(set: Set, value: string, maxSize: number): boolean { - if (set.has(value)) { - return false; - } - if (set.size >= maxSize) { - set.delete(set.values().next().value!); - } - set.add(value); - return true; - } - async createBlockProposal( blockHeader: BlockHeader, checkpointNumber: CheckpointNumber, @@ -876,7 +952,8 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) proposerAddress, { ...options, - broadcastInvalidBlockProposal: this.config.broadcastInvalidBlockProposal, + broadcastInvalidBlockProposal: + options.broadcastInvalidBlockProposal || this.config.broadcastInvalidBlockProposal, }, ); this.lastProposedBlock = newProposal; @@ -916,6 +993,13 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) options, ); this.lastProposedCheckpoint = newProposal; + // Self-record this slot's outcome on the re-execution tracker. Proposers don't run their + // own proposals through `handleCheckpointProposal`, so without this call the proposer's + // sentinel would see no outcome for slots it proposed and would mis-attribute itself as + // inactive. We pass the locally-computed `archive` (not `newProposal.archive`, which may + // be intentionally corrupted under test-only flags); from the proposer's local-view + // perspective the work it just completed is valid by definition. + this.proposalHandler.recordOwnCheckpointProposalAsValid(checkpointHeader.slotNumber, archive, checkpointNumber); return newProposal; } diff --git a/yarn-project/world-state/src/native/ipc_world_state_instance.ts b/yarn-project/world-state/src/native/ipc_world_state_instance.ts index 5489c80c37ce..cd4d20f1a003 100644 --- a/yarn-project/world-state/src/native/ipc_world_state_instance.ts +++ b/yarn-project/world-state/src/native/ipc_world_state_instance.ts @@ -279,28 +279,33 @@ export class IpcWorldState implements NativeWorldStateInstance { this.queues.set(forkId, requestQueue); } - const response = await requestQueue.execute( - async () => { - assert.notEqual(messageType, WorldStateMessageType.CLOSE, 'Use close() to close the IPC instance'); - assert.equal(this.open, true, 'IPC instance is closed'); - let response: WorldStateResponse[T]; - try { - response = await this._sendMessage(messageType, body); - } catch (error: any) { - errorHandler(error.message); - throw error; - } - return responseHandler(response); - }, - messageType, - committedOnly, - ); - - if (messageType === WorldStateMessageType.DELETE_FORK) { - await requestQueue.stop(); - this.queues.delete(forkId); + // The per-fork queue is cleaned up in `finally` even on error, so the JS-side queues map cannot outlive + // the native fork (e.g. when the native fork was already destroyed by an unwind/historical-prune and + // DELETE_FORK rejects with "Fork not found"). + try { + const response = await requestQueue.execute( + async () => { + assert.notEqual(messageType, WorldStateMessageType.CLOSE, 'Use close() to close the IPC instance'); + assert.equal(this.open, true, 'IPC instance is closed'); + let response: WorldStateResponse[T]; + try { + response = await this._sendMessage(messageType, body); + } catch (error: any) { + errorHandler(error.message); + throw error; + } + return responseHandler(response); + }, + messageType, + committedOnly, + ); + return response; + } finally { + if (messageType === WorldStateMessageType.DELETE_FORK) { + await requestQueue.stop(); + this.queues.delete(forkId); + } } - return response; } async close(): Promise { diff --git a/yarn-project/world-state/src/native/merkle_trees_facade.ts b/yarn-project/world-state/src/native/merkle_trees_facade.ts index 2cc687575e8f..2d32a8def90e 100644 --- a/yarn-project/world-state/src/native/merkle_trees_facade.ts +++ b/yarn-project/world-state/src/native/merkle_trees_facade.ts @@ -208,6 +208,7 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations { export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTreeWriteOperations { private log = createLogger('world-state:merkle-trees-fork-facade'); + private closePromise: Promise | undefined; constructor( instance: NativeWorldStateInstance, @@ -291,8 +292,17 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr }; } - public async close(): Promise { + public close(): Promise { assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set'); + // Share the in-flight close promise across duplicate dispose calls so DELETE_FORK is sent at most once. + if (this.closePromise) { + return this.closePromise; + } + this.closePromise = this.doClose(); + return this.closePromise; + } + + private async doClose(): Promise { try { await this.instance.call(WorldStateMessageType.DELETE_FORK, { forkId: this.revision.forkId }); } catch (err: any) { @@ -301,6 +311,12 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr if (err?.message === 'Native instance is closed') { return; } + // Ignore "Fork not found": the native fork was already destroyed by a pending-chain unwind or a + // historical prune (both call C++ remove_forks_for_block). Fork IDs are monotonic and never reused, + // so swallowing this on close cannot mask a deletion of a different fork. + if (err?.message === 'Fork not found') { + return; + } throw err; } } @@ -310,9 +326,6 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr void sleep(this.opts.closeDelayMs) .then(() => this.close()) .catch(err => { - if (err && 'message' in err && err.message === 'Native instance is closed') { - return; // Ignore errors due to native instance being closed - } this.log.warn('Error closing MerkleTreesForkFacade after delay', { err }); }); } else { diff --git a/yarn-project/world-state/src/native/native_world_state.test.ts b/yarn-project/world-state/src/native/native_world_state.test.ts index 47ff292af6c8..5acafa7d67b6 100644 --- a/yarn-project/world-state/src/native/native_world_state.test.ts +++ b/yarn-project/world-state/src/native/native_world_state.test.ts @@ -14,6 +14,7 @@ import { timesAsync } from '@aztec/foundation/collection'; import { randomBytes } from '@aztec/foundation/crypto/random'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { sleep } from '@aztec/foundation/sleep'; import type { SiblingPath } from '@aztec/foundation/trees'; import { PublicDataWrite } from '@aztec/stdlib/avm'; import { L2Block } from '@aztec/stdlib/block'; @@ -937,6 +938,33 @@ describe('NativeWorldState', () => { } } }); + + // Regression test for A-1055: a delayed-close fork that the C++ side has already destroyed (via + // remove_forks_for_block on an unwind or historical prune) must dispose silently rather than logging a + // warning, and its JS-side per-fork queue entry must be cleaned up. + it('does not fail when a delayed-close fork is destroyed by a reorg before its close fires', async () => { + const baseFork = await ws.fork(); + for (let i = 0; i < 3; i++) { + const { block, messages } = await mockBlock(BlockNumber(i + 1), 1, baseFork); + await ws.handleL2BlockAndMessages(block, messages); + } + await baseFork.close(); + + const closeDelayMs = 1000; + const delayedFork = await ws.fork(undefined, { closeDelayMs }); + const forkId = (delayedFork as any).revision.forkId; + const warnSpy = jest.spyOn((delayedFork as any).log, 'warn'); + + await (delayedFork as any)[Symbol.asyncDispose](); + + await ws.unwindBlocks(BlockNumber.fromBigInt(2n)); + await expect(delayedFork.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, 0n)).rejects.toThrow('Fork not found'); + + await sleep(closeDelayMs * 3); + + expect(warnSpy).not.toHaveBeenCalled(); + expect((ws as any).instance.queues.has(forkId)).toBe(false); + }); }); describe('Invalid Blocks', () => { diff --git a/yarn-project/world-state/src/native/native_world_state_instance.ts b/yarn-project/world-state/src/native/native_world_state_instance.ts index 6f4d60d0fd33..c4016ba1e477 100644 --- a/yarn-project/world-state/src/native/native_world_state_instance.ts +++ b/yarn-project/world-state/src/native/native_world_state_instance.ts @@ -184,30 +184,33 @@ export class NativeWorldState implements NativeWorldStateInstance { this.queues.set(forkId, requestQueue); } - // Enqueue the request and wait for the response - const response = await requestQueue.execute( - async () => { - assert.notEqual(messageType, WorldStateMessageType.CLOSE, 'Use close() to close the native instance'); - assert.equal(this.open, true, 'Native instance is closed'); - let response: WorldStateResponse[T]; - try { - response = await this._sendMessage(messageType, body); - } catch (error: any) { - errorHandler(error.message); - throw error; - } - return responseHandler(response); - }, - messageType, - committedOnly, - ); - - // If the request was to delete the fork then we clean it up here - if (messageType === WorldStateMessageType.DELETE_FORK) { - await requestQueue.stop(); - this.queues.delete(forkId); + // Enqueue the request and wait for the response. The per-fork queue is cleaned up in `finally` even on + // error, so the JS-side queues map cannot outlive the native fork (e.g. when the native fork was already + // destroyed by an unwind/historical-prune and DELETE_FORK rejects with "Fork not found"). + try { + const response = await requestQueue.execute( + async () => { + assert.notEqual(messageType, WorldStateMessageType.CLOSE, 'Use close() to close the native instance'); + assert.equal(this.open, true, 'Native instance is closed'); + let response: WorldStateResponse[T]; + try { + response = await this._sendMessage(messageType, body); + } catch (error: any) { + errorHandler(error.message); + throw error; + } + return responseHandler(response); + }, + messageType, + committedOnly, + ); + return response; + } finally { + if (messageType === WorldStateMessageType.DELETE_FORK) { + await requestQueue.stop(); + this.queues.delete(forkId); + } } - return response; } /**